Index: uspace/lib/libc/generic/device/char.c
===================================================================
--- uspace/lib/libc/generic/device/char.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
+++ uspace/lib/libc/generic/device/char.c	(revision bb864a054cda277111ac25d1509e68c165bf92a7)
@@ -50,5 +50,8 @@
 	aid_t req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_READ_DEV, &answer);
 	
+	printf("async_data_read_start \n");
 	int rc = async_data_read_start(dev_phone, buf, len);
+	
+	printf("async_data_read_start, rc = %d\n", rc);
 	if (rc != EOK) {
 		ipcarg_t rc_orig;
@@ -63,5 +66,7 @@
 	}
 	
+	printf("async_wait_for(req, &rc);\n", rc);
 	async_wait_for(req, &rc);
+	printf("async_serialize_end();\n", rc);
 	async_serialize_end();
 	
@@ -70,4 +75,5 @@
 	}
 	
+	printf("IPC_GET_ARG1(answer);\n", rc);
 	return IPC_GET_ARG1(answer);
 }
Index: uspace/lib/libdrv/generic/remote_char.c
===================================================================
--- uspace/lib/libdrv/generic/remote_char.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
+++ uspace/lib/libdrv/generic/remote_char.c	(revision bb864a054cda277111ac25d1509e68c165bf92a7)
@@ -85,5 +85,7 @@
 	}
 	
+	printf("remote_char_read - async_data_read_finalize\n");
 	async_data_read_finalize(callid, buf, ret);
+	printf("remote_char_read - ipc_answer_0(callid, EOK);\n");
 	ipc_answer_0(callid, EOK);	
 }
Index: uspace/srv/drivers/serial/serial.c
===================================================================
--- uspace/srv/drivers/serial/serial.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
+++ uspace/srv/drivers/serial/serial.c	(revision bb864a054cda277111ac25d1509e68c165bf92a7)
@@ -95,6 +95,18 @@
 {
 	printf(NAME ": serial_read %s\n", dev->name);
-	// TODO
-	return 0;
+	
+	int ret = 0;
+	
+	serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data;
+	fibril_mutex_lock(&data->mutex);
+	
+	while (!buf_is_empty(&data->input_buffer) && ret < count) {
+		buf[ret] = (char)buf_pop_front(&data->input_buffer);
+		ret++;
+	}
+	
+	fibril_mutex_unlock(&data->mutex);
+	
+	return ret;
 }
 
