Index: uspace/drv/hid/atkbd/atkbd.c
===================================================================
--- uspace/drv/hid/atkbd/atkbd.c	(revision 75fcf9b27d99c2f3e80a459094fb3bfaef7304f4)
+++ uspace/drv/hid/atkbd/atkbd.c	(revision 5d50c419de1e8d7b6b57065ea652ba23b83e5a97)
@@ -203,9 +203,11 @@
 {
 	at_kbd_t *kbd = arg;
+	size_t nwr;
+	int rc;
 	
 	while (true) {
 		uint8_t code = 0;
-		ssize_t size = chardev_read(kbd->chardev, &code, 1);
-		if (size != 1)
+		rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+		if (rc != EOK)
 			return EIO;
 		
@@ -217,46 +219,46 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 			
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 		} else if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code != 0x14)
 				continue;
 
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code != 0x77)
 				continue;
 
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code != 0xe1)
 				continue;
 
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code != 0xf0)
 				continue;
 
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code != 0x14)
 				continue;
 
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code != 0xf0)
 				continue;
 
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 			if (code == 0x77)
@@ -272,6 +274,6 @@
 		if (code == KBD_SCANCODE_KEY_RELEASE) {
 			type = KEY_RELEASE;
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			if (rc != EOK)
 				return EIO;
 		} else {
Index: uspace/drv/hid/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/hid/ps2mouse/ps2mouse.c	(revision 75fcf9b27d99c2f3e80a459094fb3bfaef7304f4)
+++ uspace/drv/hid/ps2mouse/ps2mouse.c	(revision 5d50c419de1e8d7b6b57065ea652ba23b83e5a97)
@@ -75,8 +75,9 @@
 	uint8_t value = (value_); \
 	uint8_t data = 0; \
-	const ssize_t size = chardev_read((mouse)->chardev, &data, 1); \
-	if (size != 1) { \
-		ddf_msg(LVL_ERROR, "Failed reading byte: %zd)", size);\
-		return size < 0 ? size : EIO; \
+	size_t nread; \
+	const int rc = chardev_read((mouse)->chardev, &data, 1, &nread); \
+	if (rc != EOK) { \
+		ddf_msg(LVL_ERROR, "Failed reading byte: %d", rc);\
+		return rc; \
 	} \
 	if (data != value) { \
@@ -91,8 +92,9 @@
 	uint8_t value = (value_); \
 	uint8_t data = (value); \
-	const ssize_t size = chardev_write((mouse)->chardev, &data, 1); \
-	if (size < 0 ) { \
-		ddf_msg(LVL_ERROR, "Failed writing byte: %hhx", value); \
-		return size; \
+	size_t nwr; \
+	const int rc = chardev_write((mouse)->chardev, &data, 1, &nwr); \
+	if (rc != EOK) { \
+		ddf_msg(LVL_ERROR, "Failed writing byte: %d", rc); \
+		return rc; \
 	} \
 } while (0)
@@ -172,6 +174,7 @@
 	/* Enable mouse data reporting. */
 	uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
-	ssize_t size = chardev_write(mouse->chardev, &report, 1);
-	if (size != 1) {
+	size_t nwr;
+	rc = chardev_write(mouse->chardev, &report, 1, &nwr);
+	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed to enable data reporting.");
 		rc = EIO;
@@ -179,6 +182,7 @@
 	}
 
-	size = chardev_read(mouse->chardev, &report, 1);
-	if (size != 1 || report != PS2_MOUSE_ACK) {
+	size_t nread;
+	rc = chardev_read(mouse->chardev, &report, 1, &nread);
+	if (rc != EOK || report != PS2_MOUSE_ACK) {
 		ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.",
 		    report);
@@ -215,15 +219,16 @@
 {
 	ps2_mouse_t *mouse = (ps2_mouse_t *) arg;
+	size_t nread;
+	int rc;
 
 	bool buttons[PS2_BUTTON_COUNT] = {};
 	while (1) {
 		uint8_t packet[PS2_BUFSIZE] = {};
-		const ssize_t size =
-		    chardev_read(mouse->chardev, packet, PS2_BUFSIZE);
-
-		if (size != PS2_BUFSIZE) {
-			ddf_msg(LVL_WARN, "Incorrect packet size: %zd.", size);
+		rc = chardev_read(mouse->chardev, packet, PS2_BUFSIZE, &nread);
+		if (rc != EOK || nread != PS2_BUFSIZE) {
+			ddf_msg(LVL_WARN, "Incorrect packet size: %zd.", nread);
 			continue;
 		}
+
 		ddf_msg(LVL_DEBUG2, "Got packet: %hhx:%hhx:%hhx.",
 		    packet[0], packet[1], packet[2]);
@@ -269,13 +274,14 @@
 {
 	ps2_mouse_t *mouse = (ps2_mouse_t *) arg;
+	size_t nread;
+	int rc;
 
 	bool buttons[INTELLIMOUSE_BUTTON_COUNT] = {};
 	while (1) {
 		uint8_t packet[INTELLIMOUSE_BUFSIZE] = {};
-		const ssize_t size = chardev_read(
-		    mouse->chardev, packet, INTELLIMOUSE_BUFSIZE);
-
-		if (size != INTELLIMOUSE_BUFSIZE) {
-			ddf_msg(LVL_WARN, "Incorrect packet size: %zd.", size);
+		rc = chardev_read(mouse->chardev, packet, INTELLIMOUSE_BUFSIZE,
+		    &nread);
+		if (rc != EOK || nread != INTELLIMOUSE_BUFSIZE) {
+			ddf_msg(LVL_WARN, "Incorrect packet size: %zd.", nread);
 			continue;
 		}
Index: uspace/drv/hid/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/hid/xtkbd/xtkbd.c	(revision 75fcf9b27d99c2f3e80a459094fb3bfaef7304f4)
+++ uspace/drv/hid/xtkbd/xtkbd.c	(revision 5d50c419de1e8d7b6b57065ea652ba23b83e5a97)
@@ -208,4 +208,6 @@
 {
 	xt_kbd_t *kbd = arg;
+	size_t nread;
+	int rc;
 	
 	while (true) {
@@ -214,6 +216,6 @@
 		
 		uint8_t code = 0;
-		ssize_t size = chardev_read(kbd->chardev, &code, 1);
-		if (size != 1)
+		rc = chardev_read(kbd->chardev, &code, 1, &nread);
+		if (rc != EOK)
 			return EIO;
 		
@@ -227,6 +229,6 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 			
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			if (rc != EOK)
 				return EIO;
 			
@@ -234,6 +236,6 @@
 			
 			if (code == 0x2a) {  /* Print Screen */
-				size = chardev_read(kbd->chardev, &code, 1);
-				if (size != 1)
+				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				if (rc != EOK)
 					return EIO;
 				
@@ -241,6 +243,6 @@
 					continue;
 				
-				size = chardev_read(kbd->chardev, &code, 1);
-				if (size != 1)
+				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				if (rc != EOK)
 					return EIO;
 				
@@ -252,6 +254,6 @@
 			
 			if (code == 0x46) {  /* Break */
-				size = chardev_read(kbd->chardev, &code, 1);
-				if (size != 1)
+				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				if (rc != EOK)
 					return EIO;
 				
@@ -259,6 +261,6 @@
 					continue;
 				
-				size = chardev_read(kbd->chardev, &code, 1);
-				if (size != 1)
+				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				if (rc != EOK)
 					return EIO;
 				
@@ -272,6 +274,6 @@
 		/* Extended special set */
 		if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			if (rc != EOK)
 				return EIO;
 			
@@ -279,6 +281,6 @@
 				continue;
 			
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			if (rc != EOK)
 				return EIO;
 			
@@ -286,6 +288,6 @@
 				continue;
 			
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			if (rc != EOK)
 				return EIO;
 			
@@ -293,6 +295,6 @@
 				continue;
 			
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			if (rc != EOK)
 				return EIO;
 			
@@ -300,6 +302,6 @@
 				continue;
 			
-			size = chardev_read(kbd->chardev, &code, 1);
-			if (size != 1)
+			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			if (rc != EOK)
 				return EIO;
 			
@@ -350,7 +352,10 @@
 		uint8_t cmds[] = { KBD_CMD_SET_LEDS, status };
 		
-		ssize_t size = chardev_write(kbd->chardev, cmds, sizeof(cmds));
-		
-		async_answer_0(icallid, size < 0 ? size : EOK);
+		size_t nwr;
+		int rc = chardev_write(kbd->chardev, cmds, sizeof(cmds), &nwr);
+		if (nwr != sizeof(cmds))
+			rc = EIO;
+
+		async_answer_0(icallid, rc);
 		break;
 	}
Index: uspace/lib/c/generic/io/chardev.c
===================================================================
--- uspace/lib/c/generic/io/chardev.c	(revision 75fcf9b27d99c2f3e80a459094fb3bfaef7304f4)
+++ uspace/lib/c/generic/io/chardev.c	(revision 5d50c419de1e8d7b6b57065ea652ba23b83e5a97)
@@ -40,4 +40,5 @@
 #include <io/chardev.h>
 #include <ipc/chardev.h>
+#include <stddef.h>
 #include <stdlib.h>
 
@@ -76,5 +77,5 @@
 }
 
-ssize_t chardev_read(chardev_t *chardev, void *data, size_t size)
+int chardev_read(chardev_t *chardev, void *data, size_t size, size_t *nread)
 {
 	if (size > 4 * sizeof(sysarg_t))
@@ -88,8 +89,16 @@
 	if (ret > 0 && (size_t)ret <= size)
 		memcpy(data, message, size);
-	return ret;
+
+	if (ret < 0) {
+		*nread = 0;
+		return ret;
+	}
+
+	*nread = ret;
+	return EOK;
 }
 
-ssize_t chardev_write(chardev_t *chardev, const void *data, size_t size)
+int chardev_write(chardev_t *chardev, const void *data, size_t size,
+    size_t *nwritten)
 {
 	int ret;
@@ -104,5 +113,12 @@
 	    message[0], message[1], message[2]);
 	async_exchange_end(exch);
-	return ret;
+
+	if (ret < 0) {
+		*nwritten = 0;
+		return ret;
+	}
+
+	*nwritten = ret;
+	return EOK;
 }
 
Index: uspace/lib/c/include/io/chardev.h
===================================================================
--- uspace/lib/c/include/io/chardev.h	(revision 75fcf9b27d99c2f3e80a459094fb3bfaef7304f4)
+++ uspace/lib/c/include/io/chardev.h	(revision 5d50c419de1e8d7b6b57065ea652ba23b83e5a97)
@@ -35,5 +35,5 @@
 
 #include <async.h>
-#include <types/common.h>
+#include <stddef.h>
 
 typedef struct {
@@ -43,6 +43,6 @@
 extern int chardev_open(async_sess_t *, chardev_t **);
 extern void chardev_close(chardev_t *);
-extern ssize_t chardev_read(chardev_t *, void *, size_t);
-extern ssize_t chardev_write(chardev_t *, const void *, size_t);
+extern int chardev_read(chardev_t *, void *, size_t, size_t *);
+extern int chardev_write(chardev_t *, const void *, size_t, size_t *);
 
 #endif
