Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision bc216a07a86e40d74455b7f4d6fb8f65e195443d)
+++ uspace/srv/hid/console/console.c	(revision 85d31de9fb7e4a793a91abe63f006b2fd2e81ece)
@@ -76,7 +76,11 @@
 } console_state_t;
 
+#define UTF8_CHAR_BUFFER_SIZE (STR_BOUNDS(1) + 1)
+
 typedef struct {
 	atomic_t refcnt;           /**< Connection reference count */
 	prodcons_t input_pc;       /**< Incoming keyboard events */
+	char char_remains[UTF8_CHAR_BUFFER_SIZE]; /**< Not yet sent bytes of last char event. */
+	size_t char_remains_len;   /**< Number of not yet sent bytes. */
 	
 	fibril_mutex_t mtx;        /**< Lock protecting mutable fields */
@@ -613,14 +617,37 @@
 	
 	size_t pos = 0;
+	
+	/*
+	 * Read input from keyboard and copy it to the buffer.
+	 * We need to handle situation when wchar is split by 2 following
+	 * reads.
+	 */
 	while (pos < size) {
-		link_t *link = prodcons_consume(&cons->input_pc);
-		kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
-		
-		if (event->type == KEY_PRESS) {
-			buf[pos] = event->c;
+		/* Copy to the buffer remaining characters. */
+		while ((pos < size) && (cons->char_remains_len > 0)) {
+			buf[pos] = cons->char_remains[0];
 			pos++;
-		}
-		
-		free(event);
+			
+			/* Unshift the array. */
+			for (size_t i = 1; i < cons->char_remains_len; i++)
+				cons->char_remains[i - 1] = cons->char_remains[i];
+			
+			cons->char_remains_len--;
+		}
+		
+		/* Still not enough? Then get another key from the queue. */
+		if (pos < size) {
+			link_t *link = prodcons_consume(&cons->input_pc);
+			kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
+			
+			/* Accept key presses of printable chars only. */
+			if ((event->type == KEY_PRESS) && (event->c != 0)) {
+				wchar_t tmp[2] = { event->c, 0 };
+				wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp);
+				cons->char_remains_len = str_size(cons->char_remains);
+			}
+			
+			free(event);
+		}
 	}
 	
@@ -930,4 +957,5 @@
 		fibril_mutex_initialize(&consoles[i].mtx);
 		prodcons_initialize(&consoles[i].input_pc);
+		consoles[i].char_remains_len = 0;
 		
 		if (graphics_state == GRAPHICS_FULL) {
Index: uspace/srv/hid/input/port/ns16550.c
===================================================================
--- uspace/srv/hid/input/port/ns16550.c	(revision bc216a07a86e40d74455b7f4d6fb8f65e195443d)
+++ uspace/srv/hid/input/port/ns16550.c	(revision 85d31de9fb7e4a793a91abe63f006b2fd2e81ece)
@@ -84,5 +84,5 @@
 	},
 	{
-		.cmd = CMD_BTEST,
+		.cmd = CMD_AND,
 		.value = LSR_DATA_READY,
 		.srcarg = 1,
Index: uspace/srv/hid/input/port/pl050.c
===================================================================
--- uspace/srv/hid/input/port/pl050.c	(revision bc216a07a86e40d74455b7f4d6fb8f65e195443d)
+++ uspace/srv/hid/input/port/pl050.c	(revision 85d31de9fb7e4a793a91abe63f006b2fd2e81ece)
@@ -80,5 +80,5 @@
 	},
 	{
-		.cmd = CMD_BTEST,
+		.cmd = CMD_AND,
 		.value = PL050_STAT_RXFULL,
 		.srcarg = 1,
