Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ HelenOS.config	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -538,5 +538,5 @@
 
 % Launch (devman) test drivers
-! [CONFIG_DEBUG=y] CONFIG_TEST_DRIVERS (y/n)
+! [CONFIG_DEBUG=y] CONFIG_TEST_DRIVERS (n/y)
 
 % Load disk drivers on startup
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ boot/Makefile.common	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -86,5 +86,5 @@
 RD_SRVS_ESSENTIAL = \
 	$(USPACE_PATH)/srv/hid/fb/fb \
-	$(USPACE_PATH)/srv/hid/kbd/kbd \
+	$(USPACE_PATH)/srv/hid/input/input \
 	$(USPACE_PATH)/srv/hid/console/console \
 	$(USPACE_PATH)/srv/fs/devfs/devfs
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ kernel/generic/include/proc/thread.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -156,4 +156,7 @@
 	int fpu_context_engaged;
 	
+	/* The thread will not be migrated if nomigrate is non-zero. */
+	int nomigrate;
+	
 	/** Thread's state. */
 	state_t state;
@@ -245,4 +248,7 @@
 extern bool thread_exists(thread_t *);
 
+extern void thread_migration_disable(void);
+extern void thread_migration_enable(void);
+
 #ifdef CONFIG_UDEBUG
 extern void thread_stack_trace(thread_id_t);
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ kernel/generic/src/proc/scheduler.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -586,5 +586,4 @@
 	 * Searching least priority queues on all CPU's first and most priority
 	 * queues on all CPU's last.
-	 *
 	 */
 	size_t acpu;
@@ -620,23 +619,24 @@
 			
 			while (link != &(cpu->rq[rq].rq_head)) {
-				thread = (thread_t *) list_get_instance(link, thread_t, rq_link);
+				thread = (thread_t *) list_get_instance(link,
+				    thread_t, rq_link);
 				
 				/*
-				 * We don't want to steal CPU-wired threads
-				 * neither threads already stolen. The latter
-				 * prevents threads from migrating between CPU's
-				 * without ever being run. We don't want to
-				 * steal threads whose FPU context is still in
-				 * CPU.
-				 *
+				 * Do not steal CPU-wired threads, threads
+				 * already stolen, threads for which migration
+				 * was temporarily disabled or threads whose
+				 * FPU context is still in the CPU.
 				 */
 				irq_spinlock_lock(&thread->lock, false);
 				
-				if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
-				    && (!(thread->fpu_context_engaged))) {
+				if (!(thread->flags & THREAD_FLAG_WIRED) &&
+				    !(thread->flags & THREAD_FLAG_STOLEN) &&
+				    !thread->nomigrate &&
+				    !thread->fpu_context_engaged) {
 					/*
 					 * Remove thread from ready queue.
 					 */
-					irq_spinlock_unlock(&thread->lock, false);
+					irq_spinlock_unlock(&thread->lock,
+					    false);
 					
 					atomic_dec(&cpu->nrdy);
@@ -660,5 +660,6 @@
 				 */
 				
-				irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
+				irq_spinlock_pass(&(cpu->rq[rq].lock),
+				    &thread->lock);
 				
 #ifdef KCPULB_VERBOSE
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ kernel/generic/src/proc/thread.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -322,4 +322,5 @@
 	thread->cpu = NULL;
 	thread->flags = flags;
+	thread->nomigrate = 0;
 	thread->state = Entering;
 	
@@ -482,4 +483,21 @@
 	/* Not reached */
 	while (true);
+}
+
+/** Prevent the current thread from being migrated to another processor. */
+void thread_migration_disable(void)
+{
+	ASSERT(THREAD);
+
+	THREAD->nomigrate++;
+}
+
+/** Allow the current thread to be migrated to another processor. */
+void thread_migration_enable(void)
+{
+	ASSERT(THREAD);
+	ASSERT(THREAD->nomigrate > 0);
+
+	THREAD->nomigrate--;
 }
 
Index: kernel/generic/src/time/delay.c
===================================================================
--- kernel/generic/src/time/delay.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ kernel/generic/src/time/delay.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -37,4 +37,5 @@
  
 #include <time/delay.h>
+#include <proc/thread.h>
 #include <typedefs.h>
 #include <cpu.h>
@@ -42,9 +43,7 @@
 #include <arch.h>
 
-/** Active delay
+/** Delay the execution for the given number of microseconds (or slightly more).
  *
- * Delay the execution for the given number
- * of microseconds (or slightly more). The delay
- * is implemented as CPU calibrated active loop.
+ * The delay is implemented as active delay loop.
  *
  * @param usec Number of microseconds to sleep.
@@ -52,17 +51,16 @@
 void delay(uint32_t usec)
 {
-	ipl_t ipl;
-	
 	/* 
-	 * The delay loop is calibrated for each and every
-	 * CPU in the system. Therefore it is necessary to
-	 * call interrupts_disable() before calling the
-	 * asm_delay_loop().
+	 * The delay loop is calibrated for each and every CPU in the system.
+	 * If running in a thread context, it is therefore necessary to disable
+	 * thread migration. We want to do this in a lightweight manner.
 	 */
-	ipl = interrupts_disable();
+	if (THREAD)
+		thread_migration_disable();
 	asm_delay_loop(usec * CPU->delay_loop_const);
-	interrupts_restore(ipl);
+	if (THREAD)
+		thread_migration_enable();
 }
 
 /** @}
- */
+*/
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/Makefile	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -85,5 +85,5 @@
 	srv/hid/s3c24xx_ts \
 	srv/hid/fb \
-	srv/hid/kbd \
+	srv/hid/input \
 	srv/hw/char/i8042 \
 	srv/hw/char/s3c24xx_uart \
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/app/init/init.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -280,6 +280,6 @@
 	
 	spawn("/srv/fb");
-	spawn("/srv/kbd");
-	console("hid_in/kbd");
+	spawn("/srv/input");
+	console("hid_in/input");
 	
 	spawn("/srv/clip");
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/app/klog/klog.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -143,6 +143,7 @@
  * Receives kernel klog notifications.
  *
- * @param callid IPC call ID.
- * @param call   IPC call structure.
+ * @param callid	IPC call ID
+ * @param call		IPC call structure
+ * @param arg		Local argument
  *
  */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/app/tester/Makefile	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -29,5 +29,5 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBEXT2_PREFIX)/libext2.a
+LIBS = $(LIBEXT2_PREFIX)/libext2.a $(LIBBLOCK_PREFIX)/libblock.a
 EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBEXT2_PREFIX)
 BINARY = tester
Index: uspace/drv/ohci/ohci.ma
===================================================================
--- uspace/drv/ohci/ohci.ma	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/drv/ohci/ohci.ma	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -10,2 +10,5 @@
 10 pci/ven=1002&dev=438a
 10 pci/ven=1002&dev=438b
+10 pci/ven=1002&dev=4397
+10 pci/ven=1002&dev=4398
+10 pci/ven=1002&dev=4399
Index: uspace/drv/usbhid/Makefile
===================================================================
--- uspace/drv/usbhid/Makefile	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/drv/usbhid/Makefile	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -43,9 +43,4 @@
 BINARY = usbhid
 
-STOLEN_LAYOUT_SOURCES = \
-        kbd/layout/us_qwerty.c \
-        kbd/layout/us_dvorak.c \
-        kbd/layout/cz.c
-
 SOURCES = \
 	main.c \
@@ -61,10 +56,3 @@
 	$(STOLEN_LAYOUT_SOURCES)
 
-EXTRA_CLEAN = $(STOLEN_LAYOUT_SOURCES)
-
-SRV_KBD = $(USPACE_PREFIX)/srv/hid/kbd
-
 include $(USPACE_PREFIX)/Makefile.common
-
-kbd/layout/%.c: $(SRV_KBD)/layout/%.c
-	ln -sfn ../../$< $@
Index: pace/drv/usbhid/kbd.h
===================================================================
--- uspace/drv/usbhid/kbd.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,5 +1,0 @@
-/*
- * Dummy file because of shared layout sources.
- *
- * Do not delete.
- */
Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -40,5 +40,6 @@
 
 #include <io/keycode.h>
-#include <ipc/kbd.h>
+#include <io/console.h>
+#include <ipc/kbdev.h>
 #include <async.h>
 #include <async_obsolete.h>
@@ -63,5 +64,4 @@
 #include "kbddev.h"
 
-#include "layout.h"
 #include "conv.h"
 #include "kbdrepeat.h"
@@ -73,5 +73,5 @@
 
 /*----------------------------------------------------------------------------*/
-/** Default modifiers when the keyboard is initialized. */
+
 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
 
@@ -101,4 +101,6 @@
 const char *HID_KBD_FUN_NAME = "keyboard";
 const char *HID_KBD_CLASS_NAME = "keyboard";
+
+static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev);
 
 /*----------------------------------------------------------------------------*/
@@ -154,19 +156,4 @@
 
 /*----------------------------------------------------------------------------*/
-/* Keyboard layouts                                                           */
-/*----------------------------------------------------------------------------*/
-
-#define NUM_LAYOUTS 3
-
-/** Keyboard layout map. */
-static layout_op_t *layout[NUM_LAYOUTS] = {
-	&us_qwerty_op,
-	&us_dvorak_op,
-	&cz_op
-};
-
-static int active_layout = 0;
-
-/*----------------------------------------------------------------------------*/
 /* IPC method handler                                                         */
 /*----------------------------------------------------------------------------*/
@@ -174,5 +161,5 @@
 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
 
-/** 
+/**
  * Default handler for IPC methods not handled by DDF.
  *
@@ -189,4 +176,5 @@
 {
 	sysarg_t method = IPC_GET_IMETHOD(*icall);
+	int callback;
 	
 	usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data;
@@ -198,6 +186,7 @@
 	}
 
-	if (method == IPC_M_CONNECT_TO_ME) {
-		int callback = IPC_GET_ARG5(*icall);
+	switch (method) {
+	case IPC_M_CONNECT_TO_ME:
+		callback = IPC_GET_ARG5(*icall);
 
 		if (kbd_dev->console_phone != -1) {
@@ -212,9 +201,15 @@
 		usb_log_debug("default_connection_handler: OK\n");
 		async_answer_0(icallid, EOK);
-		return;
-	}
-	
-	usb_log_debug("default_connection_handler: Wrong function.\n");
-	async_answer_0(icallid, EINVAL);
+		break;
+	case KBDEV_SET_IND:
+		kbd_dev->mods = IPC_GET_ARG1(*icall);
+		usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev);
+		async_answer_0(icallid, EOK);
+		break;
+	default:
+		usb_log_debug("default_connection_handler: Wrong function.\n");
+		async_answer_0(icallid, EINVAL);
+		break;
+	}
 }
 
@@ -225,7 +220,8 @@
  * Handles turning of LED lights on and off.
  *
- * In case of USB keyboards, the LEDs are handled in the driver, not in the 
- * device. When there should be a change (lock key was pressed), the driver
- * uses a Set_Report request sent to the device to set the state of the LEDs.
+ * As with most other keyboards, the LED indicators in USB keyboards are
+ * driven by software. When state of some modifier changes, the input server
+ * will call us and tell us to update the LED state and what the new state
+ * should be.
  *
  * This functions sets the LED lights according to current settings of modifiers
@@ -249,5 +245,5 @@
 	    USB_HID_REPORT_TYPE_OUTPUT);
 	
-	while (field != NULL) {		
+	while (field != NULL) {
 		
 		if ((field->usage == USB_HID_LED_NUM_LOCK) 
@@ -292,109 +288,15 @@
 
 /*----------------------------------------------------------------------------*/
-/**
- * Processes key events.
- *
- * @note This function was copied from AT keyboard driver and modified to suit
- *       USB keyboard.
- *
- * @note Lock keys are not sent to the console, as they are completely handled
- *       in the driver. It may, however, be required later that the driver
- *       sends also these keys to application (otherwise it cannot use those
- *       keys at all).
- * 
+/** Send key event.
+ *
  * @param kbd_dev Keyboard device structure.
- * @param type Type of the event (press / release). Recognized values: 
+ * @param type Type of the event (press / release). Recognized values:
  *             KEY_PRESS, KEY_RELEASE
- * @param key Key code of the key according to HID Usage Tables.
+ * @param key Key code
  */
 void usb_kbd_push_ev(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, int type, 
     unsigned int key)
 {
-	kbd_event_t ev;
-	unsigned mod_mask;
-
-	/*
-	 * These parts are copy-pasted from the AT keyboard driver.
-	 *
-	 * They definitely require some refactoring, but will keep it for later
-	 * when the console and keyboard system is changed in HelenOS.
-	 */
-	switch (key) {
-	case KC_LCTRL: mod_mask = KM_LCTRL; break;
-	case KC_RCTRL: mod_mask = KM_RCTRL; break;
-	case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
-	case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
-	case KC_LALT: mod_mask = KM_LALT; break;
-	case KC_RALT: mod_mask = KM_RALT; break;
-	default: mod_mask = 0; break;
-	}
-
-	if (mod_mask != 0) {
-		if (type == KEY_PRESS)
-			kbd_dev->mods = kbd_dev->mods | mod_mask;
-		else
-			kbd_dev->mods = kbd_dev->mods & ~mod_mask;
-	}
-
-	switch (key) {
-	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
-	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
-	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
-	default: mod_mask = 0; break;
-	}
-
-	if (mod_mask != 0) {
-		if (type == KEY_PRESS) {
-			/*
-			 * Only change lock state on transition from released
-			 * to pressed. This prevents autorepeat from messing
-			 * up the lock state.
-			 */
-			unsigned int locks_old = kbd_dev->lock_keys;
-			
-			kbd_dev->mods = 
-			    kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
-			kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask;
-
-			/* Update keyboard lock indicator lights. */
-			if (kbd_dev->lock_keys != locks_old 
-			    && hid_dev != NULL) { // ugly hack
-				usb_kbd_set_led(hid_dev, kbd_dev);
-			}
-		} else {
-			kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
-		}
-	}
-
-	if (key == KC_CAPS_LOCK || key == KC_NUM_LOCK || key == KC_SCROLL_LOCK) {
-		// do not send anything to the console, this is our business
-		return;
-	}
-	
-	if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) {
-		active_layout = 0;
-		layout[active_layout]->reset();
-		return;
-	}
-
-	if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) {
-		active_layout = 1;
-		layout[active_layout]->reset();
-		return;
-	}
-
-	if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) {
-		active_layout = 2;
-		layout[active_layout]->reset();
-		return;
-	}
-	
-	ev.type = type;
-	ev.key = key;
-	ev.mods = kbd_dev->mods;
-
-	ev.c = layout[active_layout]->parse_ev(&ev);
-
-	usb_log_debug2("Sending key %d to the console\n", ev.key);
+	usb_log_debug2("Sending kbdev event %d/%d to the console\n", type, key);
 	if (kbd_dev->console_phone < 0) {
 		usb_log_warning(
@@ -403,6 +305,5 @@
 	}
 	
-	async_obsolete_msg_4(kbd_dev->console_phone, KBD_EVENT, ev.type, ev.key, 
-	    ev.mods, ev.c);
+	async_obsolete_msg_2(kbd_dev->console_phone, KBDEV_EVENT, type, key);
 }
 
@@ -716,4 +617,7 @@
 		return ENOMEM;  // TODO: some other code??
 	}
+
+	/* Store link to HID device */
+	kbd_dev->hid_dev = hid_dev;
 	
 	/*
@@ -787,5 +691,5 @@
 	/*
 	 * Modifiers and locks
-	 */	
+	 */
 	kbd_dev->modifiers = 0;
 	kbd_dev->mods = DEFAULT_ACTIVE_MODS;
@@ -794,5 +698,5 @@
 	/*
 	 * Autorepeat
-	 */	
+	 */
 	kbd_dev->repeat.key_new = 0;
 	kbd_dev->repeat.key_repeated = 0;
Index: uspace/drv/usbhid/kbd/kbddev.h
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/drv/usbhid/kbd/kbddev.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -65,4 +65,7 @@
  */
 typedef struct usb_kbd_t {
+	/** Link to HID device structure */
+	struct usb_hid_dev *hid_dev;
+
 	/** Previously pressed keys (not translated to key codes). */
 	int32_t *keys_old;
Index: pace/drv/usbhid/kbd/layout.h
===================================================================
--- uspace/drv/usbhid/kbd/layout.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../layout.h
Index: pace/drv/usbhid/layout.h
===================================================================
--- uspace/drv/usbhid/layout.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * Copyright (c) 2011 Lubos Slovak 
- * (copied from /uspace/srv/hid/kbd/include/layout.h)
- * 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 drvusbhid
- * @{
- */
-/** @file
- * Keyboard layout.
- */
-
-#ifndef USB_HID_LAYOUT_H_
-#define USB_HID_LAYOUT_H_
-
-#include <sys/types.h>
-#include <io/console.h>
-
-typedef struct {
-	void (*reset)(void);
-	wchar_t (*parse_ev)(kbd_event_t *);
-} layout_op_t;
-
-extern layout_op_t us_qwerty_op;
-extern layout_op_t us_dvorak_op;
-extern layout_op_t cz_op;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -47,5 +47,5 @@
 #include <io/console.h>
 
-#include <ipc/kbd.h>
+#include <ipc/kbdev.h>
 #include <io/keycode.h>
 
@@ -219,8 +219,8 @@
 	for (i = 0; i < count * 3; ++i) {
 		usb_log_debug2("Sending key %d to the console\n", ev.key);
-		async_obsolete_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type, 
+		async_obsolete_msg_4(mouse_dev->wheel_phone, KBDEV_EVENT, ev.type, 
 		    ev.key, ev.mods, ev.c);
 		// send key release right away
-		async_obsolete_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE, 
+		async_obsolete_msg_4(mouse_dev->wheel_phone, KBDEV_EVENT, KEY_RELEASE, 
 		    ev.key, ev.mods, ev.c);
 	}
Index: uspace/drv/usbhid/multimedia/multimedia.c
===================================================================
--- uspace/drv/usbhid/multimedia/multimedia.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/drv/usbhid/multimedia/multimedia.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -50,5 +50,5 @@
 #include <str_error.h>
 
-#include <ipc/kbd.h>
+#include <ipc/kbdev.h>
 #include <io/console.h>
 
@@ -162,5 +162,5 @@
 	}
 	
-	async_obsolete_msg_4(multim_dev->console_phone, KBD_EVENT, ev.type, ev.key, 
+	async_obsolete_msg_4(multim_dev->console_phone, KBDEV_EVENT, ev.type, ev.key, 
 	    ev.mods, ev.c);
 }
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/async.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -166,4 +166,6 @@
 	/** Call data of the opening call. */
 	ipc_call_t call;
+	/** Local argument or NULL if none. */
+	void *carg;
 	
 	/** Identification of the closing call. */
@@ -171,5 +173,5 @@
 	
 	/** Fibril function that will be used to handle the connection. */
-	void (*cfibril)(ipc_callid_t, ipc_call_t *);
+	async_client_conn_t cfibril;
 } connection_t;
 
@@ -211,9 +213,11 @@
  * This function is defined as a weak symbol - to be redefined in user code.
  *
- * @param callid Hash of the incoming call.
- * @param call   Data of the incoming call.
- *
- */
-static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
+ * @param callid	Hash of the incoming call.
+ * @param call		Data of the incoming call.
+ * @param arg		Local argument
+ *
+ */
+static void default_client_connection(ipc_callid_t callid, ipc_call_t *call,
+    void *arg)
 {
 	ipc_answer_0(callid, ENOENT);
@@ -224,6 +228,7 @@
  * This function is defined as a weak symbol - to be redefined in user code.
  *
- * @param callid Hash of the incoming call.
- * @param call   Data of the incoming call.
+ * @param callid	Hash of the incoming call.
+ * @param call  	Data of the incoming call.
+ * @param arg		Local argument.
  *
  */
@@ -233,5 +238,5 @@
 
 static async_client_conn_t client_connection = default_client_connection;
-static async_client_conn_t interrupt_received = default_interrupt_received;
+static async_interrupt_handler_t interrupt_received = default_interrupt_received;
 
 /** Setter for client_connection function pointer.
@@ -250,5 +255,5 @@
  *             notification fibril.
  */
-void async_set_interrupt_received(async_client_conn_t intr)
+void async_set_interrupt_received(async_interrupt_handler_t intr)
 {
 	interrupt_received = intr;
@@ -633,5 +638,5 @@
 	 */
 	fibril_connection->cfibril(fibril_connection->callid,
-	    &fibril_connection->call);
+	    &fibril_connection->call, fibril_connection->carg);
 	
 	/*
@@ -704,4 +709,5 @@
  * @param cfibril       Fibril function that should be called upon opening the
  *                      connection.
+ * @param carg		Extra argument to pass to the connection fibril
  *
  * @return New fibril id or NULL on failure.
@@ -710,5 +716,5 @@
 fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     ipc_callid_t callid, ipc_call_t *call,
-    async_client_conn_t cfibril)
+    async_client_conn_t cfibril, void *carg)
 {
 	connection_t *conn = malloc(sizeof(*conn));
@@ -725,4 +731,5 @@
 	conn->callid = callid;
 	conn->close_callid = 0;
+	conn->carg = carg;
 	
 	if (call)
@@ -779,5 +786,5 @@
 		/* Open new connection with fibril, etc. */
 		async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
-		    callid, call, client_connection);
+		    callid, call, client_connection, NULL);
 		return;
 	}
@@ -1414,5 +1421,5 @@
  */
 int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_client_conn_t client_receiver)
+    sysarg_t arg3, async_client_conn_t client_receiver, void *carg)
 {
 	if (exch == NULL)
@@ -1428,5 +1435,5 @@
 	if (client_receiver != NULL)
 		async_new_connection(task_hash, phone_hash, 0, NULL,
-		    client_receiver);
+		    client_receiver, carg);
 	
 	return EOK;
Index: uspace/lib/c/generic/async_obsolete.c
===================================================================
--- uspace/lib/c/generic/async_obsolete.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/async_obsolete.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -240,5 +240,5 @@
  */
 int async_obsolete_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_client_conn_t client_receiver)
+    sysarg_t arg3, async_client_conn_t client_receiver, void *carg)
 {
 	sysarg_t task_hash;
@@ -251,5 +251,5 @@
 	if (client_receiver != NULL)
 		async_new_connection(task_hash, phone_hash, 0, NULL,
-		    client_receiver);
+		    client_receiver, carg);
 	
 	return EOK;
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/devman.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -194,5 +194,5 @@
 	
 	exch = devman_exchange_begin(DEVMAN_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0, NULL);
+	async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
 	devman_exchange_end(exch);
 	
Index: uspace/lib/c/generic/devmap.c
===================================================================
--- uspace/lib/c/generic/devmap.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/devmap.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -187,5 +187,5 @@
 	
 	exch = devmap_exchange_begin(DEVMAP_DRIVER);
-	async_connect_to_me(exch, 0, 0, 0, NULL);
+	async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
 	devmap_exchange_end(exch);
 	
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/net/modules.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -141,5 +141,6 @@
 	if (phone >= 0) {
 		/* Request the bidirectional connection */
-		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
+		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3,
+		    client_receiver, NULL);
 		if (rc != EOK) {
 			async_obsolete_hangup(phone);
Index: uspace/lib/c/generic/net/socket_client.c
===================================================================
--- uspace/lib/c/generic/net/socket_client.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/net/socket_client.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -203,6 +203,7 @@
  * @param[in] iid	The initial message identifier.
  * @param[in] icall	The initial message call structure.
- */
-static void socket_connection(ipc_callid_t iid, ipc_call_t * icall)
+ * @param[in] arg	Local argument.
+ */
+static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/generic/ns.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -42,5 +42,5 @@
 {
 	async_exch_t *exch = async_exchange_begin(session_ns);
-	int rc = async_connect_to_me(exch, service, 0, 0, NULL);
+	int rc = async_connect_to_me(exch, service, 0, 0, NULL, NULL);
 	async_exchange_end(exch);
 	
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/include/async.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -53,5 +53,16 @@
 typedef void (*async_client_data_dtor_t)(void *);
 
-typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *);
+/** Client connection handler
+ *
+ * @param callid	ID of incoming call or 0 if connection initiated from
+ *			inside using async_connect_to_me()
+ * @param call		Incoming call or 0 if connection initiated from inside
+ * @param arg		Local argument passed from async_new_connection() or
+ *			async_connect_to_me()
+ */
+typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *, void *);
+
+/** Interrupt handler */
+typedef void (*async_interrupt_handler_t)(ipc_callid_t, ipc_call_t *);
 
 /** Exchange management style
@@ -166,5 +177,5 @@
 
 extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
-    ipc_call_t *, async_client_conn_t);
+    ipc_call_t *, async_client_conn_t, void *);
 
 extern void async_usleep(suseconds_t);
@@ -177,5 +188,5 @@
 
 extern void async_set_client_connection(async_client_conn_t);
-extern void async_set_interrupt_received(async_client_conn_t);
+extern void async_set_interrupt_received(async_interrupt_handler_t);
 
 /*
@@ -351,5 +362,5 @@
 
 extern int async_connect_to_me(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
-    async_client_conn_t);
+    async_client_conn_t, void *);
 
 extern int async_hangup(async_sess_t *);
Index: uspace/lib/c/include/async_obsolete.h
===================================================================
--- uspace/lib/c/include/async_obsolete.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/c/include/async_obsolete.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -198,5 +198,5 @@
 
 extern int async_obsolete_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t,
-    async_client_conn_t);
+    async_client_conn_t, void *);
 extern int async_obsolete_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
 extern int async_obsolete_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
Index: uspace/lib/c/include/ipc/input.h
===================================================================
--- uspace/lib/c/include/ipc/input.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/lib/c/include/ipc/input.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_INPUT_H_
+#define LIBC_IPC_INPUT_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	INPUT_YIELD = IPC_FIRST_USER_METHOD,
+	INPUT_RECLAIM
+} input_request_t;
+
+typedef enum {
+	INPUT_EVENT_KEY = IPC_FIRST_USER_METHOD,
+	INPUT_EVENT_MOVE,
+	INPUT_EVENT_BUTTON
+} input_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: pace/lib/c/include/ipc/kbd.h
===================================================================
--- uspace/lib/c/include/ipc/kbd.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * 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 LIBC_IPC_KBD_H_
-#define LIBC_IPC_KBD_H_
-
-#include <ipc/common.h>
-#include <ipc/dev_iface.h>
-
-typedef enum {
-	KBD_YIELD = DEV_FIRST_CUSTOM_METHOD,
-	KBD_RECLAIM
-} kbd_request_t;
-
-typedef enum {
-	KBD_EVENT = IPC_FIRST_USER_METHOD
-} kbd_notif_t;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/c/include/ipc/kbdev.h
===================================================================
--- uspace/lib/c/include/ipc/kbdev.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/lib/c/include/ipc/kbdev.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_KBDEV_H_
+#define LIBC_IPC_KBDEV_H_
+
+#include <ipc/common.h>
+#include <ipc/dev_iface.h>
+
+typedef enum {
+	KBDEV_YIELD = DEV_FIRST_CUSTOM_METHOD,
+	KBDEV_RECLAIM,
+	KBDEV_SET_IND
+} kbdev_request_t;
+
+typedef enum {
+	KBDEV_EVENT = IPC_FIRST_USER_METHOD
+} kbdev_notif_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/drv/generic/driver.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -427,5 +427,5 @@
 
 /** Function for handling connections to device driver. */
-static void driver_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void driver_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Select interface */
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/fs/libfs.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -106,5 +106,5 @@
 	 * Ask VFS for callback connection.
 	 */
-	async_connect_to_me(exch, 0, 0, 0, conn);
+	async_connect_to_me(exch, 0, 0, 0, conn, NULL);
 	
 	/*
Index: uspace/lib/net/il/il_skel.c
===================================================================
--- uspace/lib/net/il/il_skel.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/net/il/il_skel.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -51,5 +51,6 @@
  *
  */
-static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
@@ -117,5 +118,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
+	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/netif/netif_skel.c
===================================================================
--- uspace/lib/net/netif/netif_skel.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/net/netif/netif_skel.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -365,5 +365,6 @@
  *
  */
-static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
Index: uspace/lib/net/nil/nil_skel.c
===================================================================
--- uspace/lib/net/nil/nil_skel.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/net/nil/nil_skel.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -51,5 +51,6 @@
  *
  */
-static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
@@ -117,5 +118,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
+	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/tl/tl_skel.c
===================================================================
--- uspace/lib/net/tl/tl_skel.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/net/tl/tl_skel.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -47,9 +47,11 @@
 /** Default thread for new connections.
  *
- * @param[in] iid   The initial message identifier.
- * @param[in] icall The initial message call structure.
+ * @param[in] iid  	The initial message identifier.
+ * @param[in] icall	The initial message call structure.
+ * @param[in] arg	Local argument.
  *
  */
-static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
@@ -119,5 +121,5 @@
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL);
+	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/usbvirt/src/device.c
===================================================================
--- uspace/lib/usbvirt/src/device.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/lib/usbvirt/src/device.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -49,8 +49,9 @@
 /** Main IPC call handling from virtual host controller.
  *
- * @param iid Caller identification.
- * @param icall Initial incoming call.
+ * @param iid		Caller identification
+ * @param icall		Initial incoming call
+ * @param arg		Local argument
  */
-static void callback_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void callback_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	assert(DEV != NULL);
@@ -99,5 +100,5 @@
 	
 	async_exch_t *exch = async_exchange_begin(hcd_sess);
-	rc = async_connect_to_me(exch, 0, 0, 0, callback_connection);
+	rc = async_connect_to_me(exch, 0, 0, 0, callback_connection, NULL);
 	async_exchange_end(exch);
 	
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -105,5 +105,5 @@
 static void print_syntax(void);
 static int ata_bd_init(void);
-static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt,
     void *buf);
@@ -274,5 +274,5 @@
 
 /** Block device connection handler */
-static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	void *fs_va = NULL;
Index: uspace/srv/bd/file_bd/file_bd.c
===================================================================
--- uspace/srv/bd/file_bd/file_bd.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/bd/file_bd/file_bd.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -66,5 +66,5 @@
 static void print_usage(void);
 static int file_bd_init(const char *fname);
-static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf);
 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf);
@@ -170,5 +170,5 @@
 }
 
-static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	void *fs_va = NULL;
Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -97,5 +97,5 @@
 
 static int gxe_bd_init(void);
-static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt,
     void *buf);
@@ -153,5 +153,5 @@
 }
 
-static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	void *fs_va = NULL;
Index: uspace/srv/bd/part/guid_part/guid_part.c
===================================================================
--- uspace/srv/bd/part/guid_part/guid_part.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/bd/part/guid_part/guid_part.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -99,5 +99,5 @@
 static part_t *gpt_part_new(void);
 static void gpt_pte_to_part(const gpt_entry_t *pte, part_t *part);
-static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 static int gpt_bd_read(part_t *p, aoff64_t ba, size_t cnt, void *buf);
 static int gpt_bd_write(part_t *p, aoff64_t ba, size_t cnt, const void *buf);
@@ -307,5 +307,5 @@
 }
 
-static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void gpt_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	size_t comm_size;
Index: uspace/srv/bd/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/bd/part/mbr_part/mbr_part.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/bd/part/mbr_part/mbr_part.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -150,5 +150,5 @@
 static part_t *mbr_part_new(void);
 static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
-static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 static int mbr_bd_read(part_t *p, uint64_t ba, size_t cnt, void *buf);
 static int mbr_bd_write(part_t *p, uint64_t ba, size_t cnt, const void *buf);
@@ -385,5 +385,5 @@
 }
 
-static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	size_t comm_size;
Index: uspace/srv/bd/rd/rd.c
===================================================================
--- uspace/srv/bd/rd/rd.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/bd/rd/rd.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -84,5 +84,5 @@
  * @param icall Call data of the request that opened the connection.
  */
-static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void rd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/clip/clip.c
===================================================================
--- uspace/srv/clip/clip.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/clip/clip.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -148,5 +148,5 @@
 }
 
-static void clip_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void clip_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Accept connection */
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/devman/main.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -694,5 +694,5 @@
 
 /** Function for handling connections to device manager. */
-static void devman_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void devman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Select interface. */
Index: uspace/srv/devmap/devmap.c
===================================================================
--- uspace/srv/devmap/devmap.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/devmap/devmap.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -1124,5 +1124,5 @@
  *
  */
-static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Select interface */
Index: uspace/srv/fs/devfs/devfs.c
===================================================================
--- uspace/srv/fs/devfs/devfs.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/fs/devfs/devfs.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -59,5 +59,5 @@
 fs_reg_t devfs_reg;
 
-static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	if (iid)
Index: uspace/srv/fs/ext2fs/ext2fs.c
===================================================================
--- uspace/srv/fs/ext2fs/ext2fs.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/fs/ext2fs/ext2fs.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -75,5 +75,5 @@
  * request has been completed.
  */
-static void ext2fs_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void ext2fs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	if (iid) {
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/fs/fat/fat.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -76,5 +76,5 @@
  * request has been completed.
  */
-static void fat_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void fat_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	if (iid) {
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -82,5 +82,5 @@
  * request has been completed.
  */
-static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	if (iid) {
Index: uspace/srv/hid/adb_mouse/adb_dev.c
===================================================================
--- uspace/srv/hid/adb_mouse/adb_dev.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/adb_mouse/adb_dev.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -48,5 +48,5 @@
 #include "adb_dev.h"
 
-static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall);
+static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 
 int adb_dev_init(void)
@@ -68,5 +68,6 @@
 	
 	/* NB: The callback connection is slotted for removal */
-	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, adb_dev_events) != 0) {
+	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, adb_dev_events,
+	    NULL) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
 		return false;
