Index: uspace/srv/hid/kbd/Makefile
===================================================================
--- uspace/srv/hid/kbd/Makefile	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/Makefile	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -61,97 +61,10 @@
 	port/ski.c \
 	port/sun.c \
-	port/z8530.c
-
-
-ifeq ($(UARCH),amd64)
-	SOURCES += \
-		ctl/pc.c
-endif
-
-ifeq ($(UARCH),arm32)
-	ifeq ($(MACHINE),gta02)
-		SOURCES += \
-			ctl/stty.c
-	endif
-	ifeq ($(MACHINE),testarm)
-		ifeq ($(CONFIG_FB),y)
-			SOURCES += \
-				ctl/gxe_fb.c
-		else
-			SOURCES += \
-				ctl/stty.c
-		endif
-	endif
-	ifeq ($(MACHINE),integratorcp)
-		SOURCES += \
-			ctl/pc.c
-	endif
-endif
-
-ifeq ($(UARCH),ia32)
-	SOURCES += \
-		ctl/pc.c
-endif
-
-ifeq ($(MACHINE),i460GX)
-	SOURCES += \
-		ctl/pc.c
-endif
-
-ifeq ($(MACHINE),ski)
-	SOURCES += \
-		ctl/stty.c
-endif
-
-ifeq ($(MACHINE),msim)
-	SOURCES += \
-		ctl/stty.c
-endif
-
-ifeq ($(MACHINE),lgxemul)
-	ifeq ($(CONFIG_FB),y)
-		SOURCES += \
-			ctl/gxe_fb.c
-	else
-		SOURCES += \
-			ctl/stty.c
-	endif
-endif
-
-ifeq ($(MACHINE),bgxemul)
-	ifeq ($(CONFIG_FB),y)
-		SOURCES += \
-			ctl/gxe_fb.c
-	else
-		SOURCES += \
-			ctl/stty.c
-	endif
-endif
-
-ifeq ($(UARCH),ppc32)
-	SOURCES += \
-		ctl/apple.c
-endif
-
-ifeq ($(UARCH),sparc64)
-	ifeq ($(PROCESSOR),sun4v)
-		SOURCES += \
-			ctl/stty.c
-	else
-		ifeq ($(MACHINE),serengeti)
-			SOURCES += \
-				ctl/stty.c
-		endif
-		ifeq ($(MACHINE),generic)
-			SOURCES += \
-				ctl/sun.c
-		endif
-	endif
-endif
-
-ifeq ($(UARCH),abs32le)
-	SOURCES += \
-		ctl/pc.c
-endif
+	port/z8530.c \
+	ctl/apple.c \
+	ctl/gxe_fb.c \
+	ctl/pc.c \
+	ctl/stty.c \
+	ctl/sun.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hid/kbd/ctl/apple.c
===================================================================
--- uspace/srv/hid/kbd/ctl/apple.c	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/ctl/apple.c	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -42,9 +42,19 @@
 #include <kbd_port.h>
 
+static void apple_ctl_parse_scancode(int scancode);
+static int apple_ctl_init(kbd_port_ops_t *kbd_port);
+static void apple_ctl_set_ind(unsigned mods);
+
+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 int scanmap[];
 
-int kbd_ctl_init(kbd_port_ops_t *kbd_port)
+static int apple_ctl_init(kbd_port_ops_t *kbd_port)
 {
 	(void) kbd_port;
@@ -52,5 +62,5 @@
 }
 
-void kbd_ctl_parse_scancode(int scancode)
+static void apple_ctl_parse_scancode(int scancode)
 {
 	kbd_event_type_t type;
@@ -72,5 +82,5 @@
 }
 
-void kbd_ctl_set_ind(unsigned mods)
+static void apple_ctl_set_ind(unsigned mods)
 {
 	(void) mods;
Index: uspace/srv/hid/kbd/ctl/gxe_fb.c
===================================================================
--- uspace/srv/hid/kbd/ctl/gxe_fb.c	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/ctl/gxe_fb.c	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -44,4 +44,14 @@
 #include <stroke.h>
 
+static void gxe_fb_ctl_parse_scancode(int scancode);
+static int gxe_fb_ctl_init(kbd_port_ops_t *kbd_port);
+static void gxe_fb_ctl_set_ind(unsigned mods);
+
+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
+};
+
 /** Scancode parser */
 static gsp_t sp;
@@ -52,5 +62,5 @@
 #include <stdio.h>
 
