Index: kernel/genarch/src/drivers/i8042/i8042.c
===================================================================
--- kernel/genarch/src/drivers/i8042/i8042.c	(revision a0e1b48209ddcecbae3a971fb6275aa891cdee60)
+++ kernel/genarch/src/drivers/i8042/i8042.c	(revision 1462d35d75ed11831cc803ee058338daa2ddebf2)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
 /**
  * @file
- * @brief	i8042 processor driver
+ * @brief i8042 processor driver
  *
  * It takes care of the i8042 serial communication.
@@ -43,9 +43,13 @@
 #include <mm/slab.h>
 
-#define i8042_SET_COMMAND 	0x60
-#define i8042_COMMAND 		0x69
+indev_operations_t kbrdin_ops = {
+	.poll = NULL
+};
 
-#define i8042_BUFFER_FULL_MASK	0x01
-#define i8042_WAIT_MASK		0x02
+#define i8042_SET_COMMAND  0x60
+#define i8042_COMMAND      0x69
+
+#define i8042_BUFFER_FULL_MASK  0x01
+#define i8042_WAIT_MASK         0x02
 
 static irq_ownership_t i8042_claim(irq_t *irq)
@@ -53,4 +57,5 @@
 	i8042_instance_t *i8042_instance = irq->instance;
 	i8042_t *dev = i8042_instance->i8042;
+	
 	if (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
 		return IRQ_ACCEPT;
@@ -63,29 +68,24 @@
 	i8042_instance_t *instance = irq->instance;
 	i8042_t *dev = instance->i8042;
-
-	uint8_t data;
 	uint8_t status;
-		
+	
 	if (((status = pio_read_8(&dev->status)) & i8042_BUFFER_FULL_MASK)) {
-		data = pio_read_8(&dev->data);
-			
-		if (instance->devout)
-			chardev_push_character(instance->devout, data);
+		uint8_t data = pio_read_8(&dev->data);
+		indev_push_character(&instance->kbrdin, data);
 	}
 }
 
 /** Initialize i8042. */
-bool
-i8042_init(i8042_t *dev, devno_t devno, inr_t inr, chardev_t *devout)
+indev_t *i8042_init(i8042_t *dev, devno_t devno, inr_t inr)
 {
-	i8042_instance_t *instance;
-
-	instance = malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
+	i8042_instance_t *instance
+	    = malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
 	if (!instance)
-		return false;
+		return NULL;
+	
+	indev_initialize("i8042", &instance->kbrdin, &kbrdin_ops);
 	
 	instance->devno = devno;
 	instance->i8042 = dev;
-	instance->devout = devout;
 	
 	irq_initialize(&instance->irq);
@@ -103,5 +103,5 @@
 		(void) pio_read_8(&dev->data);
 	
-	return true;
+	return &instance->kbrdin;
 }
 
Index: kernel/genarch/src/drivers/ns16550/ns16550.c
===================================================================
--- kernel/genarch/src/drivers/ns16550/ns16550.c	(revision a0e1b48209ddcecbae3a971fb6275aa891cdee60)
+++ kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 1462d35d75ed11831cc803ee058338daa2ddebf2)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
 /**
  * @file
- * @brief	NS 16550 serial controller driver.
+ * @brief NS 16550 serial controller driver.
  */
 
@@ -41,30 +41,54 @@
 #include <mm/slab.h>
 
-#define LSR_DATA_READY	0x01
+#define LSR_DATA_READY  0x01
+
+indev_operations_t kbrdin_ops = {
+	.poll = NULL
+};
+
+static irq_ownership_t ns16550_claim(irq_t *irq)
+{
+	ns16550_instance_t *instance = irq->instance;
+	ns16550_t *dev = instance->ns16550;
+	
+	if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
+		return IRQ_ACCEPT;
+	else
+		return IRQ_DECLINE;
+}
+
+static void ns16550_irq_handler(irq_t *irq)
+{
+	ns16550_instance_t *instance = irq->instance;
+	ns16550_t *dev = instance->ns16550;
+	
+	if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
+		uint8_t x = pio_read_8(&dev->rbr);
+		chardev_push_character(&instance->kbrdin, x);
+	}
+}
 
 /** Initialize ns16550.
  *
- * @param dev		Addrress of the beginning of the device in I/O space.
- * @param devno		Device number.
- * @param inr		Interrupt number.
- * @param cir		Clear interrupt function.
- * @param cir_arg	First argument to cir.
- * @param devout	Output character device.
+ * @param dev      Addrress of the beginning of the device in I/O space.
+ * @param devno    Device number.
+ * @param inr      Interrupt number.
+ * @param cir      Clear interrupt function.
+ * @param cir_arg  First argument to cir.
  *
- * @return		True on success, false on failure.
+ * @return Keyboard device pointer or NULL on failure.
+ *
  */
-bool
-ns16550_init(ns16550_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg,
-    chardev_t *devout)
+indev_t *ns16550_init(ns16550_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg)
 {
-	ns16550_instance_t *instance;
+	ns16550_instance_t *instance
+	    = malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC);
+	if (!instance)
+		return NULL;
 	
-	instance = malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC);
-	if (!instance)
-		return false;
-
+	indev_initialize("ns16550", &instance->kbrdin, &kbrdin_ops);
+	
 	instance->devno = devno;
 	instance->ns16550 = dev;
-	instance->devout = devout;
 	
 	irq_initialize(&instance->irq);