@@ -76,5 +77,5 @@
 }
 
-static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall)
+static void adb_dev_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Ignore parameters, the connection is already opened */
Index: uspace/srv/hid/adb_mouse/adb_mouse.c
===================================================================
--- uspace/srv/hid/adb_mouse/adb_mouse.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/adb_mouse/adb_mouse.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -52,5 +52,5 @@
 #include <kernel/ipc/ipc_methods.h>
 
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 static void mouse_ev_btn(int button, int press);
 static void mouse_ev_move(int dx, int dy);
@@ -94,5 +94,5 @@
 }
 
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hid/char_mouse/char_mouse.c
===================================================================
--- uspace/srv/hid/char_mouse/char_mouse.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/char_mouse/char_mouse.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -79,5 +79,5 @@
 }
 
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hid/char_mouse/chardev.c
===================================================================
--- uspace/srv/hid/char_mouse/chardev.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/char_mouse/chardev.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -45,5 +45,5 @@
 #include <mouse_port.h>
 
-static void chardev_events(ipc_callid_t iid, ipc_call_t *icall);
+static void chardev_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 
 static int dev_phone;
@@ -69,5 +69,6 @@
 	
 	/* NB: The callback connection is slotted for removal */
-	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, chardev_events) != 0) {
+	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, chardev_events,
+	    NULL) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
 		return false;
@@ -90,5 +91,5 @@
 }
 
-static void chardev_events(ipc_callid_t iid, ipc_call_t *icall)
+static void chardev_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Ignore parameters, the connection is already opened */
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/console/console.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -34,7 +35,6 @@
 
 #include <libc.h>
-#include <ipc/kbd.h>
+#include <ipc/input.h>
 #include <io/keycode.h>
-#include <ipc/mouse.h>
 #include <ipc/fb.h>
 #include <ipc/services.h>
@@ -60,5 +60,4 @@
 #include <io/style.h>
 #include <io/screenbuffer.h>
-#include <inttypes.h>
 
 #include "console.h"
@@ -66,24 +65,9 @@
 #include "keybuffer.h"
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 #define NAME       "console"
 #define NAMESPACE  "term"
 
-/** Interval for checking for new keyboard (1/4s). */
-#define HOTPLUG_WATCH_INTERVAL (1000 * 250)
-
-/* Kernel defines 32 but does not export it. */
-#define MAX_IPC_OUTGOING_PHONES 128
-
-/** To allow proper phone closing. */
-static ipc_callid_t driver_phones[MAX_IPC_OUTGOING_PHONES] = { 0 };
-
-/** Phone to the keyboard driver. */
-static int kbd_phone;
-
-/** Phone to the mouse driver. */
-static int mouse_phone;
+/** Phone to the input server. */
+static int input_phone;
 
 /** Information about framebuffer */
@@ -155,12 +139,12 @@
 }
 
-static void kbd_yield(void)
-{
-	async_obsolete_req_0_0(kbd_phone, KBD_YIELD);
-}
-
-static void kbd_reclaim(void)
-{
-	async_obsolete_req_0_0(kbd_phone, KBD_RECLAIM);
+static void input_yield(void)
+{
+	async_obsolete_req_0_0(input_phone, INPUT_YIELD);
+}
+
+static void input_reclaim(void)
+{
+	async_obsolete_req_0_0(input_phone, INPUT_RECLAIM);
 }
 
@@ -343,5 +327,5 @@
 		gcons_in_kernel();
 		screen_yield();
-		kbd_yield();
+		input_yield();
 		async_obsolete_serialize_end();
 		
@@ -358,5 +342,5 @@
 		if (active_console == kernel_console) {
 			screen_reclaim();
-			kbd_reclaim();
+			input_reclaim();
 			gcons_redraw_console();
 		}
@@ -413,19 +397,6 @@
 }
 
-static void close_driver_phone(ipc_callid_t hash)
-{
-	int i;
-	for (i = 0; i < MAX_IPC_OUTGOING_PHONES; i++) {
-		if (driver_phones[i] == hash) {
-			printf("Device %" PRIxn " gone.\n", hash);
-			driver_phones[i] = 0;
-			async_obsolete_hangup(i);
-			return;
-		}
-	}
-}
-
-/** Handler for keyboard */
-static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
+/** Handler for input events */
+static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Ignore parameters, the connection is already opened */
@@ -439,11 +410,11 @@
 		if (!IPC_GET_IMETHOD(call)) {
 			/* TODO: Handle hangup */
-			close_driver_phone(iid);
+			async_obsolete_hangup(input_phone);
 			return;
 		}
 		
 		switch (IPC_GET_IMETHOD(call)) {
-		case KBD_EVENT:
-			/* Got event from keyboard driver. */
+		case INPUT_EVENT_KEY:
+			/* Got key press/release event */
 			retval = 0;
 			ev.type = IPC_GET_ARG1(call);
@@ -466,29 +437,12 @@
 			fibril_mutex_unlock(&input_mutex);
 			break;
-		default:
-			retval = ENOENT;
-		}
-		async_answer_0(callid, retval);
-	}
-}
-
-/** Handler for mouse events */
-static void mouse_events(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/* Ignore parameters, the connection is already opened */
-	while (true) {
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		int retval;
-		
-		if (!IPC_GET_IMETHOD(call)) {
-			/* TODO: Handle hangup */
-			close_driver_phone(iid);
-			return;
-		}
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case MEVENT_BUTTON:
+		case INPUT_EVENT_MOVE:
+			/* Got pointer move event */
+			gcons_mouse_move((int) IPC_GET_ARG1(call),
+			    (int) IPC_GET_ARG2(call));
+			retval = 0;
+			break;
+		case INPUT_EVENT_BUTTON:
+			/* Got pointer button press/release event */
 			if (IPC_GET_ARG1(call) == 1) {
 				int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
@@ -498,13 +452,7 @@
 			retval = 0;
 			break;
-		case MEVENT_MOVE:
-			gcons_mouse_move((int) IPC_GET_ARG1(call),
-			    (int) IPC_GET_ARG2(call));
-			retval = 0;
-			break;
 		default:
 			retval = ENOENT;
 		}
-
 		async_answer_0(callid, retval);
 	}
@@ -597,5 +545,5 @@
 
 /** Default thread for new connections */
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	console_t *cons = NULL;
@@ -747,31 +695,10 @@
 }
 
-static int async_connect_to_me_hack(int phone, sysarg_t arg1, sysarg_t arg2,
-    sysarg_t arg3, async_client_conn_t client_receiver, ipc_callid_t *hash)
-{
-	sysarg_t task_hash;
-	sysarg_t phone_hash;
-	int rc = async_obsolete_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
-	    NULL, NULL, NULL, &task_hash, &phone_hash);
-	if (rc != EOK)
-		return rc;
-	
-	if (client_receiver != NULL)
-		async_new_connection(task_hash, phone_hash, phone_hash, NULL,
-		    client_receiver);
-	
-	if (hash != NULL)
-		*hash = phone_hash;
-	
-	return EOK;
-}
-
-static int connect_keyboard_or_mouse(const char *devname,
-    async_client_conn_t handler, const char *dev)
+static int connect_input(const char *dev_path)
 {
 	int phone;
 	devmap_handle_t handle;
 	
-	int rc = devmap_device_get_handle(dev, &handle, 0);
+	int rc = devmap_device_get_handle(dev_path, &handle, 0);
 	if (rc == EOK) {
 		phone = devmap_obsolete_device_connect(handle, 0);
@@ -780,11 +707,12 @@
 			return phone;
 		}
-	} else
+	} else {
 		return rc;
+	}
 	
 	/* NB: The callback connection is slotted for removal */
-	ipc_callid_t hash;
-	rc = async_connect_to_me_hack(phone, SERVICE_CONSOLE, 0, phone,
-	    handler, &hash);
+	rc = async_obsolete_connect_to_me(phone, SERVICE_CONSOLE, 0, 0,
+	    input_events, NULL);
+
 	if (rc != EOK) {
 		async_obsolete_hangup(phone);
@@ -794,100 +722,13 @@
 	}
 	
-	driver_phones[phone] = hash;
-	printf("%s: found %s \"%s\" (%" PRIxn ").\n", NAME, devname, dev, hash);
 	return phone;
 }
 