-int seq_defs[] = {
+static int seq_defs[] = {
 	/* Not shifted */
 
@@ -208,5 +218,5 @@
 };
 
-int kbd_ctl_init(kbd_port_ops_t *kbd_port)
+static int gxe_fb_ctl_init(kbd_port_ops_t *kbd_port)
 {
 	(void) kbd_port;
@@ -217,5 +227,5 @@
 }
 
-void kbd_ctl_parse_scancode(int scancode)
+static void gxe_fb_ctl_parse_scancode(int scancode)
 {
 	unsigned mods, key;
@@ -227,5 +237,5 @@
 }
 
-void kbd_ctl_set_ind(unsigned mods)
+static void gxe_fb_ctl_set_ind(unsigned mods)
 {
 	(void) mods;
Index: uspace/srv/hid/kbd/ctl/pc.c
===================================================================
--- uspace/srv/hid/kbd/ctl/pc.c	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/ctl/pc.c	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -43,4 +43,14 @@
 #include <gsp.h>
 
+static void pc_ctl_parse_scancode(int scancode);
+static int pc_ctl_init(kbd_port_ops_t *kbd_port);
+static void pc_ctl_set_ind(unsigned mods);
+
+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,
@@ -198,5 +208,5 @@
 };
 
-int kbd_ctl_init(kbd_port_ops_t *kbd_p)
+static int pc_ctl_init(kbd_port_ops_t *kbd_p)
 {
 	kbd_port = kbd_p;
@@ -205,5 +215,5 @@
 }
 
-void kbd_ctl_parse_scancode(int scancode)
+static void pc_ctl_parse_scancode(int scancode)
 {
 	kbd_event_type_t type;
@@ -255,5 +265,5 @@
 }
 
-void kbd_ctl_set_ind(unsigned mods)
+static void pc_ctl_set_ind(unsigned mods)
 {
 	uint8_t b;
Index: uspace/srv/hid/kbd/ctl/stty.c
===================================================================
--- uspace/srv/hid/kbd/ctl/stty.c	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/ctl/stty.c	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -43,4 +43,14 @@
 #include <stroke.h>
 
+static void stty_ctl_parse_scancode(int scancode);
+static int stty_ctl_init(kbd_port_ops_t *kbd_port);
+static void stty_ctl_set_ind(unsigned mods);
+
+kbd_ctl_ops_t stty_ctl = {
+	.parse_scancode = stty_ctl_parse_scancode,
+	.init = stty_ctl_init,
+	.set_ind = stty_ctl_set_ind
+};
+
 /** Scancode parser */
 static gsp_t sp;
@@ -51,5 +61,5 @@
 #include <stdio.h>
 
-int seq_defs[] = {
+static int seq_defs[] = {
 	/* Not shifted */
 
@@ -207,5 +217,5 @@
 };
 
-int kbd_ctl_init(kbd_port_ops_t *kbd_port)
+static int stty_ctl_init(kbd_port_ops_t *kbd_port)
 {
 	(void) kbd_port;
@@ -216,5 +226,5 @@
 }
 
-void kbd_ctl_parse_scancode(int scancode)
+static void stty_ctl_parse_scancode(int scancode)
 {
 	unsigned mods, key;
@@ -226,5 +236,5 @@
 }
 
-void kbd_ctl_set_ind(unsigned mods)
+static void stty_ctl_set_ind(unsigned mods)
 {
 	(void) mods;
Index: uspace/srv/hid/kbd/ctl/sun.c
===================================================================
--- uspace/srv/hid/kbd/ctl/sun.c	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/ctl/sun.c	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -42,4 +42,14 @@
 #include <kbd_port.h>
 
+static void sun_ctl_parse_scancode(int scancode);
+static int sun_ctl_init(kbd_port_ops_t *kbd_port);
+static void sun_ctl_set_ind(unsigned mods);
+
+kbd_ctl_ops_t sun_ctl = {
+	.parse_scancode = sun_ctl_parse_scancode,
+	.init = sun_ctl_init,
+	.set_ind = sun_ctl_set_ind
+};
+
 #define KBD_KEY_RELEASE		0x80
 #define KBD_ALL_KEYS_UP		0x7f
@@ -47,10 +57,10 @@
 static int scanmap_simple[];
 
-int kbd_ctl_init(kbd_port_ops_t *kbd_port)
+static int sun_ctl_init(kbd_port_ops_t *kbd_port)
 {
 	return 0;
 }
 
-void kbd_ctl_parse_scancode(int scancode)
+static void sun_ctl_parse_scancode(int scancode)
 {
 	kbd_event_type_t type;
@@ -75,5 +85,5 @@
 }
 
-void kbd_ctl_set_ind(unsigned mods)
+static void sun_ctl_set_ind(unsigned mods)
 {
 	(void) mods;
Index: uspace/srv/hid/kbd/generic/kbd.c
===================================================================
--- uspace/srv/hid/kbd/generic/kbd.c	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/generic/kbd.c	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -72,4 +72,5 @@
 
 static kbd_port_ops_t *kbd_port;
+static kbd_ctl_ops_t *kbd_ctl;
 
 bool irc_service = false;
@@ -89,5 +90,5 @@
 {
 /*	printf("scancode: 0x%x\n", scancode);*/
-	kbd_ctl_parse_scancode(scancode);
+	(*kbd_ctl->parse_scancode)(scancode);
 }
 
@@ -132,5 +133,5 @@
 
 			/* Update keyboard lock indicator lights. */
-			kbd_ctl_set_ind(mods);
+			(*kbd_ctl->set_ind)(mods);
 		} else {
 			lock_keys = lock_keys & ~mod_mask;
@@ -217,38 +218,57 @@
 }
 
-static kbd_port_ops_t *kbd_select_port(void)
-{
-	kbd_port_ops_t *kbd_port;
-
+static void kbd_select_drivers(kbd_port_ops_t **port, kbd_ctl_ops_t **ctl)
+{
 #if defined(UARCH_amd64)
-	kbd_port = &chardev_port;
+	*port = &chardev_port;
+	*ctl = &pc_ctl;
 #elif defined(UARCH_arm32) && defined(MACHINE_gta02)
-	kbd_port = &chardev_port;
+	*port = &chardev_port;
+	*ctl = &stty_ctl;
 #elif defined(UARCH_arm32) && defined(MACHINE_testarm)
-	kbd_port = &gxemul_port;
+	*port = &gxemul_port;
+	#ifdef CONFIG_FB
+		*ctl = &gxe_fb_ctl;
+	#else
+		*ctl = &stty_ctl;
+	#endif
 #elif defined(UARCH_arm32) && defined(MACHINE_integratorcp)
-	kbd_port = &pl050_port;
+	*port = &pl050_port;
+	*ctl = &pc_ctl;
 #elif defined(UARCH_ia32)
-	kbd_port = &chardev_port;
+	*port = &chardev_port;
+	*ctl = &pc_ctl;
 #elif defined(MACHINE_i460GX)
-	kbd_port = &chardev_port;
+	*port = &chardev_port;
+	*ctl = &pc_ctl;
 #elif defined(MACHINE_ski)
-	kbd_port = &ski_port;
+	*port = &ski_port;
+	*ctl = &stty_ctl;
 #elif defined(MACHINE_msim)
-	kbd_port = &msim_port;
+	*port = &msim_port;
+	*ctl = &stty_ctl;
 #elif defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
-	kbd_port = &gxemul_port;
+	*port = &gxemul_port;
+	#ifdef CONFIG_FB
+		*ctl = &gxe_fb_ctl;
+	#else
+		*ctl = &stty_ctl;
+	#endif
 #elif defined(UARCH_ppc32)
-	kbd_port = &adb_port;
+	*port = &adb_port;
+	*ctl = &apple_ctl;
 #elif defined(UARCH_sparc64) && defined(PROCESSOR_sun4v)
-	kbd_port = &niagara_port;
+	*port = &niagara_port;
+	*ctl = &stty_ctl;
 #elif defined(UARCH_sparc64) && defined(MACHINE_serengeti)
-	kbd_port = &sgcn_port;
+	*port = &sgcn_port;
+	*ctl = &stty_ctl;
 #elif defined(UARCH_sparc64) && defined(MACHINE_generic)
-	kbd_port = &sun_port;
+	*port = &sun_port;
+	*ctl = &sun_ctl;
 #else
-	kbd_port = &dummy_port;
+	*port = &dummy_port;
+	*ctl = &pc_ctl;
 #endif
-	return kbd_port;
 }
 
@@ -269,6 +289,6 @@
 	}
 	
-	/* Select port driver. */
-	kbd_port = kbd_select_port();
+	/* Select port and controller drivers. */
+	kbd_select_drivers(&kbd_port, &kbd_ctl);
 
 	/* Initialize port driver. */
@@ -277,5 +297,5 @@
 
 	/* Initialize controller driver. */
-	if (kbd_ctl_init(kbd_port) != 0)
+	if ((*kbd_ctl->init)(kbd_port) != 0)
 		return -1;
 
Index: uspace/srv/hid/kbd/include/kbd_ctl.h
===================================================================
--- uspace/srv/hid/kbd/include/kbd_ctl.h	(revision b1bdc7a40ece021baf719fb60fce641c683e3401)
+++ uspace/srv/hid/kbd/include/kbd_ctl.h	(revision 56ad8182fe6d96f99cbc03b4179f8a786125041c)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,7 +40,15 @@
 #include <kbd_port.h>
 
-extern void kbd_ctl_parse_scancode(int);
-extern int kbd_ctl_init(kbd_port_ops_t *);
-extern void kbd_ctl_set_ind(unsigned);
+typedef struct {
+	void (*parse_scancode)(int);
+	int (*init)(kbd_port_ops_t *);
+	void (*set_ind)(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 pc_ctl;
+extern kbd_ctl_ops_t stty_ctl;
+extern kbd_ctl_ops_t sun_ctl;
 
 #endif
