Index: kernel/genarch/include/drivers/i8042/i8042.h
===================================================================
--- kernel/genarch/include/drivers/i8042/i8042.h	(revision a0e1b48209ddcecbae3a971fb6275aa891cdee60)
+++ kernel/genarch/include/drivers/i8042/i8042.h	(revision 0e0490bd48ae43cfc5d71d6ee75ebaafa5e6f20e)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
@@ -41,19 +41,18 @@
 #include <typedefs.h>
 
-struct i8042 {
+typedef struct {
 	ioport8_t data;
 	uint8_t pad[3];
 	ioport8_t status;
-} __attribute__ ((packed));
-typedef struct i8042 i8042_t;
+} __attribute__ ((packed)) i8042_t;
 
-typedef struct i8042_instance {
+typedef struct {
 	devno_t devno;
 	irq_t irq;
 	i8042_t *i8042;
-	chardev_t *devout;
+	indev_t kbrdin;
 } i8042_instance_t;
 
-extern bool i8042_init(i8042_t *, devno_t, inr_t, chardev_t *);
+extern indev_t *i8042_init(i8042_t *, devno_t, inr_t);
 
 #endif
Index: kernel/genarch/include/drivers/ns16550/ns16550.h
===================================================================
--- kernel/genarch/include/drivers/ns16550/ns16550.h	(revision a0e1b48209ddcecbae3a971fb6275aa891cdee60)
+++ kernel/genarch/include/drivers/ns16550/ns16550.h	(revision 0e0490bd48ae43cfc5d71d6ee75ebaafa5e6f20e)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
 /**
  * @file
- * @brief	Headers for NS 16550 serial controller.
+ * @brief Headers for NS 16550 serial controller.
  */
 
@@ -42,36 +42,32 @@
 #include <console/chardev.h>
 
-#define IER_ERBFI	0x01	/** Enable Receive Buffer Full Interrupt. */
+#define IER_ERBFI  0x01  /** Enable Receive Buffer Full Interrupt. */
 
-#define LCR_DLAB	0x80	/** Divisor Latch Access bit. */
+#define LCR_DLAB   0x80  /** Divisor Latch Access bit. */
 
-#define MCR_OUT2	0x08	/** OUT2. */
+#define MCR_OUT2   0x08  /** OUT2. */
 
 /** NS16550 registers. */
-struct ns16550 {
-	ioport8_t rbr;	/**< Receiver Buffer Register. */
-	ioport8_t ier;	/**< Interrupt Enable Register. */
+typedef struct {
+	ioport8_t rbr;      /**< Receiver Buffer Register. */
+	ioport8_t ier;      /**< Interrupt Enable Register. */
 	union {
-		ioport8_t iir;	/**< Interrupt Ident Register (read). */
-		ioport8_t fcr;	/**< FIFO control register (write). */
+		ioport8_t iir;  /**< Interrupt Ident Register (read). */
+		ioport8_t fcr;  /**< FIFO control register (write). */
 	} __attribute__ ((packed));
-	ioport8_t lcr;	/**< Line Control register. */
-	ioport8_t mcr;	/**< Modem Control Register. */
-	ioport8_t lsr;	/**< Line Status Register. */
-} __attribute__ ((packed));
-typedef struct ns16550 ns16550_t;
+	ioport8_t lcr;      /**< Line Control register. */
+	ioport8_t mcr;      /**< Modem Control Register. */
+	ioport8_t lsr;      /**< Line Status Register. */
+} __attribute__ ((packed)) ns16550_t;
 
 /** Structure representing the ns16550 device. */
-typedef struct ns16550_instance {
+typedef struct {
 	devno_t devno;
 	ns16550_t *ns16550;
 	irq_t irq;
-	chardev_t *devout;
+	indev_t kbrdin;
 } ns16550_instance_t;
 
-extern bool ns16550_init(ns16550_t *, devno_t, inr_t, cir_t, void *,
-    chardev_t *);
-extern irq_ownership_t ns16550_claim(irq_t *);
-extern void ns16550_irq_handler(irq_t *);
+extern indev_t *ns16550_init(ns16550_t *, devno_t, inr_t, cir_t, void *)
 
 #endif
Index: kernel/genarch/include/drivers/z8530/z8530.h
===================================================================
--- kernel/genarch/include/drivers/z8530/z8530.h	(revision a0e1b48209ddcecbae3a971fb6275aa891cdee60)
+++ kernel/genarch/include/drivers/z8530/z8530.h	(revision 0e0490bd48ae43cfc5d71d6ee75ebaafa5e6f20e)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
 /**
  * @file
- * @brief	Headers for Zilog 8530 serial controller.
+ * @brief Headers for Zilog 8530 serial controller.
  */
 
@@ -42,60 +42,60 @@
 #include <console/chardev.h>
 
-#define WR0	0
-#define WR1	1
-#define WR2	2
-#define WR3	3
-#define WR4	4
-#define WR5	5
-#define WR6	6
-#define WR7	7
-#define WR8	8
-#define WR9	9
-#define WR10	10
-#define WR11	11
-#define WR12	12
-#define WR13	13
-#define WR14	14
-#define WR15	15
+#define WR0   0
+#define WR1   1
+#define WR2   2
+#define WR3   3
+#define WR4   4
+#define WR5   5
+#define WR6   6
+#define WR7   7
+#define WR8   8
+#define WR9   9
+#define WR10  10
+#define WR11  11
+#define WR12  12
+#define WR13  13
+#define WR14  14
+#define WR15  15
 
-#define RR0	0
-#define RR1	1
-#define RR2	2
-#define RR3	3
-#define RR8	8
-#define RR10	10
-#define RR12	12
-#define RR13	13
-#define RR14	14
-#define RR15	15
+#define RR0   0
+#define RR1   1
+#define RR2   2
+#define RR3   3
+#define RR8   8
+#define RR10  10
+#define RR12  12
+#define RR13  13
+#define RR14  14
+#define RR15  15
 
 /** Reset pending TX interrupt. */
-#define WR0_TX_IP_RST	(0x5 << 3)
-#define WR0_ERR_RST	(0x6 << 3)
+#define WR0_TX_IP_RST  (0x5 << 3)
+#define WR0_ERR_RST    (0x6 << 3)
 
 /** Receive Interrupts Disabled. */
-#define WR1_RID		(0x0 << 3)
+#define WR1_RID     (0x0 << 3)
 /** Receive Interrupt on First Character or Special Condition. */
-#define WR1_RIFCSC	(0x1 << 3)
+#define WR1_RIFCSC  (0x1 << 3)
 /** Interrupt on All Receive Characters or Special Conditions. */
-#define WR1_IARCSC	(0x2 << 3)
+#define WR1_IARCSC  (0x2 << 3)
 /** Receive Interrupt on Special Condition. */
-#define WR1_RISC	(0x3 << 3)
+#define WR1_RISC    (0x3 << 3)
 /** Parity Is Special Condition. */
-#define WR1_PISC	(0x1 << 2)
+#define WR1_PISC    (0x1 << 2)
 
 /** Rx Enable. */
-#define WR3_RX_ENABLE	(0x1 << 0)
+#define WR3_RX_ENABLE  (0x1 << 0)
 /** 8-bits per character. */
-#define WR3_RX8BITSCH	(0x3 << 6)
+#define WR3_RX8BITSCH  (0x3 << 6)
 
 /** Master Interrupt Enable. */
-#define WR9_MIE		(0x1 << 3)
+#define WR9_MIE  (0x1 << 3)
 
 /** Receive Character Available. */
-#define RR0_RCA		(0x1 << 0)
+#define RR0_RCA  (0x1 << 0)
 
 /** z8530's registers. */
-struct z8530 {
+typedef struct {
 	union {
 		ioport8_t ctl_b;
@@ -111,6 +111,5 @@
 	uint8_t pad3;
 	ioport8_t data_a;
-} __attribute__ ((packed));
-typedef struct z8530 z8530_t;
+} __attribute__ ((packed)) z8530_t;
 
 /** Structure representing the z8530 device. */
@@ -119,10 +118,8 @@
 	irq_t irq;
 	z8530_t *z8530;
-	chardev_t *devout;
+	indev_t kbrdin;
 } z8530_instance_t;
 
-extern bool z8530_init(z8530_t *, devno_t, inr_t, cir_t, void *, chardev_t *);
-extern irq_ownership_t z8530_claim(irq_t *);
-extern void z8530_irq_handler(irq_t *);
+extern devin_t *z8530_init(z8530_t *, devno_t, inr_t, cir_t, void *);
 
 #endif
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 0e0490bd48ae43cfc5d71d6ee75ebaafa5e6f20e)
@@ -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 0e0490bd48ae43cfc5d71d6ee75ebaafa5e6f20e)
@@ -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 0e0490bd48ae43cfc5d71d6ee75ebaafa5e6f20e)
@@ -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;
 }
 