-static int connect_keyboard(const char *dev)
-{
-	return connect_keyboard_or_mouse("keyboard", keyboard_events, dev);
-}
-
-static int connect_mouse(const char *dev)
-{
-	return connect_keyboard_or_mouse("mouse", mouse_events, dev);
-}
-
-struct hid_class_info {
-	char *classname;
-	int (*connection_func)(const char *);
-};
-
-/** Periodically check for new keyboards in /dev/class/.
- *
- * @param arg Class name.
- *
- * @return This function should never exit.
- *
- */
-static int check_new_device_fibril(void *arg)
-{
-	struct hid_class_info *dev_info = (struct hid_class_info *) arg;
-	
-	size_t index = 1;
-	
-	while (true) {
-		async_usleep(HOTPLUG_WATCH_INTERVAL);
-		
-		char *dev;
-		int rc = asprintf(&dev, "class/%s\\%zu",
-		    dev_info->classname, index);
-		if (rc < 0)
-			continue;
-		
-		rc = dev_info->connection_func(dev);
-		if (rc > 0) {
-			/* We do not allow unplug. */
-			index++;
-		}
-		
-		free(dev);
-	}
-	
-	return EOK;
-}
-
-/** Start a fibril monitoring hot-plugged keyboards.
- */
-static void check_new_devices_in_background(int (*connection_func)(const char *),
-    const char *classname)
-{
-	struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
-	if (dev_info == NULL) {
-		printf("%s: Out of memory, no hot-plug support.\n", NAME);
-		return;
-	}
-	
-	int rc = asprintf(&dev_info->classname, "%s", classname);
-	if (rc < 0) {
-		printf("%s: Failed to format classname: %s.\n", NAME,
-		    str_error(rc));
-		return;
-	}
-	
-	dev_info->connection_func = connection_func;
-	
-	fid_t fid = fibril_create(check_new_device_fibril, (void *) dev_info);
-	if (!fid) {
-		printf("%s: Failed to create hot-plug fibril for %s.\n", NAME,
-		    classname);
-		return;
-	}
-	
-	fibril_add_ready(fid);
-}
-
-static bool console_srv_init(char *kdev)
-{
-	/* Connect to input device */
-	kbd_phone = connect_keyboard(kdev);
-	if (kbd_phone < 0)
+static bool console_srv_init(char *input_dev)
+{
+	/* Connect to input server */
+	input_phone = connect_input(input_dev);
+	if (input_phone < 0)
 		return false;
-	
-	mouse_phone = connect_mouse("hid_in/mouse");
-	if (mouse_phone < 0) {
-		printf("%s: Failed to connect to mouse device %s\n", NAME,
-		    str_error(mouse_phone));
-	}
 	
 	/* Connect to framebuffer driver */
@@ -972,8 +813,4 @@
 		printf("%s: Error registering kconsole notifications\n", NAME);
 	
-	/* Start fibril for checking on hot-plugged keyboards. */
-	check_new_devices_in_background(connect_keyboard, "keyboard");
-	check_new_devices_in_background(connect_mouse, "mouse");
-	
 	return true;
 }
@@ -981,5 +818,5 @@
 static void usage(void)
 {
-	printf("Usage: console <input>\n");
+	printf("Usage: console <input_dev>\n");
 }
 
Index: uspace/srv/hid/console/gcons.c
===================================================================
--- uspace/srv/hid/console/gcons.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/console/gcons.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -168,6 +168,8 @@
 void gcons_change_console(size_t index)
 {
-	if (!use_gcons)
-		return;
+	if (!use_gcons) {
+		active_console = index;
+		return;
+	}
 	
 	if (active_console == KERNEL_CONSOLE) {
Index: uspace/srv/hid/fb/ega.c
===================================================================
--- uspace/srv/hid/fb/ega.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/fb/ega.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -256,5 +256,6 @@
 }
 
-static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	size_t intersize = 0;
Index: uspace/srv/hid/fb/fb.c
===================================================================
--- uspace/srv/hid/fb/fb.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/fb/fb.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -1576,5 +1576,6 @@
  *
  */
-static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	unsigned int vp = 0;
Index: uspace/srv/hid/fb/serial_console.c
===================================================================
--- uspace/srv/hid/fb/serial_console.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/fb/serial_console.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -315,5 +315,5 @@
  * Main function of the thread serving client connections.
  */
-void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	keyfield_t *interbuf = NULL;
Index: uspace/srv/hid/fb/serial_console.h
===================================================================
--- uspace/srv/hid/fb/serial_console.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/fb/serial_console.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -52,5 +52,5 @@
 extern void serial_set_scroll_region(sysarg_t);
 extern void serial_console_init(putc_function_t, sysarg_t, sysarg_t);
-extern void serial_client_connection(ipc_callid_t, ipc_call_t *);
+extern void serial_client_connection(ipc_callid_t, ipc_call_t *, void *arg);
 
 #endif
Index: uspace/srv/hid/input/Makefile
===================================================================
--- uspace/srv/hid/input/Makefile	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/Makefile	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,60 @@
+#
+# 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 = ../../..
+EXTRA_CFLAGS = -Iinclude
+BINARY = input
+
+SOURCES = \
+	generic/gsp.c \
+	generic/input.c \
+	generic/layout.c \
+	generic/mouse.c \
+	generic/stroke.c \
+	layout/cz.c \
+	layout/us_qwerty.c \
+	layout/us_dvorak.c \
+	port/adb.c \
+	port/chardev.c \
+	port/gxemul.c \
+	port/msim.c \
+	port/niagara.c \
+	port/ns16550.c \
+	port/pl050.c \
+	port/sgcn.c \
+	port/ski.c \
+	port/z8530.c \
+	ctl/apple.c \
+	ctl/gxe_fb.c \
+	ctl/kbdev.c \
+	ctl/pc.c \
+	ctl/stty.c \
+	ctl/sun.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hid/input/ctl/apple.c
===================================================================
--- uspace/srv/hid/input/ctl/apple.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/ctl/apple.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2011 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_ctl
+ * @ingroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief	Apple ADB keyboard controller driver.
+ */
+
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <kbd_ctl.h>
+#include <kbd_port.h>
+
+static void apple_ctl_parse_scancode(int);
+static int apple_ctl_init(kbd_dev_t *);
+static void apple_ctl_set_ind(kbd_dev_t *, unsigned);
+
+kbd_ctl_ops_t apple_ctl = {
+	.parse_scancode = apple_ctl_parse_scancode,
+	.init = apple_ctl_init,
+	.set_ind = apple_ctl_set_ind
+};
+
+#define KBD_KEY_RELEASE		0x80
+
+static kbd_dev_t *kbd_dev;
+
+static int scanmap[];
+
+static int apple_ctl_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	return 0;
+}
+
+static void apple_ctl_parse_scancode(int scancode)
+{
+	kbd_event_type_t type;
+	unsigned int key;
+
+	if (scancode < 0 || scancode >= 0x100)
+		return;
+
+	if (scancode & KBD_KEY_RELEASE) {
+		scancode &= ~KBD_KEY_RELEASE;
+		type = KEY_RELEASE;
+	} else {
+		type = KEY_PRESS;
+	}
+
+	key = scanmap[scancode];
+	if (key != 0)
+		kbd_push_ev(kbd_dev, type, key);
+}
+
+static void apple_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
+{
+	(void) mods;
+}
+
+static int scanmap[] = {
+	[0x00] = KC_A,
+	[0x01] = KC_S,
+	[0x02] = KC_D,
+	[0x03] = KC_F,
+	[0x04] = KC_H,
+	[0x05] = KC_G,
+	[0x06] = KC_Z,
+	[0x07] = KC_X,
+	[0x08] = KC_C,
+	[0x09] = KC_V,
+	[0x0a] = KC_BACKSLASH,
+	[0x0b] = KC_B,
+	[0x0c] = KC_Q,
+	[0x0d] = KC_W,
+	[0x0e] = KC_E,
+	[0x0f] = KC_R,
+	[0x10] = KC_Y,
+	[0x11] = KC_T,
+	[0x12] = KC_1,
+	[0x13] = KC_2,
+	[0x14] = KC_3,
+	[0x15] = KC_4,
+	[0x16] = KC_6,
+	[0x17] = KC_5,
+	[0x18] = KC_EQUALS,
+	[0x19] = KC_9,
+	[0x1a] = KC_7,
+	[0x1b] = KC_MINUS,
+	[0x1c] = KC_8,
+	[0x1d] = KC_0,
+	[0x1e] = KC_RBRACKET,
+	[0x1f] = KC_O,
+	[0x20] = KC_U,
+	[0x21] = KC_LBRACKET,
+	[0x22] = KC_I,
+	[0x23] = KC_P,
+	[0x24] = KC_ENTER,
+	[0x25] = KC_L,
+	[0x26] = KC_J,
+	[0x27] = KC_QUOTE,
+	[0x28] = KC_K,
+	[0x29] = KC_SEMICOLON,
+	[0x2a] = KC_BACKSLASH,
+	[0x2b] = KC_COMMA,
+	[0x2c] = KC_SLASH,
+	[0x2d] = KC_N,
+	[0x2e] = KC_M,
+	[0x2f] = KC_PERIOD,
+	[0x30] = KC_TAB,
+	[0x31] = KC_SPACE,
+	[0x32] = KC_BACKTICK,
+	[0x33] = KC_BACKSPACE,
+	[0x34] = 0,
+	[0x35] = KC_ESCAPE,
+	[0x36] = KC_LCTRL,
+	[0x37] = 0,
+	[0x38] = KC_LSHIFT,
+	[0x39] = KC_CAPS_LOCK,
+	[0x3a] = KC_LALT,
+	[0x3b] = KC_LEFT,
+	[0x3c] = KC_RIGHT,
+	[0x3d] = KC_DOWN,
+	[0x3e] = KC_UP,
+	[0x3f] = 0,
+	[0x40] = 0,
+	[0x41] = KC_NPERIOD,
+	[0x42] = 0,
+	[0x43] = KC_NTIMES,
+	[0x44] = 0,
+	[0x45] = KC_NPLUS,
+	[0x46] = 0,
+	[0x47] = KC_NUM_LOCK,
+	[0x48] = 0,
+	[0x49] = 0,
+	[0x4a] = 0,
+	[0x4b] = KC_NSLASH,
+	[0x4c] = KC_NENTER,
+	[0x4d] = 0,
+	[0x4e] = KC_NMINUS,
+	[0x4f] = 0,
+	[0x50] = 0,
+	[0x51] = 0,
+	[0x52] = KC_N0,
+	[0x53] = KC_N1,
+	[0x54] = KC_N2,
+	[0x55] = KC_N3,
+	[0x56] = KC_N4,
+	[0x57] = KC_N5,
+	[0x58] = KC_N6,
+	[0x59] = KC_N7,
+	[0x5a] = 0,
+	[0x5b] = KC_N8,
+	[0x5c] = KC_N9,
+	[0x5d] = 0,
+	[0x5e] = 0,
+	[0x5f] = 0,
+	[0x60] = KC_F5,
+	[0x61] = KC_F6,
+	[0x62] = KC_F7,
+	[0x63] = KC_F3,
+	[0x64] = KC_F8,
+	[0x65] = KC_F9,
+	[0x66] = 0,
+	[0x67] = KC_F11,
+	[0x68] = 0,
+	[0x69] = 0,
+	[0x6a] = 0,
+	[0x6b] = KC_SCROLL_LOCK,
+	[0x6c] = 0,
+	[0x6d] = KC_F10,
+	[0x6e] = 0,
+	[0x6f] = KC_F12,
+	[0x70] = 0,
+	[0x71] = 0,
+	[0x72] = KC_INSERT,
+	[0x73] = KC_HOME,
+	[0x74] = KC_PAGE_UP,
+	[0x75] = KC_DELETE,
+	[0x76] = KC_F4,
+	[0x77] = KC_END,
+	[0x78] = KC_F2,
+	[0x79] = KC_PAGE_DOWN,
+	[0x7a] = KC_F1,
+	[0x7b] = KC_RSHIFT,
+	[0x7c] = KC_RALT,
+	[0x7d] = KC_RCTRL,
+	[0x7e] = 0,
+	[0x7f] = 0
+};
+
+/** @}
+ */
Index: uspace/srv/hid/input/ctl/gxe_fb.c
===================================================================
--- uspace/srv/hid/input/ctl/gxe_fb.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/ctl/gxe_fb.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2011 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_ctl
+ * @ingroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief	GXEmul framebuffer-mode keyboard controller driver.
+ */
+
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <kbd_ctl.h>
+#include <kbd_port.h>
+#include <gsp.h>
+#include <stroke.h>
+
+static void gxe_fb_ctl_parse_scancode(int);
+static int gxe_fb_ctl_init(kbd_dev_t *);
+static void gxe_fb_ctl_set_ind(kbd_dev_t *, unsigned);
+
+kbd_ctl_ops_t gxe_fb_ctl = {
+	.parse_scancode = gxe_fb_ctl_parse_scancode,
+	.init = gxe_fb_ctl_init,
+	.set_ind = gxe_fb_ctl_set_ind
+};
+
+static kbd_dev_t *kbd_dev;
+
+/** Scancode parser */
+static gsp_t sp;
+
+/** Current parser state */
+static int ds;
+
+#include <stdio.h>
+
+static int seq_defs[] = {
+	/* Not shifted */
+
+	0,	KC_BACKTICK,	0x60, GSP_END,
+
+	0,	KC_1,		0x31, GSP_END,
+	0,	KC_2,		0x32, GSP_END,
+	0,	KC_3,		0x33, GSP_END,
+	0,	KC_4,		0x34, GSP_END,
+	0,	KC_5,		0x35, GSP_END,
+	0,	KC_6,		0x36, GSP_END,
+	0,	KC_7,		0x37, GSP_END,
+	0,	KC_8,		0x38, GSP_END,
+	0,	KC_9,		0x39, GSP_END,
+	0,	KC_0,		0x30, GSP_END,
+
+	0,	KC_MINUS,	0x2d, GSP_END,
+	0,	KC_EQUALS,	0x3d, GSP_END,
+	0,	KC_BACKSPACE,	0x08, GSP_END,
+
+	0,	KC_TAB,		0x09, GSP_END,
+
+	0,	KC_Q,		0x71, GSP_END,
+	0,	KC_W,		0x77, GSP_END,
+	0,	KC_E,		0x65, GSP_END,
+	0,	KC_R,		0x72, GSP_END,
+	0,	KC_T,		0x74, GSP_END,
+	0,	KC_Y,		0x79, GSP_END,
+	0,	KC_U,		0x75, GSP_END,
+	0,	KC_I,		0x69, GSP_END,
+	0,	KC_O,		0x6f, GSP_END,
+	0,	KC_P,		0x70, GSP_END,
+
+	0,	KC_LBRACKET,	0x5b, GSP_END,
+	0,	KC_RBRACKET,	0x5d, GSP_END,
+
+	0,	KC_A,		0x61, GSP_END,
+	0,	KC_S,		0x73, GSP_END,
+	0,	KC_D,		0x64, GSP_END,
+	0,	KC_F,		0x66, GSP_END,
+	0,	KC_G,		0x67, GSP_END,
+	0,	KC_H,		0x68, GSP_END,
+	0,	KC_J,		0x6a, GSP_END,
+	0,	KC_K,		0x6b, GSP_END,
+	0,	KC_L,		0x6c, GSP_END,
+
+	0,	KC_SEMICOLON,	0x3b, GSP_END,
+	0,	KC_QUOTE,	0x27, GSP_END,
+	0,	KC_BACKSLASH,	0x5c, GSP_END,
+
+	0,	KC_Z,		0x7a, GSP_END,
+	0,	KC_X,		0x78, GSP_END,
+	0,	KC_C,		0x63, GSP_END,
+	0,	KC_V,		0x76, GSP_END,
+	0,	KC_B,		0x62, GSP_END,
+	0,	KC_N,		0x6e, GSP_END,
+	0,	KC_M,		0x6d, GSP_END,
+
+	0,	KC_COMMA,	0x2c, GSP_END,
+	0,	KC_PERIOD,	0x2e, GSP_END,
+	0,	KC_SLASH,	0x2f, GSP_END,
+
+	/* Shifted */
+
+	KM_SHIFT,	KC_BACKTICK,	0x7e, GSP_END,
+
+	KM_SHIFT,	KC_1,		0x21, GSP_END,
+	KM_SHIFT,	KC_2,		0x40, GSP_END,
+	KM_SHIFT,	KC_3,		0x23, GSP_END,
+	KM_SHIFT,	KC_4,		0x24, GSP_END,
+	KM_SHIFT,	KC_5,		0x25, GSP_END,
+	KM_SHIFT,	KC_6,		0x5e, GSP_END,
+	KM_SHIFT,	KC_7,		0x26, GSP_END,
+	KM_SHIFT,	KC_8,		0x2a, GSP_END,
+	KM_SHIFT,	KC_9,		0x28, GSP_END,
+	KM_SHIFT,	KC_0,		0x29, GSP_END,
+
+	KM_SHIFT,	KC_MINUS,	0x5f, GSP_END,
+	KM_SHIFT,	KC_EQUALS,	0x2b, GSP_END,
+
+	KM_SHIFT,	KC_Q,		0x51, GSP_END,
+	KM_SHIFT,	KC_W,		0x57, GSP_END,
+	KM_SHIFT,	KC_E,		0x45, GSP_END,
+	KM_SHIFT,	KC_R,		0x52, GSP_END,
+	KM_SHIFT,	KC_T,		0x54, GSP_END,
+	KM_SHIFT,	KC_Y,		0x59, GSP_END,
+	KM_SHIFT,	KC_U,		0x55, GSP_END,
+	KM_SHIFT,	KC_I,		0x49, GSP_END,
+	KM_SHIFT,	KC_O,		0x4f, GSP_END,
+	KM_SHIFT,	KC_P,		0x50, GSP_END,
+
+	KM_SHIFT,	KC_LBRACKET,	0x7b, GSP_END,
+	KM_SHIFT,	KC_RBRACKET,	0x7d, GSP_END,
+
+	KM_SHIFT,	KC_A,		0x41, GSP_END,
+	KM_SHIFT,	KC_S,		0x53, GSP_END,
+	KM_SHIFT,	KC_D,		0x44, GSP_END,
+	KM_SHIFT,	KC_F,		0x46, GSP_END,
+	KM_SHIFT,	KC_G,		0x47, GSP_END,
+	KM_SHIFT,	KC_H,		0x48, GSP_END,
+	KM_SHIFT,	KC_J,		0x4a, GSP_END,
+	KM_SHIFT,	KC_K,		0x4b, GSP_END,
+	KM_SHIFT,	KC_L,		0x4c, GSP_END,
+
+	KM_SHIFT,	KC_SEMICOLON,	0x3a, GSP_END,
+	KM_SHIFT,	KC_QUOTE,	0x22, GSP_END,
+	KM_SHIFT,	KC_BACKSLASH,	0x7c, GSP_END,
+
+	KM_SHIFT,	KC_Z,		0x5a, GSP_END,
+	KM_SHIFT,	KC_X,		0x58, GSP_END,
+	KM_SHIFT,	KC_C,		0x43, GSP_END,
+	KM_SHIFT,	KC_V,		0x56, GSP_END,
+	KM_SHIFT,	KC_B,		0x42, GSP_END,
+	KM_SHIFT,	KC_N,		0x4e, GSP_END,
+	KM_SHIFT,	KC_M,		0x4d, GSP_END,
+
+	KM_SHIFT,	KC_COMMA,	0x3c, GSP_END,
+	KM_SHIFT,	KC_PERIOD,	0x3e, GSP_END,
+	KM_SHIFT,	KC_SLASH,	0x3f, GSP_END,
+
+	/* ... */
+
+	0,	KC_SPACE,	0x20, GSP_END,
+	0,	KC_ENTER,	0x0a, GSP_END,
+	0,	KC_ENTER,	0x0d, GSP_END,
+
+	0,	KC_ESCAPE,	0x1b, 0x1b, GSP_END,
+
+	0,	KC_F1,		0x1b, 0x5b, 0x4f, 0x50, GSP_END,
+	0,	KC_F2,		0x1b, 0x5b, 0x4f, 0x51, GSP_END,
+	0,	KC_F3,		0x1b, 0x5b, 0x4f, 0x52, GSP_END,
+	0,	KC_F4,		0x1b, 0x5b, 0x4f, 0x53, GSP_END,
+	0,	KC_F5,		0x1b, 0x5b, 0x31, 0x35, GSP_END,
+	0,	KC_F6,		0x1b, 0x5b, 0x31, 0x37, GSP_END,
+	0,	KC_F7,		0x1b, 0x5b, 0x31, 0x38, GSP_END,
+	0,	KC_F8,		0x1b, 0x5b, 0x31, 0x39, GSP_END,
+	0,	KC_F9,		0x1b, 0x5b, 0x32, 0x38, GSP_END,
+	0,	KC_F10,		0x1b, 0x5b, 0x32, 0x39, GSP_END,
+	0,	KC_F11,		0x1b, 0x5b, 0x32, 0x33, GSP_END,
+	0,	KC_F12,		0x1b, 0x5b, 0x32, 0x34, GSP_END,
+
+	0,	KC_INSERT,	0x1b, 0x5b, 0x32, 0x7e, GSP_END,
+	0,	KC_HOME,	0x1b, 0x5b, 0x48, GSP_END,
+	0,	KC_PAGE_UP,	0x1b, 0x5b, 0x35, 0x7e, GSP_END,
+	0,	KC_DELETE,	0x1b, 0x5b, 0x33, 0x7e, GSP_END,
+	0,	KC_END,		0x1b, 0x5b, 0x46, GSP_END,
+	0,	KC_PAGE_DOWN,	0x1b, 0x5b, 0x36, 0x7e, GSP_END,
+
+	0,	KC_UP,		0x1b, 0x5b, 0x41, GSP_END,
+	0,	KC_LEFT,	0x1b, 0x5b, 0x44, GSP_END,
+	0,	KC_DOWN,	0x1b, 0x5b, 0x42, GSP_END,
+	0,	KC_RIGHT,	0x1b, 0x5b, 0x43, GSP_END,
+
+	0,	0
+};
+
+static int gxe_fb_ctl_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	ds = 0;
+
+	gsp_init(&sp);
+	return gsp_insert_defs(&sp, seq_defs);
+}
+
+static void gxe_fb_ctl_parse_scancode(int scancode)
+{
+	unsigned mods, key;
+
+	ds = gsp_step(&sp, ds, scancode, &mods, &key);
+	if (key != 0) {
+		stroke_sim(kbd_dev, mods, key);
+	}
+}
+
+static void gxe_fb_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
+{
+	(void) mods;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/ctl/kbdev.c
===================================================================
--- uspace/srv/hid/input/ctl/kbdev.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/ctl/kbdev.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2011 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_ctl
+ * @ingroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief Keyboard device connector controller driver.
+ */
+
+#include <async.h>
+#include <bool.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <gsp.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <ipc/kbdev.h>
+#include <input.h>
+#include <kbd.h>
+#include <kbd_ctl.h>
+#include <kbd_port.h>
+#include <stdlib.h>
+#include <vfs/vfs_sess.h>
+
+
+static int kbdev_ctl_init(kbd_dev_t *);
+static void kbdev_ctl_set_ind(kbd_dev_t *, unsigned);
+
+static void kbdev_callback_conn(ipc_callid_t, ipc_call_t *, void *arg);
+
+kbd_ctl_ops_t kbdev_ctl = {
+	.parse_scancode = NULL,
+	.init = kbdev_ctl_init,
+	.set_ind = kbdev_ctl_set_ind
+};
+
+/** Kbdev softstate */
+typedef struct {
+	/** Link to generic keyboard device */
+	kbd_dev_t *kbd_dev;
+
+	/** Session with kbdev device */
+	async_sess_t *sess;
+
+	/** File descriptor of open kbdev device */
+	int fd;
+} kbdev_t;
+
+static kbdev_t *kbdev_new(kbd_dev_t *kdev)
+{
+	kbdev_t *kbdev;
+
+	kbdev = calloc(1, sizeof(kbdev_t));
+	if (kbdev == NULL)
+		return NULL;
+
+	kbdev->kbd_dev = kdev;
+	kbdev->fd = -1;
+
+	return kbdev;
+}
+
+static void kbdev_destroy(kbdev_t *kbdev)
+{
+	if (kbdev->sess != NULL)
+		async_hangup(kbdev->sess);
+	if (kbdev->fd >= 0)
+		close(kbdev->fd);
+	free(kbdev);
+}
+
+static int kbdev_ctl_init(kbd_dev_t *kdev)
+{
+	const char *pathname;
+	async_sess_t *sess;
+	async_exch_t *exch;
+	kbdev_t *kbdev;
+	int fd;
+	int rc;
+
+	pathname = kdev->dev_path;
+
+	fd = open(pathname, O_RDWR);
+	if (fd < 0) {
+		return -1;
+	}
+
+	sess = fd_session(EXCHANGE_SERIALIZE, fd);
+	if (sess == NULL) {
+		printf(NAME ": Failed starting session with '%s'\n", pathname);
+		close(fd);
+		return -1;
+	}
+
+	kbdev = kbdev_new(kdev);
+	if (kbdev == NULL) {
+		printf(NAME ": Failed allocating device structure for '%s'.\n",
+		    pathname);
+		return -1;
+	}
+
+	kbdev->fd = fd;
+	kbdev->sess = sess;
+
+	exch = async_exchange_begin(sess);
+	if (exch == NULL) {
+		printf(NAME ": Failed starting exchange with '%s'.\n", pathname);
+		kbdev_destroy(kbdev);
+		return -1;
+	}
+
+	rc = async_connect_to_me(exch, 0, 0, 0, kbdev_callback_conn, kbdev);
+	if (rc != EOK) {
+		printf(NAME ": Failed creating callback connection from '%s'.\n",
+		    pathname);
+		async_exchange_end(exch);
+		kbdev_destroy(kbdev);
+		return -1;
+	}
+
+	async_exchange_end(exch);
+
+	kdev->ctl_private = (void *) kbdev;
+	return 0;
+}
+
+static void kbdev_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
+{
+	async_sess_t *sess;
+	async_exch_t *exch;
+
+	sess = ((kbdev_t *) kdev->ctl_private)->sess;
+
+	exch = async_exchange_begin(sess);
+	if (!exch)
+		return;
+
+	async_msg_1(exch, KBDEV_SET_IND, mods);
+	async_exchange_end(exch);
+}
+
+static void kbdev_callback_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	kbdev_t *kbdev;
+	int retval;
+	int type, key;
+
+	/* Kbdev device structure */
+	kbdev = arg;
+
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid;
+
+		callid = async_get_call(&call);
+		if (!IPC_GET_IMETHOD(call)) {
+			/* XXX Handle hangup */
+			return;
+		}
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case KBDEV_EVENT:
+			/* Got event from keyboard device */
+			retval = 0;
+			type = IPC_GET_ARG1(call);
+			key = IPC_GET_ARG2(call);
+			kbd_push_ev(kbdev->kbd_dev, type, key);
+			break;
+		default:
+			retval = ENOTSUP;
+			break;
+		}
+
+		async_answer_0(callid, retval);
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/ctl/pc.c
===================================================================
--- uspace/srv/hid/input/ctl/pc.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/ctl/pc.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2011 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_ctl
+ * @ingroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief PC keyboard controller driver.
+ */
+
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <kbd_ctl.h>
+#include <kbd_port.h>
+#include <gsp.h>
+
+static void pc_ctl_parse_scancode(int);
+static int pc_ctl_init(kbd_dev_t *);
+static void pc_ctl_set_ind(kbd_dev_t *, unsigned);
+
+kbd_ctl_ops_t pc_ctl = {
+	.parse_scancode = pc_ctl_parse_scancode,
+	.init = pc_ctl_init,
+	.set_ind = pc_ctl_set_ind
+};
+
+enum dec_state {
+	ds_s,
+	ds_e
+};
+
+enum special_code {
+	SC_ACK = 0xfa,
+	SC_NAK = 0xfe
+};
+
+enum lock_ind_bits {
+	LI_SCROLL	= 0x01,
+	LI_NUM		= 0x02,
+	LI_CAPS		= 0x04
+};
+
+enum kbd_command {
+	KBD_CMD_SET_LEDS = 0xed
+};
+
+static enum dec_state ds;
+static kbd_dev_t *kbd_dev;
+
+static int scanmap_simple[] = {
+
+	[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,
+
+	[0x46] = KC_SCROLL_LOCK,
+
+	[0x1c] = KC_ENTER,
+
+	[0x45] = KC_NUM_LOCK,
+	[0x37] = KC_NTIMES,
+	[0x4a] = KC_NMINUS,
+	[0x4e] = KC_NPLUS,
+	[0x47] = KC_N7,
+	[0x48] = KC_N8,
+	[0x49] = KC_N9,
+	[0x4b] = KC_N4,
+	[0x4c] = KC_N5,
+	[0x4d] = KC_N6,
+	[0x4f] = KC_N1,
+	[0x50] = KC_N2,
+	[0x51] = KC_N3,
+	[0x52] = KC_N0,
+	[0x53] = KC_NPERIOD
+};
+
+static int scanmap_e0[] = {
+	[0x38] = KC_RALT,
+	[0x1d] = KC_RSHIFT,
+
+	[0x37] = KC_PRTSCR,
+
+	[0x52] = KC_INSERT,
+	[0x47] = KC_HOME,
+	[0x49] = KC_PAGE_UP,
+
+	[0x53] = KC_DELETE,
+	[0x4f] = KC_END,
+	[0x51] = KC_PAGE_DOWN,
+
+	[0x48] = KC_UP,
+	[0x4b] = KC_LEFT,
+	[0x50] = KC_DOWN,
+	[0x4d] = KC_RIGHT,
+
+	[0x35] = KC_NSLASH,
+	[0x1c] = KC_NENTER
+};
+
+static int pc_ctl_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	ds = ds_s;
+	return 0;
+}
+
+static void pc_ctl_parse_scancode(int scancode)
+{
+	kbd_event_type_t type;
+	unsigned int key;
+	int *map;
+	size_t map_length;
+
+	/*
+	 * ACK/NAK are returned as response to us sending a command.
+	 * We are not interested in them.
+	 */
+	if (scancode == SC_ACK || scancode == SC_NAK)
+		return;
+
+	if (scancode == 0xe0) {
+		ds = ds_e;
+		return;
+	}
+
+	switch (ds) {
+	case ds_s:
+		map = scanmap_simple;
+		map_length = sizeof(scanmap_simple) / sizeof(int);
+		break;
+	case ds_e:
+		map = scanmap_e0;
+		map_length = sizeof(scanmap_e0) / sizeof(int);
+		break;
+	default:
+		map = NULL;
+		map_length = 0;
+	}
+
+	ds = ds_s;
+
+	if (scancode & 0x80) {
+		scancode &= ~0x80;
+		type = KEY_RELEASE;
+	} else {
+		type = KEY_PRESS;
+	}
+
+	if ((scancode < 0) || ((size_t) scancode >= map_length))
+		return;
+
+	key = map[scancode];
+	if (key != 0)
+		kbd_push_ev(kbd_dev, type, key);
+}
+
+static void pc_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
+{
+	uint8_t b;
+
+	b = 0;
+	if ((mods & KM_CAPS_LOCK) != 0)
+		b = b | LI_CAPS;
+	if ((mods & KM_NUM_LOCK) != 0)
+		b = b | LI_NUM;
+	if ((mods & KM_SCROLL_LOCK) != 0)
+		b = b | LI_SCROLL;
+
+	(*kbd_dev->port_ops->write)(KBD_CMD_SET_LEDS);
+	(*kbd_dev->port_ops->write)(b);
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/ctl/stty.c
===================================================================
--- uspace/srv/hid/input/ctl/stty.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/ctl/stty.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2011 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_ctl
+ * @ingroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief	Serial TTY-like keyboard controller driver.
+ */
+
+#include <kbd.h>
+#include <io/keycode.h>
+#include <kbd_ctl.h>
+#include <kbd_port.h>
+#include <gsp.h>
+#include <stroke.h>
+
+static void stty_ctl_parse_scancode(int);
+static int stty_ctl_init(kbd_dev_t *);
+static void stty_ctl_set_ind(kbd_dev_t *, unsigned);
+
+kbd_ctl_ops_t stty_ctl = {
+	.parse_scancode = stty_ctl_parse_scancode,
+	.init = stty_ctl_init,
+	.set_ind = stty_ctl_set_ind
+};
+
+static kbd_dev_t *kbd_dev;
+
+/** Scancode parser */
+static gsp_t sp;
+
+/** Current parser state */
+static int ds;
+
+#include <stdio.h>
+
+static int seq_defs[] = {
+	/* Not shifted */
+
+	0,	KC_BACKTICK,	0x60, GSP_END,
+
+	0,	KC_1,		0x31, GSP_END,
+	0,	KC_2,		0x32, GSP_END,
+	0,	KC_3,		0x33, GSP_END,
+	0,	KC_4,		0x34, GSP_END,
+	0,	KC_5,		0x35, GSP_END,
+	0,	KC_6,		0x36, GSP_END,
+	0,	KC_7,		0x37, GSP_END,
+	0,	KC_8,		0x38, GSP_END,
+	0,	KC_9,		0x39, GSP_END,
+	0,	KC_0,		0x30, GSP_END,
+
+	0,	KC_MINUS,	0x2d, GSP_END,
+	0,	KC_EQUALS,	0x3d, GSP_END,
+	0,	KC_BACKSPACE,	0x08, GSP_END,
+
+	0,	KC_TAB,		0x09, GSP_END,
+
+	0,	KC_Q,		0x71, GSP_END,
+	0,	KC_W,		0x77, GSP_END,
+	0,	KC_E,		0x65, GSP_END,
+	0,	KC_R,		0x72, GSP_END,
+	0,	KC_T,		0x74, GSP_END,
+	0,	KC_Y,		0x79, GSP_END,
+	0,	KC_U,		0x75, GSP_END,
+	0,	KC_I,		0x69, GSP_END,
+	0,	KC_O,		0x6f, GSP_END,
+	0,	KC_P,		0x70, GSP_END,
+
+	0,	KC_LBRACKET,	0x5b, GSP_END,
+	0,	KC_RBRACKET,	0x5d, GSP_END,
+
+	0,	KC_A,		0x61, GSP_END,
+	0,	KC_S,		0x73, GSP_END,
+	0,	KC_D,		0x64, GSP_END,
+	0,	KC_F,		0x66, GSP_END,
+	0,	KC_G,		0x67, GSP_END,
+	0,	KC_H,		0x68, GSP_END,
+	0,	KC_J,		0x6a, GSP_END,
+	0,	KC_K,		0x6b, GSP_END,
+	0,	KC_L,		0x6c, GSP_END,
+
+	0,	KC_SEMICOLON,	0x3b, GSP_END,
+	0,	KC_QUOTE,	0x27, GSP_END,
+	0,	KC_BACKSLASH,	0x5c, GSP_END,
+
+	0,	KC_Z,		0x7a, GSP_END,
+	0,	KC_X,		0x78, GSP_END,
+	0,	KC_C,		0x63, GSP_END,
+	0,	KC_V,		0x76, GSP_END,
+	0,	KC_B,		0x62, GSP_END,
+	0,	KC_N,		0x6e, GSP_END,
+	0,	KC_M,		0x6d, GSP_END,
+
+	0,	KC_COMMA,	0x2c, GSP_END,
+	0,	KC_PERIOD,	0x2e, GSP_END,
+	0,	KC_SLASH,	0x2f, GSP_END,
+
+	/* Shifted */
+
+	KM_SHIFT,	KC_BACKTICK,	0x7e, GSP_END,
+
+	KM_SHIFT,	KC_1,		0x21, GSP_END,
+	KM_SHIFT,	KC_2,		0x40, GSP_END,
+	KM_SHIFT,	KC_3,		0x23, GSP_END,
+	KM_SHIFT,	KC_4,		0x24, GSP_END,
+	KM_SHIFT,	KC_5,		0x25, GSP_END,
+	KM_SHIFT,	KC_6,		0x5e, GSP_END,
+	KM_SHIFT,	KC_7,		0x26, GSP_END,
+	KM_SHIFT,	KC_8,		0x2a, GSP_END,
+	KM_SHIFT,	KC_9,		0x28, GSP_END,
+	KM_SHIFT,	KC_0,		0x29, GSP_END,
+
+	KM_SHIFT,	KC_MINUS,	0x5f, GSP_END,
+	KM_SHIFT,	KC_EQUALS,	0x2b, GSP_END,
+
+	KM_SHIFT,	KC_Q,		0x51, GSP_END,
+	KM_SHIFT,	KC_W,		0x57, GSP_END,
+	KM_SHIFT,	KC_E,		0x45, GSP_END,
+	KM_SHIFT,	KC_R,		0x52, GSP_END,
+	KM_SHIFT,	KC_T,		0x54, GSP_END,
+	KM_SHIFT,	KC_Y,		0x59, GSP_END,
+	KM_SHIFT,	KC_U,		0x55, GSP_END,
+	KM_SHIFT,	KC_I,		0x49, GSP_END,
+	KM_SHIFT,	KC_O,		0x4f, GSP_END,
+	KM_SHIFT,	KC_P,		0x50, GSP_END,
+
+	KM_SHIFT,	KC_LBRACKET,	0x7b, GSP_END,
+	KM_SHIFT,	KC_RBRACKET,	0x7d, GSP_END,
+
+	KM_SHIFT,	KC_A,		0x41, GSP_END,
+	KM_SHIFT,	KC_S,		0x53, GSP_END,
+	KM_SHIFT,	KC_D,		0x44, GSP_END,
+	KM_SHIFT,	KC_F,		0x46, GSP_END,
+	KM_SHIFT,	KC_G,		0x47, GSP_END,
+	KM_SHIFT,	KC_H,		0x48, GSP_END,
+	KM_SHIFT,	KC_J,		0x4a, GSP_END,
+	KM_SHIFT,	KC_K,		0x4b, GSP_END,
+	KM_SHIFT,	KC_L,		0x4c, GSP_END,
+
+	KM_SHIFT,	KC_SEMICOLON,	0x3a, GSP_END,
+	KM_SHIFT,	KC_QUOTE,	0x22, GSP_END,
+	KM_SHIFT,	KC_BACKSLASH,	0x7c, GSP_END,
+
+	KM_SHIFT,	KC_Z,		0x5a, GSP_END,
+	KM_SHIFT,	KC_X,		0x58, GSP_END,
+	KM_SHIFT,	KC_C,		0x43, GSP_END,
+	KM_SHIFT,	KC_V,		0x56, GSP_END,
+	KM_SHIFT,	KC_B,		0x42, GSP_END,
+	KM_SHIFT,	KC_N,		0x4e, GSP_END,
+	KM_SHIFT,	KC_M,		0x4d, GSP_END,
+
+	KM_SHIFT,	KC_COMMA,	0x3c, GSP_END,
+	KM_SHIFT,	KC_PERIOD,	0x3e, GSP_END,
+	KM_SHIFT,	KC_SLASH,	0x3f, GSP_END,
+
+	/* ... */
+
+	0,	KC_SPACE,	0x20, GSP_END,
+	0,	KC_ENTER,	0x0a, GSP_END,
+	0,	KC_ENTER,	0x0d, GSP_END,
+
+	0,	KC_ESCAPE,	0x1b, 0x1b, GSP_END,
+
+	0,	KC_F1,		0x1b, 0x4f, 0x50, GSP_END,
+	0,	KC_F2,		0x1b, 0x4f, 0x51, GSP_END,
+	0,	KC_F3,		0x1b, 0x4f, 0x52, GSP_END,
+	0,	KC_F4,		0x1b, 0x4f, 0x53, GSP_END,
+	0,	KC_F5,		0x1b, 0x5b, 0x31, 0x35, 0x7e, GSP_END,
+	0,	KC_F6,		0x1b, 0x5b, 0x31, 0x37, 0x7e, GSP_END,
+	0,	KC_F7,		0x1b, 0x5b, 0x31, 0x38, 0x7e, GSP_END,
+	0,	KC_F8,		0x1b, 0x5b, 0x31, 0x39, 0x7e, GSP_END,
+	0,	KC_F9,		0x1b, 0x5b, 0x32, 0x30, 0x7e, GSP_END,
+	0,	KC_F10,		0x1b, 0x5b, 0x32, 0x31, 0x7e, GSP_END,
+	0,	KC_F11,		0x1b, 0x5b, 0x32, 0x33, 0x7e, GSP_END,
+	0,	KC_F12,		0x1b, 0x5b, 0x32, 0x34, 0x7e, GSP_END,
+
+	0,	KC_INSERT,	0x1b, 0x5b, 0x32, 0x7e, GSP_END,
+	0,	KC_HOME,	0x1b, 0x5b, 0x48, GSP_END,
+	0,	KC_PAGE_UP,	0x1b, 0x5b, 0x35, 0x7e, GSP_END,
+	0,	KC_DELETE,	0x1b, 0x5b, 0x33, 0x7e, GSP_END,
+	0,	KC_END,		0x1b, 0x5b, 0x46, GSP_END,
+	0,	KC_PAGE_DOWN,	0x1b, 0x5b, 0x36, 0x7e, GSP_END,
+
+	0,	KC_UP,		0x1b, 0x5b, 0x41, GSP_END,
+	0,	KC_LEFT,	0x1b, 0x5b, 0x44, GSP_END,
+	0,	KC_DOWN,	0x1b, 0x5b, 0x42, GSP_END,
+	0,	KC_RIGHT,	0x1b, 0x5b, 0x43, GSP_END,
+
+	0,	0
+};
+
+static int stty_ctl_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	ds = 0;
+
+	gsp_init(&sp);
+	return gsp_insert_defs(&sp, seq_defs);
+}
+
+static void stty_ctl_parse_scancode(int scancode)
+{
+	unsigned mods, key;
+
+	ds = gsp_step(&sp, ds, scancode, &mods, &key);
+	if (key != 0) {
+		stroke_sim(kbd_dev, mods, key);
+	}
+}
+
+static void stty_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
+{
+	(void) mods;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/ctl/sun.c
===================================================================
--- uspace/srv/hid/input/ctl/sun.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/ctl/sun.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2011 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_ctl
+ * @ingroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief	Sun keyboard controller driver.
+ */
+
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <kbd_ctl.h>
+#include <kbd_port.h>
+
+static void sun_ctl_parse_scancode(int);
+static int sun_ctl_init(kbd_dev_t *);
+static void sun_ctl_set_ind(kbd_dev_t *, unsigned);
+
+kbd_ctl_ops_t sun_ctl = {
+	.parse_scancode = sun_ctl_parse_scancode,
+	.init = sun_ctl_init,
+	.set_ind = sun_ctl_set_ind
+};
+
+static kbd_dev_t *kbd_dev;
+
+#define KBD_KEY_RELEASE		0x80
+#define KBD_ALL_KEYS_UP		0x7f
+
+static int scanmap_simple[];
+
+static int sun_ctl_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	return 0;
+}
+
+static void sun_ctl_parse_scancode(int scancode)
+{
+	kbd_event_type_t type;
+	unsigned int key;
+
+	if (scancode < 0 || scancode >= 0x100)
+		return;
+
+	if (scancode == KBD_ALL_KEYS_UP)
+		return;
+
+	if (scancode & KBD_KEY_RELEASE) {
+		scancode &= ~KBD_KEY_RELEASE;
+		type = KEY_RELEASE;
+	} else {
+		type = KEY_PRESS;
+	}
+
+	key = scanmap_simple[scancode];
+	if (key != 0)
+		kbd_push_ev(kbd_dev, type, key);
+}
+
+static void sun_ctl_set_ind(kbd_dev_t *kdev, unsigned mods)
+{
+	(void) mods;
+}
+
+/** Primary meaning of scancodes. */
+static int scanmap_simple[] = {
+	[0x00] = 0,
+	[0x01] = 0,
+	[0x02] = 0,
+	[0x03] = 0,
+	[0x04] = 0,
+	[0x05] = KC_F1,
+	[0x06] = KC_F2,
+	[0x07] = KC_F10,
+	[0x08] = KC_F3,
+	[0x09] = KC_F11,
+	[0x0a] = KC_F4,
+	[0x0b] = KC_F12,
+	[0x0c] = KC_F5,
+	[0x0d] = KC_RALT,
+	[0x0e] = KC_F6,
+	[0x0f] = 0,
+	[0x10] = KC_F7,
+	[0x11] = KC_F8,
+	[0x12] = KC_F9,
+	[0x13] = KC_LALT,
+	[0x14] = KC_UP,
+	[0x15] = KC_PAUSE,
+	[0x16] = 0,
+	[0x17] = KC_SCROLL_LOCK,
+	[0x18] = KC_LEFT,
+	[0x19] = 0,
+	[0x1a] = 0,
+	[0x1b] = KC_DOWN,
+	[0x1c] = KC_RIGHT,
+	[0x1d] = KC_ESCAPE,
+	[0x1e] = KC_1,
+	[0x1f] = KC_2,
+	[0x20] = KC_3,
+	[0x21] = KC_4,
+	[0x22] = KC_5,
+	[0x23] = KC_6,
+	[0x24] = KC_7,
+	[0x25] = KC_8,
+	[0x26] = KC_9,
+	[0x27] = KC_0,
+	[0x28] = KC_MINUS,
+	[0x29] = KC_EQUALS,
+	[0x2a] = KC_BACKTICK,
+	[0x2b] = KC_BACKSPACE,
+	[0x2c] = KC_INSERT,
+	[0x2d] = 0,
+	[0x2e] = KC_NSLASH,
+	[0x2f] = KC_NTIMES,
+	[0x30] = 0,
+	[0x31] = 0,
+	[0x32] = KC_NPERIOD,
+	[0x33] = 0,
+	[0x34] = KC_HOME,
+	[0x35] = KC_TAB,
+	[0x36] = KC_Q,
+	[0x37] = KC_W,
+	[0x38] = KC_E,
+	[0x39] = KC_R,
+	[0x3a] = KC_T,
+	[0x3b] = KC_Y,
+	[0x3c] = KC_U,
+	[0x3d] = KC_I,
+	[0x3e] = KC_O,
+	[0x3f] = KC_P,
+	[0x40] = KC_LBRACKET,
+	[0x41] = KC_RBRACKET,
+	[0x42] = KC_DELETE,
+	[0x43] = 0,
+	[0x44] = KC_N7,
+	[0x45] = KC_N8,
+	[0x46] = KC_N9,
+	[0x47] = KC_NMINUS,
+	[0x48] = 0,
+	[0x49] = 0,
+	[0x4a] = KC_END,
+	[0x4b] = 0,
+	[0x4c] = KC_LCTRL,
+	[0x4d] = KC_A,
+	[0x4e] = KC_S,
+	[0x4f] = KC_D,
+	[0x50] = KC_F,
+	[0x51] = KC_G,
+	[0x52] = KC_H,
+	[0x53] = KC_J,
+	[0x54] = KC_K,
+	[0x55] = KC_L,
+	[0x56] = KC_SEMICOLON,
+	[0x57] = KC_QUOTE,
+	[0x58] = KC_BACKSLASH,
+	[0x59] = KC_ENTER,
+	[0x5a] = KC_NENTER,
+	[0x5b] = KC_N4,
+	[0x5c] = KC_N5,
+	[0x5d] = KC_N6,
+	[0x5e] = KC_N0,
+	[0x5f] = 0,
+	[0x60] = KC_PAGE_UP,
+	[0x61] = 0,
+	[0x62] = KC_NUM_LOCK,
+	[0x63] = KC_LSHIFT,
+	[0x64] = KC_Z,
+	[0x65] = KC_X,
+	[0x66] = KC_C,
+	[0x67] = KC_V,
+	[0x68] = KC_B,
+	[0x69] = KC_N,
+	[0x6a] = KC_M,
+	[0x6b] = KC_COMMA,
+	[0x6c] = KC_PERIOD,
+	[0x6d] = KC_SLASH,
+	[0x6e] = KC_RSHIFT,
+	[0x6f] = 0,
+	[0x70] = KC_N1,
+	[0x71] = KC_N2,
+	[0x72] = KC_N3,
+	[0x73] = 0,
+	[0x74] = 0,
+	[0x75] = 0,
+	[0x76] = 0,
+	[0x77] = KC_CAPS_LOCK,
+	[0x78] = 0,
+	[0x79] = KC_SPACE,
+	[0x7a] = 0,
+	[0x7b] = KC_PAGE_DOWN,
+	[0x7c] = 0,
+	[0x7d] = KC_NPLUS,
+	[0x7e] = 0,
+	[0x7f] = 0
+};
+
+/** @}
+ */
Index: uspace/srv/hid/input/generic/gsp.c
===================================================================
--- uspace/srv/hid/input/generic/gsp.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/generic/gsp.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,289 @@
+/*
+ * 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
+ * @ingroup  input
+ * @{
+ */ 
+/** @file
+ * @brief	Generic scancode parser.
+ *
+ * The scancode parser is a simple finite state machine. It is described
+ * using sequences of input symbols (scancodes) and the corresponding output
+ * value (mods, key pair). When the parser recognizes a sequence,
+ * it outputs the value and restarts. If a transition is undefined,
+ * the parser restarts, too.
+ *
+ * Apart from precise values, GSP_DEFAULT allows to catch general cases.
+ * I.e. if we knew that after 0x1b 0x4f there always follow two more
+ * scancodes, we can define (0x1b, 0x4f, GSP_DEFAULT, GSP_DEFAULT, GSP_END)
+ * with null output. This will force the parser to read the entire sequence,
+ * not leaving garbage on the input if it does not recognize the specific
+ * sequence.
+ */
+
+#include <gsp.h>
+#include <adt/hash_table.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define TRANS_TABLE_CHAINS 256
+
+/*
+ * Hash table operations for the transition function.
+ */
+
+static hash_index_t trans_op_hash(unsigned long key[]);
+static int trans_op_compare(unsigned long key[], hash_count_t keys,
+    link_t *item);
+static void trans_op_remove_callback(link_t *item);
+
+static hash_table_operations_t trans_ops = {
+	.hash = trans_op_hash,
+	.compare = trans_op_compare,
+	.remove_callback = trans_op_remove_callback
+};
+
+static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input);
+static void trans_insert(gsp_t *p, gsp_trans_t *t);
+static gsp_trans_t *trans_new(void);
+
+/** Initialise scancode parser. */
+void gsp_init(gsp_t *p)
+{
+	p->states = 1;
+	hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);
+}
+
+/** Insert a series of definitions into the parser.
+ *
+ * @param p	The parser.
+ * @param defs	Definition list. Each definition starts with two output values
+ *		(mods, key) and continues with a sequence of input values
+ *		terminated with GSP_END. The definition list is terminated
+ *		with two zeroes (0, 0) for output values.
+ */
+int gsp_insert_defs(gsp_t *p, const int *defs)
+{
+	unsigned mods, key;
+	const int *dp;
+	int rc;
+
+	dp = defs;
+
+	while (1) {
+		/* Read the output values. */
+		mods = *dp++;
+		key = *dp++;
+		if (key == 0) break;
+
+		/* Insert one sequence. */		
+		rc = gsp_insert_seq(p, dp, mods, key);
+		if (rc != 0)
+			return rc;
+
+		/* Skip to the next definition. */
+		while (*dp != GSP_END)
+			++dp;
+		++dp;
+	}
+
+	return 0;
+}
+
+/** Insert one sequence into the parser.
+ *
+ * @param p	The parser.
+ * @param seq	Sequence of input values terminated with GSP_END.
+ * @param mods	Corresponsing output value.
+ * @param key	Corresponsing output value.
+ */
+int gsp_insert_seq(gsp_t *p, const int *seq, unsigned mods, unsigned key)
+{
+	int state;
+	gsp_trans_t *t;
+
+	state = 0;
+	t = NULL;
+
+	/* Input sequence must be non-empty. */
+	if (*seq == GSP_END)
+		return -1;
+
+	while (*(seq + 1) != GSP_END) {
+		t = trans_lookup(p, state, *seq);
+		if (t == NULL) {
+			/* Create new state. */
+			t = trans_new();
+			t->old_state = state;
+			t->input = *seq;
+			t->new_state = p->states++;
+
+			t->out_mods = 0;
+			t->out_key = 0;
+
+			trans_insert(p, t);
+		}
+		state = t->new_state;
+		++seq;
+	}
+
+	/* Process the last transition. */
+	t = trans_lookup(p, state, *seq);
+	if (t != NULL) {
+		exit(1);
+		return -1;	/* Conflicting definition. */
+	}
+
+	t = trans_new();
+	t->old_state = state;
+	t->input = *seq;
+	t->new_state = 0;
+
+	t->out_mods = mods;
+	t->out_key = key;
+
+	trans_insert(p, t);
+
+	return 0;
+}
+
+/** Compute one parser step.
+ *
+ * Computes the next state and output values for a given state and input.
+ * This handles everything including restarts and default branches.
+ *
+ * @param p		The parser.
+ * @param state		Old state.
+ * @param input		Input symbol (scancode).
+ * @param mods		Output value (modifier).
+ * @param key		Output value (key).
+ * @return		New state.
+ */
+int gsp_step(gsp_t *p, int state, int input, unsigned *mods, unsigned *key)
+{
+	gsp_trans_t *t;
+
+	t = trans_lookup(p, state, input);
+	if (t == NULL) {
+		t = trans_lookup(p, state, GSP_DEFAULT);
+	}
+
+	if (t == NULL) {
+		printf("gsp_step: not found\n");
+		*mods = 0;
+		*key = 0;
+		return 0;
+	}
+
+	*mods = t->out_mods;
+	*key = t->out_key;
+	return t->new_state;
+}
+
+/** Transition function lookup.
+ *
+ * Returns the value of the transition function for the given state
+ * and input. Note that the transition must be specified precisely,
+ * to obtain the default branch use input = GSP_DEFAULT.
+ *
+ * @param p		Parser.
+ * @param state		Current state.
+ * @param input		Input value.
+ * @return		The transition or @c NULL if not defined.
+ */
+static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input)
+{
+	link_t *item;
+	unsigned long key[2];
+
+	key[0] = state;
+	key[1] = input;
+
+	item = hash_table_find(&p->trans, key);
+	if (item == NULL) return NULL;
+
+	return hash_table_get_instance(item, gsp_trans_t, link);
+}
+
+/** Define a new transition.
+ *
+ * @param p	The parser.
+ * @param t	Transition with all fields defined.
+ */
+static void trans_insert(gsp_t *p, gsp_trans_t *t)
+{
+	unsigned long key[2];
+
+	key[0] = t->old_state;
+	key[1] = t->input;
+
+	hash_table_insert(&p->trans, key, &t->link);
+}
+
+/** Allocate transition structure. */
+static gsp_trans_t *trans_new(void)
+{
+	gsp_trans_t *t;
+
+	t = malloc(sizeof(gsp_trans_t));
+	if (t == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return t;
+}
+
+/*
+ * Transition function hash table operations.
+ */
+
+static hash_index_t trans_op_hash(unsigned long key[])
+{
+	return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;
+}
+
+static int trans_op_compare(unsigned long key[], hash_count_t keys,
+    link_t *item)
+{
+	gsp_trans_t *t;
+
+	t = hash_table_get_instance(item, gsp_trans_t, link);
+	return ((key[0] == (unsigned long) t->old_state)
+	    && (key[1] == (unsigned long) t->input));
+}
+
+static void trans_op_remove_callback(link_t *item)
+{
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/generic/input.c
===================================================================
--- uspace/srv/hid/input/generic/input.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/generic/input.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief HelenOS input server.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#include <adt/list.h>
+#include <ipc/services.h>
+#include <ipc/input.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ns.h>
+#include <ns_obsolete.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <errno.h>
+#include <adt/fifo.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <devmap.h>
+#include <input.h>
+#include <kbd.h>
+#include <kbd_port.h>
+#include <kbd_ctl.h>
+#include <layout.h>
+#include <mouse.h>
+
+// FIXME: remove this header
+#include <kernel/ipc/ipc_methods.h>
+
+/* In microseconds */
+#define DISCOVERY_POLL_INTERVAL		(10*1000*1000)
+
+static void kbd_devs_yield(void);
+static void kbd_devs_reclaim(void);
+
+static void input_event_key(int, unsigned int, unsigned, wchar_t);
+
+int client_phone = -1;
+
+/** List of keyboard devices */
+static link_t kbd_devs;
+
+/** List of mouse devices */
+link_t mouse_devs;
+
+bool irc_service = false;
+int irc_phone = -1;
+
+#define NUM_LAYOUTS 3
+
+static layout_ops_t *layout[NUM_LAYOUTS] = {
+	&us_qwerty_ops,
+	&us_dvorak_ops,
+	&cz_ops
+};
+
+void kbd_push_scancode(kbd_dev_t *kdev, int scancode)
+{
+/*	printf("scancode: 0x%x\n", scancode);*/
+	(*kdev->ctl_ops->parse_scancode)(scancode);
+}
+
+void kbd_push_ev(kbd_dev_t *kdev, int type, unsigned int key)
+{
+	kbd_event_t ev;
+	unsigned mod_mask;
+
+	switch (key) {
+	case KC_LCTRL: mod_mask = KM_LCTRL; break;
+	case KC_RCTRL: mod_mask = KM_RCTRL; break;
+	case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
+	case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
+	case KC_LALT: mod_mask = KM_LALT; break;
+	case KC_RALT: mod_mask = KM_RALT; break;
+	default: mod_mask = 0; break;
+	}
+
+	if (mod_mask != 0) {
+		if (type == KEY_PRESS)
+			kdev->mods = kdev->mods | mod_mask;
+		else
+			kdev->mods = kdev->mods & ~mod_mask;
+	}
+
+	switch (key) {
+	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
+	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
+	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
+	default: mod_mask = 0; break;
+	}
+
+	if (mod_mask != 0) {
+		if (type == KEY_PRESS) {
+			/*
+			 * Only change lock state on transition from released
+			 * to pressed. This prevents autorepeat from messing
+			 * up the lock state.
+			 */
+			kdev->mods = kdev->mods ^ (mod_mask & ~kdev->lock_keys);
+			kdev->lock_keys = kdev->lock_keys | mod_mask;
+
+			/* Update keyboard lock indicator lights. */
+			(*kdev->ctl_ops->set_ind)(kdev, kdev->mods);
+		} else {
+			kdev->lock_keys = kdev->lock_keys & ~mod_mask;
+		}
+	}
+/*
+	printf("type: %d\n", type);
+	printf("mods: 0x%x\n", mods);
+	printf("keycode: %u\n", key);
+*/
+	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
+		key == KC_F1) {
+		layout_destroy(kdev->active_layout);
+		kdev->active_layout = layout_create(layout[0]);
+		return;
+	}
+
+	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
+		key == KC_F2) {
+		layout_destroy(kdev->active_layout);
+		kdev->active_layout = layout_create(layout[1]);
+		return;
+	}
+
+	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
+		key == KC_F3) {
+		layout_destroy(kdev->active_layout);
+		kdev->active_layout = layout_create(layout[2]);
+		return;
+	}
+
+	ev.type = type;
+	ev.key = key;
+	ev.mods = kdev->mods;
+
+	ev.c = layout_parse_ev(kdev->active_layout, &ev);
+	input_event_key(ev.type, ev.key, ev.mods, ev.c);
+}
+
+/** Key has been pressed or released. */
+static void input_event_key(int type, unsigned int key, unsigned mods,
+    wchar_t c)
+{
+	async_obsolete_msg_4(client_phone, INPUT_EVENT_KEY, type, key,
+	    mods, c);
+}
+
+/** Mouse pointer has moved. */
+void input_event_move(int dx, int dy)
+{
+	async_obsolete_msg_2(client_phone, INPUT_EVENT_MOVE, dx, dy);
+}
+
+/** Mouse button has been pressed. */
+void input_event_button(int bnum, int press)
+{
+	async_obsolete_msg_2(client_phone, INPUT_EVENT_BUTTON, bnum, press);
+}
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	int retval;
+
+	async_answer_0(iid, EOK);
+
+	while (true) {
+		callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			if (client_phone != -1) {
+				async_obsolete_hangup(client_phone);
+				client_phone = -1;
+			}
+			
+			async_answer_0(callid, EOK);
+			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case IPC_M_CONNECT_TO_ME:
+			if (client_phone != -1) {
+				retval = ELIMIT;
+				break;
+			}
+			client_phone = IPC_GET_ARG5(call);
+			retval = 0;
+			break;
+		case INPUT_YIELD:
+			kbd_devs_yield();
+			retval = 0;
+			break;
+		case INPUT_RECLAIM:
+			kbd_devs_reclaim();
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+		}
+		async_answer_0(callid, retval);
+	}	
+}
+
+static kbd_dev_t *kbd_dev_new(void)
+{
+	kbd_dev_t *kdev;
+
+	kdev = calloc(1, sizeof(kbd_dev_t));
+	if (kdev == NULL) {
+		printf(NAME ": Error allocating keyboard device. "
+		    "Out of memory.\n");
+		return NULL;
+	}
+
+	link_initialize(&kdev->kbd_devs);
+
+	kdev->mods = KM_NUM_LOCK;
+	kdev->lock_keys = 0;
+	kdev->active_layout = layout_create(layout[0]);
+
+	return kdev;
+}
+
+/** Add new legacy keyboard device. */
+static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl)
+{
+	kbd_dev_t *kdev;
+
+	kdev = kbd_dev_new();
+	if (kdev == NULL)
+		return;
+
+	kdev->port_ops = port;
+	kdev->ctl_ops = ctl;
+	kdev->dev_path = NULL;
+
+	/* Initialize port driver. */
+	if ((*kdev->port_ops->init)(kdev) != 0)
+		goto fail;
+
+	/* Initialize controller driver. */
+	if ((*kdev->ctl_ops->init)(kdev) != 0) {
+		/* XXX Uninit port */
+		goto fail;
+	}
+
+	list_append(&kdev->kbd_devs, &kbd_devs);
+	return;
+fail:
+	free(kdev);
+}
+
+/** Add new kbdev device.
+ *
+ * @param dev_path	Filesystem path to the device (/dev/class/...)
+ */
+static int kbd_add_kbdev(const char *dev_path)
+{
+	kbd_dev_t *kdev;
+
+	kdev = kbd_dev_new();
+	if (kdev == NULL)
+		return -1;
+
+	kdev->dev_path = dev_path;
+	kdev->port_ops = NULL;
+	kdev->ctl_ops = &kbdev_ctl;
+
+	/* Initialize controller driver. */
+	if ((*kdev->ctl_ops->init)(kdev) != 0) {
+		goto fail;
+	}
+
+	list_append(&kdev->kbd_devs, &kbd_devs);
+	return EOK;
+fail:
+	free(kdev);
+	return -1;
+}
+
+/** Add legacy drivers/devices. */
+static void kbd_add_legacy_devs(void)
+{
+	/*
+	 * Need to add these drivers based on config unless we can probe
+	 * them automatically.
+	 */
+#if defined(UARCH_amd64)
+	kbd_add_dev(&chardev_port, &pc_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_gta02)
+	kbd_add_dev(&chardev_port, &stty_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_testarm) && defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_testarm) && !defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &stty_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_integratorcp)
+	kbd_add_dev(&pl050_port, &pc_ctl);
+#endif
+#if defined(UARCH_ia32)
+	kbd_add_dev(&chardev_port, &pc_ctl);
+#endif
+#if defined(MACHINE_i460GX)
+	kbd_add_dev(&chardev_port, &pc_ctl);
+#endif
+#if defined(MACHINE_ski)
+	kbd_add_dev(&ski_port, &stty_ctl);
+#endif
+#if defined(MACHINE_msim)
+	kbd_add_dev(&msim_port, &pc_ctl);
+#endif
+#if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
+#endif
+#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) && !defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &stty_ctl);
+#endif
+#if defined(UARCH_ppc32)
+	kbd_add_dev(&adb_port, &apple_ctl);
+#endif
+#if defined(UARCH_sparc64) && defined(PROCESSOR_sun4v)
+	kbd_add_dev(&niagara_port, &stty_ctl);
+#endif
+#if defined(UARCH_sparc64) && defined(MACHINE_serengeti)
+	kbd_add_dev(&sgcn_port, &stty_ctl);
+#endif
+#if defined(UARCH_sparc64) && defined(MACHINE_generic)
+	kbd_add_dev(&z8530_port, &sun_ctl);
+	kbd_add_dev(&ns16550_port, &sun_ctl);
+#endif
+	/* Silence warning on abs32le about kbd_add_dev() being unused */
+	(void) kbd_add_dev;
+}
+
+static void kbd_devs_yield(void)
+{
+	/* For each keyboard device */
+	list_foreach(kbd_devs, kdev_link) {
+		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
+		    kbd_devs);
+
+		/* Yield port */
+		if (kdev->port_ops != NULL)
+			(*kdev->port_ops->yield)();
+	}
+}
+
+static void kbd_devs_reclaim(void)
+{
+	/* For each keyboard device */
+	list_foreach(kbd_devs, kdev_link) {
+		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
+		    kbd_devs);
+
+		/* Reclaim port */
+		if (kdev->port_ops != NULL)
+			(*kdev->port_ops->reclaim)();
+	}
+}
+
+/** Periodically check for new input devices.
+ *
+ * Looks under /dev/class/keyboard and /dev/class/mouse.
+ *
+ * @param arg	Ignored
+ */
+static int dev_discovery_fibril(void *arg)
+{
+	char *dev_path;
+	size_t kbd_id = 1;
+	size_t mouse_id = 1;
+	int rc;
+
+	while (true) {
+		async_usleep(DISCOVERY_POLL_INTERVAL);
+
+		/*
+		 * Check for new keyboard device
+		 */
+		rc = asprintf(&dev_path, "/dev/class/keyboard\\%zu", kbd_id);
+		if (rc < 0)
+			continue;
+
+		if (kbd_add_kbdev(dev_path) == EOK) {
+			printf(NAME ": Connected keyboard device '%s'\n",
+			    dev_path);
+
+			/* XXX Handle device removal */
+			++kbd_id;
+		}
+
+		free(dev_path);
+
+		/*
+		 * Check for new mouse device
+		 */
+		rc = asprintf(&dev_path, "/dev/class/mouse\\%zu", mouse_id);
+		if (rc < 0)
+			continue;
+
+		if (mouse_add_dev(dev_path) == EOK) {
+			printf(NAME ": Connected mouse device '%s'\n",
+			    dev_path);
+
+			/* XXX Handle device removal */
+			++mouse_id;
+		}
+
+		free(dev_path);
+	}
+
+	return EOK;
+}
+
+/** Start a fibril for discovering new devices. */
+static void input_start_dev_discovery(void)
+{
+	fid_t fid;
+
+	fid = fibril_create(dev_discovery_fibril, NULL);
+	if (!fid) {
+		printf(NAME ": Failed to create device discovery fibril.\n");
+		return;
+	}
+
+	fibril_add_ready(fid);
+}
+
+int main(int argc, char **argv)
+{
+	printf("%s: HelenOS input service\n", NAME);
+	
+	sysarg_t fhc;
+	sysarg_t obio;
+	
+	list_initialize(&kbd_devs);
+	list_initialize(&mouse_devs);
+	
+	if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
+	    || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)))
+		irc_service = true;
+	
+	if (irc_service) {
+		while (irc_phone < 0)
+			irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
+	}
+	
+	/* Add legacy keyboard devices. */
+	kbd_add_legacy_devs();
+
+	/* Add legacy (devmap-style) mouse device. */
+	(void) mouse_add_dev("/dev/hid_in/mouse");
+	
+	/* Register driver */
+	int rc = devmap_driver_register(NAME, client_connection);
+	if (rc < 0) {
+		printf("%s: Unable to register driver (%d)\n", NAME, rc);
+		return -1;
+	}
+	
+	char kbd[DEVMAP_NAME_MAXLEN + 1];
+	snprintf(kbd, DEVMAP_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
+	
+	devmap_handle_t devmap_handle;
+	if (devmap_device_register(kbd, &devmap_handle) != EOK) {
+		printf("%s: Unable to register device %s\n", NAME, kbd);
+		return -1;
+	}
+
+	/* Start looking for new input devices */
+	input_start_dev_discovery();
+
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+
+	/* Not reached. */
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/generic/layout.c
===================================================================
--- uspace/srv/hid/input/generic/layout.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/generic/layout.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief Keyboard layouts
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#include <errno.h>
+#include <input.h>
+#include <layout.h>
+#include <stdlib.h>
+
+/** Create a new layout instance. */
+layout_t *layout_create(layout_ops_t *ops)
+{
+	layout_t *layout;
+
+	layout = calloc(1, sizeof(layout_t));
+	if (layout == NULL) {
+		printf(NAME ": Out of memory.\n");
+		return NULL;
+	}
+
+	layout->ops = ops;
+	if ((*ops->create)(layout) != EOK) {
+		free(layout);
+		return NULL;
+	}
+
+	return layout;
+}
+
+/** Destroy layout instance. */
+void layout_destroy(layout_t *layout)
+{
+	(*layout->ops->destroy)(layout);
+	free(layout);
+}
+
+/** Parse keyboard event. */
+wchar_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
+{
+	return (*layout->ops->parse_ev)(layout, ev);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/generic/mouse.c
===================================================================
--- uspace/srv/hid/input/generic/mouse.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/generic/mouse.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief Mouse device handling.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#include <adt/list.h>
+#include <async.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <input.h>
+#include <ipc/mouse.h>
+#include <mouse.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vfs/vfs_sess.h>
+
+static void mouse_callback_conn(ipc_callid_t, ipc_call_t *, void *);
+
+static mouse_dev_t *mouse_dev_new(void)
+{
+	mouse_dev_t *mdev;
+
+	mdev = calloc(1, sizeof(mouse_dev_t));
+	if (mdev == NULL) {
+		printf(NAME ": Error allocating mouse device. "
+		    "Out of memory.\n");
+		return NULL;
+	}
+
+	link_initialize(&mdev->mouse_devs);
+	return mdev;
+}
+
+static int mouse_dev_connect(mouse_dev_t *mdev, const char *dev_path)
+{
+	async_sess_t *sess;
+	async_exch_t *exch;
+	int fd;
+	int rc;
+
+	fd = open(dev_path, O_RDWR);
+	if (fd < 0) {
+		return -1;
+	}
+
+	sess = fd_session(EXCHANGE_SERIALIZE, fd);
+	if (sess == NULL) {
+		printf(NAME ": Failed starting session with '%s'\n", dev_path);
+		close(fd);
+		return -1;
+	}
+
+	exch = async_exchange_begin(sess);
+	if (exch == NULL) {
+		printf(NAME ": Failed starting exchange with '%s'.\n", dev_path);
+		return -1;
+	}
+
+	rc = async_connect_to_me(exch, 0, 0, 0, mouse_callback_conn, mdev);
+	if (rc != EOK) {
+		printf(NAME ": Failed creating callback connection from '%s'.\n",
+		    dev_path);
+		async_exchange_end(exch);
+		return -1;
+	}
+
+	async_exchange_end(exch);
+
+	mdev->dev_path = dev_path;
+	return 0;
+}
+
+/** Add new mouse device.
+ *
+ * @param dev_path	Filesystem path to the device (/dev/class/...)
+ */
+int mouse_add_dev(const char *dev_path)
+{
+	mouse_dev_t *mdev;
+	int rc;
+
+	mdev = mouse_dev_new();
+	if (mdev == NULL)
+		return -1;
+
+	rc = mouse_dev_connect(mdev, dev_path);
+	if (rc != EOK) {
+		free(mdev);
+		return -1;
+	}
+
+	list_append(&mdev->mouse_devs, &mouse_devs);
+	return EOK;
+}
+
+/** Mouse device callback connection handler. */
+static void mouse_callback_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	int retval;
+
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid;
+
+		callid = async_get_call(&call);
+		if (!IPC_GET_IMETHOD(call)) {
+			/* XXX Handle hangup */
+			return;
+		}
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case MEVENT_BUTTON:
+			input_event_button(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			retval = 0;
+			break;
+		case MEVENT_MOVE:
+			input_event_move(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			retval = 0;
+			break;
+		default:
+			retval = ENOTSUP;
+			break;
+		}
+
+		async_answer_0(callid, retval);
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/generic/stroke.c
===================================================================
--- uspace/srv/hid/input/generic/stroke.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/generic/stroke.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011 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 input
+ * @{
+ */
+/**
+ * @file
+ * @brief Stroke simulator.
+ *
+ * When simulating a keyboard using a serial TTY we need to convert the
+ * recognized strokes (such as Shift-A) to sequences of key presses and
+ * releases (such as 'press Shift, press A, release A, release Shift').
+ *
+ */
+
+#include <stroke.h>
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+
+/** Correspondence between modifers and the modifier keycodes. */
+static unsigned int mods_keys[][2] = {
+	{ KM_LSHIFT, KC_LSHIFT },
+	{ 0, 0 }
+};
+
+/** Simulate keystroke using sequences of key presses and releases. */
+void stroke_sim(kbd_dev_t *kdev, unsigned mod, unsigned key)
+{
+	int i;
+
+	/* Simulate modifier presses. */
+	i = 0;
+	while (mods_keys[i][0] != 0) {
+		if (mod & mods_keys[i][0]) {
+			kbd_push_ev(kdev, KEY_PRESS, mods_keys[i][1]);
+		}
+		++i;
+	}
+
+	/* Simulate key press and release. */
+	if (key != 0) {
+		kbd_push_ev(kdev, KEY_PRESS, key);
+		kbd_push_ev(kdev, KEY_RELEASE, key);
+	}
+
+	/* Simulate modifier releases. */
+	i = 0;
+	while (mods_keys[i][0] != 0) {
+		if (mod & mods_keys[i][0]) {
+			kbd_push_ev(kdev, KEY_RELEASE, mods_keys[i][1]);
+		}
+		++i;
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/include/gsp.h
===================================================================
--- uspace/srv/hid/input/include/gsp.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/gsp.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,84 @@
+/*
+ * 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 inputgen generic
+ * @brief	Generic scancode parser.
+ * @ingroup  input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_GSP_H_
+#define KBD_GSP_H_
+
+#include <adt/hash_table.h>
+
+enum {
+	GSP_END		= -1,	/**< Terminates a sequence. */
+	GSP_DEFAULT	= -2	/**< Wildcard, catches unhandled cases. */
+};
+
+/** Scancode parser description */
+typedef struct {
+	/** Transition table, (state, input) -> (state, output) */
+	hash_table_t trans;
+
+	/** Number of states */
+	int states;
+} gsp_t;
+
+/** Scancode parser transition. */
+typedef struct {
+	link_t link;		/**< Link to hash table in @c gsp_t */ 
+
+	/* Preconditions */
+
+	int old_state;		/**< State before transition */
+	int input;		/**< Input symbol (scancode) */
+
+	/* Effects */
+
+	int new_state;		/**< State after transition */
+
+	/* Output emitted during transition */
+
+	unsigned out_mods;	/**< Modifier to emit */
+	unsigned out_key;	/**< Keycode to emit */
+} gsp_trans_t;
+
+extern void gsp_init(gsp_t *);
+extern int gsp_insert_defs(gsp_t *, const int *);
+extern int gsp_insert_seq(gsp_t *, const int *, unsigned, unsigned);
+extern int gsp_step(gsp_t *, int, int, unsigned *, unsigned *);
+
+#endif
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/include/input.h
===================================================================
--- uspace/srv/hid/input/include/input.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/input.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief HelenOS input server.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef INPUT_H_
+#define INPUT_H_
+
+#include <bool.h>
+
+#define NAME       "input"
+#define NAMESPACE  "hid_in"
+
+extern bool irc_service;
+extern int irc_phone;
+
+extern link_t mouse_devs;
+
+void input_event_move(int, int);
+void input_event_button(int bnum, int press);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/include/kbd.h
===================================================================
--- uspace/srv/hid/input/include/kbd.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/kbd.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief HelenOS input server.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_KBD_H_
+#define KBD_KBD_H_
+
+#include <adt/list.h>
+
+struct kbd_port_ops;
+struct kbd_ctl_ops;
+struct layout;
+
+typedef struct kbd_dev {
+	/** Link to kbd_devs list */
+	link_t kbd_devs;
+
+	/** Path to the device (only for kbdev devices) */
+	const char *dev_path;
+
+	/** Port ops */
+	struct kbd_port_ops *port_ops;
+
+	/** Ctl ops */
+	struct kbd_ctl_ops *ctl_ops;
+
+	/** Controller-private data */
+	void *ctl_private;
+
+	/** Currently active modifiers. */
+	unsigned mods;
+
+	/** Currently pressed lock keys. We track these to tackle autorepeat. */
+	unsigned lock_keys;
+
+	/** Active keyboard layout */
+	struct layout *active_layout;
+} kbd_dev_t;
+
+extern void kbd_push_scancode(kbd_dev_t *, int);
+extern void kbd_push_ev(kbd_dev_t *, int, unsigned int);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/include/kbd_ctl.h
===================================================================
--- uspace/srv/hid/input/include/kbd_ctl.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/kbd_ctl.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief	Keyboard controller driver interface.
+ * @ingroup  input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_CTL_H_
+#define KBD_CTL_H_
+
+#include <kbd_port.h>
+
+struct kbd_dev;
+
+typedef struct kbd_ctl_ops {
+	void (*parse_scancode)(int);
+	int (*init)(struct kbd_dev *);
+	void (*set_ind)(struct kbd_dev *, unsigned);
+} kbd_ctl_ops_t;
+
+extern kbd_ctl_ops_t apple_ctl;
+extern kbd_ctl_ops_t gxe_fb_ctl;
+extern kbd_ctl_ops_t kbdev_ctl;
+extern kbd_ctl_ops_t pc_ctl;
+extern kbd_ctl_ops_t stty_ctl;
+extern kbd_ctl_ops_t sun_ctl;
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/hid/input/include/kbd_port.h
===================================================================
--- uspace/srv/hid/input/include/kbd_port.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/kbd_port.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief	Keyboard port driver interface.
+ * @ingroup  input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_PORT_H_
+#define KBD_PORT_H_
+
+#include <sys/types.h>
+
+struct kbd_dev;
+
+typedef struct kbd_port_ops {
+	int (*init)(struct kbd_dev *);
+	void (*yield)(void);
+	void (*reclaim)(void);
+	void (*write)(uint8_t);
+} kbd_port_ops_t;
+
+extern kbd_port_ops_t adb_port;
+extern kbd_port_ops_t chardev_port;
+extern kbd_port_ops_t dummy_port;
+extern kbd_port_ops_t gxemul_port;
+extern kbd_port_ops_t msim_port;
+extern kbd_port_ops_t niagara_port;
+extern kbd_port_ops_t ns16550_port;
+extern kbd_port_ops_t pl050_port;
+extern kbd_port_ops_t sgcn_port;
+extern kbd_port_ops_t ski_port;
+extern kbd_port_ops_t z8530_port;
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/hid/input/include/layout.h
===================================================================
--- uspace/srv/hid/input/include/layout.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/layout.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,71 @@
+/*
+ * 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 inputgen generic
+ * @brief Keyboard layout interface.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_LAYOUT_H_
+#define KBD_LAYOUT_H_
+
+#include <sys/types.h>
+#include <io/console.h>
+
+/** Layout instance state */
+typedef struct layout {
+	/** Ops structure */
+	struct layout_ops *ops;
+
+	/* Layout-private data */
+	void *layout_priv;
+} layout_t;
+
+/** Layout ops */
+typedef struct layout_ops {
+	int (*create)(layout_t *);
+	void (*destroy)(layout_t *);
+	wchar_t (*parse_ev)(layout_t *, kbd_event_t *);
+} layout_ops_t;
+
+extern layout_ops_t us_qwerty_ops;
+extern layout_ops_t us_dvorak_ops;
+extern layout_ops_t cz_ops;
+
+extern layout_t *layout_create(layout_ops_t *);
+extern void layout_destroy(layout_t *);
+extern wchar_t layout_parse_ev(layout_t *, kbd_event_t *);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/include/mouse.h
===================================================================
--- uspace/srv/hid/input/include/mouse.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/mouse.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief Mouse device handling.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef MOUSE_H_
+#define MOUSE_H_
+
+#include <adt/list.h>
+
+typedef struct mouse_dev {
+	/** Link to mouse_devs list */
+	link_t mouse_devs;
+
+	/** Path to the device */
+	const char *dev_path;
+} mouse_dev_t;
+
+int mouse_add_dev(const char *dev_path);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/include/stroke.h
===================================================================
--- uspace/srv/hid/input/include/stroke.h	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/include/stroke.h	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011 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 inputgen generic
+ * @brief	Generic scancode parser.
+ * @ingroup  input
+ * @{
+ */ 
+/** @file
+ */
+
+#ifndef KBD_STROKE_H_
+#define KBD_STROKE_H_
+
+#include <kbd.h>
+
+extern void stroke_sim(kbd_dev_t *, unsigned, unsigned);
+
+#endif
+
+/**
+ * @}
+ */ 
+
Index: uspace/srv/hid/input/layout/cz.c
===================================================================
--- uspace/srv/hid/input/layout/cz.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/layout/cz.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2011 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 input
+ * @brief Czech QWERTZ layout.
+ * @{
+ */
+
+#include <errno.h>
+#include <input.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <bool.h>
+#include <layout.h>
+#include <stdlib.h>
+
+static int cz_create(layout_t *);
+static void cz_destroy(layout_t *);
+static wchar_t cz_parse_ev(layout_t *, kbd_event_t *ev);
+
+enum m_state {
+	ms_start,
+	ms_hacek,
+	ms_carka
+};
+
+typedef struct {
+	enum m_state mstate;
+} layout_cz_t;
+
+layout_ops_t cz_ops = {
+	.create = cz_create,
+	.destroy = cz_destroy,
+	.parse_ev = cz_parse_ev
+};
+
+static wchar_t map_lcase[] = {
+	[KC_Q] = 'q',
+	[KC_W] = 'w',
+	[KC_E] = 'e',
+	[KC_R] = 'r',
+	[KC_T] = 't',
+	[KC_Y] = 'z',
+	[KC_U] = 'u',
+	[KC_I] = 'i',
+	[KC_O] = 'o',
+	[KC_P] = 'p',
+
+	[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_Z] = 'y',
+	[KC_X] = 'x',
+	[KC_C] = 'c',
+	[KC_V] = 'v',
+	[KC_B] = 'b',
+	[KC_N] = 'n',
+	[KC_M] = 'm',
+};
+
+static wchar_t map_ucase[] = {
+	[KC_Q] = 'Q',
+	[KC_W] = 'W',
+	[KC_E] = 'E',
+	[KC_R] = 'R',
+	[KC_T] = 'T',
+	[KC_Y] = 'Z',
+	[KC_U] = 'U',
+	[KC_I] = 'I',
+	[KC_O] = 'O',
+	[KC_P] = 'P',
+
+	[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_Z] = 'Y',
+	[KC_X] = 'X',
+	[KC_C] = 'C',
+	[KC_V] = 'V',
+	[KC_B] = 'B',
+	[KC_N] = 'N',
+	[KC_M] = 'M',
+};
+
+static wchar_t map_not_shifted[] = {
+	[KC_BACKTICK] = ';',
+
+	[KC_1] = '+',
+
+	[KC_MINUS] = '=',
+
+	[KC_RBRACKET] = ')',
+
+	[KC_QUOTE] = L'§',
+
+	[KC_COMMA] = ',',
+	[KC_PERIOD] = '.',
+	[KC_SLASH] = '-',
+};
+
+static wchar_t map_shifted[] = {
+	[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_LBRACKET] = '/',
+	[KC_RBRACKET] = '(',
+
+	[KC_SEMICOLON] = '"',
+	[KC_QUOTE] = '!',
+	[KC_BACKSLASH] = '\'',
+
+	[KC_COMMA] = '?',
+	[KC_PERIOD] = ':',
+	[KC_SLASH] = '_',
+};
+
+static wchar_t map_ns_nocaps[] = {
+	[KC_2] = L'ě',
+	[KC_3] = L'š',
+	[KC_4] = L'č',
+	[KC_5] = L'ř',
+	[KC_6] = L'ž',
+	[KC_7] = L'ý',
+	[KC_8] = L'á',
+	[KC_9] = L'í',
+	[KC_0] = L'é',
+
+	[KC_LBRACKET] = L'ú',
+	[KC_SEMICOLON] = L'ů'
+};
+
+static wchar_t map_ns_caps[] = {
+	[KC_2] = L'Ě',
+	[KC_3] = L'Š',
+	[KC_4] = L'Č',
+	[KC_5] = L'Ř',
+	[KC_6] = L'Ž',
+	[KC_7] = L'Ý',
+	[KC_8] = L'Á',
+	[KC_9] = L'Í',
+	[KC_0] = L'É',
+
+	[KC_LBRACKET] = L'Ú',
+	[KC_SEMICOLON] = L'Ů'
+};
+
+static wchar_t map_neutral[] = {
+	[KC_BACKSPACE] = '\b',
+	[KC_TAB] = '\t',
+	[KC_ENTER] = '\n',
+	[KC_SPACE] = ' ',
+
+	[KC_NSLASH] = '/',
+	[KC_NTIMES] = '*',
+	[KC_NMINUS] = '-',
+	[KC_NPLUS] = '+',
+	[KC_NENTER] = '\n'
+};
+
+static wchar_t map_numeric[] = {
+	[KC_N7] = '7',
+	[KC_N8] = '8',
+	[KC_N9] = '9',
+	[KC_N4] = '4',
+	[KC_N5] = '5',
+	[KC_N6] = '6',
+	[KC_N1] = '1',
+	[KC_N2] = '2',
+	[KC_N3] = '3',
+
+	[KC_N0] = '0',
+	[KC_NPERIOD] = '.'
+};
+
+static wchar_t map_hacek_lcase[] = {
+	[KC_E] = L'ě',
+	[KC_R] = L'ř',
+	[KC_T] = L'ť',
+	[KC_Y] = L'ž',
+	[KC_U] = L'ů',
+
+	[KC_S] = L'š',
+	[KC_D] = L'ď',
+
+	[KC_C] = L'č',
+	[KC_N] = L'ň'
+};
+
+static wchar_t map_hacek_ucase[] = {
+	[KC_E] = L'Ě',
+	[KC_R] = L'Ř',
+	[KC_T] = L'Ť',
+	[KC_Y] = L'Ž',
+	[KC_U] = L'Ů',
+
+	[KC_S] = L'Š',
+	[KC_D] = L'Ď',
+
+	[KC_C] = L'Č',
+	[KC_N] = L'Ň'
+};
+
+static wchar_t map_carka_lcase[] = {
+	[KC_E] = L'é',
+	[KC_U] = L'ú',
+	[KC_I] = L'í',
+	[KC_O] = L'ó',
+
+	[KC_A] = L'á',
+
+	[KC_Z] = L'ý',
+};
+
+static wchar_t map_carka_ucase[] = {
+	[KC_E] = L'É',
+	[KC_U] = L'Ú',
+	[KC_I] = L'Í',
+	[KC_O] = L'Ó',
+
+	[KC_A] = L'Á',
+
+	[KC_Z] = L'Ý',
+};
+
+static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+{
+	if (key >= map_length)
+		return 0;
+	return map[key];
+}
+
+static wchar_t parse_ms_hacek(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	wchar_t c;
+
+	cz_state->mstate = ms_start;
+
+	/* Produce no characters when Ctrl or Alt is pressed. */
+	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
+		return 0;
+
+	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
+		c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
+
+	return c;
+}
+
+static wchar_t parse_ms_carka(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	wchar_t c;
+
+	cz_state->mstate = ms_start;
+
+	/* Produce no characters when Ctrl or Alt is pressed. */
+	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
+		return 0;
+
+	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
+		c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
+
+	return c;
+}
+
+static wchar_t parse_ms_start(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	wchar_t c;
+
+	/* Produce no characters when Ctrl or Alt is pressed. */
+	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
+		return 0;
+
+	if (ev->key == KC_EQUALS) {
+		if ((ev->mods & KM_SHIFT) != 0)
+			cz_state->mstate = ms_hacek;
+		else
+			cz_state->mstate = ms_carka;
+
+		return 0;
+	}
+
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_SHIFT) == 0) {
+		if ((ev->mods & KM_CAPS_LOCK) != 0)
+			c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
+		else
+			c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
+
+		if (c != 0)
+			return c;
+	}	
+
+	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_SHIFT) != 0)
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_NUM_LOCK) != 0)
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+	else
+		c = 0;
+
+	return c;
+}
+
+static bool key_is_mod(unsigned key)
+{
+	switch (key) {
+	case KC_LSHIFT:
+	case KC_RSHIFT:
+	case KC_LALT:
+	case KC_RALT:
+	case KC_LCTRL:
+	case KC_RCTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int cz_create(layout_t *state)
+{
+	layout_cz_t *cz_state;
+
+	cz_state = malloc(sizeof(layout_cz_t));
+	if (cz_state == NULL) {
+		printf(NAME ": Out of memory.\n");
+		return ENOMEM;
+	}
+
+	cz_state->mstate = ms_start;
+	state->layout_priv = (void *) cz_state;
+
+	return EOK;
+}
+
+static void cz_destroy(layout_t *state)
+{
+	free(state->layout_priv);
+}
+
+static wchar_t cz_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	layout_cz_t *cz_state = (layout_cz_t *) state->layout_priv;
+
+	if (ev->type != KEY_PRESS)
+		return 0;
+	
+	if (key_is_mod(ev->key))
+		return 0;
+	
+	switch (cz_state->mstate) {
+	case ms_start:
+		return parse_ms_start(cz_state, ev);
+	case ms_hacek:
+		return parse_ms_hacek(cz_state, ev);
+	case ms_carka:
+		return parse_ms_carka(cz_state, ev);
+	}
+	
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/input/layout/us_dvorak.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/layout/us_dvorak.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2011 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 input
+ * @brief US Dvorak Simplified Keyboard layout.
+ * @{
+ */
+
+#include <errno.h>
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <layout.h>
+
+static int us_dvorak_create(layout_t *);
+static void us_dvorak_destroy(layout_t *);
+static wchar_t us_dvorak_parse_ev(layout_t *, kbd_event_t *ev);
+
+layout_ops_t us_dvorak_ops = {
+	.create = us_dvorak_create,
+	.destroy = us_dvorak_destroy,
+	.parse_ev = us_dvorak_parse_ev
+};
+
+static wchar_t map_lcase[] = {
+	[KC_R] = 'p',
+	[KC_T] = 'y',
+	[KC_Y] = 'f',
+	[KC_U] = 'g',
+	[KC_I] = 'c',
+	[KC_O] = 'r',
+	[KC_P] = 'l',
+
+	[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_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',
+};
+
+static wchar_t map_ucase[] = {
+	[KC_R] = 'P',
+	[KC_T] = 'Y',
+	[KC_Y] = 'F',
+	[KC_U] = 'G',
+	[KC_I] = 'C',
+	[KC_O] = 'R',
+	[KC_P] = 'L',
+
+	[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_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',
+};
+
+static wchar_t map_not_shifted[] = {
+	[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_Q] = '\'',
+	[KC_W] = ',',
+	[KC_E] = '.',
+
+	[KC_LBRACKET] = '/',
+	[KC_RBRACKET] = '=',
+
+	[KC_QUOTE] = '-',
+	[KC_BACKSLASH] = '\\',
+
+	[KC_Z] = ';',
+};
+
+static wchar_t map_shifted[] = {
+	[KC_BACKTICK] = '~',
+
+	[KC_1] = '!',
+	[KC_2] = '@',
+	[KC_3] = '#',
+	[KC_4] = '$',
+	[KC_5] = '%',
+	[KC_6] = '^',
+	[KC_7] = '&',
+	[KC_8] = '*',
+	[KC_9] = '(',
+	[KC_0] = ')',
+
+	[KC_MINUS] = '{',
+	[KC_EQUALS] = '}',
+
+	[KC_Q] = '"',
+	[KC_W] = '<',
+	[KC_E] = '>',
+
+	[KC_LBRACKET] = '?',
+	[KC_RBRACKET] = '+',
+
+	[KC_QUOTE] = '_',
+	[KC_BACKSLASH] = '|',
+
+	[KC_Z] = ':',
+};
+
+static wchar_t map_neutral[] = {
+	[KC_BACKSPACE] = '\b',
+	[KC_TAB] = '\t',
+	[KC_ENTER] = '\n',
+	[KC_SPACE] = ' ',
+
+	[KC_NSLASH] = '/',
+	[KC_NTIMES] = '*',
+	[KC_NMINUS] = '-',
+	[KC_NPLUS] = '+',
+	[KC_NENTER] = '\n'
+};
+
+static wchar_t map_numeric[] = {
+	[KC_N7] = '7',
+	[KC_N8] = '8',
+	[KC_N9] = '9',
+	[KC_N4] = '4',
+	[KC_N5] = '5',
+	[KC_N6] = '6',
+	[KC_N1] = '1',
+	[KC_N2] = '2',
+	[KC_N3] = '3',
+
+	[KC_N0] = '0',
+	[KC_NPERIOD] = '.'
+};
+
+static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+{
+	if (key >= map_length)
+		return 0;
+	return map[key];
+}
+
+static int us_dvorak_create(layout_t *state)
+{
+	return EOK;
+}
+
+static void us_dvorak_destroy(layout_t *state)
+{
+}
+
+static wchar_t us_dvorak_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	wchar_t c;
+
+	/* Produce no characters when Ctrl or Alt is pressed. */
+	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
+		return 0;
+
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	if (c != 0)
+		return c;
+
+	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_SHIFT) != 0)
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_NUM_LOCK) != 0)
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+	else
+		c = 0;
+
+	return c;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/input/layout/us_qwerty.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/layout/us_qwerty.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2011 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 input
+ * @brief	US QWERTY layout.
+ * @{
+ */
+
+#include <errno.h>
+#include <kbd.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <layout.h>
+
+static int us_qwerty_create(layout_t *);
+static void us_qwerty_destroy(layout_t *);
+static wchar_t us_qwerty_parse_ev(layout_t *, kbd_event_t *ev);
+
+layout_ops_t us_qwerty_ops = {
+	.create = us_qwerty_create,
+	.destroy = us_qwerty_destroy,
+	.parse_ev = us_qwerty_parse_ev
+};
+
+static wchar_t map_lcase[] = {
+	[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_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_Z] = 'z',
+	[KC_X] = 'x',
+	[KC_C] = 'c',
+	[KC_V] = 'v',
+	[KC_B] = 'b',
+	[KC_N] = 'n',
+	[KC_M] = 'm',
+};
+
+static wchar_t map_ucase[] = {
+	[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_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_Z] = 'Z',
+	[KC_X] = 'X',
+	[KC_C] = 'C',
+	[KC_V] = 'V',
+	[KC_B] = 'B',
+	[KC_N] = 'N',
+	[KC_M] = 'M',
+};
+
+static wchar_t map_not_shifted[] = {
+	[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_LBRACKET] = '[',
+	[KC_RBRACKET] = ']',
+
+	[KC_SEMICOLON] = ';',
+	[KC_QUOTE] = '\'',
+	[KC_BACKSLASH] = '\\',
+
+	[KC_COMMA] = ',',
+	[KC_PERIOD] = '.',
+	[KC_SLASH] = '/',
+};
+
+static wchar_t map_shifted[] = {
+	[KC_BACKTICK] = '~',
+
+	[KC_1] = '!',
+	[KC_2] = '@',
+	[KC_3] = '#',
+	[KC_4] = '$',
+	[KC_5] = '%',
+	[KC_6] = '^',
+	[KC_7] = '&',
+	[KC_8] = '*',
+	[KC_9] = '(',
+	[KC_0] = ')',
+
+	[KC_MINUS] = '_',
+	[KC_EQUALS] = '+',
+
+	[KC_LBRACKET] = '{',
+	[KC_RBRACKET] = '}',
+
+	[KC_SEMICOLON] = ':',
+	[KC_QUOTE] = '"',
+	[KC_BACKSLASH] = '|',
+
+	[KC_COMMA] = '<',
+	[KC_PERIOD] = '>',
+	[KC_SLASH] = '?',
+};
+
+static wchar_t map_neutral[] = {
+	[KC_BACKSPACE] = '\b',
+	[KC_TAB] = '\t',
+	[KC_ENTER] = '\n',
+	[KC_SPACE] = ' ',
+
+	[KC_NSLASH] = '/',
+	[KC_NTIMES] = '*',
+	[KC_NMINUS] = '-',
+	[KC_NPLUS] = '+',
+	[KC_NENTER] = '\n'
+};
+
+static wchar_t map_numeric[] = {
+	[KC_N7] = '7',
+	[KC_N8] = '8',
+	[KC_N9] = '9',
+	[KC_N4] = '4',
+	[KC_N5] = '5',
+	[KC_N6] = '6',
+	[KC_N1] = '1',
+	[KC_N2] = '2',
+	[KC_N3] = '3',
+
+	[KC_N0] = '0',
+	[KC_NPERIOD] = '.'
+};
+
+static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+{
+	if (key >= map_length)
+		return 0;
+	return map[key];
+}
+
+static int us_qwerty_create(layout_t *state)
+{
+	return EOK;
+}
+
+static void us_qwerty_destroy(layout_t *state)
+{
+}
+
+static wchar_t us_qwerty_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	wchar_t c;
+
+	/* Produce no characters when Ctrl or Alt is pressed. */
+	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
+		return 0;
+
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	if (c != 0)
+		return c;
+
+	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_SHIFT) != 0)
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+	else
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+
+	if (c != 0)
+		return c;
+
+	if ((ev->mods & KM_NUM_LOCK) != 0)
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+	else
+		c = 0;
+
+	return c;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/port/adb.c
===================================================================
--- uspace/srv/hid/input/port/adb.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/adb.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2011 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_port
+ * @ingroup kbd
+ * @{
+ */
+/** @file
+ * @brief ADB keyboard port driver.
+ */
+
+#include <ipc/adb.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <input.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include <vfs/vfs.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <devmap.h>
+#include <devmap_obsolete.h>
+
+static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
+static void adb_kbd_reg0_data(uint16_t data);
+
+static int adb_port_init(kbd_dev_t *);
+static void adb_port_yield(void);
+static void adb_port_reclaim(void);
+static void adb_port_write(uint8_t data);
+
+kbd_port_ops_t adb_port = {
+	.init = adb_port_init,
+	.yield = adb_port_yield,
+	.reclaim = adb_port_reclaim,
+	.write = adb_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+static int dev_phone;
+
+static int adb_port_init(kbd_dev_t *kdev)
+{
+	const char *dev = "adb/kbd";
+	devmap_handle_t handle;
+
+	kbd_dev = kdev;
+	
+	int rc = devmap_device_get_handle(dev, &handle, 0);
+	if (rc == EOK) {
+		dev_phone = devmap_obsolete_device_connect(handle, 0);
+		if (dev_phone < 0) {
+			printf("%s: Failed to connect to device\n", NAME);
+			return dev_phone;
+		}
+	} else
+		return rc;
+	
+	/* NB: The callback connection is slotted for removal */
+	rc = async_obsolete_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events,
+	    NULL);
+	if (rc != EOK) {
+		printf(NAME ": Failed to create callback from device\n");
+		return rc;
+	}
+	
+	return EOK;
+}
+
+static void adb_port_yield(void)
+{
+}
+
+static void adb_port_reclaim(void)
+{
+}
+
+static void adb_port_write(uint8_t data)
+{
+	/*async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);*/
+}
+
+static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	/* Ignore parameters, the connection is already opened */
+	while (true) {
+
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+
+		int retval;
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* TODO: Handle hangup */
+			return;
+		}
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case ADB_REG_NOTIF:
+			adb_kbd_reg0_data(IPC_GET_ARG1(call));
+			break;
+		default:
+			retval = ENOENT;
+		}
+		async_answer_0(callid, retval);
+	}
+}
+
+static void adb_kbd_reg0_data(uint16_t data)
+{
+	uint8_t b0, b1;
+
+	b0 = (data >> 8) & 0xff;
+	b1 = data & 0xff;
+
+	if (b0 != 0xff)
+		kbd_push_scancode(kbd_dev, b0);
+	if (b1 != 0xff)
+		kbd_push_scancode(kbd_dev, b1);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/port/chardev.c
===================================================================
--- uspace/srv/hid/input/port/chardev.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/chardev.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2011 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_port
+ * @ingroup kbd
+ * @{
+ */
+/** @file
+ * @brief Chardev keyboard port driver.
+ */
+
+#include <ipc/char.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <input.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include <devmap.h>
+#include <devmap_obsolete.h>
+#include <errno.h>
+#include <stdio.h>
+
+static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
+
+static int chardev_port_init(kbd_dev_t *);
+static void chardev_port_yield(void);
+static void chardev_port_reclaim(void);
+static void chardev_port_write(uint8_t data);
+
+kbd_port_ops_t chardev_port = {
+	.init = chardev_port_init,
+	.yield = chardev_port_yield,
+	.reclaim = chardev_port_reclaim,
+	.write = chardev_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+static int dev_phone;
+
+/** List of devices to try connecting to. */
+static const char *in_devs[] = {
+	"char/ps2a",
+	"char/s3c24ser"
+};
+
+static const unsigned int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
+
+static int chardev_port_init(kbd_dev_t *kdev)
+{
+	devmap_handle_t handle;
+	unsigned int i;
+	int rc;
+	
+	kbd_dev = kdev;
+	
+	for (i = 0; i < num_devs; i++) {
+		rc = devmap_device_get_handle(in_devs[i], &handle, 0);
+		if (rc == EOK)
+			break;
+	}
+	
+	if (i >= num_devs) {
+		printf("%s: Could not find any suitable input device\n", NAME);
+		return -1;
+	}
+	
+	dev_phone = devmap_obsolete_device_connect(handle, IPC_FLAG_BLOCKING);
+	if (dev_phone < 0) {
+		printf("%s: Failed connecting to device\n", NAME);
+		return ENOENT;
+	}
+	
+	/* NB: The callback connection is slotted for removal */
+	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events,
+	    NULL) != 0) {
+		printf(NAME ": Failed to create callback from device\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void chardev_port_yield(void)
+{
+}
+
+static void chardev_port_reclaim(void)
+{
+}
+
+static void chardev_port_write(uint8_t data)
+{
+	async_obsolete_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
+}
+
+static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	/* Ignore parameters, the connection is already opened */
+	while (true) {
+
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			/* TODO: Handle hangup */
+			return;
+		}
+
+		int retval;
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case CHAR_NOTIF_BYTE:
+			kbd_push_scancode(kbd_dev, IPC_GET_ARG1(call));
+			break;
+		default:
+			retval = ENOENT;
+		}
+		async_answer_0(callid, retval);
+	}
+}
+
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/port/gxemul.c
===================================================================
--- uspace/srv/hid/input/port/gxemul.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/gxemul.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2011 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_port
+ * @{
+ * @ingroup  kbd
+ */ 
+/** @file
+ * @brief	GXEmul keyboard port driver.
+ */
+
+#include <async.h>
+#include <sysinfo.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include <ddi.h>
+#include <errno.h>
+
+static int gxemul_port_init(kbd_dev_t *);
+static void gxemul_port_yield(void);
+static void gxemul_port_reclaim(void);
+static void gxemul_port_write(uint8_t data);
+
+kbd_port_ops_t gxemul_port = {
+	.init = gxemul_port_init,
+	.yield = gxemul_port_yield,
+	.reclaim = gxemul_port_reclaim,
+	.write = gxemul_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+static irq_cmd_t gxemul_cmds[] = {
+	{ 
+		.cmd = CMD_PIO_READ_8, 
+		.addr = (void *) 0, 	/* will be patched in run-time */
+		.dstarg = 2,
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t gxemul_kbd = {
+	sizeof(gxemul_cmds) / sizeof(irq_cmd_t),
+	gxemul_cmds
+};
+
+static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+/** Initializes keyboard handler. */
+static int gxemul_port_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	
+	sysarg_t addr;
+	if (sysinfo_get_value("kbd.address.virtual", &addr) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	async_set_interrupt_received(gxemul_irq_handler);
+	gxemul_cmds[0].addr = (void *) addr;
+	register_irq(inr, device_assign_devno(), 0, &gxemul_kbd);
+	return 0;
+}
+
+static void gxemul_port_yield(void)
+{
+}
+
+static void gxemul_port_reclaim(void)
+{
+}
+
+static void gxemul_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+/** 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(kbd_dev, scan_code);
+}
+
+/** @}
+ */
Index: uspace/srv/hid/input/port/msim.c
===================================================================
--- uspace/srv/hid/input/port/msim.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/msim.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 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_port
+ * @ingroup  kbd
+ * @{
+ */
+/** @file
+ * @brief Msim keyboard port driver.
+ */
+
+#include <async.h>
+#include <sysinfo.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include <ddi.h>
+#include <errno.h>
+
+static int msim_port_init(kbd_dev_t *);
+static void msim_port_yield(void);
+static void msim_port_reclaim(void);
+static void msim_port_write(uint8_t data);
+
+kbd_port_ops_t msim_port = {
+	.init = msim_port_init,
+	.yield = msim_port_yield,
+	.reclaim = msim_port_reclaim,
+	.write = msim_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+static irq_cmd_t msim_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = (void *) 0,	/* will be patched in run-time */
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t msim_kbd = {
+	sizeof(msim_cmds) / sizeof(irq_cmd_t),
+	msim_cmds
+};
+
+static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+static int msim_port_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+
+	sysarg_t vaddr;
+	if (sysinfo_get_value("kbd.address.virtual", &vaddr) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	msim_cmds[0].addr = (void *) vaddr;
+	async_set_interrupt_received(msim_irq_handler);
+	register_irq(inr, device_assign_devno(), 0, &msim_kbd);
+	
+	return 0;
+}
+
+static void msim_port_yield(void)
+{
+}
+
+static void msim_port_reclaim(void)
+{
+}
+
+static void msim_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int scan_code = IPC_GET_ARG2(*call);
+	kbd_push_scancode(kbd_dev, scan_code);
+}
+
+/** @}
+*/
Index: uspace/srv/hid/input/port/niagara.c
===================================================================
--- uspace/srv/hid/input/port/niagara.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/niagara.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2008 Pavel Rimsky
+ * Copyright (c) 2011 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_port
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ * @brief	Niagara console keyboard port driver.
+ */
+
+#include <as.h>
+#include <ddi.h>
+#include <async.h>
+#include <kbd.h>
+#include <kbd_port.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <thread.h>
+#include <bool.h>
+#include <errno.h>
+
+static int niagara_port_init(kbd_dev_t *);
+static void niagara_port_yield(void);
+static void niagara_port_reclaim(void);
+static void niagara_port_write(uint8_t data);
+
+kbd_port_ops_t niagara_port = {
+	.init = niagara_port_init,
+	.yield = niagara_port_yield,
+	.reclaim = niagara_port_reclaim,
+	.write = niagara_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+#define POLL_INTERVAL  10000
+
+/**
+ * Virtual address mapped to the buffer shared with the kernel counterpart.
+ */
+static uintptr_t input_buffer_addr;
+
+/*
+ * Kernel counterpart of the driver pushes characters (it has read) here.
+ * Keep in sync with the definition from
+ * kernel/arch/sparc64/src/drivers/niagara.c.
+ */
+#define INPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
+
+typedef volatile struct {
+	uint64_t write_ptr;
+	uint64_t read_ptr;
+	char data[INPUT_BUFFER_SIZE];
+}
+	__attribute__ ((packed))
+	__attribute__ ((aligned(PAGE_SIZE)))
+	*input_buffer_t;
+
+/* virtual address of the shared buffer */
+static input_buffer_t input_buffer;
+
+static volatile bool polling_disabled = false;
+static void niagara_thread_impl(void *arg);
+
+/**
+ * Initializes the Niagara driver.
+ * Maps the shared buffer and creates the polling thread. 
+ */
+static int niagara_port_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	
+	sysarg_t paddr;
+	if (sysinfo_get_value("niagara.inbuf.address", &paddr) != EOK)
+		return -1;
+	
+	input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
+	int rc = physmem_map((void *) paddr, (void *) input_buffer_addr,
+	    1, AS_AREA_READ | AS_AREA_WRITE);
+	
+	if (rc != 0) {
+		printf("Niagara: uspace driver couldn't map physical memory: %d\n",
+		    rc);
+		return rc;
+	}
+	
+	input_buffer = (input_buffer_t) input_buffer_addr;
+	
+	thread_id_t tid;
+	rc = thread_create(niagara_thread_impl, NULL, "kbd_poll", &tid);
+	if (rc != 0)
+		return rc;
+	
+	return 0;
+}
+
+static void niagara_port_yield(void)
+{
+	polling_disabled = true;
+}
+
+static void niagara_port_reclaim(void)
+{
+	polling_disabled = false;
+}
+
+static void niagara_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+/**
+ * Called regularly by the polling thread. Reads codes of all the
+ * pressed keys from the buffer. 
+ */
+static void niagara_key_pressed(void)
+{
+	char c;
+	
+	while (input_buffer->read_ptr != input_buffer->write_ptr) {
+		c = input_buffer->data[input_buffer->read_ptr];
+		input_buffer->read_ptr =
+			((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
+		kbd_push_scancode(kbd_dev, c);
+	}
+}
+
+/**
+ * Thread to poll SGCN for keypresses.
+ */
+static void niagara_thread_impl(void *arg)
+{
+	(void) arg;
+
+	while (1) {
+		if (polling_disabled == false)
+			niagara_key_pressed();
+		usleep(POLL_INTERVAL);
+	}
+}
+/** @}
+ */
Index: uspace/srv/hid/input/port/ns16550.c
===================================================================
--- uspace/srv/hid/input/port/ns16550.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/ns16550.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 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_port
+ * @ingroup  kbd
+ * @{
+ */
+/** @file
+ * @brief NS16550 port driver.
+ */
+
+#include <ipc/irc.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <sysinfo.h>
+#include <input.h>
+#include <kbd.h>
+#include <kbd_port.h>
+#include <ddi.h>
+#include <errno.h>
+
+static int ns16550_port_init(kbd_dev_t *);
+static void ns16550_port_yield(void);
+static void ns16550_port_reclaim(void);
+static void ns16550_port_write(uint8_t data);
+
+kbd_port_ops_t ns16550_port = {
+	.init = ns16550_port_init,
+	.yield = ns16550_port_yield,
+	.reclaim = ns16550_port_reclaim,
+	.write = ns16550_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+/* NS16550 registers */
+#define RBR_REG  0  /** Receiver Buffer Register. */
+#define IER_REG  1  /** Interrupt Enable Register. */
+#define IIR_REG  2  /** Interrupt Ident Register (read). */
+#define FCR_REG  2  /** FIFO control register (write). */
+#define LCR_REG  3  /** Line Control register. */
+#define MCR_REG  4  /** Modem Control Register. */
+#define LSR_REG  5  /** Line Status Register. */
+
+#define LSR_DATA_READY  0x01
+
+static irq_cmd_t ns16550_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = (void *) 0,     /* Will be patched in run-time */
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_BTEST,
+		.value = LSR_DATA_READY,
+		.srcarg = 1,
+		.dstarg = 3
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 2,
+		.srcarg = 3
+	},
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = (void *) 0,     /* Will be patched in run-time */
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+irq_code_t ns16550_kbd = {
+	sizeof(ns16550_cmds) / sizeof(irq_cmd_t),
+	ns16550_cmds
+};
+
+static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+static uintptr_t ns16550_physical;
+static uintptr_t ns16550_kernel;
+
+static kbd_dev_t *kbd_dev;
+
+static int ns16550_port_init(kbd_dev_t *kdev)
+{
+	void *vaddr;
+	
+	kbd_dev = kdev;
+	
+	sysarg_t ns16550;
+	if (sysinfo_get_value("kbd.type.ns16550", &ns16550) != EOK)
+		return -1;
+	if (!ns16550)
+		return -1;
+	
+	if (sysinfo_get_value("kbd.address.physical", &ns16550_physical) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("kbd.address.kernel", &ns16550_kernel) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
+	ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
+	
+	async_set_interrupt_received(ns16550_irq_handler);
+	register_irq(inr, device_assign_devno(), inr, &ns16550_kbd);
+	
+	return pio_enable((void *) ns16550_physical, 8, &vaddr);
+}
+
+static void ns16550_port_yield(void)
+{
+}
+
+static void ns16550_port_reclaim(void)
+{
+}
+
+static void ns16550_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int scan_code = IPC_GET_ARG2(*call);
+	kbd_push_scancode(kbd_dev, scan_code);
+	
+	if (irc_service)
+		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
+		    IPC_GET_IMETHOD(*call));
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/port/pl050.c
===================================================================
--- uspace/srv/hid/input/port/pl050.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/pl050.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * Copyright (c) 2011 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_port
+ * @ingroup kbd
+ * @{
+ */ 
+/** @file
+ * @brief pl050 port driver.
+ */
+
+#include <ddi.h>
+#include <libarch/ddi.h>
+#include <async.h>
+#include <unistd.h>
+#include <sysinfo.h>
+#include <kbd_port.h>
+#include <kbd.h>
+#include <ddi.h>
+#include <stdio.h>
+#include <errno.h>
+
+static int pl050_port_init(kbd_dev_t *);
+static void pl050_port_yield(void);
+static void pl050_port_reclaim(void);
+static void pl050_port_write(uint8_t data);
+
+kbd_port_ops_t pl050_port = {
+	.init = pl050_port_init,
+	.yield = pl050_port_yield,
+	.reclaim = pl050_port_reclaim,
+	.write = pl050_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+#define PL050_STAT_RXFULL  (1 << 4)
+
+static irq_cmd_t pl050_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = NULL,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_BTEST,
+		.value = PL050_STAT_RXFULL,
+		.srcarg = 1,
+		.dstarg = 3
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 2,
+		.srcarg = 3
+	},
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = NULL,  /* Will be patched in run-time */
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t pl050_kbd = {
+	sizeof(pl050_cmds) / sizeof(irq_cmd_t),
+	pl050_cmds
+};
+
+static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+static int pl050_port_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	
+	sysarg_t addr;
+	if (sysinfo_get_value("kbd.address.status", &addr) != EOK)
+		return -1;
+	
+	pl050_kbd.cmds[0].addr = (void *) addr;
+	
+	if (sysinfo_get_value("kbd.address.data", &addr) != EOK)
+		return -1;
+	
+	pl050_kbd.cmds[3].addr = (void *) addr;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	async_set_interrupt_received(pl050_irq_handler);
+	register_irq(inr, device_assign_devno(), 0, &pl050_kbd);
+	
+	return 0;
+}
+
+static void pl050_port_yield(void)
+{
+}
+
+static void pl050_port_reclaim(void)
+{
+}
+
+static void pl050_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int scan_code = IPC_GET_ARG2(*call);
+
+	kbd_push_scancode(kbd_dev, scan_code);
+	return;
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/port/sgcn.c
===================================================================
--- uspace/srv/hid/input/port/sgcn.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/sgcn.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2008 Pavel Rimsky
+ * Copyright (c) 2011 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_port
+ * @ingroup  kbd
+ * @{
+ */
+/** @file
+ * @brief SGCN (Serengeti Console) keyboard port driver.
+ */
+
+#include <as.h>
+#include <ddi.h>
+#include <async.h>
+#include <kbd.h>
+#include <kbd_port.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <thread.h>
+#include <bool.h>
+#include <errno.h>
+
+static int sgcn_port_init(kbd_dev_t *);
+static void sgcn_port_yield(void);
+static void sgcn_port_reclaim(void);
+static void sgcn_port_write(uint8_t data);
+
+kbd_port_ops_t sgcn_port = {
+	.init = sgcn_port_init,
+	.yield = sgcn_port_yield,
+	.reclaim = sgcn_port_reclaim,
+	.write = sgcn_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+#define POLL_INTERVAL  10000
+
+/**
+ * SGCN buffer header. It is placed at the very beginning of the SGCN
+ * buffer.
+ */
+typedef struct {
+	/** hard-wired to "CON" */
+	char magic[4];
+	
+	/** we don't need this */
+	char unused[8];
+	
+	/** offset within the SGCN buffer of the input buffer start */
+	uint32_t in_begin;
+	
+	/** offset within the SGCN buffer of the input buffer end */
+	uint32_t in_end;
+	
+	/** offset within the SGCN buffer of the input buffer read pointer */
+	uint32_t in_rdptr;
+	
+	/** offset within the SGCN buffer of the input buffer write pointer */
+	uint32_t in_wrptr;
+} __attribute__ ((packed)) sgcn_buffer_header_t;
+
+/*
+ * Returns a pointer to the object of a given type which is placed at the given
+ * offset from the console buffer beginning.
+ */
+#define SGCN_BUFFER(type, offset) \
+		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
+
+/** Returns a pointer to the console buffer header. */
+#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
+
+/**
+ * Virtual address mapped to SRAM.
+ */
+static uintptr_t sram_virt_addr;
+
+/**
+ * SGCN buffer offset within SGCN.
+ */
+static uintptr_t sram_buffer_offset;
+
+/* polling thread */
+static void sgcn_thread_impl(void *arg);
+
+static volatile bool polling_disabled = false;
+
+/**
+ * Initializes the SGCN driver.
+ * Maps the physical memory (SRAM) and creates the polling thread. 
+ */
+static int sgcn_port_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	
+	sysarg_t sram_paddr;
+	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
+		return -1;
+	
+	sysarg_t sram_size;
+	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
+		return -1;
+	
+	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
+		sram_buffer_offset = 0;
+	
+	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
+	
+	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
+	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
+		printf("SGCN: uspace driver could not map physical memory.");
+		return -1;
+	}
+	
+	thread_id_t tid;
+	int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
+	if (rc != 0)
+		return rc;
+	
+	return 0;
+}
+
+static void sgcn_port_yield(void)
+{
+	polling_disabled = true;
+}
+
+static void sgcn_port_reclaim(void)
+{
+	polling_disabled = false;
+}
+
+static void sgcn_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+/**
+ * Handler of the "key pressed" event. Reads codes of all the pressed keys from
+ * the buffer. 
+ */
+static void sgcn_key_pressed(void)
+{
+	char c;
+	
+	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
+	uint32_t end = SGCN_BUFFER_HEADER->in_end;
+	uint32_t size = end - begin;
+	
+	volatile char *buf_ptr = (volatile char *)
+		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
+	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
+	
+	while (*in_rdptr_ptr != *in_wrptr_ptr) {
+		c = *buf_ptr;
+		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
+		buf_ptr = (volatile char *)
+			SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+		kbd_push_scancode(kbd_dev, c);
+	}
+}
+
+/**
+ * Thread to poll SGCN for keypresses.
+ */
+static void sgcn_thread_impl(void *arg)
+{
+	(void) arg;
+
+	while (1) {
+		if (polling_disabled == false)
+			sgcn_key_pressed();
+		usleep(POLL_INTERVAL);
+	}
+}
+
+/** @}
+ */
Index: uspace/srv/hid/input/port/ski.c
===================================================================
--- uspace/srv/hid/input/port/ski.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/ski.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2011 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_port
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ * @brief	Ski console keyboard port driver.
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <kbd.h>
+#include <kbd_port.h>
+#include <sys/types.h>
+#include <thread.h>
+#include <bool.h>
+
+static int ski_port_init(kbd_dev_t *);
+static void ski_port_yield(void);
+static void ski_port_reclaim(void);
+static void ski_port_write(uint8_t data);
+
+kbd_port_ops_t ski_port = {
+	.init = ski_port_init,
+	.yield = ski_port_yield,
+	.reclaim = ski_port_reclaim,
+	.write = ski_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+#define SKI_GETCHAR		21
+
+#define POLL_INTERVAL		10000
+
+static void ski_thread_impl(void *arg);
+static int32_t ski_getchar(void);
+
+static volatile bool polling_disabled = false;
+
+/** Initialize Ski port driver. */
+static int ski_port_init(kbd_dev_t *kdev)
+{
+	thread_id_t tid;
+	int rc;
+
+	kbd_dev = kdev;
+
+	rc = thread_create(ski_thread_impl, NULL, "kbd_poll", &tid);
+	if (rc != 0) {
+		return rc;
+	}
+
+	return 0;
+}
+
+static void ski_port_yield(void)
+{
+	polling_disabled = true;
+}
+
+static void ski_port_reclaim(void)
+{
+	polling_disabled = false;
+}
+
+static void ski_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+/** Thread to poll Ski for keypresses. */
+static void ski_thread_impl(void *arg)
+{
+	int32_t c;
+	(void) arg;
+
+	while (1) {
+		while (polling_disabled == false) {
+			c = ski_getchar();
+			if (c == 0)
+				break;
+			kbd_push_scancode(kbd_dev, c);
+		}
+
+		usleep(POLL_INTERVAL);
+	}
+}
+
+/** Ask Ski if a key was pressed.
+ *
+ * Use SSC (Simulator System Call) to get character from the debug console.
+ * This call is non-blocking.
+ *
+ * @return ASCII code of pressed key or 0 if no key pressed.
+ */
+static int32_t ski_getchar(void)
+{
+	uint64_t ch;
+	
+#ifdef UARCH_ia64
+	asm volatile (
+		"mov r15 = %1\n"
+		"break 0x80000;;\n"	/* modifies r8 */
+		"mov %0 = r8;;\n"		
+
+		: "=r" (ch)
+		: "i" (SKI_GETCHAR)
+		: "r15", "r8"
+	);
+#else
+	ch = 0;
+#endif
+	return (int32_t) ch;
+}
+
+/** @}
+ */
Index: uspace/srv/hid/input/port/z8530.c
===================================================================
--- uspace/srv/hid/input/port/z8530.c	(revision e99564dc2111119a734299639f28432400d665d2)
+++ uspace/srv/hid/input/port/z8530.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2011 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_port
+ * @ingroup  kbd
+ * @{
+ */
+/** @file
+ * @brief Z8530 keyboard port driver.
+ */
+
+#include <ipc/irc.h>
+#include <async.h>
+#include <async_obsolete.h>
+#include <sysinfo.h>
+#include <input.h>
+#include <kbd.h>
+#include <kbd_port.h>
+#include <sys/types.h>
+#include <ddi.h>
+#include <errno.h>
+
+static int z8530_port_init(kbd_dev_t *);
+static void z8530_port_yield(void);
+static void z8530_port_reclaim(void);
+static void z8530_port_write(uint8_t data);
+
+kbd_port_ops_t z8530_port = {
+	.init = z8530_port_init,
+	.yield = z8530_port_yield,
+	.reclaim = z8530_port_reclaim,
+	.write = z8530_port_write
+};
+
+static kbd_dev_t *kbd_dev;
+
+#define CHAN_A_STATUS  4
+#define CHAN_A_DATA    6
+
+#define RR0_RCA  1
+
+static irq_cmd_t z8530_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = (void *) 0,     /* Will be patched in run-time */
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_BTEST,
+		.value = RR0_RCA,
+		.srcarg = 1,
+		.dstarg = 3
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 2,
+		.srcarg = 3
+	},
+	{
+		.cmd = CMD_PIO_READ_8,
+		.addr = (void *) 0,     /* Will be patched in run-time */
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t z8530_kbd = {
+	sizeof(z8530_cmds) / sizeof(irq_cmd_t),
+	z8530_cmds
+};
+
+static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+
+static int z8530_port_init(kbd_dev_t *kdev)
+{
+	kbd_dev = kdev;
+	
+	sysarg_t z8530;
+	if (sysinfo_get_value("kbd.type.z8530", &z8530) != EOK)
+		return -1;
+	if (!z8530)
+		return -1;
+	
+	sysarg_t kaddr;
+	if (sysinfo_get_value("kbd.address.kernel", &kaddr) != EOK)
+		return -1;
+	
+	sysarg_t inr;
+	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
+		return -1;
+	
+	z8530_cmds[0].addr = (void *) kaddr + CHAN_A_STATUS;
+	z8530_cmds[3].addr = (void *) kaddr + CHAN_A_DATA;
+	
+	async_set_interrupt_received(z8530_irq_handler);
+	register_irq(inr, device_assign_devno(), inr, &z8530_kbd);
+	
+	return 0;
+}
+
+static void z8530_port_yield(void)
+{
+}
+
+static void z8530_port_reclaim(void)
+{
+}
+
+static void z8530_port_write(uint8_t data)
+{
+	(void) data;
+}
+
+static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int scan_code = IPC_GET_ARG2(*call);
+	kbd_push_scancode(kbd_dev, scan_code);
+	
+	if (irc_service)
+		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
+		    IPC_GET_IMETHOD(*call));
+}
+
+/** @}
+ */
Index: pace/srv/hid/kbd/Makefile
===================================================================
--- uspace/srv/hid/kbd/Makefile	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,167 +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 = ../../..
-ROOT_PATH = $(USPACE_PREFIX)/..
-
-COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
-CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
-
-EXTRA_CFLAGS = -Iinclude
-BINARY = kbd
-
--include $(COMMON_MAKEFILE)
--include $(CONFIG_MAKEFILE)
-
-## Sources
-#
-
-SOURCES = \
-	generic/kbd.c \
-	genarch/gsp.c \
-	genarch/stroke.c \
-	layout/cz.c \
-	layout/us_qwerty.c \
-	layout/us_dvorak.c
-
-ifeq ($(UARCH),amd64)
-	SOURCES += \
-		port/chardev.c \
-		ctl/pc.c
-endif
-
-ifeq ($(UARCH),arm32)
-	ifeq ($(MACHINE),gta02)
-		SOURCES += \
-			port/chardev.c \
-			ctl/stty.c
-	endif
-	ifeq ($(MACHINE),testarm)
-		SOURCES += \
-			port/gxemul.c
-		
-		ifeq ($(CONFIG_FB),y)
-			SOURCES += \
-				ctl/gxe_fb.c
-		else
-			SOURCES += \
-				ctl/stty.c
-		endif
-	endif
-	ifeq ($(MACHINE),integratorcp)
-		SOURCES += \
-			port/pl050.c \
-			ctl/pc.c
-	endif
-endif
-
-ifeq ($(UARCH),ia32)
-	SOURCES += \
-		port/chardev.c \
-		ctl/pc.c
-endif
-
-ifeq ($(MACHINE),i460GX)
-	SOURCES += \
-		port/chardev.c \
-		ctl/pc.c
-endif
-
-ifeq ($(MACHINE),ski)
-	SOURCES += \
-		port/ski.c \
-		ctl/stty.c
-endif
-
-ifeq ($(MACHINE),msim)
-	SOURCES += \
-		port/msim.c \
-		ctl/stty.c
-endif
-
-ifeq ($(MACHINE),lgxemul)
-	SOURCES += \
-		port/gxemul.c
-	
-	ifeq ($(CONFIG_FB),y)
-		SOURCES += \
-			ctl/gxe_fb.c
-	else
-		SOURCES += \
-			ctl/stty.c
-	endif
-endif
-
-ifeq ($(MACHINE),bgxemul)
-	SOURCES += \
-		port/gxemul.c
-	
-	ifeq ($(CONFIG_FB),y)
-		SOURCES += \
-			ctl/gxe_fb.c
-	else
-		SOURCES += \
-			ctl/stty.c
-	endif
-endif
-
-ifeq ($(UARCH),ppc32)
-	SOURCES += \
-		port/adb.c \
-		ctl/apple.c
-endif
-
-ifeq ($(UARCH),sparc64)
-	ifeq ($(PROCESSOR),sun4v)
-		SOURCES += \
-			port/niagara.c \
-			ctl/stty.c
-	else
-		ifeq ($(MACHINE),serengeti)
-			SOURCES += \
-				port/sgcn.c \
-				ctl/stty.c
-		endif
-		ifeq ($(MACHINE),generic)
-			SOURCES += \
-			port/sun.c \
-			port/z8530.c \
-			port/ns16550.c \
-			ctl/sun.c
-		endif
-	endif
-endif
-
-ifeq ($(UARCH),abs32le)
-	SOURCES += \
-		port/dummy.c \
-		ctl/pc.c
-endif
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/hid/kbd/ctl/apple.c
===================================================================
--- uspace/srv/hid/kbd/ctl/apple.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,209 +1,0 @@
-/*
- * Copyright (c) 2010 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_ctl
- * @ingroup kbd
- * @{
- */
-/**
- * @file
- * @brief	Apple ADB keyboard controller driver.
- */
-
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <kbd_ctl.h>
-
-#define KBD_KEY_RELEASE		0x80
-
-static int scanmap[];
-
-int kbd_ctl_init(void)
-{
-	return 0;
-}
-
-void kbd_ctl_parse_scancode(int scancode)
-{
-	kbd_event_type_t type;
-	unsigned int key;
-
-	if (scancode < 0 || scancode >= 0x100)
-		return;
-
-	if (scancode & KBD_KEY_RELEASE) {
-		scancode &= ~KBD_KEY_RELEASE;
-		type = KEY_RELEASE;
-	} else {
-		type = KEY_PRESS;
-	}
-
-	key = scanmap[scancode];
-	if (key != 0)
-		kbd_push_ev(type, key);
-}
-
-void kbd_ctl_set_ind(unsigned mods)
-{
-	(void) mods;
-}
-
-static int scanmap[] = {
-	[0x00] = KC_A,
-	[0x01] = KC_S,
-	[0x02] = KC_D,
-	[0x03] = KC_F,
-	[0x04] = KC_H,
-	[0x05] = KC_G,
-	[0x06] = KC_Z,
-	[0x07] = KC_X,
-	[0x08] = KC_C,
-	[0x09] = KC_V,
-	[0x0a] = KC_BACKSLASH,
-	[0x0b] = KC_B,
-	[0x0c] = KC_Q,
-	[0x0d] = KC_W,
-	[0x0e] = KC_E,
-	[0x0f] = KC_R,
-	[0x10] = KC_Y,
-	[0x11] = KC_T,
-	[0x12] = KC_1,
-	[0x13] = KC_2,
-	[0x14] = KC_3,
-	[0x15] = KC_4,
-	[0x16] = KC_6,
-	[0x17] = KC_5,
-	[0x18] = KC_EQUALS,
-	[0x19] = KC_9,
-	[0x1a] = KC_7,
-	[0x1b] = KC_MINUS,
-	[0x1c] = KC_8,
-	[0x1d] = KC_0,
-	[0x1e] = KC_RBRACKET,
-	[0x1f] = KC_O,
-	[0x20] = KC_U,
-	[0x21] = KC_LBRACKET,
-	[0x22] = KC_I,
-	[0x23] = KC_P,
-	[0x24] = KC_ENTER,
-	[0x25] = KC_L,
-	[0x26] = KC_J,
-	[0x27] = KC_QUOTE,
-	[0x28] = KC_K,
-	[0x29] = KC_SEMICOLON,
-	[0x2a] = KC_BACKSLASH,
-	[0x2b] = KC_COMMA,
-	[0x2c] = KC_SLASH,
-	[0x2d] = KC_N,
-	[0x2e] = KC_M,
-	[0x2f] = KC_PERIOD,
-	[0x30] = KC_TAB,
-	[0x31] = KC_SPACE,
-	[0x32] = KC_BACKTICK,
-	[0x33] = KC_BACKSPACE,
-	[0x34] = 0,
-	[0x35] = KC_ESCAPE,
-	[0x36] = KC_LCTRL,
-	[0x37] = 0,
-	[0x38] = KC_LSHIFT,
-	[0x39] = KC_CAPS_LOCK,
-	[0x3a] = KC_LALT,
-	[0x3b] = KC_LEFT,
-	[0x3c] = KC_RIGHT,
-	[0x3d] = KC_DOWN,
-	[0x3e] = KC_UP,
-	[0x3f] = 0,
-	[0x40] = 0,
-	[0x41] = KC_NPERIOD,
-	[0x42] = 0,
-	[0x43] = KC_NTIMES,
-	[0x44] = 0,
-	[0x45] = KC_NPLUS,
-	[0x46] = 0,
-	[0x47] = KC_NUM_LOCK,
-	[0x48] = 0,
-	[0x49] = 0,
-	[0x4a] = 0,
-	[0x4b] = KC_NSLASH,
-	[0x4c] = KC_NENTER,
-	[0x4d] = 0,
-	[0x4e] = KC_NMINUS,
-	[0x4f] = 0,
-	[0x50] = 0,
-	[0x51] = 0,
-	[0x52] = KC_N0,
-	[0x53] = KC_N1,
-	[0x54] = KC_N2,
-	[0x55] = KC_N3,
-	[0x56] = KC_N4,
-	[0x57] = KC_N5,
-	[0x58] = KC_N6,
-	[0x59] = KC_N7,
-	[0x5a] = 0,
-	[0x5b] = KC_N8,
-	[0x5c] = KC_N9,
-	[0x5d] = 0,
-	[0x5e] = 0,
-	[0x5f] = 0,
-	[0x60] = KC_F5,
-	[0x61] = KC_F6,
-	[0x62] = KC_F7,
-	[0x63] = KC_F3,
-	[0x64] = KC_F8,
-	[0x65] = KC_F9,
-	[0x66] = 0,
-	[0x67] = KC_F11,
-	[0x68] = 0,
-	[0x69] = 0,
-	[0x6a] = 0,
-	[0x6b] = KC_SCROLL_LOCK,
-	[0x6c] = 0,
-	[0x6d] = KC_F10,
-	[0x6e] = 0,
-	[0x6f] = KC_F12,
-	[0x70] = 0,
-	[0x71] = 0,
-	[0x72] = KC_INSERT,
-	[0x73] = KC_HOME,
-	[0x74] = KC_PAGE_UP,
-	[0x75] = KC_DELETE,
-	[0x76] = KC_F4,
-	[0x77] = KC_END,
-	[0x78] = KC_F2,
-	[0x79] = KC_PAGE_DOWN,
-	[0x7a] = KC_F1,
-	[0x7b] = KC_RSHIFT,
-	[0x7c] = KC_RALT,
-	[0x7d] = KC_RCTRL,
-	[0x7e] = 0,
-	[0x7f] = 0
-};
-
-/** @}
- */
Index: pace/srv/hid/kbd/ctl/gxe_fb.c
===================================================================
--- uspace/srv/hid/kbd/ctl/gxe_fb.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,234 +1,0 @@
-/*
- * 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_ctl
- * @ingroup kbd
- * @{
- */
-/**
- * @file
- * @brief	GXEmul framebuffer-mode keyboard controller driver.
- */
-
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <gsp.h>
-#include <stroke.h>
-
-/** Scancode parser */
-static gsp_t sp;
-
-/** Current parser state */
-static int ds;
-
-#include <stdio.h>
-
-int seq_defs[] = {
-	/* Not shifted */
-
-	0,	KC_BACKTICK,	0x60, GSP_END,
-
-	0,	KC_1,		0x31, GSP_END,
-	0,	KC_2,		0x32, GSP_END,
-	0,	KC_3,		0x33, GSP_END,
-	0,	KC_4,		0x34, GSP_END,
-	0,	KC_5,		0x35, GSP_END,
-	0,	KC_6,		0x36, GSP_END,
-	0,	KC_7,		0x37, GSP_END,
-	0,	KC_8,		0x38, GSP_END,
-	0,	KC_9,		0x39, GSP_END,
-	0,	KC_0,		0x30, GSP_END,
-
-	0,	KC_MINUS,	0x2d, GSP_END,
-	0,	KC_EQUALS,	0x3d, GSP_END,
-	0,	KC_BACKSPACE,	0x08, GSP_END,
-
-	0,	KC_TAB,		0x09, GSP_END,
-
-	0,	KC_Q,		0x71, GSP_END,
-	0,	KC_W,		0x77, GSP_END,
-	0,	KC_E,		0x65, GSP_END,
-	0,	KC_R,		0x72, GSP_END,
-	0,	KC_T,		0x74, GSP_END,
-	0,	KC_Y,		0x79, GSP_END,
-	0,	KC_U,		0x75, GSP_END,
-	0,	KC_I,		0x69, GSP_END,
-	0,	KC_O,		0x6f, GSP_END,
-	0,	KC_P,		0x70, GSP_END,
-
-	0,	KC_LBRACKET,	0x5b, GSP_END,
-	0,	KC_RBRACKET,	0x5d, GSP_END,
-
-	0,	KC_A,		0x61, GSP_END,
-	0,	KC_S,		0x73, GSP_END,
-	0,	KC_D,		0x64, GSP_END,
-	0,	KC_F,		0x66, GSP_END,
-	0,	KC_G,		0x67, GSP_END,
-	0,	KC_H,		0x68, GSP_END,
-	0,	KC_J,		0x6a, GSP_END,
-	0,	KC_K,		0x6b, GSP_END,
-	0,	KC_L,		0x6c, GSP_END,
-
-	0,	KC_SEMICOLON,	0x3b, GSP_END,
-	0,	KC_QUOTE,	0x27, GSP_END,
-	0,	KC_BACKSLASH,	0x5c, GSP_END,
-
-	0,	KC_Z,		0x7a, GSP_END,
-	0,	KC_X,		0x78, GSP_END,
-	0,	KC_C,		0x63, GSP_END,
-	0,	KC_V,		0x76, GSP_END,
-	0,	KC_B,		0x62, GSP_END,
-	0,	KC_N,		0x6e, GSP_END,
-	0,	KC_M,		0x6d, GSP_END,
-
-	0,	KC_COMMA,	0x2c, GSP_END,
-	0,	KC_PERIOD,	0x2e, GSP_END,
-	0,	KC_SLASH,	0x2f, GSP_END,
-
-	/* Shifted */
-
-	KM_SHIFT,	KC_BACKTICK,	0x7e, GSP_END,
-
-	KM_SHIFT,	KC_1,		0x21, GSP_END,
-	KM_SHIFT,	KC_2,		0x40, GSP_END,
-	KM_SHIFT,	KC_3,		0x23, GSP_END,
-	KM_SHIFT,	KC_4,		0x24, GSP_END,
-	KM_SHIFT,	KC_5,		0x25, GSP_END,
-	KM_SHIFT,	KC_6,		0x5e, GSP_END,
-	KM_SHIFT,	KC_7,		0x26, GSP_END,
-	KM_SHIFT,	KC_8,		0x2a, GSP_END,
-	KM_SHIFT,	KC_9,		0x28, GSP_END,
-	KM_SHIFT,	KC_0,		0x29, GSP_END,
-
-	KM_SHIFT,	KC_MINUS,	0x5f, GSP_END,
-	KM_SHIFT,	KC_EQUALS,	0x2b, GSP_END,
-
-	KM_SHIFT,	KC_Q,		0x51, GSP_END,
-	KM_SHIFT,	KC_W,		0x57, GSP_END,
-	KM_SHIFT,	KC_E,		0x45, GSP_END,
-	KM_SHIFT,	KC_R,		0x52, GSP_END,
-	KM_SHIFT,	KC_T,		0x54, GSP_END,
-	KM_SHIFT,	KC_Y,		0x59, GSP_END,
-	KM_SHIFT,	KC_U,		0x55, GSP_END,
-	KM_SHIFT,	KC_I,		0x49, GSP_END,
-	KM_SHIFT,	KC_O,		0x4f, GSP_END,
-	KM_SHIFT,	KC_P,		0x50, GSP_END,
-
-	KM_SHIFT,	KC_LBRACKET,	0x7b, GSP_END,
-	KM_SHIFT,	KC_RBRACKET,	0x7d, GSP_END,
-
-	KM_SHIFT,	KC_A,		0x41, GSP_END,
-	KM_SHIFT,	KC_S,		0x53, GSP_END,
-	KM_SHIFT,	KC_D,		0x44, GSP_END,
-	KM_SHIFT,	KC_F,		0x46, GSP_END,
-	KM_SHIFT,	KC_G,		0x47, GSP_END,
-	KM_SHIFT,	KC_H,		0x48, GSP_END,
-	KM_SHIFT,	KC_J,		0x4a, GSP_END,
-	KM_SHIFT,	KC_K,		0x4b, GSP_END,
-	KM_SHIFT,	KC_L,		0x4c, GSP_END,
-
-	KM_SHIFT,	KC_SEMICOLON,	0x3a, GSP_END,
-	KM_SHIFT,	KC_QUOTE,	0x22, GSP_END,
-	KM_SHIFT,	KC_BACKSLASH,	0x7c, GSP_END,
-
-	KM_SHIFT,	KC_Z,		0x5a, GSP_END,
-	KM_SHIFT,	KC_X,		0x58, GSP_END,
-	KM_SHIFT,	KC_C,		0x43, GSP_END,
-	KM_SHIFT,	KC_V,		0x56, GSP_END,
-	KM_SHIFT,	KC_B,		0x42, GSP_END,
-	KM_SHIFT,	KC_N,		0x4e, GSP_END,
-	KM_SHIFT,	KC_M,		0x4d, GSP_END,
-
-	KM_SHIFT,	KC_COMMA,	0x3c, GSP_END,
-	KM_SHIFT,	KC_PERIOD,	0x3e, GSP_END,
-	KM_SHIFT,	KC_SLASH,	0x3f, GSP_END,
-
-	/* ... */
-
-	0,	KC_SPACE,	0x20, GSP_END,
-	0,	KC_ENTER,	0x0a, GSP_END,
-	0,	KC_ENTER,	0x0d, GSP_END,
-
-	0,	KC_ESCAPE,	0x1b, 0x1b, GSP_END,
-
-	0,	KC_F1,		0x1b, 0x5b, 0x4f, 0x50, GSP_END,
-	0,	KC_F2,		0x1b, 0x5b, 0x4f, 0x51, GSP_END,
-	0,	KC_F3,		0x1b, 0x5b, 0x4f, 0x52, GSP_END,
-	0,	KC_F4,		0x1b, 0x5b, 0x4f, 0x53, GSP_END,
-	0,	KC_F5,		0x1b, 0x5b, 0x31, 0x35, GSP_END,
-	0,	KC_F6,		0x1b, 0x5b, 0x31, 0x37, GSP_END,
-	0,	KC_F7,		0x1b, 0x5b, 0x31, 0x38, GSP_END,
-	0,	KC_F8,		0x1b, 0x5b, 0x31, 0x39, GSP_END,
-	0,	KC_F9,		0x1b, 0x5b, 0x32, 0x38, GSP_END,
-	0,	KC_F10,		0x1b, 0x5b, 0x32, 0x39, GSP_END,
-	0,	KC_F11,		0x1b, 0x5b, 0x32, 0x33, GSP_END,
-	0,	KC_F12,		0x1b, 0x5b, 0x32, 0x34, GSP_END,
-
-	0,	KC_INSERT,	0x1b, 0x5b, 0x32, 0x7e, GSP_END,
-	0,	KC_HOME,	0x1b, 0x5b, 0x48, GSP_END,
-	0,	KC_PAGE_UP,	0x1b, 0x5b, 0x35, 0x7e, GSP_END,
-	0,	KC_DELETE,	0x1b, 0x5b, 0x33, 0x7e, GSP_END,
-	0,	KC_END,		0x1b, 0x5b, 0x46, GSP_END,
-	0,	KC_PAGE_DOWN,	0x1b, 0x5b, 0x36, 0x7e, GSP_END,
-
-	0,	KC_UP,		0x1b, 0x5b, 0x41, GSP_END,
-	0,	KC_LEFT,	0x1b, 0x5b, 0x44, GSP_END,
-	0,	KC_DOWN,	0x1b, 0x5b, 0x42, GSP_END,
-	0,	KC_RIGHT,	0x1b, 0x5b, 0x43, GSP_END,
-
-	0,	0
-};
-
-int kbd_ctl_init(void)
-{
-	ds = 0;
-
-	gsp_init(&sp);
-	return gsp_insert_defs(&sp, seq_defs);
-}
-
-void kbd_ctl_parse_scancode(int scancode)
-{
-	unsigned mods, key;
-
-	ds = gsp_step(&sp, ds, scancode, &mods, &key);
-	if (key != 0) {
-		stroke_sim(mods, key);
-	}
-}
-
-void kbd_ctl_set_ind(unsigned mods)
-{
-	(void) mods;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/ctl/pc.c
===================================================================
--- uspace/srv/hid/kbd/ctl/pc.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,273 +1,0 @@
-/*
- * 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_ctl
- * @ingroup kbd
- * @{
- */
-/**
- * @file
- * @brief PC keyboard controller driver.
- */
-
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
-#include <gsp.h>
-
-enum dec_state {
-	ds_s,
-	ds_e
-};
-
-enum special_code {
-	SC_ACK = 0xfa,
-	SC_NAK = 0xfe
-};
-
-enum lock_ind_bits {
-	LI_SCROLL	= 0x01,
-	LI_NUM		= 0x02,
-	LI_CAPS		= 0x04
-};
-
-enum kbd_command {
-	KBD_CMD_SET_LEDS = 0xed
-};
-
-static enum dec_state ds;
-
-static int scanmap_simple[] = {
-
-	[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,
-
-	[0x46] = KC_SCROLL_LOCK,
-
-	[0x1c] = KC_ENTER,
-
-	[0x45] = KC_NUM_LOCK,
-	[0x37] = KC_NTIMES,
-	[0x4a] = KC_NMINUS,
-	[0x4e] = KC_NPLUS,
-	[0x47] = KC_N7,
-	[0x48] = KC_N8,
-	[0x49] = KC_N9,
-	[0x4b] = KC_N4,
-	[0x4c] = KC_N5,
-	[0x4d] = KC_N6,
-	[0x4f] = KC_N1,
-	[0x50] = KC_N2,
-	[0x51] = KC_N3,
-	[0x52] = KC_N0,
-	[0x53] = KC_NPERIOD
-};
-
-static int scanmap_e0[] = {
-	[0x38] = KC_RALT,
-	[0x1d] = KC_RSHIFT,
-
-	[0x37] = KC_PRTSCR,
-
-	[0x52] = KC_INSERT,
-	[0x47] = KC_HOME,
-	[0x49] = KC_PAGE_UP,
-
-	[0x53] = KC_DELETE,
-	[0x4f] = KC_END,
-	[0x51] = KC_PAGE_DOWN,
-
-	[0x48] = KC_UP,
-	[0x4b] = KC_LEFT,
-	[0x50] = KC_DOWN,
-	[0x4d] = KC_RIGHT,
-
-	[0x35] = KC_NSLASH,
-	[0x1c] = KC_NENTER
-};
-
-int kbd_ctl_init(void)
-{
-	ds = ds_s;
-	return 0;
-}
-
-void kbd_ctl_parse_scancode(int scancode)
-{
-	kbd_event_type_t type;
-	unsigned int key;
-	int *map;
-	size_t map_length;
-
-	/*
-	 * ACK/NAK are returned as response to us sending a command.
-	 * We are not interested in them.
-	 */
-	if (scancode == SC_ACK || scancode == SC_NAK)
-		return;
-
-	if (scancode == 0xe0) {
-		ds = ds_e;
-		return;
-	}
-
-	switch (ds) {
-	case ds_s:
-		map = scanmap_simple;
-		map_length = sizeof(scanmap_simple) / sizeof(int);
-		break;
-	case ds_e:
-		map = scanmap_e0;
-		map_length = sizeof(scanmap_e0) / sizeof(int);
-		break;
-	default:
-		map = NULL;
-		map_length = 0;
-	}
-
-	ds = ds_s;
-
-	if (scancode & 0x80) {
-		scancode &= ~0x80;
-		type = KEY_RELEASE;
-	} else {
-		type = KEY_PRESS;
-	}
-
-	if ((scancode < 0) || ((size_t) scancode >= map_length))
-		return;
-
-	key = map[scancode];
-	if (key != 0)
-		kbd_push_ev(type, key);
-}
-
-void kbd_ctl_set_ind(unsigned mods)
-{
-	uint8_t b;
-
-	b = 0;
-	if ((mods & KM_CAPS_LOCK) != 0)
-		b = b | LI_CAPS;
-	if ((mods & KM_NUM_LOCK) != 0)
-		b = b | LI_NUM;
-	if ((mods & KM_SCROLL_LOCK) != 0)
-		b = b | LI_SCROLL;
-
-	kbd_port_write(KBD_CMD_SET_LEDS);
-	kbd_port_write(b);
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/ctl/stty.c
===================================================================
--- uspace/srv/hid/kbd/ctl/stty.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,233 +1,0 @@
-/*
- * 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_ctl
- * @ingroup kbd
- * @{
- */
-/**
- * @file
- * @brief	Serial TTY-like keyboard controller driver.
- */
-
-#include <kbd.h>
-#include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <gsp.h>
-#include <stroke.h>
-
-/** Scancode parser */
-static gsp_t sp;
-
-/** Current parser state */
-static int ds;
-
-#include <stdio.h>
-
-int seq_defs[] = {
-	/* Not shifted */
-
-	0,	KC_BACKTICK,	0x60, GSP_END,
-
-	0,	KC_1,		0x31, GSP_END,
-	0,	KC_2,		0x32, GSP_END,
-	0,	KC_3,		0x33, GSP_END,
-	0,	KC_4,		0x34, GSP_END,
-	0,	KC_5,		0x35, GSP_END,
-	0,	KC_6,		0x36, GSP_END,
-	0,	KC_7,		0x37, GSP_END,
-	0,	KC_8,		0x38, GSP_END,
-	0,	KC_9,		0x39, GSP_END,
-	0,	KC_0,		0x30, GSP_END,
-
-	0,	KC_MINUS,	0x2d, GSP_END,
-	0,	KC_EQUALS,	0x3d, GSP_END,
-	0,	KC_BACKSPACE,	0x08, GSP_END,
-
-	0,	KC_TAB,		0x09, GSP_END,
-
-	0,	KC_Q,		0x71, GSP_END,
-	0,	KC_W,		0x77, GSP_END,
-	0,	KC_E,		0x65, GSP_END,
-	0,	KC_R,		0x72, GSP_END,
-	0,	KC_T,		0x74, GSP_END,
-	0,	KC_Y,		0x79, GSP_END,
-	0,	KC_U,		0x75, GSP_END,
-	0,	KC_I,		0x69, GSP_END,
-	0,	KC_O,		0x6f, GSP_END,
-	0,	KC_P,		0x70, GSP_END,
-
-	0,	KC_LBRACKET,	0x5b, GSP_END,
-	0,	KC_RBRACKET,	0x5d, GSP_END,
-
-	0,	KC_A,		0x61, GSP_END,
-	0,	KC_S,		0x73, GSP_END,
-	0,	KC_D,		0x64, GSP_END,
-	0,	KC_F,		0x66, GSP_END,
-	0,	KC_G,		0x67, GSP_END,
-	0,	KC_H,		0x68, GSP_END,
-	0,	KC_J,		0x6a, GSP_END,
-	0,	KC_K,		0x6b, GSP_END,
-	0,	KC_L,		0x6c, GSP_END,
-
-	0,	KC_SEMICOLON,	0x3b, GSP_END,
-	0,	KC_QUOTE,	0x27, GSP_END,
-	0,	KC_BACKSLASH,	0x5c, GSP_END,
-
-	0,	KC_Z,		0x7a, GSP_END,
-	0,	KC_X,		0x78, GSP_END,
-	0,	KC_C,		0x63, GSP_END,
-	0,	KC_V,		0x76, GSP_END,
-	0,	KC_B,		0x62, GSP_END,
-	0,	KC_N,		0x6e, GSP_END,
-	0,	KC_M,		0x6d, GSP_END,
-
-	0,	KC_COMMA,	0x2c, GSP_END,
-	0,	KC_PERIOD,	0x2e, GSP_END,
-	0,	KC_SLASH,	0x2f, GSP_END,
-
-	/* Shifted */
-
-	KM_SHIFT,	KC_BACKTICK,	0x7e, GSP_END,
-
-	KM_SHIFT,	KC_1,		0x21, GSP_END,
-	KM_SHIFT,	KC_2,		0x40, GSP_END,
-	KM_SHIFT,	KC_3,		0x23, GSP_END,
-	KM_SHIFT,	KC_4,		0x24, GSP_END,
-	KM_SHIFT,	KC_5,		0x25, GSP_END,
-	KM_SHIFT,	KC_6,		0x5e, GSP_END,
-	KM_SHIFT,	KC_7,		0x26, GSP_END,
-	KM_SHIFT,	KC_8,		0x2a, GSP_END,
-	KM_SHIFT,	KC_9,		0x28, GSP_END,
-	KM_SHIFT,	KC_0,		0x29, GSP_END,
-
-	KM_SHIFT,	KC_MINUS,	0x5f, GSP_END,
-	KM_SHIFT,	KC_EQUALS,	0x2b, GSP_END,
-
-	KM_SHIFT,	KC_Q,		0x51, GSP_END,
-	KM_SHIFT,	KC_W,		0x57, GSP_END,
-	KM_SHIFT,	KC_E,		0x45, GSP_END,
-	KM_SHIFT,	KC_R,		0x52, GSP_END,
-	KM_SHIFT,	KC_T,		0x54, GSP_END,
-	KM_SHIFT,	KC_Y,		0x59, GSP_END,
-	KM_SHIFT,	KC_U,		0x55, GSP_END,
-	KM_SHIFT,	KC_I,		0x49, GSP_END,
-	KM_SHIFT,	KC_O,		0x4f, GSP_END,
-	KM_SHIFT,	KC_P,		0x50, GSP_END,
-
-	KM_SHIFT,	KC_LBRACKET,	0x7b, GSP_END,
-	KM_SHIFT,	KC_RBRACKET,	0x7d, GSP_END,
-
-	KM_SHIFT,	KC_A,		0x41, GSP_END,
-	KM_SHIFT,	KC_S,		0x53, GSP_END,
-	KM_SHIFT,	KC_D,		0x44, GSP_END,
-	KM_SHIFT,	KC_F,		0x46, GSP_END,
-	KM_SHIFT,	KC_G,		0x47, GSP_END,
-	KM_SHIFT,	KC_H,		0x48, GSP_END,
-	KM_SHIFT,	KC_J,		0x4a, GSP_END,
-	KM_SHIFT,	KC_K,		0x4b, GSP_END,
-	KM_SHIFT,	KC_L,		0x4c, GSP_END,
-
-	KM_SHIFT,	KC_SEMICOLON,	0x3a, GSP_END,
-	KM_SHIFT,	KC_QUOTE,	0x22, GSP_END,
-	KM_SHIFT,	KC_BACKSLASH,	0x7c, GSP_END,
-
-	KM_SHIFT,	KC_Z,		0x5a, GSP_END,
-	KM_SHIFT,	KC_X,		0x58, GSP_END,
-	KM_SHIFT,	KC_C,		0x43, GSP_END,
-	KM_SHIFT,	KC_V,		0x56, GSP_END,
-	KM_SHIFT,	KC_B,		0x42, GSP_END,
-	KM_SHIFT,	KC_N,		0x4e, GSP_END,
-	KM_SHIFT,	KC_M,		0x4d, GSP_END,
-
-	KM_SHIFT,	KC_COMMA,	0x3c, GSP_END,
-	KM_SHIFT,	KC_PERIOD,	0x3e, GSP_END,
-	KM_SHIFT,	KC_SLASH,	0x3f, GSP_END,
-
-	/* ... */
-
-	0,	KC_SPACE,	0x20, GSP_END,
-	0,	KC_ENTER,	0x0a, GSP_END,
-	0,	KC_ENTER,	0x0d, GSP_END,
-
-	0,	KC_ESCAPE,	0x1b, 0x1b, GSP_END,
-
-	0,	KC_F1,		0x1b, 0x4f, 0x50, GSP_END,
-	0,	KC_F2,		0x1b, 0x4f, 0x51, GSP_END,
-	0,	KC_F3,		0x1b, 0x4f, 0x52, GSP_END,
-	0,	KC_F4,		0x1b, 0x4f, 0x53, GSP_END,
-	0,	KC_F5,		0x1b, 0x5b, 0x31, 0x35, 0x7e, GSP_END,
-	0,	KC_F6,		0x1b, 0x5b, 0x31, 0x37, 0x7e, GSP_END,
-	0,	KC_F7,		0x1b, 0x5b, 0x31, 0x38, 0x7e, GSP_END,
-	0,	KC_F8,		0x1b, 0x5b, 0x31, 0x39, 0x7e, GSP_END,
-	0,	KC_F9,		0x1b, 0x5b, 0x32, 0x30, 0x7e, GSP_END,
-	0,	KC_F10,		0x1b, 0x5b, 0x32, 0x31, 0x7e, GSP_END,
-	0,	KC_F11,		0x1b, 0x5b, 0x32, 0x33, 0x7e, GSP_END,
-	0,	KC_F12,		0x1b, 0x5b, 0x32, 0x34, 0x7e, GSP_END,
-
-	0,	KC_INSERT,	0x1b, 0x5b, 0x32, 0x7e, GSP_END,
-	0,	KC_HOME,	0x1b, 0x5b, 0x48, GSP_END,
-	0,	KC_PAGE_UP,	0x1b, 0x5b, 0x35, 0x7e, GSP_END,
-	0,	KC_DELETE,	0x1b, 0x5b, 0x33, 0x7e, GSP_END,
-	0,	KC_END,		0x1b, 0x5b, 0x46, GSP_END,
-	0,	KC_PAGE_DOWN,	0x1b, 0x5b, 0x36, 0x7e, GSP_END,
-
-	0,	KC_UP,		0x1b, 0x5b, 0x41, GSP_END,
-	0,	KC_LEFT,	0x1b, 0x5b, 0x44, GSP_END,
-	0,	KC_DOWN,	0x1b, 0x5b, 0x42, GSP_END,
-	0,	KC_RIGHT,	0x1b, 0x5b, 0x43, GSP_END,
-
-	0,	0
-};
-
-int kbd_ctl_init(void)
-{
-	ds = 0;
-
-	gsp_init(&sp);
-	return gsp_insert_defs(&sp, seq_defs);
-}
-
-void kbd_ctl_parse_scancode(int scancode)
-{
-	unsigned mods, key;
-
-	ds = gsp_step(&sp, ds, scancode, &mods, &key);
-	if (key != 0) {
-		stroke_sim(mods, key);
-	}
-}
-
-void kbd_ctl_set_ind(unsigned mods)
-{
-	(void) mods;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/ctl/sun.c
===================================================================
--- uspace/srv/hid/kbd/ctl/sun.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,214 +1,0 @@
-/*
- * Copyright (c) 2006 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.
- */
-
-/** @addtogroup kbd_ctl
- * @ingroup kbd
- * @{
- */
-/**
- * @file
- * @brief	Sun keyboard controller driver.
- */
-
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <kbd_ctl.h>
-
-#define KBD_KEY_RELEASE		0x80
-#define KBD_ALL_KEYS_UP		0x7f
-
-static int scanmap_simple[];
-
-int kbd_ctl_init(void)
-{
-	return 0;
-}
-
-void kbd_ctl_parse_scancode(int scancode)
-{
-	kbd_event_type_t type;
-	unsigned int key;
-
-	if (scancode < 0 || scancode >= 0x100)
-		return;
-
-	if (scancode == KBD_ALL_KEYS_UP)
-		return;
-
-	if (scancode & KBD_KEY_RELEASE) {
-		scancode &= ~KBD_KEY_RELEASE;
-		type = KEY_RELEASE;
-	} else {
-		type = KEY_PRESS;
-	}
-
-	key = scanmap_simple[scancode];
-	if (key != 0)
-		kbd_push_ev(type, key);
-}
-
-void kbd_ctl_set_ind(unsigned mods)
-{
-	(void) mods;
-}
-
-/** Primary meaning of scancodes. */
-static int scanmap_simple[] = {
-	[0x00] = 0,
-	[0x01] = 0,
-	[0x02] = 0,
-	[0x03] = 0,
-	[0x04] = 0,
-	[0x05] = KC_F1,
-	[0x06] = KC_F2,
-	[0x07] = KC_F10,
-	[0x08] = KC_F3,
-	[0x09] = KC_F11,
-	[0x0a] = KC_F4,
-	[0x0b] = KC_F12,
-	[0x0c] = KC_F5,
-	[0x0d] = KC_RALT,
-	[0x0e] = KC_F6,
-	[0x0f] = 0,
-	[0x10] = KC_F7,
-	[0x11] = KC_F8,
-	[0x12] = KC_F9,
-	[0x13] = KC_LALT,
-	[0x14] = KC_UP,
-	[0x15] = KC_PAUSE,
-	[0x16] = 0,
-	[0x17] = KC_SCROLL_LOCK,
-	[0x18] = KC_LEFT,
-	[0x19] = 0,
-	[0x1a] = 0,
-	[0x1b] = KC_DOWN,
-	[0x1c] = KC_RIGHT,
-	[0x1d] = KC_ESCAPE,
-	[0x1e] = KC_1,
-	[0x1f] = KC_2,
-	[0x20] = KC_3,
-	[0x21] = KC_4,
-	[0x22] = KC_5,
-	[0x23] = KC_6,
-	[0x24] = KC_7,
-	[0x25] = KC_8,
-	[0x26] = KC_9,
-	[0x27] = KC_0,
-	[0x28] = KC_MINUS,
-	[0x29] = KC_EQUALS,
-	[0x2a] = KC_BACKTICK,
-	[0x2b] = KC_BACKSPACE,
-	[0x2c] = KC_INSERT,
-	[0x2d] = 0,
-	[0x2e] = KC_NSLASH,
-	[0x2f] = KC_NTIMES,
-	[0x30] = 0,
-	[0x31] = 0,
-	[0x32] = KC_NPERIOD,
-	[0x33] = 0,
-	[0x34] = KC_HOME,
-	[0x35] = KC_TAB,
-	[0x36] = KC_Q,
-	[0x37] = KC_W,
-	[0x38] = KC_E,
-	[0x39] = KC_R,
-	[0x3a] = KC_T,
-	[0x3b] = KC_Y,
-	[0x3c] = KC_U,
-	[0x3d] = KC_I,
-	[0x3e] = KC_O,
-	[0x3f] = KC_P,
-	[0x40] = KC_LBRACKET,
-	[0x41] = KC_RBRACKET,
-	[0x42] = KC_DELETE,
-	[0x43] = 0,
-	[0x44] = KC_N7,
-	[0x45] = KC_N8,
-	[0x46] = KC_N9,
-	[0x47] = KC_NMINUS,
-	[0x48] = 0,
-	[0x49] = 0,
-	[0x4a] = KC_END,
-	[0x4b] = 0,
-	[0x4c] = KC_LCTRL,
-	[0x4d] = KC_A,
-	[0x4e] = KC_S,
-	[0x4f] = KC_D,
-	[0x50] = KC_F,
-	[0x51] = KC_G,
-	[0x52] = KC_H,
-	[0x53] = KC_J,
-	[0x54] = KC_K,
-	[0x55] = KC_L,
-	[0x56] = KC_SEMICOLON,
-	[0x57] = KC_QUOTE,
-	[0x58] = KC_BACKSLASH,
-	[0x59] = KC_ENTER,
-	[0x5a] = KC_NENTER,
-	[0x5b] = KC_N4,
-	[0x5c] = KC_N5,
-	[0x5d] = KC_N6,
-	[0x5e] = KC_N0,
-	[0x5f] = 0,
-	[0x60] = KC_PAGE_UP,
-	[0x61] = 0,
-	[0x62] = KC_NUM_LOCK,
-	[0x63] = KC_LSHIFT,
-	[0x64] = KC_Z,
-	[0x65] = KC_X,
-	[0x66] = KC_C,
-	[0x67] = KC_V,
-	[0x68] = KC_B,
-	[0x69] = KC_N,
-	[0x6a] = KC_M,
-	[0x6b] = KC_COMMA,
-	[0x6c] = KC_PERIOD,
-	[0x6d] = KC_SLASH,
-	[0x6e] = KC_RSHIFT,
-	[0x6f] = 0,
-	[0x70] = KC_N1,
-	[0x71] = KC_N2,
-	[0x72] = KC_N3,
-	[0x73] = 0,
-	[0x74] = 0,
-	[0x75] = 0,
-	[0x76] = 0,
-	[0x77] = KC_CAPS_LOCK,
-	[0x78] = 0,
-	[0x79] = KC_SPACE,
-	[0x7a] = 0,
-	[0x7b] = KC_PAGE_DOWN,
-	[0x7c] = 0,
-	[0x7d] = KC_NPLUS,
-	[0x7e] = 0,
-	[0x7f] = 0
-};
-
-/** @}
- */
Index: pace/srv/hid/kbd/genarch/gsp.c
===================================================================
--- uspace/srv/hid/kbd/genarch/gsp.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,289 +1,0 @@
-/*
- * 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
- * @ingroup  kbd
- * @{
- */ 
-/** @file
- * @brief	Generic scancode parser.
- *
- * The scancode parser is a simple finite state machine. It is described
- * using sequences of input symbols (scancodes) and the corresponding output
- * value (mods, key pair). When the parser recognizes a sequence,
- * it outputs the value and restarts. If a transition is undefined,
- * the parser restarts, too.
- *
- * Apart from precise values, GSP_DEFAULT allows to catch general cases.
- * I.e. if we knew that after 0x1b 0x4f there always follow two more
- * scancodes, we can define (0x1b, 0x4f, GSP_DEFAULT, GSP_DEFAULT, GSP_END)
- * with null output. This will force the parser to read the entire sequence,
- * not leaving garbage on the input if it does not recognize the specific
- * sequence.
- */
-
-#include <gsp.h>
-#include <adt/hash_table.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define TRANS_TABLE_CHAINS 256
-
-/*
- * Hash table operations for the transition function.
- */
-
-static hash_index_t trans_op_hash(unsigned long key[]);
-static int trans_op_compare(unsigned long key[], hash_count_t keys,
-    link_t *item);
-static void trans_op_remove_callback(link_t *item);
-
-static hash_table_operations_t trans_ops = {
-	.hash = trans_op_hash,
-	.compare = trans_op_compare,
-	.remove_callback = trans_op_remove_callback
-};
-
-static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input);
-static void trans_insert(gsp_t *p, gsp_trans_t *t);
-static gsp_trans_t *trans_new(void);
-
-/** Initialise scancode parser. */
-void gsp_init(gsp_t *p)
-{
-	p->states = 1;
-	hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);
-}
-
-/** Insert a series of definitions into the parser.
- *
- * @param p	The parser.
- * @param defs	Definition list. Each definition starts with two output values
- *		(mods, key) and continues with a sequence of input values
- *		terminated with GSP_END. The definition list is terminated
- *		with two zeroes (0, 0) for output values.
- */
-int gsp_insert_defs(gsp_t *p, const int *defs)
-{
-	unsigned mods, key;
-	const int *dp;
-	int rc;
-
-	dp = defs;
-
-	while (1) {
-		/* Read the output values. */
-		mods = *dp++;
-		key = *dp++;
-		if (key == 0) break;
-
-		/* Insert one sequence. */		
-		rc = gsp_insert_seq(p, dp, mods, key);
-		if (rc != 0)
-			return rc;
-
-		/* Skip to the next definition. */
-		while (*dp != GSP_END)
-			++dp;
-		++dp;
-	}
-
-	return 0;
-}
-
-/** Insert one sequence into the parser.
- *
- * @param p	The parser.
- * @param seq	Sequence of input values terminated with GSP_END.
- * @param mods	Corresponsing output value.
- * @param key	Corresponsing output value.
- */
-int gsp_insert_seq(gsp_t *p, const int *seq, unsigned mods, unsigned key)
-{
-	int state;
-	gsp_trans_t *t;
-
-	state = 0;
-	t = NULL;
-
-	/* Input sequence must be non-empty. */
-	if (*seq == GSP_END)
-		return -1;
-
-	while (*(seq + 1) != GSP_END) {
-		t = trans_lookup(p, state, *seq);
-		if (t == NULL) {
-			/* Create new state. */
-			t = trans_new();
-			t->old_state = state;
-			t->input = *seq;
-			t->new_state = p->states++;
-
-			t->out_mods = 0;
-			t->out_key = 0;
-
-			trans_insert(p, t);
-		}
-		state = t->new_state;
-		++seq;
-	}
-
-	/* Process the last transition. */
-	t = trans_lookup(p, state, *seq);
-	if (t != NULL) {
-		exit(1);
-		return -1;	/* Conflicting definition. */
-	}
-
-	t = trans_new();
-	t->old_state = state;
-	t->input = *seq;
-	t->new_state = 0;
-
-	t->out_mods = mods;
-	t->out_key = key;
-
-	trans_insert(p, t);
-
-	return 0;
-}
-
-/** Compute one parser step.
- *
- * Computes the next state and output values for a given state and input.
- * This handles everything including restarts and default branches.
- *
- * @param p		The parser.
- * @param state		Old state.
- * @param input		Input symbol (scancode).
- * @param mods		Output value (modifier).
- * @param key		Output value (key).
- * @return		New state.
- */
-int gsp_step(gsp_t *p, int state, int input, unsigned *mods, unsigned *key)
-{
-	gsp_trans_t *t;
-
-	t = trans_lookup(p, state, input);
-	if (t == NULL) {
-		t = trans_lookup(p, state, GSP_DEFAULT);
-	}
-
-	if (t == NULL) {
-		printf("gsp_step: not found\n");
-		*mods = 0;
-		*key = 0;
-		return 0;
-	}
-
-	*mods = t->out_mods;
-	*key = t->out_key;
-	return t->new_state;
-}
-
-/** Transition function lookup.
- *
- * Returns the value of the transition function for the given state
- * and input. Note that the transition must be specified precisely,
- * to obtain the default branch use input = GSP_DEFAULT.
- *
- * @param p		Parser.
- * @param state		Current state.
- * @param input		Input value.
- * @return		The transition or @c NULL if not defined.
- */
-static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input)
-{
-	link_t *item;
-	unsigned long key[2];
-
-	key[0] = state;
-	key[1] = input;
-
-	item = hash_table_find(&p->trans, key);
-	if (item == NULL) return NULL;
-
-	return hash_table_get_instance(item, gsp_trans_t, link);
-}
-
-/** Define a new transition.
- *
- * @param p	The parser.
- * @param t	Transition with all fields defined.
- */
-static void trans_insert(gsp_t *p, gsp_trans_t *t)
-{
-	unsigned long key[2];
-
-	key[0] = t->old_state;
-	key[1] = t->input;
-
-	hash_table_insert(&p->trans, key, &t->link);
-}
-
-/** Allocate transition structure. */
-static gsp_trans_t *trans_new(void)
-{
-	gsp_trans_t *t;
-
-	t = malloc(sizeof(gsp_trans_t));
-	if (t == NULL) {
-		printf("Memory allocation failed.\n");
-		exit(1);
-	}
-
-	return t;
-}
-
-/*
- * Transition function hash table operations.
- */
-
-static hash_index_t trans_op_hash(unsigned long key[])
-{
-	return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;
-}
-
-static int trans_op_compare(unsigned long key[], hash_count_t keys,
-    link_t *item)
-{
-	gsp_trans_t *t;
-
-	t = hash_table_get_instance(item, gsp_trans_t, link);
-	return ((key[0] == (unsigned long) t->old_state)
-	    && (key[1] == (unsigned long) t->input));
-}
-
-static void trans_op_remove_callback(link_t *item)
-{
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/genarch/stroke.c
===================================================================
--- uspace/srv/hid/kbd/genarch/stroke.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
- * 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
- * @{
- */
-/**
- * @file
- * @brief Stroke simulator.
- *
- * When simulating a keyboard using a serial TTY we need to convert the
- * recognized strokes (such as Shift-A) to sequences of key presses and
- * releases (such as 'press Shift, press A, release A, release Shift').
- *
- */
-
-#include <stroke.h>
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-
-/** Correspondence between modifers and the modifier keycodes. */
-static unsigned int mods_keys[][2] = {
-	{ KM_LSHIFT, KC_LSHIFT },
-	{ 0, 0 }
-};
-
-/** Simulate keystroke using sequences of key presses and releases. */
-void stroke_sim(unsigned mod, unsigned key)
-{
-	int i;
-
-	/* Simulate modifier presses. */
-	i = 0;
-	while (mods_keys[i][0] != 0) {
-		if (mod & mods_keys[i][0]) {
-			kbd_push_ev(KEY_PRESS, mods_keys[i][1]);
-		}
-		++i;
-	}
-
-	/* Simulate key press and release. */
-	if (key != 0) {
-		kbd_push_ev(KEY_PRESS, key);
-		kbd_push_ev(KEY_RELEASE, key);
-	}
-
-	/* Simulate modifier releases. */
-	i = 0;
-	while (mods_keys[i][0] != 0) {
-		if (mod & mods_keys[i][0]) {
-			kbd_push_ev(KEY_RELEASE, mods_keys[i][1]);
-		}
-		++i;
-	}
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/generic/kbd.c
===================================================================
--- uspace/srv/hid/kbd/generic/kbd.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,270 +1,0 @@
-/*
- * 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 kbdgen generic
- * @brief HelenOS generic uspace keyboard handler.
- * @ingroup kbd
- * @{
- */
-/** @file
- */
-
-#include <ipc/services.h>
-#include <ipc/kbd.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ns.h>
-#include <ns_obsolete.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <errno.h>
-#include <adt/fifo.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <devmap.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <kbd_ctl.h>
-#include <layout.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
-#define NAME       "kbd"
-#define NAMESPACE  "hid_in"
-
-int client_phone = -1;
-
-/** Currently active modifiers. */
-static unsigned mods = KM_NUM_LOCK;
-
-/** Currently pressed lock keys. We track these to tackle autorepeat. */
-static unsigned lock_keys;
-
-bool irc_service = false;
-int irc_phone = -1;
-
-#define NUM_LAYOUTS 3
-
-static layout_op_t *layout[NUM_LAYOUTS] = {
-	&us_qwerty_op,
-	&us_dvorak_op,
-	&cz_op
-};
-
-static int active_layout = 0;
-
-void kbd_push_scancode(int scancode)
-{
-/*	printf("scancode: 0x%x\n", scancode);*/
-	kbd_ctl_parse_scancode(scancode);
-}
-
-void kbd_push_ev(int type, unsigned int key)
-{
-	kbd_event_t ev;
-	unsigned mod_mask;
-
-	switch (key) {
-	case KC_LCTRL: mod_mask = KM_LCTRL; break;
-	case KC_RCTRL: mod_mask = KM_RCTRL; break;
-	case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
-	case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
-	case KC_LALT: mod_mask = KM_LALT; break;
-	case KC_RALT: mod_mask = KM_RALT; break;
-	default: mod_mask = 0; break;
-	}
-
-	if (mod_mask != 0) {
-		if (type == KEY_PRESS)
-			mods = mods | mod_mask;
-		else
-			mods = mods & ~mod_mask;
-	}
-
-	switch (key) {
-	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
-	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
-	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
-	default: mod_mask = 0; break;
-	}
-
-	if (mod_mask != 0) {
-		if (type == KEY_PRESS) {
-			/*
-			 * Only change lock state on transition from released
-			 * to pressed. This prevents autorepeat from messing
-			 * up the lock state.
-			 */
-			mods = mods ^ (mod_mask & ~lock_keys);
-			lock_keys = lock_keys | mod_mask;
-
-			/* Update keyboard lock indicator lights. */
-			kbd_ctl_set_ind(mods);
-		} else {
-			lock_keys = lock_keys & ~mod_mask;
-		}
-	}
-/*
-	printf("type: %d\n", type);
-	printf("mods: 0x%x\n", mods);
-	printf("keycode: %u\n", key);
-*/
-	if (type == KEY_PRESS && (mods & KM_LCTRL) &&
-		key == KC_F1) {
-		active_layout = 0;
-		layout[active_layout]->reset();
-		return;
-	}
-
-	if (type == KEY_PRESS && (mods & KM_LCTRL) &&
-		key == KC_F2) {
-		active_layout = 1;
-		layout[active_layout]->reset();
-		return;
-	}
-
-	if (type == KEY_PRESS && (mods & KM_LCTRL) &&
-		key == KC_F3) {
-		active_layout = 2;
-		layout[active_layout]->reset();
-		return;
-	}
-
-	ev.type = type;
-	ev.key = key;
-	ev.mods = mods;
-
-	ev.c = layout[active_layout]->parse_ev(&ev);
-
-	async_obsolete_msg_4(client_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
-}
-
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-	int retval;
-
-	async_answer_0(iid, EOK);
-
-	while (true) {
-		callid = async_get_call(&call);
-		
-		if (!IPC_GET_IMETHOD(call)) {
-			if (client_phone != -1) {
-				async_obsolete_hangup(client_phone);
-				client_phone = -1;
-			}
-			
-			async_answer_0(callid, EOK);
-			return;
-		}
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case IPC_M_CONNECT_TO_ME:
-			if (client_phone != -1) {
-				retval = ELIMIT;
-				break;
-			}
-			client_phone = IPC_GET_ARG5(call);
-			retval = 0;
-			break;
-		case KBD_YIELD:
-			kbd_port_yield();
-			retval = 0;
-			break;
-		case KBD_RECLAIM:
-			kbd_port_reclaim();
-			retval = 0;
-			break;
-		default:
-			retval = EINVAL;
-		}
-		async_answer_0(callid, retval);
-	}	
-}
-
-
-int main(int argc, char **argv)
-{
-	printf("%s: HelenOS Keyboard service\n", NAME);
-	
-	sysarg_t fhc;
-	sysarg_t obio;
-	
-	if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
-	    || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)))
-		irc_service = true;
-	
-	if (irc_service) {
-		while (irc_phone < 0)
-			irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
-	}
-	
-	/* Initialize port driver. */
-	if (kbd_port_init() != 0)
-		return -1;
-
-	/* Initialize controller driver. */
-	if (kbd_ctl_init() != 0)
-		return -1;
-
-	/* Initialize (reset) layout. */
-	layout[active_layout]->reset();
-	
-	/* Register driver */
-	int rc = devmap_driver_register(NAME, client_connection);
-	if (rc < 0) {
-		printf("%s: Unable to register driver (%d)\n", NAME, rc);
-		return -1;
-	}
-	
-	char kbd[DEVMAP_NAME_MAXLEN + 1];
-	snprintf(kbd, DEVMAP_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
-	
-	devmap_handle_t devmap_handle;
-	if (devmap_device_register(kbd, &devmap_handle) != EOK) {
-		printf("%s: Unable to register device %s\n", NAME, kbd);
-		return -1;
-	}
-
-	printf(NAME ": Accepting connections\n");
-	async_manager();
-
-	/* Not reached. */
-	return 0;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/include/gsp.h
===================================================================
--- uspace/srv/hid/kbd/include/gsp.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/*
- * 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	Generic scancode parser.
- * @ingroup  kbd
- * @{
- */ 
-/** @file
- */
-
-#ifndef KBD_GSP_H_
-#define KBD_GSP_H_
-
-#include <adt/hash_table.h>
-
-enum {
-	GSP_END		= -1,	/**< Terminates a sequence. */
-	GSP_DEFAULT	= -2	/**< Wildcard, catches unhandled cases. */
-};
-
-/** Scancode parser description */
-typedef struct {
-	/** Transition table, (state, input) -> (state, output) */
-	hash_table_t trans;
-
-	/** Number of states */
-	int states;
-} gsp_t;
-
-/** Scancode parser transition. */
-typedef struct {
-	link_t link;		/**< Link to hash table in @c gsp_t */ 
-
-	/* Preconditions */
-
-	int old_state;		/**< State before transition */
-	int input;		/**< Input symbol (scancode) */
-
-	/* Effects */
-
-	int new_state;		/**< State after transition */
-
-	/* Output emitted during transition */
-
-	unsigned out_mods;	/**< Modifier to emit */
-	unsigned out_key;	/**< Keycode to emit */
-} gsp_trans_t;
-
-extern void gsp_init(gsp_t *);
-extern int gsp_insert_defs(gsp_t *, const int *);
-extern int gsp_insert_seq(gsp_t *, const int *, unsigned, unsigned);
-extern int gsp_step(gsp_t *, int, int, unsigned *, unsigned *);
-
-#endif
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/include/kbd.h
===================================================================
--- uspace/srv/hid/kbd/include/kbd.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * 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 kbdgen generic
- * @brief HelenOS generic uspace keyboard handler.
- * @ingroup kbd
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_KBD_H_
-#define KBD_KBD_H_
-
-#include <bool.h>
-
-extern bool irc_service;
-extern int irc_phone;
-
-extern void kbd_push_scancode(int);
-extern void kbd_push_ev(int, unsigned int);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/include/kbd_ctl.h
===================================================================
--- uspace/srv/hid/kbd/include/kbd_ctl.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * 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);
-extern int kbd_ctl_init(void);
-extern void kbd_ctl_set_ind(unsigned);
-
-#endif
-
-/**
- * @}
- */ 
-
Index: pace/srv/hid/kbd/include/kbd_port.h
===================================================================
--- uspace/srv/hid/kbd/include/kbd_port.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * 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_
-
-#include <sys/types.h>
-
-extern int kbd_port_init(void);
-extern void kbd_port_yield(void);
-extern void kbd_port_reclaim(void);
-extern void kbd_port_write(uint8_t);
-
-#endif
-
-/**
- * @}
- */ 
-
Index: pace/srv/hid/kbd/include/layout.h
===================================================================
--- uspace/srv/hid/kbd/include/layout.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * 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 <sys/types.h>
-#include <io/console.h>
-
-typedef struct {
-	void (*reset)(void);
-	wchar_t (*parse_ev)(kbd_event_t *);
-} layout_op_t;
-
-extern layout_op_t us_qwerty_op;
-extern layout_op_t us_dvorak_op;
-extern layout_op_t cz_op;
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/include/stroke.h
===================================================================
--- uspace/srv/hid/kbd/include/stroke.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * 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	Generic scancode parser.
- * @ingroup  kbd
- * @{
- */ 
-/** @file
- */
-
-#ifndef KBD_STROKE_H_
-#define KBD_STROKE_H_
-
-extern void stroke_sim(unsigned, unsigned);
-
-#endif
-
-/**
- * @}
- */ 
-
Index: pace/srv/hid/kbd/include/sun.h
===================================================================
--- uspace/srv/hid/kbd/include/sun.h	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * Copyright (c) 2009 Martin Decky
- * 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 Sun keyboard virtual port driver.
- * @ingroup kbd
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_SUN_H_
-#define KBD_SUN_H_
-
-extern int ns16550_port_init(void);
-extern int z8530_port_init(void);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/layout/cz.c
===================================================================
--- uspace/srv/hid/kbd/layout/cz.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,408 +1,0 @@
-/*
- * 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 Czech QWERTZ layout.
- * @{
- */
-
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <bool.h>
-#include <layout.h>
-
-static void layout_reset(void);
-static wchar_t layout_parse_ev(kbd_event_t *ev);
-
-enum m_state {
-	ms_start,
-	ms_hacek,
-	ms_carka
-};
-
-static enum m_state mstate;
-
-layout_op_t cz_op = {
-	layout_reset,
-	layout_parse_ev
-};
-
-static wchar_t map_lcase[] = {
-	[KC_Q] = 'q',
-	[KC_W] = 'w',
-	[KC_E] = 'e',
-	[KC_R] = 'r',
-	[KC_T] = 't',
-	[KC_Y] = 'z',
-	[KC_U] = 'u',
-	[KC_I] = 'i',
-	[KC_O] = 'o',
-	[KC_P] = 'p',
-
-	[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_Z] = 'y',
-	[KC_X] = 'x',
-	[KC_C] = 'c',
-	[KC_V] = 'v',
-	[KC_B] = 'b',
-	[KC_N] = 'n',
-	[KC_M] = 'm',
-};
-
-static wchar_t map_ucase[] = {
-	[KC_Q] = 'Q',
-	[KC_W] = 'W',
-	[KC_E] = 'E',
-	[KC_R] = 'R',
-	[KC_T] = 'T',
-	[KC_Y] = 'Z',
-	[KC_U] = 'U',
-	[KC_I] = 'I',
-	[KC_O] = 'O',
-	[KC_P] = 'P',
-
-	[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_Z] = 'Y',
-	[KC_X] = 'X',
-	[KC_C] = 'C',
-	[KC_V] = 'V',
-	[KC_B] = 'B',
-	[KC_N] = 'N',
-	[KC_M] = 'M',
-};
-
-static wchar_t map_not_shifted[] = {
-	[KC_BACKTICK] = ';',
-
-	[KC_1] = '+',
-
-	[KC_MINUS] = '=',
-
-	[KC_RBRACKET] = ')',
-
-	[KC_QUOTE] = L'§',
-
-	[KC_COMMA] = ',',
-	[KC_PERIOD] = '.',
-	[KC_SLASH] = '-',
-};
-
-static wchar_t map_shifted[] = {
-	[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_LBRACKET] = '/',
-	[KC_RBRACKET] = '(',
-
-	[KC_SEMICOLON] = '"',
-	[KC_QUOTE] = '!',
-	[KC_BACKSLASH] = '\'',
-
-	[KC_COMMA] = '?',
-	[KC_PERIOD] = ':',
-	[KC_SLASH] = '_',
-};
-
-static wchar_t map_ns_nocaps[] = {
-	[KC_2] = L'ě',
-	[KC_3] = L'š',
-	[KC_4] = L'č',
-	[KC_5] = L'ř',
-	[KC_6] = L'ž',
-	[KC_7] = L'ý',
-	[KC_8] = L'á',
-	[KC_9] = L'í',
-	[KC_0] = L'é',
-
-	[KC_LBRACKET] = L'ú',
-	[KC_SEMICOLON] = L'ů'
-};
-
-static wchar_t map_ns_caps[] = {
-	[KC_2] = L'Ě',
-	[KC_3] = L'Š',
-	[KC_4] = L'Č',
-	[KC_5] = L'Ř',
-	[KC_6] = L'Ž',
-	[KC_7] = L'Ý',
-	[KC_8] = L'Á',
-	[KC_9] = L'Í',
-	[KC_0] = L'É',
-
-	[KC_LBRACKET] = L'Ú',
-	[KC_SEMICOLON] = L'Ů'
-};
-
-static wchar_t map_neutral[] = {
-	[KC_BACKSPACE] = '\b',
-	[KC_TAB] = '\t',
-	[KC_ENTER] = '\n',
-	[KC_SPACE] = ' ',
-
-	[KC_NSLASH] = '/',
-	[KC_NTIMES] = '*',
-	[KC_NMINUS] = '-',
-	[KC_NPLUS] = '+',
-	[KC_NENTER] = '\n'
-};
-
-static wchar_t map_numeric[] = {
-	[KC_N7] = '7',
-	[KC_N8] = '8',
-	[KC_N9] = '9',
-	[KC_N4] = '4',
-	[KC_N5] = '5',
-	[KC_N6] = '6',
-	[KC_N1] = '1',
-	[KC_N2] = '2',
-	[KC_N3] = '3',
-
-	[KC_N0] = '0',
-	[KC_NPERIOD] = '.'
-};
-
-static wchar_t map_hacek_lcase[] = {
-	[KC_E] = L'ě',
-	[KC_R] = L'ř',
-	[KC_T] = L'ť',
-	[KC_Y] = L'ž',
-	[KC_U] = L'ů',
-
-	[KC_S] = L'š',
-	[KC_D] = L'ď',
-
-	[KC_C] = L'č',
-	[KC_N] = L'ň'
-};
-
-static wchar_t map_hacek_ucase[] = {
-	[KC_E] = L'Ě',
-	[KC_R] = L'Ř',
-	[KC_T] = L'Ť',
-	[KC_Y] = L'Ž',
-	[KC_U] = L'Ů',
-
-	[KC_S] = L'Š',
-	[KC_D] = L'Ď',
-
-	[KC_C] = L'Č',
-	[KC_N] = L'Ň'
-};
-
-static wchar_t map_carka_lcase[] = {
-	[KC_E] = L'é',
-	[KC_U] = L'ú',
-	[KC_I] = L'í',
-	[KC_O] = L'ó',
-
-	[KC_A] = L'á',
-
-	[KC_Z] = L'ý',
-};
-
-static wchar_t map_carka_ucase[] = {
-	[KC_E] = L'É',
-	[KC_U] = L'Ú',
-	[KC_I] = L'Í',
-	[KC_O] = L'Ó',
-
-	[KC_A] = L'Á',
-
-	[KC_Z] = L'Ý',
-};
-
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
-{
-	if (key >= map_length)
-		return 0;
-	return map[key];
-}
-
-static wchar_t parse_ms_hacek(kbd_event_t *ev)
-{
-	wchar_t c;
-
-	mstate = ms_start;
-
-	/* Produce no characters when Ctrl or Alt is pressed. */
-	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
-		return 0;
-
-	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
-
-	return c;
-}
-
-static wchar_t parse_ms_carka(kbd_event_t *ev)
-{
-	wchar_t c;
-
-	mstate = ms_start;
-
-	/* Produce no characters when Ctrl or Alt is pressed. */
-	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
-		return 0;
-
-	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
-
-	return c;
-}
-
-static wchar_t parse_ms_start(kbd_event_t *ev)
-{
-	wchar_t c;
-
-	/* Produce no characters when Ctrl or Alt is pressed. */
-	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
-		return 0;
-
-	if (ev->key == KC_EQUALS) {
-		if ((ev->mods & KM_SHIFT) != 0)
-			mstate = ms_hacek;
-		else
-			mstate = ms_carka;
-
-		return 0;
-	}
-
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_SHIFT) == 0) {
-		if ((ev->mods & KM_CAPS_LOCK) != 0)
-			c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
-		else
-			c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
-
-		if (c != 0)
-			return c;
-	}	
-
-	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
-
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
-
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
-	else
-		c = 0;
-
-	return c;
-}
-
-static bool key_is_mod(unsigned key)
-{
-	switch (key) {
-	case KC_LSHIFT:
-	case KC_RSHIFT:
-	case KC_LALT:
-	case KC_RALT:
-	case KC_LCTRL:
-	case KC_RCTRL:
-		return true;
-	default:
-		return false;
-	}
-}
-
-static void layout_reset(void)
-{
-	mstate = ms_start;
-}
-
-static wchar_t layout_parse_ev(kbd_event_t *ev)
-{
-	if (ev->type != KEY_PRESS)
-		return 0;
-	
-	if (key_is_mod(ev->key))
-		return 0;
-	
-	switch (mstate) {
-	case ms_start:
-		return parse_ms_start(ev);
-	case ms_hacek:
-		return parse_ms_hacek(ev);
-	case ms_carka:
-		return parse_ms_carka(ev);
-	}
-	
-	return 0;
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/kbd/layout/us_dvorak.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,250 +1,0 @@
-/*
- * 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 <io/console.h>
-#include <io/keycode.h>
-#include <layout.h>
-
-static void layout_reset(void);
-static wchar_t layout_parse_ev(kbd_event_t *ev);
-
-layout_op_t us_dvorak_op = {
-	layout_reset,
-	layout_parse_ev
-};
-
-static wchar_t map_lcase[] = {
-	[KC_R] = 'p',
-	[KC_T] = 'y',
-	[KC_Y] = 'f',
-	[KC_U] = 'g',
-	[KC_I] = 'c',
-	[KC_O] = 'r',
-	[KC_P] = 'l',
-
-	[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_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',
-};
-
-static wchar_t map_ucase[] = {
-	[KC_R] = 'P',
-	[KC_T] = 'Y',
-	[KC_Y] = 'F',
-	[KC_U] = 'G',
-	[KC_I] = 'C',
-	[KC_O] = 'R',
-	[KC_P] = 'L',
-
-	[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_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',
-};
-
-static wchar_t map_not_shifted[] = {
-	[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_Q] = '\'',
-	[KC_W] = ',',
-	[KC_E] = '.',
-
-	[KC_LBRACKET] = '/',
-	[KC_RBRACKET] = '=',
-
-	[KC_QUOTE] = '-',
-	[KC_BACKSLASH] = '\\',
-
-	[KC_Z] = ';',
-};
-
-static wchar_t map_shifted[] = {
-	[KC_BACKTICK] = '~',
-
-	[KC_1] = '!',
-	[KC_2] = '@',
-	[KC_3] = '#',
-	[KC_4] = '$',
-	[KC_5] = '%',
-	[KC_6] = '^',
-	[KC_7] = '&',
-	[KC_8] = '*',
-	[KC_9] = '(',
-	[KC_0] = ')',
-
-	[KC_MINUS] = '{',
-	[KC_EQUALS] = '}',
-
-	[KC_Q] = '"',
-	[KC_W] = '<',
-	[KC_E] = '>',
-
-	[KC_LBRACKET] = '?',
-	[KC_RBRACKET] = '+',
-
-	[KC_QUOTE] = '_',
-	[KC_BACKSLASH] = '|',
-
-	[KC_Z] = ':',
-};
-
-static wchar_t map_neutral[] = {
-	[KC_BACKSPACE] = '\b',
-	[KC_TAB] = '\t',
-	[KC_ENTER] = '\n',
-	[KC_SPACE] = ' ',
-
-	[KC_NSLASH] = '/',
-	[KC_NTIMES] = '*',
-	[KC_NMINUS] = '-',
-	[KC_NPLUS] = '+',
-	[KC_NENTER] = '\n'
-};
-
-static wchar_t map_numeric[] = {
-	[KC_N7] = '7',
-	[KC_N8] = '8',
-	[KC_N9] = '9',
-	[KC_N4] = '4',
-	[KC_N5] = '5',
-	[KC_N6] = '6',
-	[KC_N1] = '1',
-	[KC_N2] = '2',
-	[KC_N3] = '3',
-
-	[KC_N0] = '0',
-	[KC_NPERIOD] = '.'
-};
-
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
-{
-	if (key >= map_length)
-		return 0;
-	return map[key];
-}
-
-static void layout_reset(void)
-{
-}
-
-static wchar_t layout_parse_ev(kbd_event_t *ev)
-{
-	wchar_t c;
-
-	/* Produce no characters when Ctrl or Alt is pressed. */
-	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
-		return 0;
-
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
-	if (c != 0)
-		return c;
-
-	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
-
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
-
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
-	else
-		c = 0;
-
-	return c;
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/kbd/layout/us_qwerty.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,244 +1,0 @@
-/*
- * 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 layout.
- * @{
- */ 
-
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <layout.h>
-
-static void layout_reset(void);
-static wchar_t layout_parse_ev(kbd_event_t *ev);
-
-layout_op_t us_qwerty_op = {
-	layout_reset,
-	layout_parse_ev
-};
-
-static wchar_t map_lcase[] = {
-	[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_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_Z] = 'z',
-	[KC_X] = 'x',
-	[KC_C] = 'c',
-	[KC_V] = 'v',
-	[KC_B] = 'b',
-	[KC_N] = 'n',
-	[KC_M] = 'm',
-};
-
-static wchar_t map_ucase[] = {
-	[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_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_Z] = 'Z',
-	[KC_X] = 'X',
-	[KC_C] = 'C',
-	[KC_V] = 'V',
-	[KC_B] = 'B',
-	[KC_N] = 'N',
-	[KC_M] = 'M',
-};
-
-static wchar_t map_not_shifted[] = {
-	[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_LBRACKET] = '[',
-	[KC_RBRACKET] = ']',
-
-	[KC_SEMICOLON] = ';',
-	[KC_QUOTE] = '\'',
-	[KC_BACKSLASH] = '\\',
-
-	[KC_COMMA] = ',',
-	[KC_PERIOD] = '.',
-	[KC_SLASH] = '/',
-};
-
-static wchar_t map_shifted[] = {
-	[KC_BACKTICK] = '~',
-
-	[KC_1] = '!',
-	[KC_2] = '@',
-	[KC_3] = '#',
-	[KC_4] = '$',
-	[KC_5] = '%',
-	[KC_6] = '^',
-	[KC_7] = '&',
-	[KC_8] = '*',
-	[KC_9] = '(',
-	[KC_0] = ')',
-
-	[KC_MINUS] = '_',
-	[KC_EQUALS] = '+',
-
-	[KC_LBRACKET] = '{',
-	[KC_RBRACKET] = '}',
-
-	[KC_SEMICOLON] = ':',
-	[KC_QUOTE] = '"',
-	[KC_BACKSLASH] = '|',
-
-	[KC_COMMA] = '<',
-	[KC_PERIOD] = '>',
-	[KC_SLASH] = '?',
-};
-
-static wchar_t map_neutral[] = {
-	[KC_BACKSPACE] = '\b',
-	[KC_TAB] = '\t',
-	[KC_ENTER] = '\n',
-	[KC_SPACE] = ' ',
-
-	[KC_NSLASH] = '/',
-	[KC_NTIMES] = '*',
-	[KC_NMINUS] = '-',
-	[KC_NPLUS] = '+',
-	[KC_NENTER] = '\n'
-};
-
-static wchar_t map_numeric[] = {
-	[KC_N7] = '7',
-	[KC_N8] = '8',
-	[KC_N9] = '9',
-	[KC_N4] = '4',
-	[KC_N5] = '5',
-	[KC_N6] = '6',
-	[KC_N1] = '1',
-	[KC_N2] = '2',
-	[KC_N3] = '3',
-
-	[KC_N0] = '0',
-	[KC_NPERIOD] = '.'
-};
-
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
-{
-	if (key >= map_length)
-		return 0;
-	return map[key];
-}
-
-static void layout_reset(void)
-{
-}
-
-static wchar_t layout_parse_ev(kbd_event_t *ev)
-{
-	wchar_t c;
-
-	/* Produce no characters when Ctrl or Alt is pressed. */
-	if ((ev->mods & (KM_CTRL | KM_ALT)) != 0)
-		return 0;
-
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
-	if (c != 0)
-		return c;
-
-	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
-
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
-	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
-
-	if (c != 0)
-		return c;
-
-	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
-	else
-		c = 0;
-
-	return c;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/port/adb.c
===================================================================
--- uspace/srv/hid/kbd/port/adb.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,134 +1,0 @@
-/*
- * Copyright (c) 2010 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_port
- * @ingroup kbd
- * @{
- */
-/** @file
- * @brief ADB keyboard port driver.
- */
-
-#include <ipc/adb.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <kbd_port.h>
-#include <kbd.h>
-#include <vfs/vfs.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <devmap.h>
-#include <devmap_obsolete.h>
-
-static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall);
-static void adb_kbd_reg0_data(uint16_t data);
-
-static int dev_phone;
-
-#define NAME "kbd"
-
-int kbd_port_init(void)
-{
-	const char *dev = "adb/kbd";
-	devmap_handle_t handle;
-	
-	int rc = devmap_device_get_handle(dev, &handle, 0);
-	if (rc == EOK) {
-		dev_phone = devmap_obsolete_device_connect(handle, 0);
-		if (dev_phone < 0) {
-			printf("%s: Failed to connect to device\n", NAME);
-			return dev_phone;
-		}
-	} else
-		return rc;
-	
-	/* NB: The callback connection is slotted for removal */
-	rc = async_obsolete_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events);
-	if (rc != EOK) {
-		printf(NAME ": Failed to create callback from device\n");
-		return rc;
-	}
-	
-	return EOK;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	/*async_msg_1(dev_phone, CHAR_WRITE_BYTE, data);*/
-}
-
-static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/* Ignore parameters, the connection is already opened */
-	while (true) {
-
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-
-		int retval;
-		
-		if (!IPC_GET_IMETHOD(call)) {
-			/* TODO: Handle hangup */
-			return;
-		}
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case ADB_REG_NOTIF:
-			adb_kbd_reg0_data(IPC_GET_ARG1(call));
-			break;
-		default:
-			retval = ENOENT;
-		}
-		async_answer_0(callid, retval);
-	}
-}
-
-static void adb_kbd_reg0_data(uint16_t data)
-{
-	uint8_t b0, b1;
-
-	b0 = (data >> 8) & 0xff;
-	b1 = data & 0xff;
-
-	if (b0 != 0xff)
-		kbd_push_scancode(b0);
-	if (b1 != 0xff)
-		kbd_push_scancode(b1);
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/port/chardev.c
===================================================================
--- uspace/srv/hid/kbd/port/chardev.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,135 +1,0 @@
-/*
- * 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_port
- * @ingroup kbd
- * @{
- */
-/** @file
- * @brief Chardev keyboard port driver.
- */
-
-#include <ipc/char.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <kbd_port.h>
-#include <kbd.h>
-#include <devmap.h>
-#include <devmap_obsolete.h>
-#include <errno.h>
-#include <stdio.h>
-
-#define NAME  "kbd/chardev"
-
-static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall);
-
-static int dev_phone;
-
-/** List of devices to try connecting to. */
-static const char *in_devs[] = {
-	"char/ps2a",
-	"char/s3c24ser"
-};
-
-static const unsigned int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
-
-int kbd_port_init(void)
-{
-	devmap_handle_t handle;
-	unsigned int i;
-	int rc;
-	
-	for (i = 0; i < num_devs; i++) {
-		rc = devmap_device_get_handle(in_devs[i], &handle, 0);
-		if (rc == EOK)
-			break;
-	}
-	
-	if (i >= num_devs) {
-		printf("%s: Could not find any suitable input device\n", NAME);
-		return -1;
-	}
-	
-	dev_phone = devmap_obsolete_device_connect(handle, IPC_FLAG_BLOCKING);
-	if (dev_phone < 0) {
-		printf("%s: Failed connecting to device\n", NAME);
-		return ENOENT;
-	}
-	
-	/* NB: The callback connection is slotted for removal */
-	if (async_obsolete_connect_to_me(dev_phone, 0, 0, 0, kbd_port_events) != 0) {
-		printf(NAME ": Failed to create callback from device\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	async_obsolete_msg_1(dev_phone, CHAR_WRITE_BYTE, data);
-}
-
-static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall)
-{
-	/* Ignore parameters, the connection is already opened */
-	while (true) {
-
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		if (!IPC_GET_IMETHOD(call)) {
-			/* TODO: Handle hangup */
-			return;
-		}
-
-		int retval;
-
-		switch (IPC_GET_IMETHOD(call)) {
-		case CHAR_NOTIF_BYTE:
-			kbd_push_scancode(IPC_GET_ARG1(call));
-			break;
-		default:
-			retval = ENOENT;
-		}
-		async_answer_0(callid, retval);
-	}
-}
-
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/port/dummy.c
===================================================================
--- uspace/srv/hid/kbd/port/dummy.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/*
- * 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_port
- * @brief	Dummy keyboard port driver.
- * @ingroup  kbd
- * @{
- */ 
-/** @file
- */
-
-#include <kbd_port.h>
-#include <kbd.h>
-
-int kbd_port_init(void)
-{
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/** @}
-*/
Index: pace/srv/hid/kbd/port/gxemul.c
===================================================================
--- uspace/srv/hid/kbd/port/gxemul.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,107 +1,0 @@
-/*
- * 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_port
- * @{
- * @ingroup  kbd
- */ 
-/** @file
- * @brief	GXEmul keyboard port driver.
- */
-
-#include <async.h>
-#include <sysinfo.h>
-#include <kbd_port.h>
-#include <kbd.h>
-#include <ddi.h>
-#include <errno.h>
-
-static irq_cmd_t gxemul_cmds[] = {
-	{ 
-		.cmd = CMD_PIO_READ_8, 
-		.addr = (void *) 0, 	/* will be patched in run-time */
-		.dstarg = 2,
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-static irq_code_t gxemul_kbd = {
-	sizeof(gxemul_cmds) / sizeof(irq_cmd_t),
-	gxemul_cmds
-};
-
-static void gxemul_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-/** Initializes keyboard handler. */
-int kbd_port_init(void)
-{
-	sysarg_t addr;
-	if (sysinfo_get_value("kbd.address.virtual", &addr) != EOK)
-		return -1;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	async_set_interrupt_received(gxemul_irq_handler);
-	gxemul_cmds[0].addr = (void *) addr;
-	register_irq(inr, device_assign_devno(), 0, &gxemul_kbd);
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/** 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: pace/srv/hid/kbd/port/msim.c
===================================================================
--- uspace/srv/hid/kbd/port/msim.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,100 +1,0 @@
-/*
- * 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_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief Msim keyboard port driver.
- */
-
-#include <async.h>
-#include <sysinfo.h>
-#include <kbd_port.h>
-#include <kbd.h>
-#include <ddi.h>
-#include <errno.h>
-
-irq_cmd_t msim_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,	/* will be patched in run-time */
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-	
-};
-
-irq_code_t msim_kbd = {
-	sizeof(msim_cmds) / sizeof(irq_cmd_t),
-	msim_cmds
-};
-
-static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-int kbd_port_init(void)
-{
-	sysarg_t vaddr;
-	if (sysinfo_get_value("kbd.address.virtual", &vaddr) != EOK)
-		return -1;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	msim_cmds[0].addr = (void *) vaddr;
-	async_set_interrupt_received(msim_irq_handler);
-	register_irq(inr, device_assign_devno(), 0, &msim_kbd);
-	
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-static void msim_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	int scan_code = IPC_GET_ARG2(*call);
-	kbd_push_scancode(scan_code);
-}
-
-/** @}
-*/
Index: pace/srv/hid/kbd/port/niagara.c
===================================================================
--- uspace/srv/hid/kbd/port/niagara.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,152 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * 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_port
- * @ingroup  kbd
- * @{
- */ 
-/** @file
- * @brief	Niagara console keyboard port driver.
- */
-
-#include <as.h>
-#include <ddi.h>
-#include <async.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <thread.h>
-#include <bool.h>
-#include <errno.h>
-
-#define POLL_INTERVAL  10000
-
-/**
- * Virtual address mapped to the buffer shared with the kernel counterpart.
- */
-static uintptr_t input_buffer_addr;
-
-/*
- * Kernel counterpart of the driver pushes characters (it has read) here.
- * Keep in sync with the definition from
- * kernel/arch/sparc64/src/drivers/niagara.c.
- */
-#define INPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
-
-typedef volatile struct {
-	uint64_t write_ptr;
-	uint64_t read_ptr;
-	char data[INPUT_BUFFER_SIZE];
-}
-	__attribute__ ((packed))
-	__attribute__ ((aligned(PAGE_SIZE)))
-	*input_buffer_t;
-
-/* virtual address of the shared buffer */
-input_buffer_t input_buffer;
-
-static volatile bool polling_disabled = false;
-static void niagara_thread_impl(void *arg);
-
-/**
- * Initializes the Niagara driver.
- * Maps the shared buffer and creates the polling thread. 
- */
-int kbd_port_init(void)
-{
-	sysarg_t paddr;
-	if (sysinfo_get_value("niagara.inbuf.address", &paddr) != EOK)
-		return -1;
-	
-	input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE);
-	int rc = physmem_map((void *) paddr, (void *) input_buffer_addr,
-	    1, AS_AREA_READ | AS_AREA_WRITE);
-	
-	if (rc != 0) {
-		printf("Niagara: uspace driver couldn't map physical memory: %d\n",
-		    rc);
-		return rc;
-	}
-	
-	input_buffer = (input_buffer_t) input_buffer_addr;
-	
-	thread_id_t tid;
-	rc = thread_create(niagara_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0)
-		return rc;
-	
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-	polling_disabled = true;
-}
-
-void kbd_port_reclaim(void)
-{
-	polling_disabled = false;
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/**
- * Called regularly by the polling thread. Reads codes of all the
- * pressed keys from the buffer. 
- */
-static void niagara_key_pressed(void)
-{
-	char c;
-	
-	while (input_buffer->read_ptr != input_buffer->write_ptr) {
-		c = input_buffer->data[input_buffer->read_ptr];
-		input_buffer->read_ptr =
-			((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE;
-		kbd_push_scancode(c);
-	}
-}
-
-/**
- * Thread to poll SGCN for keypresses.
- */
-static void niagara_thread_impl(void *arg)
-{
-	(void) arg;
-
-	while (1) {
-		if (polling_disabled == false)
-			niagara_key_pressed();
-		usleep(POLL_INTERVAL);
-	}
-}
-/** @}
- */
Index: pace/srv/hid/kbd/port/ns16550.c
===================================================================
--- uspace/srv/hid/kbd/port/ns16550.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,130 +1,0 @@
-/*
- * 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_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief NS16550 port driver.
- */
-
-#include <ipc/irc.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <sysinfo.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sun.h>
-#include <ddi.h>
-#include <errno.h>
-
-/* NS16550 registers */
-#define RBR_REG  0  /** Receiver Buffer Register. */
-#define IER_REG  1  /** Interrupt Enable Register. */
-#define IIR_REG  2  /** Interrupt Ident Register (read). */
-#define FCR_REG  2  /** FIFO control register (write). */
-#define LCR_REG  3  /** Line Control register. */
-#define MCR_REG  4  /** Modem Control Register. */
-#define LSR_REG  5  /** Line Status Register. */
-
-#define LSR_DATA_READY  0x01
-
-static irq_cmd_t ns16550_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_BTEST,
-		.value = LSR_DATA_READY,
-		.srcarg = 1,
-		.dstarg = 3
-	},
-	{
-		.cmd = CMD_PREDICATE,
-		.value = 2,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-irq_code_t ns16550_kbd = {
-	sizeof(ns16550_cmds) / sizeof(irq_cmd_t),
-	ns16550_cmds
-};
-
-static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-static uintptr_t ns16550_physical;
-static uintptr_t ns16550_kernel; 
-
-int ns16550_port_init(void)
-{
-	void *vaddr;
-
-	if (sysinfo_get_value("kbd.address.physical", &ns16550_physical) != EOK)
-		return -1;
-	
-	if (sysinfo_get_value("kbd.address.kernel", &ns16550_kernel) != EOK)
-		return -1;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
-	ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
-	
-	async_set_interrupt_received(ns16550_irq_handler);
-	register_irq(inr, device_assign_devno(), inr, &ns16550_kbd);
-	
-	return pio_enable((void *) ns16550_physical, 8, &vaddr);
-}
-
-static void ns16550_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	int scan_code = IPC_GET_ARG2(*call);
-	kbd_push_scancode(scan_code);
-	
-	if (irc_service)
-		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
-		    IPC_GET_IMETHOD(*call));
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/kbd/port/pl050.c
===================================================================
--- uspace/srv/hid/kbd/port/pl050.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,130 +1,0 @@
-/*
- * Copyright (c) 2009 Vineeth Pillai
- * 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_port
- * @ingroup kbd
- * @{
- */ 
-/** @file
- * @brief pl050 port driver.
- */
-
-#include <ddi.h>
-#include <libarch/ddi.h>
-#include <async.h>
-#include <unistd.h>
-#include <sysinfo.h>
-#include <kbd_port.h>
-#include <kbd.h>
-#include <ddi.h>
-#include <stdio.h>
-#include <errno.h>
-
-#define PL050_STAT_RXFULL  (1 << 4)
-
-static irq_cmd_t pl050_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = NULL,
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_BTEST,
-		.value = PL050_STAT_RXFULL,
-		.srcarg = 1,
-		.dstarg = 3
-	},
-	{
-		.cmd = CMD_PREDICATE,
-		.value = 2,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = NULL,  /* Will be patched in run-time */
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-static irq_code_t pl050_kbd = {
-	sizeof(pl050_cmds) / sizeof(irq_cmd_t),
-	pl050_cmds
-};
-
-static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-int kbd_port_init(void)
-{
-	sysarg_t addr;
-	if (sysinfo_get_value("kbd.address.status", &addr) != EOK)
-		return -1;
-	
-	pl050_kbd.cmds[0].addr = (void *) addr;
-	
-	if (sysinfo_get_value("kbd.address.data", &addr) != EOK)
-		return -1;
-	
-	pl050_kbd.cmds[3].addr = (void *) addr;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	async_set_interrupt_received(pl050_irq_handler);
-	register_irq(inr, device_assign_devno(), 0, &pl050_kbd);
-	
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-static void pl050_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	int scan_code = IPC_GET_ARG2(*call);
-
-	kbd_push_scancode(scan_code);
-	return;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/kbd/port/sgcn.c
===================================================================
--- uspace/srv/hid/kbd/port/sgcn.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,188 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * 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_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief SGCN (Serengeti Console) keyboard port driver.
- */
-
-#include <as.h>
-#include <ddi.h>
-#include <async.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <thread.h>
-#include <bool.h>
-#include <errno.h>
-
-#define POLL_INTERVAL  10000
-
-/**
- * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer.
- */
-typedef struct {
-	/** hard-wired to "CON" */
-	char magic[4];
-	
-	/** we don't need this */
-	char unused[8];
-	
-	/** offset within the SGCN buffer of the input buffer start */
-	uint32_t in_begin;
-	
-	/** offset within the SGCN buffer of the input buffer end */
-	uint32_t in_end;
-	
-	/** offset within the SGCN buffer of the input buffer read pointer */
-	uint32_t in_rdptr;
-	
-	/** offset within the SGCN buffer of the input buffer write pointer */
-	uint32_t in_wrptr;
-} __attribute__ ((packed)) sgcn_buffer_header_t;
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the console buffer beginning.
- */
-#define SGCN_BUFFER(type, offset) \
-		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
-
-/** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-/**
- * Virtual address mapped to SRAM.
- */
-static uintptr_t sram_virt_addr;
-
-/**
- * SGCN buffer offset within SGCN.
- */
-static uintptr_t sram_buffer_offset;
-
-/* polling thread */
-static void sgcn_thread_impl(void *arg);
-
-static volatile bool polling_disabled = false;
-
-/**
- * Initializes the SGCN driver.
- * Maps the physical memory (SRAM) and creates the polling thread. 
- */
-int kbd_port_init(void)
-{
-	sysarg_t sram_paddr;
-	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
-		return -1;
-	
-	sysarg_t sram_size;
-	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
-		return -1;
-	
-	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
-		sram_buffer_offset = 0;
-	
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
-	
-	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
-	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
-		printf("SGCN: uspace driver could not map physical memory.");
-		return -1;
-	}
-	
-	thread_id_t tid;
-	int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0)
-		return rc;
-	
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-	polling_disabled = true;
-}
-
-void kbd_port_reclaim(void)
-{
-	polling_disabled = false;
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/**
- * Handler of the "key pressed" event. Reads codes of all the pressed keys from
- * the buffer. 
- */
-static void sgcn_key_pressed(void)
-{
-	char c;
-	
-	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->in_end;
-	uint32_t size = end - begin;
-	
-	volatile char *buf_ptr = (volatile char *)
-		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
-	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
-	
-	while (*in_rdptr_ptr != *in_wrptr_ptr) {
-		c = *buf_ptr;
-		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
-		buf_ptr = (volatile char *)
-			SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-		kbd_push_scancode(c);
-	}
-}
-
-/**
- * Thread to poll SGCN for keypresses.
- */
-static void sgcn_thread_impl(void *arg)
-{
-	(void) arg;
-
-	while (1) {
-		if (polling_disabled == false)
-			sgcn_key_pressed();
-		usleep(POLL_INTERVAL);
-	}
-}
-
-/** @}
- */
Index: pace/srv/hid/kbd/port/ski.c
===================================================================
--- uspace/srv/hid/kbd/port/ski.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,128 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar
- * 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_port
- * @ingroup  kbd
- * @{
- */ 
-/** @file
- * @brief	Ski console keyboard port driver.
- */
-
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sys/types.h>
-#include <thread.h>
-#include <bool.h>
-
-#define SKI_GETCHAR		21
-
-#define POLL_INTERVAL		10000
-
-static void ski_thread_impl(void *arg);
-static int32_t ski_getchar(void);
-
-static volatile bool polling_disabled = false;
-
-/** Initialize Ski port driver. */
-int kbd_port_init(void)
-{
-	thread_id_t tid;
-	int rc;
-
-	rc = thread_create(ski_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0) {
-		return rc;
-	}
-
-	return 0;
-}
-
-void kbd_port_yield(void)
-{
-	polling_disabled = true;
-}
-
-void kbd_port_reclaim(void)
-{
-	polling_disabled = false;
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/** Thread to poll Ski for keypresses. */
-static void ski_thread_impl(void *arg)
-{
-	int32_t c;
-	(void) arg;
-
-	while (1) {
-		while (polling_disabled == false) {
-			c = ski_getchar();
-			if (c == 0)
-				break;
-			kbd_push_scancode(c);
-		}
-
-		usleep(POLL_INTERVAL);
-	}
-}
-
-/** Ask Ski if a key was pressed.
- *
- * Use SSC (Simulator System Call) to get character from the debug console.
- * This call is non-blocking.
- *
- * @return ASCII code of pressed key or 0 if no key pressed.
- */
-static int32_t ski_getchar(void)
-{
-	uint64_t ch;
-	
-	asm volatile (
-		"mov r15 = %1\n"
-		"break 0x80000;;\n"	/* modifies r8 */
-		"mov %0 = r8;;\n"		
-
-		: "=r" (ch)
-		: "i" (SKI_GETCHAR)
-		: "r15", "r8"
-	);
-
-	return (int32_t) ch;
-}
-
-/** @}
- */
Index: pace/srv/hid/kbd/port/sun.c
===================================================================
--- uspace/srv/hid/kbd/port/sun.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,89 +1,0 @@
-/*
- * Copyright (c) 2009 Martin Decky
- * 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_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief Sun keyboard virtual port driver.
- */
-
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sun.h>
-#include <sysinfo.h>
-#include <errno.h>
-#include <bool.h>
-
-/** Sun keyboard virtual port driver.
- *
- * This is a virtual port driver which can use
- * both ns16550_port_init and z8530_port_init
- * according to the information passed from the
- * kernel. This is just a temporal hack.
- *
- */
-int kbd_port_init(void)
-{
-	sysarg_t z8530;
-	if (sysinfo_get_value("kbd.type.z8530", &z8530) != EOK)
-		z8530 = false;
-	
-	sysarg_t ns16550;
-	if (sysinfo_get_value("kbd.type.ns16550", &ns16550) != EOK)
-		ns16550 = false;
-	
-	if (z8530) {
-		if (z8530_port_init() == 0)
-			return 0;
-	}
-	
-	if (ns16550) {
-		if (ns16550_port_init() == 0)
-			return 0;
-	}
-	
-	return -1;
-}
-
-void kbd_port_yield(void)
-{
-}
-
-void kbd_port_reclaim(void)
-{
-}
-
-void kbd_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/** @}
-*/
Index: pace/srv/hid/kbd/port/z8530.c
===================================================================
--- uspace/srv/hid/kbd/port/z8530.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*
- * Copyright (c) 2006 Martin Decky
- * 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_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief Z8530 keyboard port driver.
- */
-
-#include <ipc/irc.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <sysinfo.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sun.h>
-#include <sys/types.h>
-#include <ddi.h>
-#include <errno.h>
-
-#define CHAN_A_STATUS  4
-#define CHAN_A_DATA    6
-
-#define RR0_RCA  1
-
-static irq_cmd_t z8530_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_BTEST,
-		.value = RR0_RCA,
-		.srcarg = 1,
-		.dstarg = 3
-	},
-	{
-		.cmd = CMD_PREDICATE,
-		.value = 2,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-	
-irq_code_t z8530_kbd = {
-	sizeof(z8530_cmds) / sizeof(irq_cmd_t),
-	z8530_cmds
-};
-
-static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-int z8530_port_init(void)
-{
-	sysarg_t kaddr;
-	if (sysinfo_get_value("kbd.address.kernel", &kaddr) != EOK)
-		return -1;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	z8530_cmds[0].addr = (void *) kaddr + CHAN_A_STATUS;
-	z8530_cmds[3].addr = (void *) kaddr + CHAN_A_DATA;
-	
-	async_set_interrupt_received(z8530_irq_handler);
-	register_irq(inr, device_assign_devno(), inr, &z8530_kbd);
-	
-	return 0;
-}
-
-static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	int scan_code = IPC_GET_ARG2(*call);
-	kbd_push_scancode(scan_code);
-	
-	if (irc_service)
-		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
-		    IPC_GET_IMETHOD(*call));
-}
-
-/** @}
- */
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -73,5 +73,6 @@
 static s3c24xx_ts_t *ts;
 
-static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg);
 static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 static void s3c24xx_ts_pen_down(s3c24xx_ts_t *ts);
@@ -373,5 +374,6 @@
 
 /** Handle mouse client connection. */
-static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -57,5 +57,5 @@
 #define NAME "cuda_adb"
 
-static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 static int cuda_init(void);
 static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call);
@@ -193,5 +193,5 @@
 
 /** Character device connection handler */
-static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/char/i8042/i8042.c
===================================================================
--- uspace/srv/hw/char/i8042/i8042.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/char/i8042/i8042.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -122,5 +122,5 @@
 
 static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
 static int i8042_init(void);
 static void i8042_port_write(int devid, uint8_t data);
@@ -216,5 +216,5 @@
 
 /** Character device connection handler */
-static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -71,5 +71,6 @@
 static s3c24xx_uart_t *uart;
 
-static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg);
 static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call);
 static int s3c24xx_uart_init(s3c24xx_uart_t *uart);
@@ -113,5 +114,6 @@
 
 /** Character device connection handler. */
-static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/irc/apic/apic.c
===================================================================
--- uspace/srv/hw/irc/apic/apic.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/irc/apic/apic.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -64,7 +64,7 @@
  * @param iid   Hash of the request that opened the connection.
  * @param icall Call data of the request that opened the connection.
- *
+ * @param arg	Local argument.
  */
-static void apic_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void apic_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/irc/fhc/fhc.c
===================================================================
--- uspace/srv/hw/irc/fhc/fhc.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/irc/fhc/fhc.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -66,6 +66,7 @@
  * @param iid		Hash of the request that opened the connection.
  * @param icall		Call data of the request that opened the connection.
+ * @param arg		Local argument.
  */
-static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/irc/i8259/i8259.c
===================================================================
--- uspace/srv/hw/irc/i8259/i8259.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/irc/i8259/i8259.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -98,7 +98,7 @@
  * @param iid   Hash of the request that opened the connection.
  * @param icall Call data of the request that opened the connection.
- *
+ * @param arg	Local argument.
  */
-static void i8259_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void i8259_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/hw/irc/obio/obio.c
===================================================================
--- uspace/srv/hw/irc/obio/obio.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/hw/irc/obio/obio.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -76,6 +76,7 @@
  * @param iid		Hash of the request that opened the connection.
  * @param icall		Call data of the request that opened the connection.
+ * @param arg		Local argument.
  */
-static void obio_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void obio_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	ipc_callid_t callid;
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/loader/main.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -410,5 +410,5 @@
  * to execute the loaded program).
  */
-static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void ldr_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	/* Already have a connection? */
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/il/arp/arp.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -416,7 +416,7 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- *
- */
-static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in]	  arg	Local argument.
+ */
+static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/il/ip/ip.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -123,5 +123,5 @@
 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
 
-static void ip_receiver(ipc_callid_t, ipc_call_t *);
+static void ip_receiver(ipc_callid_t, ipc_call_t *, void *);
 
 /** Releases the packet and returns the result.
@@ -1594,7 +1594,7 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- *
- */
-static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in]     arg   Local argument.
+ */
+static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/net/net.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -680,9 +680,10 @@
 /** Default thread for new connections.
  *
- * @param[in] iid The initial message identifier.
+ * @param[in] iid   The initial message identifier.
  * @param[in] icall The initial message call structure.
- *
- */
-static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in] arg   Local argument.
+ */
+static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
 {
 	/*
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/nil/eth/eth.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -231,6 +231,7 @@
  * @param[in] iid	The message identifier.
  * @param[in,out] icall	The message parameters.
- */
-static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in] arg	Local argument.
+ */
+static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -102,7 +102,7 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- *
- */
-static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in]     arg   Local argument.
+ */
+static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -608,7 +608,7 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- *
- */
-static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in]     arg   Local argument.
+ */
+static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -2442,7 +2442,7 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- *
+ * @param[in]     arg   Local argument.
  */
-static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
+static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/net/tl/udp/udp.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -341,7 +341,7 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- *
- */
-static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall)
+ * @param[in]     arg   Local argument.
+ */
+static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	packet_t *packet;
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision 36ab7c737a9b47469d540e94a850fab80bda101c)
+++ uspace/srv/vfs/vfs.c	(revision e99564dc2111119a734299639f28432400d665d2)
@@ -49,5 +49,5 @@
 #define NAME  "vfs"
 
-static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall)
+static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
 	bool cont = true;
