Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ HelenOS.config	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -393,2 +393,7 @@
 % External ramdisk
 ! [PLATFORM=sparc64] CONFIG_RD_EXTERNAL (y/n)
+
+% Keyboard layout
+@ "us_qwerty" US QWERTY
+@ "us_dvorak" US Dvorak
+! KBD_LAYOUT (choice)
Index: uspace/lib/libc/generic/io/stream.c
===================================================================
--- uspace/lib/libc/generic/io/stream.c	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/lib/libc/generic/io/stream.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -68,5 +68,5 @@
 				rc = kbd_get_event(&ev);
 				if (rc < 0) return -1;
-			} while (ev.c == 0);
+			} while (ev.c == 0 || ev.type == KE_RELEASE);
 
 			((char *) buf)[i++] = ev.c;
Index: uspace/lib/libc/generic/kbd.c
===================================================================
--- uspace/lib/libc/generic/kbd.c	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/lib/libc/generic/kbd.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -51,7 +51,7 @@
 
 	ev->type = r0;
-	ev->c = r1;
-	ev->key = r2;
-	ev->mods = r3;
+	ev->key = r1;
+	ev->mods = r2;
+	ev->c = r3;
 
 	return 0;
Index: uspace/lib/libc/include/kbd/keycode.h
===================================================================
--- uspace/lib/libc/include/kbd/keycode.h	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/lib/libc/include/kbd/keycode.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -55,5 +55,5 @@
 	/* Main block row 1 */
 
-	KC_BACKTICK,
+	KC_BACKTICK = 1,
 
 	KC_1,
Index: uspace/srv/console/console.c
===================================================================
--- uspace/srv/console/console.c	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/srv/console/console.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -37,4 +37,5 @@
 #include <ipc/ipc.h>
 #include <keys.h>
+#include <kbd/keycode.h>
 #include <ipc/fb.h>
 #include <ipc/services.h>
@@ -332,10 +333,10 @@
 			conn = &connections[active_console];
 
