Index: uspace/app/test_serial/Makefile
===================================================================
--- uspace/app/test_serial/Makefile	(revision 7e752b2a0d66c871748e5fa9e8bbe3a27c70a202)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../..
-BINARY = test_serial
-
-SOURCES = \
-	test_serial.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/test_serial/test_serial.c
===================================================================
--- uspace/app/test_serial/test_serial.c	(revision 7e752b2a0d66c871748e5fa9e8bbe3a27c70a202)
+++ 	(revision )
@@ -1,167 +1,0 @@
-/*
- * Copyright (c) 2009 Lenka Trochtova
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup test_serial
- * @brief	test the serial port driver - read from the serial port
- * @{
- */
-/**
- * @file
- */
-
-#include <inttypes.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ipc/ipc.h>
-#include <sys/types.h>
-#include <async.h>
-#include <ipc/services.h>
-#include <ipc/devman.h>
-#include <devman.h>
-#include <device/char.h>
-#include <str.h>
-#include <ipc/serial_ctl.h>
-
-#define NAME 		"test serial"
-
-
-static void print_usage(void)
-{
-	printf("Usage: \n test_serial count \n where count is the number of "
-	    "characters to be read\n");
-}
-
-int main(int argc, char *argv[])
-{
-	if (argc != 2) {
-		printf(NAME ": incorrect number of arguments.\n");
-		print_usage();
-		return 0;
-	}
-	
-	long int cnt = strtol(argv[1], NULL, 10);
-	
-	int res;
-	res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
-	devman_handle_t handle;
-	
-	res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle,
-	    IPC_FLAG_BLOCKING);
-	if (EOK != res) {
-		printf(NAME ": could not get the device handle, errno = %d.\n",
-		    -res);
-		return 1;
-	}
-	
-	printf(NAME ": trying to read %ld characters from device with handle "
-	    "%" PRIun ".\n", cnt, handle);
-	
-	int phone = devman_device_connect(handle, IPC_FLAG_BLOCKING);
-	if (0 > phone) {
-		printf(NAME ": could not connect to the device, errno = %d.\n",
-		    -res);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		return 2;
-	}
-	
-	char *buf = (char *) malloc(cnt + 1);
-	if (NULL == buf) {
-		printf(NAME ": failed to allocate the input buffer\n");
-		ipc_hangup(phone);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		return 3;
-	}
-	
-	ipcarg_t old_baud, old_par, old_stop, old_word_size;
-	
-	res = ipc_call_sync_0_4(phone, SERIAL_GET_COM_PROPS, &old_baud,
-	    &old_par, &old_word_size, &old_stop);
-	if (EOK != res) {
-		printf(NAME ": failed to get old communication parameters, "
-		    "errno = %d.\n", -res);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		ipc_hangup(phone);
-		free(buf);
-		return 4;
-	}
-	
-	res = ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, 1200,
-	    SERIAL_NO_PARITY, 8, 1);
-	if (EOK != res) {
-		printf(NAME ": failed to set communication parameters, errno = "
-		    "%d.\n", -res);
-		devman_hangup_phone(DEVMAN_CLIENT);
-		ipc_hangup(phone);
-		free(buf);
-		return 4;
-	}
-	
-	int total = 0;
-	int read = 0;
-	while (total < cnt) {
-		read = read_dev(phone, buf, cnt - total);
-		if (0 > read) {
-			printf(NAME ": failed read from device, errno = %d.\n",
-			    -read);
-			ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
-			    old_par, old_word_size, old_stop);
-			ipc_hangup(phone);
-			devman_hangup_phone(DEVMAN_CLIENT);
-			free(buf);
-			return 5;
-		}
-		total += read;
-		if (read > 0) {
-			buf[read] = 0;
-			printf(buf);
-			/*
-			 * Write data back to the device to test the opposite
-			 * direction of data transfer.
-			 */
-			write_dev(phone, buf, read);
-		} else {
-			usleep(100000);
-		}	
-	}
-	
-	const char *the_end = "\n---------\nTHE END\n---------\n";
-	write_dev(phone, (void *)the_end, str_size(the_end));
-	
-	/* restore original communication settings */
-	ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud, old_par,
-	    old_word_size, old_stop);
-	devman_hangup_phone(DEVMAN_CLIENT);
-	ipc_hangup(phone);
-	free(buf);
-	
-	return 0;
-}
-
-/** @}
- */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 7e752b2a0d66c871748e5fa9e8bbe3a27c70a202)
+++ uspace/app/tester/Makefile	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
@@ -50,5 +50,6 @@
 	ipc/connect.c \
 	loop/loop1.c \