@@ -77,5 +101,5 @@
 	instance->irq.cir_arg = cir_arg;
 	irq_register(&instance->irq);
-
+	
 	while ((pio_read_8(&dev->lsr) & LSR_DATA_READY))
 		(void) pio_read_8(&dev->rbr);
@@ -85,30 +109,5 @@
 	pio_write_8(&dev->mcr, MCR_OUT2);
 	
-	return true;
-}
-
-irq_ownership_t ns16550_claim(irq_t *irq)
-{
-	ns16550_instance_t *instance = irq->instance;
-	ns16550_t *dev = instance->ns16550;
-
-	if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
-		return IRQ_ACCEPT;
-	else
-		return IRQ_DECLINE;
-}
-
-void ns16550_irq_handler(irq_t *irq)
-{
-	ns16550_instance_t *instance = irq->instance;
-	ns16550_t *dev = instance->ns16550;
-
-	if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
-		uint8_t x;
-		
-		x = pio_read_8(&dev->rbr);
-		if (instance->devout)
-			chardev_push_character(instance->devout, x);
-	}
+	return &instance->kbrdin;
 }
 
Index: kernel/genarch/src/drivers/z8530/z8530.c
===================================================================
--- kernel/genarch/src/drivers/z8530/z8530.c	(revision a0e1b48209ddcecbae3a971fb6275aa891cdee60)
+++ kernel/genarch/src/drivers/z8530/z8530.c	(revision 1462d35d75ed11831cc803ee058338daa2ddebf2)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
 /**
  * @file
- * @brief	Zilog 8530 serial controller driver.
+ * @brief Zilog 8530 serial controller driver.
  */
 
@@ -41,4 +41,8 @@
 #include <mm/slab.h>
 
+indev_operations_t kbrdin_ops = {
+	.poll = NULL
+};
+
 static inline void z8530_write(ioport8_t *ctl, uint8_t reg, uint8_t val)
 {
@@ -47,6 +51,6 @@
 	 * command as their bit 3 is 1.
 	 */
-	pio_write_8(ctl, reg);	/* select register */
-	pio_write_8(ctl, val);	/* write value */
+	pio_write_8(ctl, reg);  /* Select register */
+	pio_write_8(ctl, val);  /* Write value */
 }
 
@@ -57,23 +61,43 @@
 	 * command as their bit 3 is 1.
 	 */
-	pio_write_8(ctl, reg);	/* select register */
+	pio_write_8(ctl, reg);   /* Select register */
 	return pio_read_8(ctl);
 }
 
+static irq_ownership_t z8530_claim(irq_t *irq)
+{
+	z8530_instance_t *instance = irq->instance;
+	z8530_t *dev = instance->z8530;
+	
+	if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA)
+		return IRQ_ACCEPT;
+	else
+		return IRQ_DECLINE;
+}
+
+static void z8530_irq_handler(irq_t *irq)
+{
+	z8530_instance_t *instance = irq->instance;
+	z8530_t *dev = instance->z8530;
+	
+	if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) {
+		uint8_t x = z8530_read(&dev->ctl_a, RR8);
+		chardev_push_character(&instance->kbrdin, x);
+	}
+}
+
 /** Initialize z8530. */
-bool
-z8530_init(z8530_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg,
-    chardev_t *devout)
+indev_t *z8530_init(z8530_t *dev, devno_t devno, inr_t inr, cir_t cir, void *cir_arg)
 {
-	z8530_instance_t *instance;
-
-	instance = malloc(sizeof(z8530_instance_t), FRAME_ATOMIC);
+	z8530_instance_t *instance
+	    = malloc(sizeof(z8530_instance_t), FRAME_ATOMIC);
 	if (!instance)
 		return false;
-
+	
+	indev_initialize("z8530", &instance->kbrdin, &kbrdin_ops);
+	
 	instance->devno = devno;
 	instance->z8530 = dev;
-	instance->devout = devout;
-
+	
 	irq_initialize(&instance->irq);
 	instance->irq.devno = devno;
@@ -85,7 +109,7 @@
 	instance->irq.cir_arg = cir_arg;
 	irq_register(&instance->irq);
-
+	
 	(void) z8530_read(&dev->ctl_a, RR8);
-
+	
 	/*
 	 * Clear any pending TX interrupts or we never manage
@@ -93,8 +117,8 @@
 	 */
 	z8530_write(&dev->ctl_a, WR0, WR0_TX_IP_RST);
-
+	
 	/* interrupt on all characters */
 	z8530_write(&dev->ctl_a, WR1, WR1_IARCSC);
-
+	
 	/* 8 bits per character and enable receiver */
 	z8530_write(&dev->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
@@ -102,30 +126,6 @@
 	/* Master Interrupt Enable. */
 	z8530_write(&dev->ctl_a, WR9, WR9_MIE);
-
-	return true;
-}
-
-irq_ownership_t z8530_claim(irq_t *irq)
-{
-	z8530_instance_t *instance = irq->instance;
-	z8530_t *dev = instance->z8530;
-
-	if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA)
-		return IRQ_ACCEPT;
-	else
-		return IRQ_DECLINE;
-}
-
-void z8530_irq_handler(irq_t *irq)
-{
-	z8530_instance_t *instance = irq->instance;
-	z8530_t *dev = instance->z8530;
-	uint8_t x;
-
-	if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) {
-		x = z8530_read(&dev->ctl_a, RR8);
-		if (instance->devout)
-			chardev_push_character(instance->devout, x);
-	}
+	
+	return &instance->kbrdin;
 }
 