-			if ((ev.key >= 0x101) && (ev.key < 0x101 +
+			if ((ev.key >= KC_F1) && (ev.key < KC_F1 +
 			    CONSOLE_COUNT)) {
-				if (ev.key == 0x112)
+				if (ev.key == KC_F12)
 					change_console(KERNEL_CONSOLE);
 				else
-					change_console(ev.key - 0x101);
+					change_console(ev.key - KC_F1);
 				break;
 			}
Index: uspace/srv/kbd/Makefile
===================================================================
--- uspace/srv/kbd/Makefile	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/srv/kbd/Makefile	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -47,52 +47,117 @@
 	generic/key_buffer.c
 
-ARCH_SOURCES = \
-	arch/$(UARCH)/src/kbd.c
-
+ARCH_SOURCES =
+GENARCH_SOURCES =
+
+ifeq ($(KBD_LAYOUT), us_qwerty)
+	GENARCH_SOURCES += layout/us_qwerty.c
+endif
+ifeq ($(KBD_LAYOUT), us_dvorak)
+	GENARCH_SOURCES += layout/us_dvorak.c
+endif
+
+ifeq ($(UARCH), amd64)
+	GENARCH_SOURCES += \
+		port/i8042.c \
+		ctl/pc.c
+endif
+ifeq ($(UARCH), arm32)
+	GENARCH_SOURCES += \
+		port/gxemul.c
+	ifeq ($(CONFIG_FB), y)
+		GENARCH_SOURCES += \
+			ctl/gxe_fb.c
+	else
+		GENARCH_SOURCES += \
+			ctl/stty.c
+	endif
+endif
 ifeq ($(UARCH), ia32)
-	ARCH_SOURCES += \
-		arch/$(UARCH)/src/mouse.c \
-		arch/$(UARCH)/src/scanc.c
-	GENARCH_SOURCES = \
-		genarch/src/kbd.c
-	CFLAGS += -DMOUSE_ENABLED
+	GENARCH_SOURCES += \
+		port/i8042.c \
+		ctl/pc.c
 endif
 ifeq ($(UARCH), ia64)
-	ARCH_SOURCES += \
-		arch/$(UARCH)/src/mouse.c \
-		arch/$(UARCH)/src/scanc.c \
-		arch/$(UARCH)/src/lkbd.c
-	GENARCH_SOURCES = \
-		genarch/src/kbd.c
-	CFLAGS += -DMOUSE_ENABLED
-endif
-ifeq ($(UARCH), amd64)
-	ARCH_SOURCES += \
-		arch/$(UARCH)/src/mouse.c \
-		arch/$(UARCH)/src/scanc.c
-	GENARCH_SOURCES = \
-		genarch/src/kbd.c
-	CFLAGS += -DMOUSE_ENABLED
+	GENARCH_SOURCES += \
+		port/dummy.c \
+		ctl/stty.c
+endif
+ifeq ($(MACHINE), msim)
+	GENARCH_SOURCES += \
+		port/msim.c \
+		ctl/stty.c
+endif
+ifeq ($(MACHINE), lgxemul)
+	GENARCH_SOURCES += \
+		port/gxemul.c
+	ifeq ($(CONFIG_FB), y)
+		GENARCH_SOURCES += \
+			ctl/gxe_fb.c
+	else
+		GENARCH_SOURCES += \
+			ctl/stty.c
+	endif
+endif
+ifeq ($(MACHINE), bgxemul)
+	GENARCH_SOURCES += \
+		port/gxemul.c \
+		ctl/stty.c
+endif
+ifeq ($(UARCH), ppc32)
+	GENARCH_SOURCES += \
+		port/dummy.c \
+		ctl/stty.c
 endif
 ifeq ($(UARCH), sparc64)
-	ARCH_SOURCES += \
-		arch/$(UARCH)/src/scanc.c \
-		arch/$(UARCH)/src/sgcn.c
-	GENARCH_SOURCES = \
-		genarch/src/kbd.c \
-		genarch/src/nofb.c
-endif
-ifeq ($(UARCH), arm32)
-	ARCH_SOURCES += \
-		arch/$(UARCH)/src/kbd_gxemul.c
-endif
-ifeq ($(UARCH), mips32)
-	GENARCH_SOURCES += \
-	    genarch/src/nofb.c
-endif
-ifeq ($(UARCH), mips32eb)
-	GENARCH_SOURCES += \
-	    genarch/src/nofb.c
-endif
+	GENARCH_SOURCES += \
+		port/dummy.c \
+		ctl/stty.c
+endif
+
+# ifeq ($(UARCH), ia32)
+# 	ARCH_SOURCES += \
+# 		arch/$(UARCH)/src/mouse.c \
+# 		arch/$(UARCH)/src/scanc.c
+# 	GENARCH_SOURCES = \
+# 		genarch/src/kbd.c
+# 	CFLAGS += -DMOUSE_ENABLED
+# endif
+# ifeq ($(UARCH), ia64)
+# 	ARCH_SOURCES += \
+# 		arch/$(UARCH)/src/mouse.c \
+# 		arch/$(UARCH)/src/scanc.c \
+# 		arch/$(UARCH)/src/lkbd.c
+# 	GENARCH_SOURCES = \
+# 		genarch/src/kbd.c
+# 	CFLAGS += -DMOUSE_ENABLED
+# endif
+# ifeq ($(UARCH), amd64)
+# 	ARCH_SOURCES += \
+# 		arch/$(UARCH)/src/mouse.c \
+# 		arch/$(UARCH)/src/scanc.c
+# 	GENARCH_SOURCES = \
+# 		genarch/src/kbd.c
+# 	CFLAGS += -DMOUSE_ENABLED
+# endif
+# ifeq ($(UARCH), sparc64)
+# 	ARCH_SOURCES += \
+# 		arch/$(UARCH)/src/scanc.c \
+# 		arch/$(UARCH)/src/sgcn.c
+# 	GENARCH_SOURCES = \
+# 		genarch/src/kbd.c \
+# 		genarch/src/nofb.c
+# endif
+# ifeq ($(UARCH), arm32)
+# 	ARCH_SOURCES += \
+# 		arch/$(UARCH)/src/kbd_gxemul.c
+# endif
+# ifeq ($(UARCH), mips32)
+# 	GENARCH_SOURCES += \
+# 	    genarch/src/nofb.c
+# endif
+# ifeq ($(UARCH), mips32eb)
+# 	GENARCH_SOURCES += \
+# 	    genarch/src/nofb.c
+# endif
 
 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
Index: uspace/srv/kbd/ctl/gxe_fb.c
===================================================================
--- uspace/srv/kbd/ctl/gxe_fb.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/ctl/gxe_fb.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbd
+ * @brief	GXEmul framebuffer-mode keyboard controller driver.
+ * @{
+ */ 
+
+#include <kbd.h>
+#include <kbd/kbd.h>
+#include <kbd/keycode.h>
+#include <kbd_ctl.h>
+
+static void parse_ds_start(int scancode);
+static void parse_ds_e(int scancode);
+static void parse_ds_e1(int scancode);
+static void parse_ds_e1a(int scancode);
+static void parse_ds_e1b(int scancode);
+static void parse_ds_e1c(int scancode);
+
+static void parse_leaf(int scancode, int *map, size_t map_length);
+
+enum dec_state {
+	ds_start,
+	ds_e,
+	ds_e1,
+	ds_e1a,
+	ds_e1b,
+	ds_e1c
+};
+
+static int map_start[] = {
+
+	[0x60] = KC_BACKTICK,
+
+	[0x31] = KC_1,
+	[0x32] = KC_2,
+	[0x33] = KC_3,
+	[0x34] = KC_4,
+	[0x35] = KC_5,
+	[0x36] = KC_6,
+	[0x37] = KC_7,
+	[0x38] = KC_8,
+	[0x39] = KC_9,
+	[0x30] = KC_0,
+
+	[0x2d] = KC_MINUS,
+	[0x3d] = KC_EQUALS,
+	[0x08] = KC_BACKSPACE,
+
+	[0x0f] = KC_TAB,
+
+	[0x71] = KC_Q,
+	[0x77] = KC_W,
+	[0x65] = KC_E,
+	[0x72] = KC_R,
+	[0x74] = KC_T,
+	[0x79] = KC_Y,
+	[0x75] = KC_U,
+	[0x69] = KC_I,
+	[0x6f] = KC_O,
+	[0x70] = KC_P,
+
+	[0x5b] = KC_LBRACKET,
+	[0x5d] = KC_RBRACKET,
+
+//	[0x3a] = KC_CAPS_LOCK,
+
+	[0x61] = KC_A,
+	[0x73] = KC_S,
+	[0x64] = KC_D,
+	[0x66] = KC_F,
+	[0x67] = KC_G,
+	[0x68] = KC_H,
+	[0x6a] = KC_J,
+	[0x6b] = KC_K,
+	[0x6c] = KC_L,
+
+	[0x3b] = KC_SEMICOLON,
+	[0x27] = KC_QUOTE,
+	[0x5c] = KC_BACKSLASH,
+
+//	[0x2a] = KC_LSHIFT,
+
+	[0x7a] = KC_Z,
+	[0x78] = KC_X,
+	[0x63] = KC_C,
+	[0x76] = KC_V,
+	[0x62] = KC_B,
+	[0x6e] = KC_N,
+	[0x6d] = KC_M,
+
+	[0x2c] = KC_COMMA,
+	[0x2e] = KC_PERIOD,
+	[0x2f] = KC_SLASH,
+
+//	[0x36] = KC_RSHIFT,
+
+//	[0x1d] = KC_LCTRL,
+//	[0x38] = KC_LALT,
+	[0x20] = KC_SPACE,
+
+	[0x1b] = KC_ESCAPE,
+
+	[0x0a] = KC_ENTER,
+	[0x0d] = KC_ENTER
+
+/*
+	[0x1] = KC_PRNSCR,
+	[0x1] = KC_SCROLL_LOCK,
+	[0x1] = KC_PAUSE,
+*/
+};
+
+static int map_e1[] =
+{
+};
+
+static int map_e1a[] =
+{
+	[0x50] = KC_F1,
+	[0x51] = KC_F2,
+	[0x52] = KC_F3,
+	[0x53] = KC_F4,
+};
+
+static int map_e1b[] =
+{
+	[0x33] = KC_F5,
+	[0x37] = KC_F6,
+	[0x38] = KC_F7,
+	[0x39] = KC_F8,
+};
+
+static int map_e1c[] =
+{
+	[0x38] = KC_F9,
+	[0x39] = KC_F10,
+	[0x33] = KC_F11,
+	[0x34] = KC_F12,
+};
+
+
+static enum dec_state ds = ds_start;
+
+void kbd_ctl_parse_scancode(int scancode)
+{
+	switch (ds) {
+	case ds_start:	parse_ds_start(scancode); break;
+	case ds_e: 	parse_ds_e(scancode); break;
+	case ds_e1:	parse_ds_e1(scancode); break;
+	case ds_e1a:	parse_ds_e1a(scancode); break;
+	case ds_e1b:	parse_ds_e1b(scancode); break;
+	case ds_e1c:	parse_ds_e1c(scancode); break;
+	}
+}
+
+static void parse_ds_start(int scancode)
+{
+	if (scancode == 0x1b) {
+		ds = ds_e;
+		return;
+	}
+
+	parse_leaf(scancode, map_start, sizeof(map_start) / sizeof(int));
+}
+
+static void parse_ds_e(int scancode)
+{
+	switch (scancode) {
+	case 0x5b: ds = ds_e1; return;
+	case 0x1b: ds = ds_start; break;
+	default: ds = ds_start; return;
+	}
+
+	kbd_push_ev(KE_PRESS, KC_ESCAPE, 0);
+}
+
+static void parse_ds_e1(int scancode)
+{
+	switch (scancode) {
+	case 0x4f: ds = ds_e1a; return;
+	case 0x31: ds = ds_e1b; return;
+	case 0x32: ds = ds_e1c; return;
+	default: ds = ds_start; break;
+	}
+
+	parse_leaf(scancode, map_e1, sizeof(map_e1) / sizeof(int));
+}
+
+static void parse_ds_e1a(int scancode)
+{
+	parse_leaf(scancode, map_e1a, sizeof(map_e1a) / sizeof(int));
+}
+
+static void parse_ds_e1b(int scancode)
+{
+	parse_leaf(scancode, map_e1b, sizeof(map_e1b) / sizeof(int));
+}
+
+static void parse_ds_e1c(int scancode)
+{
+	parse_leaf(scancode, map_e1c, sizeof(map_e1c) / sizeof(int));
+}
+
+static void parse_leaf(int scancode, int *map, size_t map_length)
+{
+	unsigned int key;
+
+	ds = ds_start;
+
+	if (scancode < 0 || scancode >= map_length)
+		return;
+
+	key = map[scancode];
+	if (key != 0)
+		kbd_push_ev(KE_PRESS, key, 0);
+}
+
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/ctl/pc.c
===================================================================
--- uspace/srv/kbd/ctl/pc.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/ctl/pc.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbd
+ * @brief	PC keyboard controller driver.
+ * @{
+ */ 
+
+#include <kbd.h>
+#include <kbd/kbd.h>
+#include <kbd/keycode.h>
+#include <kbd_ctl.h>
+
+int scanmap_simple[];
+
+void kbd_ctl_parse_scancode(int scancode)
+{
+	kbd_ev_type_t type;
+	unsigned int key;
+
+	if (scancode < 0 || scancode >= 0x100) return;
+
+	if (scancode & 0x80) {
+		scancode &= ~0x80;
+		type = KE_RELEASE;
+	} else {
+		type = KE_PRESS;
+	}
+
+	key = scanmap_simple[scancode];
+	if (key != 0)
+		kbd_push_ev(type, key, 0);
+}
+
+int scanmap_simple[128] = {
+
+	[0x29] = KC_BACKTICK,
+
+	[0x02] = KC_1,
+	[0x03] = KC_2,
+	[0x04] = KC_3,
+	[0x05] = KC_4,
+	[0x06] = KC_5,
+	[0x07] = KC_6,
+	[0x08] = KC_7,
+	[0x09] = KC_8,
+	[0x0a] = KC_9,
+	[0x0b] = KC_0,
+
+	[0x0c] = KC_MINUS,
+	[0x0d] = KC_EQUALS,
+	[0x0e] = KC_BACKSPACE,
+
+	[0x0f] = KC_TAB,
+
+	[0x10] = KC_Q,
+	[0x11] = KC_W,
+	[0x12] = KC_E,
+	[0x13] = KC_R,
+	[0x14] = KC_T,
+	[0x15] = KC_Y,
+	[0x16] = KC_U,
+	[0x17] = KC_I,
+	[0x18] = KC_O,
+	[0x19] = KC_P,
+
+	[0x1a] = KC_LBRACKET,
+	[0x1b] = KC_RBRACKET,
+
+	[0x3a] = KC_CAPS_LOCK,
+
+	[0x1e] = KC_A,
+	[0x1f] = KC_S,
+	[0x20] = KC_D,
+	[0x21] = KC_F,
+	[0x22] = KC_G,
+	[0x23] = KC_H,
+	[0x24] = KC_J,
+	[0x25] = KC_K,
+	[0x26] = KC_L,
+
+	[0x27] = KC_SEMICOLON,
+	[0x28] = KC_QUOTE,
+	[0x2b] = KC_BACKSLASH,
+
+	[0x2a] = KC_LSHIFT,
+
+	[0x2c] = KC_Z,
+	[0x2d] = KC_X,
+	[0x2e] = KC_C,
+	[0x2f] = KC_V,
+	[0x30] = KC_B,
+	[0x31] = KC_N,
+	[0x32] = KC_M,
+
+	[0x33] = KC_COMMA,
+	[0x34] = KC_PERIOD,
+	[0x35] = KC_SLASH,
+
+	[0x36] = KC_RSHIFT,
+
+	[0x1d] = KC_LCTRL,
+	[0x38] = KC_LALT,
+	[0x39] = KC_SPACE,
+
+	[0x01] = KC_ESCAPE,
+
+	[0x3b] = KC_F1,
+	[0x3c] = KC_F2,
+	[0x3d] = KC_F3,
+	[0x3e] = KC_F4,
+	[0x3f] = KC_F5,
+	[0x40] = KC_F6,
+	[0x41] = KC_F7,
+
+	[0x42] = KC_F8,
+	[0x43] = KC_F9,
+	[0x44] = KC_F10,
+
+	[0x57] = KC_F11,
+	[0x58] = KC_F12,
+
+	[0x1c] = KC_ENTER
+
+/*
+	[0x1] = KC_PRNSCR,
+	[0x1] = KC_SCROLL_LOCK,
+	[0x1] = KC_PAUSE,
+*/
+};
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/ctl/stty.c
===================================================================
--- uspace/srv/kbd/ctl/stty.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/ctl/stty.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbd
+ * @brief	Serial TTY-like keyboard controller driver.
+ * @{
+ */ 
+
+#include <kbd.h>
+#include <kbd/kbd.h>
+#include <kbd/keycode.h>
+#include <kbd_ctl.h>
+
+static void parse_ds_start(int scancode);
+static void parse_ds_e(int scancode);
+static void parse_ds_e1(int scancode);
+static void parse_ds_e2(int scancode);
+static void parse_ds_e2a(int scancode);
+static void parse_ds_e2b(int scancode);
+
+static void parse_leaf(int scancode, int *map, size_t map_length);
+
+enum dec_state {
+	ds_start,
+	ds_e,
+	ds_e1,
+	ds_e2,
+	ds_e2a,
+	ds_e2b
+};
+
+static int map_start[] = {
+
+	[0x60] = KC_BACKTICK,
+
+	[0x31] = KC_1,
+	[0x32] = KC_2,
+	[0x33] = KC_3,
+	[0x34] = KC_4,
+	[0x35] = KC_5,
+	[0x36] = KC_6,
+	[0x37] = KC_7,
+	[0x38] = KC_8,
+	[0x39] = KC_9,
+	[0x30] = KC_0,
+
+	[0x2d] = KC_MINUS,
+	[0x3d] = KC_EQUALS,
+	[0x08] = KC_BACKSPACE,
+
+	[0x0f] = KC_TAB,
+
+	[0x71] = KC_Q,
+	[0x77] = KC_W,
+	[0x65] = KC_E,
+	[0x72] = KC_R,
+	[0x74] = KC_T,
+	[0x79] = KC_Y,
+	[0x75] = KC_U,
+	[0x69] = KC_I,
+	[0x6f] = KC_O,
+	[0x70] = KC_P,
+
+	[0x5b] = KC_LBRACKET,
+	[0x5d] = KC_RBRACKET,
+
+//	[0x3a] = KC_CAPS_LOCK,
+
+	[0x61] = KC_A,
+	[0x73] = KC_S,
+	[0x64] = KC_D,
+	[0x66] = KC_F,
+	[0x67] = KC_G,
+	[0x68] = KC_H,
+	[0x6a] = KC_J,
+	[0x6b] = KC_K,
+	[0x6c] = KC_L,
+
+	[0x3b] = KC_SEMICOLON,
+	[0x27] = KC_QUOTE,
+	[0x5c] = KC_BACKSLASH,
+
+//	[0x2a] = KC_LSHIFT,
+
+	[0x7a] = KC_Z,
+	[0x78] = KC_X,
+	[0x63] = KC_C,
+	[0x76] = KC_V,
+	[0x62] = KC_B,
+	[0x6e] = KC_N,
+	[0x6d] = KC_M,
+
+	[0x2c] = KC_COMMA,
+	[0x2e] = KC_PERIOD,
+	[0x2f] = KC_SLASH,
+
+//	[0x36] = KC_RSHIFT,
+
+//	[0x1d] = KC_LCTRL,
+//	[0x38] = KC_LALT,
+	[0x20] = KC_SPACE,
+
+	[0x1b] = KC_ESCAPE,
+
+	[0x0a] = KC_ENTER,
+	[0x0d] = KC_ENTER
+
+/*
+	[0x1] = KC_PRNSCR,
+	[0x1] = KC_SCROLL_LOCK,
+	[0x1] = KC_PAUSE,
+*/
+};
+
+static int map_e1[] =
+{
+	[0x50] = KC_F1,
+	[0x51] = KC_F2,
+	[0x52] = KC_F3,
+	[0x53] = KC_F4,
+};
+
+static int map_e2[] =
+{
+	[0x41] = KC_UP,
+	[0x42] = KC_DOWN,
+	[0x44] = KC_LEFT,
+	[0x43] = KC_RIGHT,
+};
+
+static int map_e2a[] =
+{
+	[0x35] = KC_F5,
+	[0x37] = KC_F6,
+	[0x38] = KC_F7,
+	[0x39] = KC_F8,
+};
+
+static int map_e2b[] =
+{
+	[0x30] = KC_F9,
+	[0x31] = KC_F10,
+	[0x32] = KC_F11,
+	[0x33] = KC_F12,
+};
+
+
+static enum dec_state ds;
+
+void kbd_ctl_parse_scancode(int scancode)
+{
+	switch (ds) {
+	case ds_start:	parse_ds_start(scancode); break;
+	case ds_e: 	parse_ds_e(scancode); break;
+	case ds_e1:	parse_ds_e1(scancode); break;
+	case ds_e2:	parse_ds_e2(scancode); break;
+	case ds_e2a:	parse_ds_e2a(scancode); break;
+	case ds_e2b:	parse_ds_e2b(scancode); break;
+	}
+}
+
+static void parse_ds_start(int scancode)
+{
+	if (scancode < 0 || scancode >= sizeof(map_start) / sizeof(int))
+		return;
+
+	if (scancode == 0x1b) {
+		ds = ds_e;
+		return;
+	}
+
+	parse_leaf(scancode, map_start, sizeof(map_start) / sizeof(int));
+}
+
+static void parse_ds_e(int scancode)
+{
+	if (scancode < 0 || scancode >= 0x80) return;
+
+	switch (scancode) {
+	case 0x4f: ds = ds_e1; return;
+	case 0x5b: ds = ds_e2; return;
+	case 0x1b: ds = ds_start; break;
+	default: ds = ds_start; return;
+	}
+
+	kbd_push_ev(KE_PRESS, KC_ESCAPE, 0);
+}
+
+static void parse_ds_e1(int scancode)
+{
+	parse_leaf(scancode, map_e1, sizeof(map_e1) / sizeof(int));
+}
+
+static void parse_ds_e2(int scancode)
+{
+	switch (scancode) {
+	case 0x31: ds = ds_e2a; break;
+	case 0x32: ds = ds_e2b; break;
+	default: ds = ds_start; break;
+	}
+
+	parse_leaf(scancode, map_e2, sizeof(map_e2) / sizeof(int));
+}
+
+static void parse_ds_e2a(int scancode)
+{
+	parse_leaf(scancode, map_e2a, sizeof(map_e2a) / sizeof(int));
+}
+
+static void parse_ds_e2b(int scancode)
+{
+	parse_leaf(scancode, map_e2b, sizeof(map_e2b) / sizeof(int));
+}
+
+static void parse_leaf(int scancode, int *map, size_t map_length)
+{
+	unsigned int key;
+
+	ds = ds_start;
+
+	if (scancode < 0 || scancode >= map_length)
+		return;
+
+	key = map[scancode];
+	if (key != 0)
+		kbd_push_ev(KE_PRESS, key, 0);
+}
+
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/generic/kbd.c
===================================================================
--- uspace/srv/kbd/generic/kbd.c	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/srv/kbd/generic/kbd.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -48,8 +48,9 @@
 #include <kbd/kbd.h>
 
-#include <arch/kbd.h>
 #include <kbd.h>
 #include <key_buffer.h>
-#include <keys.h>
+#include <kbd_port.h>
+#include <kbd_ctl.h>
+#include <layout.h>
 
 #define NAME "kbd"
@@ -59,29 +60,48 @@
 keybuffer_t keybuffer;	
 
-static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
+void kbd_push_scancode(int scancode)
+{
+	printf("scancode: 0x%x\n", scancode);
+	kbd_ctl_parse_scancode(scancode);
+}
+
+#include <kbd/keycode.h>
+void kbd_push_ev(int type, unsigned int key, unsigned int mods)
 {
 	kbd_event_t ev;
 
-#ifdef MOUSE_ENABLED
-	if (mouse_arch_process(phone2cons, call))
-		return;
-#endif
-	
-	kbd_arch_process(&keybuffer, call);
+	printf("type: %d\n", type);
+	printf("mods: 0x%x\n", mods);
+	printf("keycode: %u\n", key);
 
-	if (cons_connected && phone2cons != -1) {
-		/*
-		 * One interrupt can produce more than one event so the result
-		 * is stored in a FIFO.
-		 */
-		while (!keybuffer_empty(&keybuffer)) {
-			if (!keybuffer_pop(&keybuffer, &ev))
-				break;
+	ev.type = type;
+	ev.key = key;
+	ev.mods = mods;
 
-			async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key,
-			    ev.mods, ev.c);
-		}
-	}
+	ev.c = layout_parse_ev(&ev);
+
+	async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
 }
+
+//static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
+//{
+//	kbd_event_t ev;
+//
+//	kbd_arch_process(&keybuffer, call);
+//
+//	if (cons_connected && phone2cons != -1) {
+//		/*
+//		 * One interrupt can produce more than one event so the result
+//		 * is stored in a FIFO.
+//		 */
+//		while (!keybuffer_empty(&keybuffer)) {
+//			if (!keybuffer_pop(&keybuffer, &ev))
+//				break;
+//
+//			async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key,
+//			    ev.mods, ev.c);
+//		}
+//	}
+//}
 
 static void console_connection(ipc_callid_t iid, ipc_call_t *icall)
@@ -123,4 +143,5 @@
 
 
+
 int main(int argc, char **argv)
 {
@@ -129,6 +150,6 @@
 	ipcarg_t phonead;
 	
-	/* Initialize arch dependent parts */
-	if (kbd_arch_init())
+	/* Initialize port driver. */
+	if (kbd_port_init())
 		return -1;
 	
@@ -137,6 +158,6 @@
 	
 	async_set_client_connection(console_connection);
-	async_set_interrupt_received(irq_handler);
-	/* Register service at nameserver */
+
+	/* Register service at nameserver. */
 	if (ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, 0, &phonead) != 0)
 		return -1;
@@ -145,5 +166,5 @@
 	async_manager();
 
-	/* Never reached */
+	/* Not reached. */
 	return 0;
 }
Index: uspace/srv/kbd/include/kbd.h
===================================================================
--- uspace/srv/kbd/include/kbd.h	(revision 96e0748d7558e9aeb4c97ff5d520f773c406eeac)
+++ uspace/srv/kbd/include/kbd.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -40,7 +40,12 @@
 #include <key_buffer.h>
 
-extern int kbd_arch_init(void);
-extern int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call);
-extern int mouse_arch_process(int phoneid, ipc_call_t *call);
+#define KBD_EVENT	1024
+#define KBD_MS_LEFT	1025
+#define KBD_MS_RIGHT	1026
+#define KBD_MS_MIDDLE	1027
+#define KBD_MS_MOVE	1028
+
+extern void kbd_push_scancode(int);
+extern void kbd_push_ev(int, unsigned int, unsigned int);
 
 #endif
Index: uspace/srv/kbd/include/kbd_ctl.h
===================================================================
--- uspace/srv/kbd/include/kbd_ctl.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/include/kbd_ctl.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbdgen generic
+ * @brief	HelenOS generic uspace keyboard handler.
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#ifndef KBD_CTL_H_
+#define KBD_CTL_H_
+
+extern void kbd_ctl_parse_scancode(int);
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/kbd/include/kbd_port.h
===================================================================
--- uspace/srv/kbd/include/kbd_port.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/include/kbd_port.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbdgen generic
+ * @brief	HelenOS generic uspace keyboard handler.
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#ifndef KBD_PORT_H_
+#define KBD_PORT_H_
+
+extern int kbd_port_init(void);
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/kbd/include/layout.h
===================================================================
--- uspace/srv/kbd/include/layout.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/include/layout.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbdgen generic
+ * @brief	HelenOS generic uspace keyboard handler.
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#ifndef KBD_LAYOUT_H_
+#define KBD_LAYOUT_H_
+
+#include <kbd/kbd.h>
+
+extern char layout_parse_ev(kbd_event_t *);
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/kbd/layout/us_dvorak.c
===================================================================
--- uspace/srv/kbd/layout/us_dvorak.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/layout/us_dvorak.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbd
+ * @brief	US Dvorak Simplified Keyboard layout.
+ * @{
+ */ 
+
+#include <kbd.h>
+#include <kbd/kbd.h>
+#include <kbd/keycode.h>
+#include <layout.h>
+
+static int map_normal[] = {
+	[KC_BACKTICK] = '`',
+
+	[KC_1] = '1',
+	[KC_2] = '2',
+	[KC_3] = '3',
+	[KC_4] = '4',
+	[KC_5] = '5',
+	[KC_6] = '6',
+	[KC_7] = '7',
+	[KC_8] = '8',
+	[KC_9] = '9',
+	[KC_0] = '0',
+
+	[KC_MINUS] = '[',
+	[KC_EQUALS] = ']',
+	[KC_BACKSPACE] = '\b',
+
+	[KC_TAB] = '\t',
+
+	[KC_Q] = '\'',
+	[KC_W] = ',',
+	[KC_E] = '.',
+	[KC_R] = 'p',
+	[KC_T] = 'y',
+	[KC_Y] = 'f',
+	[KC_U] = 'g',
+	[KC_I] = 'c',
+	[KC_O] = 'r',
+	[KC_P] = 'l',
+
+	[KC_LBRACKET] = '/',
+	[KC_RBRACKET] = '=',
+
+	[KC_A] = 'a',
+	[KC_S] = 'o',
+	[KC_D] = 'e',
+	[KC_F] = 'u',
+	[KC_G] = 'i',
+	[KC_H] = 'd',
+	[KC_J] = 'h',
+	[KC_K] = 't',
+	[KC_L] = 'n',
+
+	[KC_SEMICOLON] = 's',
+	[KC_QUOTE] = '-',
+	[KC_BACKSLASH] = '\\',
+
+	[KC_Z] = ';',
+	[KC_X] = 'q',
+	[KC_C] = 'j',
+	[KC_V] = 'k',
+	[KC_B] = 'x',
+	[KC_N] = 'b',
+	[KC_M] = 'm',
+
+	[KC_COMMA] = 'w',
+	[KC_PERIOD] = 'v',
+	[KC_SLASH] = 'z',
+
+	[KC_ENTER] = '\n'
+};
+
+char layout_parse_ev(kbd_event_t *ev)
+{
+	if (ev->key >= sizeof(map_normal) / sizeof(int))
+		return 0;
+
+	return map_normal[ev->key];
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/layout/us_qwerty.c
===================================================================
--- uspace/srv/kbd/layout/us_qwerty.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/layout/us_qwerty.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbd
+ * @brief	US QWERTY leyout.
+ * @{
+ */ 
+
+#include <kbd.h>
+#include <kbd/kbd.h>
+#include <kbd/keycode.h>
+#include <layout.h>
+
+static int map_normal[] = {
+	[KC_BACKTICK] = '`',
+
+	[KC_1] = '1',
+	[KC_2] = '2',
+	[KC_3] = '3',
+	[KC_4] = '4',
+	[KC_5] = '5',
+	[KC_6] = '6',
+	[KC_7] = '7',
+	[KC_8] = '8',
+	[KC_9] = '9',
+	[KC_0] = '0',
+
+	[KC_MINUS] = '-',
+	[KC_EQUALS] = '=',
+	[KC_BACKSPACE] = '\b',
+
+	[KC_TAB] = '\t',
+
+	[KC_Q] = 'q',
+	[KC_W] = 'w',
+	[KC_E] = 'e',
+	[KC_R] = 'r',
+	[KC_T] = 't',
+	[KC_Y] = 'y',
+	[KC_U] = 'u',
+	[KC_I] = 'i',
+	[KC_O] = 'o',
+	[KC_P] = 'p',
+
+	[KC_LBRACKET] = '[',
+	[KC_RBRACKET] = ']',
+
+	[KC_A] = 'a',
+	[KC_S] = 's',
+	[KC_D] = 'd',
+	[KC_F] = 'f',
+	[KC_G] = 'g',
+	[KC_H] = 'h',
+	[KC_J] = 'j',
+	[KC_K] = 'k',
+	[KC_L] = 'l',
+
+	[KC_SEMICOLON] = ';',
+	[KC_QUOTE] = '\'',
+	[KC_BACKSLASH] = '\\',
+	[KC_ENTER] = '\n',
+
+	[KC_Z] = 'z',
+	[KC_X] = 'x',
+	[KC_C] = 'c',
+	[KC_V] = 'v',
+	[KC_B] = 'b',
+	[KC_N] = 'n',
+	[KC_M] = 'm',
+
+	[KC_COMMA] = ',',
+	[KC_PERIOD] = '.',
+	[KC_SLASH] = '/',
+
+	[KC_SPACE] = ' '
+};
+
+char layout_parse_ev(kbd_event_t *ev)
+{
+	if (ev->key >= sizeof(map_normal) / sizeof(int))
+		return 0;
+
+	return map_normal[ev->key];
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/port/dummy.c
===================================================================
--- uspace/srv/kbd/port/dummy.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/port/dummy.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * 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 kbd
+ * @brief	Dummy keyboard port driver.
+ * @{
+ */ 
+/** @file
+ */
+
+#include <kbd_port.h>
+#include <kbd.h>
+
+int kbd_port_init(void)
+{
+	return 0;
+}
+
+/** @}
+*/
Index: uspace/srv/kbd/port/gxemul.c
===================================================================
--- uspace/srv/kbd/port/gxemul.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/port/gxemul.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * 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 kbd
+ * @{
+ */ 
+/** @file
+ * @brief	GXEmul keyboard port driver.
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <sysinfo.h>
+#include <kbd_port.h>
+#include <kbd.h>
+
+static irq_cmd_t gxemul_cmds[] = {
+	{ 
+		CMD_MEM_READ_1, 
+		(void *) 0, 
+		0, 
+		2
+	}
+};
+
+static irq_code_t gxemul_kbd = {
+	1,
+	gxemul_cmds
+};
+
+static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+/** Initializes keyboard handler. */
+int kbd_port_init(void)
+{
+	async_set_interrupt_received(gxemul_irq_handler);
+	gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
+	ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"),
+	    0, &gxemul_kbd);
+	return 0;
+}
+
+/** Process data sent when a key is pressed.
+ *  
+ *  @param keybuffer Buffer of pressed keys.
+ *  @param call      IPC call.
+ *
+ *  @return Always 1.
+ */
+static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int scan_code = IPC_GET_ARG2(*call);
+
+	kbd_push_scancode(scan_code);
+}
+
+/** @}
+ */
Index: uspace/srv/kbd/port/i8042.c
===================================================================
--- uspace/srv/kbd/port/i8042.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/port/i8042.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2006 Josef Cejka
+ * 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 kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <unistd.h>
+#include <sysinfo.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include "i8042.h"
+
+/* Interesting bits for status register */
+#define i8042_OUTPUT_FULL  0x1
+#define i8042_INPUT_FULL   0x2
+#define i8042_MOUSE_DATA   0x20
+
+/* Command constants */
+#define i8042_CMD_KBD 0x60
+#define i8042_CMD_MOUSE  0xd4
+
+/* Keyboard cmd byte */
+#define i8042_KBD_IE        0x1
+#define i8042_MOUSE_IE      0x2
+#define i8042_KBD_DISABLE   0x10
+#define i8042_MOUSE_DISABLE 0x20
+#define i8042_KBD_TRANSLATE 0x40
+
+/* Mouse constants */
+#define MOUSE_OUT_INIT  0xf4
+#define MOUSE_ACK       0xfa
+
+static irq_cmd_t i8042_cmds[2] = {
+	{ CMD_PORT_READ_1, (void *) 0x64, 0, 1 },
+	{ CMD_PORT_READ_1, (void *) 0x60, 0, 2 }
+};
+
+static irq_code_t i8042_kbd = {
+	2,
+	i8042_cmds
+};
+
+static void wait_ready(void) {
+	while (i8042_status_read() & i8042_INPUT_FULL)
+	    ;
+}
+
+static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+int kbd_port_init(void)
+{
+//	int i;
+	int mouseenabled = 0;
+
+	async_set_interrupt_received(i8042_irq_handler);
+	iospace_enable(task_get_id(), (void *) i8042_DATA, 5);
+
+	/* Disable kbd, enable mouse */
+	i8042_command_write(i8042_CMD_KBD);
+	wait_ready();
+	i8042_command_write(i8042_CMD_KBD);
+	wait_ready();
+	i8042_data_write(i8042_KBD_DISABLE);
+	wait_ready();
+
+	/* Flush all current IO */
+	while (i8042_status_read() & i8042_OUTPUT_FULL)
+		i8042_data_read();
+	
+	/* Initialize mouse */
+/*	i8042_command_write(i8042_CMD_MOUSE);
+	wait_ready();
+	i8042_data_write(MOUSE_OUT_INIT);
+	wait_ready();
+	
+	int mouseanswer = 0;
+	for (i=0;i < 1000; i++) {
+		int status = i8042_status_read();
+		if (status & i8042_OUTPUT_FULL) {
+			int data = i8042_data_read();
+			if (status & i8042_MOUSE_DATA) {
+				mouseanswer = data;
+				break;
+			}
+		}
+		usleep(1000);
+	}*/
+//	if (mouseanswer == MOUSE_ACK) {
+//		/* enable mouse */
+//		mouseenabled = 1;
+//		
+//		ipc_register_irq(sysinfo_value("mouse.inr"), sysinfo_value("mouse.devno"), 0, &i8042_kbd);
+//	}
+
+	/* Enable kbd */
+	ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &i8042_kbd);
+
+	int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
+	if (mouseenabled)
+		newcontrol |= i8042_MOUSE_IE;
+	
+	i8042_command_write(i8042_CMD_KBD);
+	wait_ready();
+	i8042_data_write(newcontrol);
+	wait_ready();
+	
+	return 0;
+}
+
+static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int status = IPC_GET_ARG1(*call);
+
+	if ((status & i8042_MOUSE_DATA))
+		return 0;
+
+	int scan_code = IPC_GET_ARG2(*call);
+
+	kbd_push_scancode(scan_code);
+	return 1;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/port/i8042.h
===================================================================
--- uspace/srv/kbd/port/i8042.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/port/i8042.h	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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 kbdamd64 amd64
+ * @brief	HelenOS ia32 / amd64 arch dependent parts of uspace keyboard and mouse handler.
+ * @ingroup  kbd
+ * @{
+ */
+
+/** @file
+ * @ingroup kbdia32
+ */
+
+#ifndef KBD_PORT_i8042_H_
+#define KBD_PORT_i8042_H_
+
+#include <ddi.h>
+#include <libarch/ddi.h>
+
+#define i8042_DATA      0x60
+#define i8042_STATUS    0X64
+
+
+typedef unsigned char u8;
+typedef short u16;
+
+static inline void i8042_data_write(u8 data)
+{
+	outb(i8042_DATA, data);
+}
+
+static inline u8 i8042_data_read(void)
+{
+	return inb(i8042_DATA);
+}
+
+static inline u8 i8042_status_read(void)
+{
+	return inb(i8042_STATUS);
+}
+
+static inline void i8042_command_write(u8 command)
+{
+	outb(i8042_STATUS, command);
+}
+
+#endif
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/port/msim.c
===================================================================
--- uspace/srv/kbd/port/msim.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
+++ uspace/srv/kbd/port/msim.c	(revision f89979b1e04f036c3b08e99110d2269a0314f7c9)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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 kbd
+ * @brief	Msim keyboard port driver.
+ * @{
+ */ 
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <sysinfo.h>
+#include <kbd_port.h>
+#include <kbd.h>
+
+irq_cmd_t msim_cmds[1] = {
+	{ CMD_MEM_READ_1, (void *) 0, 0, 2 }
+};
+
+irq_code_t msim_kbd = {
+	1,
+	msim_cmds
+};
+
+static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+int kbd_port_init(void)
+{
+	async_set_interrupt_received(msim_irq_handler);
+	msim_cmds[0].addr = sysinfo_value("kbd.address.virtual");
+	ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"),
+	    0, &msim_kbd);
+	return 0;
+}
+
+static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int scan_code = IPC_GET_ARG2(*call);
+//	static int esc_count=0;
+
+//	if (scan_code == 0x1b) {
+//		esc_count++;
+//		if (esc_count == 3)
+//			__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
+//	} else {
+//		esc_count=0;
+//	}
+
+//	if (fb_fb)
+//		return kbd_arch_process_fb(keybuffer, scan_code);
+
+	kbd_push_scancode(scan_code);
+}
+
+/** @}
+*/