-	mm/malloc1.c
+	mm/malloc1.c \
+	hw/serial/serial1.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
+++ uspace/app/tester/hw/serial/serial1.c	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2009 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup tester
+ * @brief Test the serial port driver - loopback test
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <inttypes.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ipc/ipc.h>
+#include <sys/types.h>
+#include <async.h>
+#include <ipc/services.h>
+#include <ipc/devman.h>
+#include <devman.h>
+#include <device/char.h>
+#include <str.h>
+#include <ipc/serial_ctl.h>
+#include "../../tester.h"
+
+#define DEFAULT_COUNT  1024
+#define DEFAULT_SLEEP  100000
+#define EOT            "####> End of transfer <####\n"
+
+const char *test_serial1(void)
+{
+	size_t cnt;
+	
+	if (test_argc < 1)
+		cnt = DEFAULT_COUNT;
+	else
+		switch (str_size_t(test_argv[0], NULL, 0, true, &cnt)) {
+		case EOK:
+			break;
+		case EINVAL:
+			return "Invalid argument, unsigned integer expected";
+		case EOVERFLOW:
+			return "Argument size overflow";
+		default:
+			return "Unexpected argument error";
+		}
+	
+	int res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
+	
+	devman_handle_t handle;
+	res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle,
+	    IPC_FLAG_BLOCKING);
+	if (res != EOK)
+		return "Could not get serial device handle";
+	
+	int phone = devman_device_connect(handle, IPC_FLAG_BLOCKING);
+	if (phone < 0) {
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Unable to connect to serial device";
+	}
+	
+	char *buf = (char *) malloc(cnt + 1);
+	if (buf == NULL) {
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Failed to allocate input buffer";
+	}
+	
+	ipcarg_t old_baud;
+	ipcarg_t old_par;
+	ipcarg_t old_stop;
+	ipcarg_t old_word_size;
+	
+	res = ipc_call_sync_0_4(phone, SERIAL_GET_COM_PROPS, &old_baud,
+	    &old_par, &old_word_size, &old_stop);
+	if (res != EOK) {
+		free(buf);
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Failed to get old serial communication parameters";
+	}
+	
+	res = ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, 1200,
+	    SERIAL_NO_PARITY, 8, 1);
+	if (EOK != res) {
+		free(buf);
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return "Failed to set serial communication parameters";
+	}
+	
+	TPRINTF("Trying to read %zu characters from serial device "
+	    "(handle=%" PRIun ")\n", cnt, handle);
+	
+	size_t total = 0;
+	while (total < cnt) {
+		ssize_t read = read_dev(phone, buf, cnt - total);
+		
+		if (read < 0) {
+			ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+			    old_par, old_word_size, old_stop);
+			free(buf);
+			ipc_hangup(phone);
+			devman_hangup_phone(DEVMAN_CLIENT);
+			return "Failed read from serial device";
+		}
+		
+		if ((size_t) read > cnt - total) {
+			ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+			    old_par, old_word_size, old_stop);
+			free(buf);
+			ipc_hangup(phone);
+			devman_hangup_phone(DEVMAN_CLIENT);
+			return "Read more data than expected";
+		}
+		
+		TPRINTF("Read %zd bytes\n", read);
+		
+		if (read == 0)
+			usleep(DEFAULT_SLEEP);
+		else {
+			buf[read] = 0;
+			
+			/*
+			 * Write data back to the device to test the opposite
+			 * direction of data transfer.
+			 */
+			ssize_t written = write_dev(phone, buf, read);
+			
+			if (written < 0) {
+				ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+				    old_par, old_word_size, old_stop);
+				free(buf);
+				ipc_hangup(phone);
+				devman_hangup_phone(DEVMAN_CLIENT);
+				return "Failed write to serial device";
+			}
+			
+			if (written != read) {
+				ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+				    old_par, old_word_size, old_stop);
+				free(buf);
+				ipc_hangup(phone);
+				devman_hangup_phone(DEVMAN_CLIENT);
+				return "Written less data than read from serial device";
+			}
+			
+			TPRINTF("Written %zd bytes\n", written);
+		}
+		
+		total += read;
+	}
+	
+	TPRINTF("Trying to write EOT banner to the serial device\n");
+	
+	size_t eot_size = str_size(EOT);
+	ssize_t written = write_dev(phone, (void *) EOT, eot_size);
+	
+	ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
+	    old_par, old_word_size, old_stop);
+	free(buf);
+	ipc_hangup(phone);
+	devman_hangup_phone(DEVMAN_CLIENT);
+	
+	if (written < 0)
+		return "Failed to write EOT banner to serial device";
+	
+	if ((size_t) written != eot_size)
+		return "Written less data than the size of the EOT banner "
+		    "to serial device";
+	
+	return NULL;
+}
+
+/** @}
+ */
Index: uspace/app/tester/hw/serial/serial1.def
===================================================================
--- uspace/app/tester/hw/serial/serial1.def	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
+++ uspace/app/tester/hw/serial/serial1.def	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
@@ -0,0 +1,6 @@
+{
+	"serial1",
+	"Serial loopback test",
+	&test_serial1,
+	false
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 7e752b2a0d66c871748e5fa9e8bbe3a27c70a202)
+++ uspace/app/tester/tester.c	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
@@ -64,4 +64,5 @@
 #include "loop/loop1.def"
 #include "mm/malloc1.def"
+#include "hw/serial/serial1.def"
 	{NULL, NULL, NULL, false}
 };
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 7e752b2a0d66c871748e5fa9e8bbe3a27c70a202)
+++ uspace/app/tester/tester.h	(revision 6ec0acda16c7d0a65518b4b1da94518f72ebcf73)
@@ -81,4 +81,5 @@
 extern const char *test_loop1(void);
 extern const char *test_malloc1(void);
+extern const char *test_serial1(void);
 
 extern test_t tests[];
