Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/Makefile.common	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -195,7 +195,7 @@
 
 ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y)
-	OPTIMIZATION = s
-else
-	OPTIMIZATION = 3
+	OPTIMIZATION = 0
+else
+	OPTIMIZATION = 0
 endif
 
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/i8042/i8042.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -2,5 +2,5 @@
  * Copyright (c) 2001-2004 Jakub Jermar
  * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2009 Jiri Svoboda
+ * Copyright (c) 2014 Jiri Svoboda
  * Copyright (c) 2011 Jan Vesely
  * All rights reserved.
@@ -39,11 +39,13 @@
  */
 
+#include <ddf/log.h>
+#include <ddf/interrupt.h>
+#include <ddi.h>
 #include <device/hw_res.h>
-#include <ddi.h>
 #include <errno.h>
 #include <str_error.h>
 #include <inttypes.h>
-#include <ddf/log.h>
-#include <ddf/interrupt.h>
+#include <io/chardev_srv.h>
+
 #include "i8042.h"
 
@@ -64,9 +66,11 @@
 #define i8042_KBD_TRANSLATE  0x40  /* Use this to switch to XT scancodes */
 
-static void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
-
-/** Port function operations. */
-static ddf_dev_ops_t ops = {
-	.default_handler = default_handler
+static void i8042_char_conn(ipc_callid_t, ipc_call_t *, void *);
+static int i8042_read(chardev_srv_t *, void *, size_t);
+static int i8042_write(chardev_srv_t *, const void *, size_t);
+
+static chardev_ops_t i8042_chardev_ops = {
+	.read = i8042_read,
+	.write = i8042_write
 };
 
@@ -106,10 +110,4 @@
 };
 
-/** Get i8042 soft state from device node. */
-static i8042_t *dev_i8042(ddf_dev_t *dev)
-{
-	return ddf_dev_data_get(dev);
-}
-
 /** Wait until it is safe to write to the device. */
 static void wait_ready(i8042_t *dev)
@@ -131,5 +129,5 @@
     ddf_dev_t *dev)
 {
-	i8042_t *controller = dev_i8042(dev);
+	i8042_t *controller = ddf_dev_data_get(dev);
 	
 	const uint8_t status = IPC_GET_ARG1(*call);
@@ -186,4 +184,15 @@
 	};
 	
+	dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t));
+	if (dev->kbd == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+	
+	dev->kbd->ctl = dev;
+	chardev_srvs_init(&dev->kbd->cds);
+	dev->kbd->cds.ops = &i8042_chardev_ops;
+	dev->kbd->cds.sarg = dev->kbd;
+	
 	rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
 	if (rc != EOK)
@@ -196,10 +205,21 @@
 	}
 	
+	dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t));
+	if (dev->aux == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+	
+	dev->aux->ctl = dev;
+	chardev_srvs_init(&dev->aux->cds);
+	dev->aux->cds.ops = &i8042_chardev_ops;
+	dev->aux->cds.sarg = dev->aux;
+	
 	rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
 	if (rc != EOK)
 		goto error;
 	
-	ddf_fun_set_ops(dev->kbd_fun, &ops);
-	ddf_fun_set_ops(dev->aux_fun, &ops);
+	ddf_fun_set_conn_handler(dev->kbd_fun, i8042_char_conn);
+	ddf_fun_set_conn_handler(dev->aux_fun, i8042_char_conn);
 	
 	buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
@@ -298,36 +318,33 @@
 }
 
-// FIXME TODO use shared instead this
-enum {
-	IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
-	IPC_CHAR_WRITE,
-};
-
 /** Write data to i8042 port.
  *
- * @param fun    DDF function.
- * @param buffer Data source.
- * @param size   Data size.
+ * @param srv	 Connection-specific data
+ * @param buffer Data source
+ * @param size   Data size
  *
  * @return Bytes written.
  *
  */
-static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
-{
-	i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun));
-	fibril_mutex_lock(&controller->write_guard);
+static int i8042_write(chardev_srv_t *srv, const void *data, size_t size)
+{
+	i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
+	i8042_t *i8042 = port->ctl;
+	const char *dp = (const char *)data;
+	
+	fibril_mutex_lock(&i8042->write_guard);
 	
 	for (size_t i = 0; i < size; ++i) {
-		if (controller->aux_fun == fun) {
-			wait_ready(controller);
-			pio_write_8(&controller->regs->status,
+		if (port == i8042->aux) {
+			wait_ready(i8042);
+			pio_write_8(&i8042->regs->status,
 			    i8042_CMD_WRITE_AUX);
 		}
 		
-		wait_ready(controller);
-		pio_write_8(&controller->regs->data, buffer[i]);
-	}
-	
-	fibril_mutex_unlock(&controller->write_guard);
+		wait_ready(i8042);
+		pio_write_8(&i8042->regs->data, dp[i]);
+	}
+	
+	fibril_mutex_unlock(&i8042->write_guard);
 	return size;
 }
@@ -335,19 +352,22 @@
 /** Read data from i8042 port.
  *
- * @param fun    DDF function.
- * @param buffer Data place.
- * @param size   Data place size.
+ * @param srv	 Connection-specific data
+ * @param buffer Data place
+ * @param size   Data place size
  *
  * @return Bytes read.
  *
  */
-static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
-{
-	i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun));
-	buffer_t *buffer = (fun == controller->aux_fun) ?
-	    &controller->aux_buffer : &controller->kbd_buffer;
+static int i8042_read(chardev_srv_t *srv, void *dest, size_t size)
+{
+	i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
+	i8042_t *i8042 = port->ctl;
+	uint8_t *destp = (uint8_t *)dest;
+	
+	buffer_t *buffer = (port == i8042->aux) ?
+	    &i8042->aux_buffer : &i8042->kbd_buffer;
 	
 	for (size_t i = 0; i < size; ++i)
-		*data++ = buffer_read(buffer);
+		*destp++ = buffer_read(buffer);
 	
 	return size;
@@ -356,42 +376,13 @@
 /** Handle data requests.
  *
- * @param fun  ddf_fun_t function.
  * @param id   callid
  * @param call IPC request.
- *
- */
-static void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call)
-{
-	const sysarg_t method = IPC_GET_IMETHOD(*call);
-	const size_t size = IPC_GET_ARG1(*call);
-	
-	switch (method) {
-	case IPC_CHAR_READ:
-		if (size <= 4 * sizeof(sysarg_t)) {
-			sysarg_t message[4] = {};
-			
-			i8042_read(fun, (char *) message, size);
-			async_answer_4(id, size, message[0], message[1],
-			    message[2], message[3]);
-		} else
-			async_answer_0(id, ELIMIT);
-		break;
-	
-	case IPC_CHAR_WRITE:
-		if (size <= 3 * sizeof(sysarg_t)) {
-			const sysarg_t message[3] = {
-				IPC_GET_ARG2(*call),
-				IPC_GET_ARG3(*call),
-				IPC_GET_ARG4(*call)
-			};
-			
-			i8042_write(fun, (char *) message, size);
-			async_answer_0(id, size);
-		} else
-			async_answer_0(id, ELIMIT);
-	
-	default:
-		async_answer_0(id, EINVAL);
-	}
+ * @param arg  ddf_fun_t function.
+ */
+void i8042_char_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	i8042_port_t *port = ddf_fun_data_get((ddf_fun_t *)arg);
+
+	chardev_conn(iid, icall, &port->cds);
 }
 
Index: uspace/drv/char/i8042/i8042.h
===================================================================
--- uspace/drv/char/i8042/i8042.h	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/i8042/i8042.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -40,4 +40,5 @@
 #define i8042_H_
 
+#include <io/chardev_srv.h>
 #include <sys/types.h>
 #include <fibril_synch.h>
@@ -56,5 +57,11 @@
 } __attribute__ ((packed)) i8042_regs_t;
 
-/** i8042 driver structure. */
+/** i8042 Port. */
+typedef struct {
+	struct i8042 *ctl;		/**< Controller */
+	chardev_srvs_t cds;		/**< Character device server data */
+} i8042_port_t;
+
+/** i8042 Controller. */
 typedef struct i8042 {
 	i8042_regs_t *regs;             /**< I/O registers. */
@@ -65,6 +72,9 @@
 	uint8_t aux_data[BUFFER_SIZE];  /**< Primary port buffer space. */
 	uint8_t kbd_data[BUFFER_SIZE];  /**< Aux. port buffer space. */
+	i8042_port_t *kbd;
+	i8042_port_t *aux;
 	fibril_mutex_t write_guard;     /**< Prevents simultanous port writes.*/
 } i8042_t;
+
 
 extern int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *);
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/pl050/pl050.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -38,4 +38,5 @@
 #include <ddf/log.h>
 #include <device/hw_res_parsed.h>
+#include <io/chardev_srv.h>
 
 #define NAME "pl050"
@@ -45,9 +46,4 @@
 
 #define PL050_STAT_RXFULL  (1 << 4)
-
-enum {
-	IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
-	IPC_CHAR_WRITE,
-};
 
 enum {
@@ -59,4 +55,6 @@
 static int pl050_fun_offline(ddf_fun_t *);
 static void pl050_char_conn(ipc_callid_t, ipc_call_t *, void *);
+static int pl050_read(chardev_srv_t *, void *, size_t);
+static int pl050_write(chardev_srv_t *, const void *, size_t);
 
 static driver_ops_t driver_ops = {
@@ -71,8 +69,16 @@
 };
 
+static chardev_ops_t pl050_chardev_ops = {
+	.read = pl050_read,
+	.write = pl050_write
+};
+
 typedef struct {
+	async_sess_t *parent_sess;
 	ddf_dev_t *dev;
+
 	ddf_fun_t *fun_a;
-	async_sess_t *parent_sess;
+	chardev_srvs_t cds;
+
 	uintptr_t iobase;
 	size_t iosize;
@@ -135,4 +141,6 @@
 	size_t nidx;
 
+	ddf_msg(LVL_NOTE, "Interrupt");
+
 	fibril_mutex_lock(&pl050->buf_lock);
 	nidx = (pl050->buf_wp + 1) % buffer_size;
@@ -209,14 +217,17 @@
 }
 
-static int pl050_read(pl050_t *pl050, void *buffer, size_t size)
-{
+static int pl050_read(chardev_srv_t *srv, void *buffer, size_t size)
+{
+	pl050_t *pl050 = (pl050_t *)srv->srvs->sarg;
 	uint8_t *bp = buffer;
+	size_t left;
 	fibril_mutex_lock(&pl050->buf_lock);
 
-	while (size > 0) {
+	left = size;
+	while (left > 0) {
 		while (pl050->buf_rp == pl050->buf_wp)
 			fibril_condvar_wait(&pl050->buf_cv, &pl050->buf_lock);
 		*bp++ = pl050->buffer[pl050->buf_rp];
-		--size;
+		--left;
 		pl050->buf_rp = (pl050->buf_rp + 1) % buffer_size;
 	}
@@ -224,10 +235,10 @@
 	fibril_mutex_unlock(&pl050->buf_lock);
 
-	return EOK;
-}
-
-static int pl050_write(pl050_t *pl050, void *data, size_t size)
-{
-	return EOK;
+	return size;
+}
+
+static int pl050_write(chardev_srv_t *srv, const void *data, size_t size)
+{
+	return size;
 }
 
@@ -236,48 +247,5 @@
 	pl050_t *pl050 = pl050_from_fun((ddf_fun_t *)arg);
 
-	/* Accept the connection */
-	async_answer_0(iid, EOK);
-
-	while (true) {
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
-		size_t size = IPC_GET_ARG1(call);
-
-		if (!method) {
-			/* The other side has hung up */
-			async_answer_0(callid, EOK);
-			break;
-		}
-
-		switch (method) {
-		case IPC_CHAR_READ:
-			if (size <= 4 * sizeof(sysarg_t)) {
-				sysarg_t message[4] = {};
-
-				pl050_read(pl050, (char *) message, size);
-				async_answer_4(callid, size, message[0], message[1],
-				    message[2], message[3]);
-			} else
-				async_answer_0(callid, ELIMIT);
-			break;
-
-		case IPC_CHAR_WRITE:
-			if (size <= 3 * sizeof(sysarg_t)) {
-				const sysarg_t message[3] = {
-					IPC_GET_ARG2(call),
-					IPC_GET_ARG3(call),
-					IPC_GET_ARG4(call)
-				};
-
-				pl050_write(pl050, (char *) message, size);
-				async_answer_0(callid, size);
-			} else
-				async_answer_0(callid, ELIMIT);
-
-		default:
-			async_answer_0(callid, EINVAL);
-		}
-	}
+	chardev_conn(iid, icall, &pl050->cds);
 }
 
@@ -289,5 +257,5 @@
 	int rc;
 
-	ddf_msg(LVL_DEBUG, "pl050_dev_add()");
+	ddf_msg(LVL_NOTE, "pl050_dev_add()");
 
 	pl050 = ddf_dev_data_alloc(dev, sizeof(pl050_t));
@@ -308,8 +276,9 @@
 	pl050->dev = dev;
 
+if (1) {
 	rc = pl050_init(pl050);
 	if (rc != EOK)
 		goto error;
-
+}
 	rc = ddf_fun_add_match_id(fun_a, "char/xtkbd", 10);
 	if (rc != EOK) {
@@ -319,6 +288,12 @@
 	}
 
+	ddf_msg(LVL_NOTE, "Init srvs");
+	if (1) {
+	chardev_srvs_init(&pl050->cds);
+	pl050->cds.ops = &pl050_chardev_ops;
+	pl050->cds.sarg = pl050;
+
 	ddf_fun_set_conn_handler(fun_a, pl050_char_conn);
-
+}
 	rc = ddf_fun_bind(fun_a);
 	if (rc != EOK) {
@@ -328,4 +303,5 @@
 	}
 
+	ddf_msg(LVL_NOTE, "Device added");
 	ddf_msg(LVL_DEBUG, "Device added.");
 	return EOK;
Index: uspace/drv/char/ps2mouse/Makefile
===================================================================
--- uspace/drv/char/ps2mouse/Makefile	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/ps2mouse/Makefile	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -33,5 +33,4 @@
 
 SOURCES = \
-	chardev.c \
 	main.c \
 	ps2mouse.c
Index: pace/drv/char/ps2mouse/chardev.c
===================================================================
--- uspace/drv/char/ps2mouse/chardev.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ 	(revision )
@@ -1,68 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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.
- */
-
-#include <errno.h>
-#include <mem.h>
-#include <ipc/dev_iface.h>
-#include <ddf/log.h>
-
-#include "chardev.h"
-
-// TODO make this shared
-enum {
-	IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
-	IPC_CHAR_WRITE,
-};
-
-ssize_t chardev_read(async_exch_t *exch, void *data, size_t size)
-{
-	if (!exch)
-		return EBADMEM;
-	if (size > 4 * sizeof(sysarg_t))
-		return ELIMIT;
-
-	sysarg_t message[4] = { 0 };
-	const ssize_t ret = async_req_1_4(exch, IPC_CHAR_READ, size,
-	    &message[0], &message[1], &message[2], &message[3]);
-	if (ret > 0 && (size_t)ret <= size)
-		memcpy(data, message, size);
-	return ret;
-}
-
-ssize_t chardev_write(async_exch_t *exch, const void *data, size_t size)
-{
-	if (!exch)
-		return EBADMEM;
-	if (size > 3 * sizeof(sysarg_t))
-		return ELIMIT;
-
-	sysarg_t message[3] = { 0 };
-	memcpy(message, data, size);
-	return async_req_4_0(exch, IPC_CHAR_WRITE, size,
-	    message[0], message[1], message[2]);
-}
Index: pace/drv/char/ps2mouse/chardev.h
===================================================================
--- uspace/drv/char/ps2mouse/chardev.h	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 drvmouse
- * @{
- */
-/** @file
- * @brief ps/2 mouse driver.
- */
-
-#ifndef _CHARDEV_H_
-#define _CHARDEV_H_
-
-#include <libarch/types.h>
-#include <async.h>
-
-ssize_t chardev_read(async_exch_t *, void *, size_t);
-ssize_t chardev_write(async_exch_t *, const void *, size_t);
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/char/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/char/ps2mouse/ps2mouse.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/ps2mouse/ps2mouse.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -37,4 +37,5 @@
 #include <ddf/log.h>
 #include <io/keycode.h>
+#include <io/chardev.h>
 #include <io/console.h>
 #include <ipc/mouseev.h>
@@ -42,5 +43,4 @@
 
 #include "ps2mouse.h"
-#include "chardev.h"
 
 #define PS2_MOUSE_GET_DEVICE_ID   0xf2
Index: uspace/drv/char/xtkbd/Makefile
===================================================================
--- uspace/drv/char/xtkbd/Makefile	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/xtkbd/Makefile	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -33,5 +33,4 @@
 
 SOURCES = \
-	chardev.c \
 	main.c \
 	xtkbd.c
Index: pace/drv/char/xtkbd/chardev.c
===================================================================
--- uspace/drv/char/xtkbd/chardev.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ 	(revision )
@@ -1,68 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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.
- */
-
-#include <errno.h>
-#include <mem.h>
-#include <ipc/dev_iface.h>
-#include <ddf/log.h>
-
-#include "chardev.h"
-
-// TODO make this shared
-enum {
-	IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,
-	IPC_CHAR_WRITE,
-};
-
-ssize_t chardev_read(async_exch_t *exch, void *data, size_t size)
-{
-	if (!exch)
-		return EBADMEM;
-	if (size > 4 * sizeof(sysarg_t))
-		return ELIMIT;
-
-	sysarg_t message[4] = { 0 };
-	const ssize_t ret = async_req_1_4(exch, IPC_CHAR_READ, size,
-	    &message[0], &message[1], &message[2], &message[3]);
-	if (ret > 0 && (size_t)ret <= size)
-		memcpy(data, message, size);
-	return ret;
-}
-
-ssize_t chardev_write(async_exch_t *exch, const void *data, size_t size)
-{
-	if (!exch)
-		return EBADMEM;
-	if (size > 3 * sizeof(sysarg_t))
-		return ELIMIT;
-
-	sysarg_t message[3] = { 0 };
-	memcpy(message, data, size);
-	return async_req_4_0(exch, IPC_CHAR_WRITE, size,
-	    message[0], message[1], message[2]);
-}
Index: pace/drv/char/xtkbd/chardev.h
===================================================================
--- uspace/drv/char/xtkbd/chardev.h	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 drvkbd
- * @{
- */
-/** @file
- * @brief ps/2 mouse driver.
- */
-
-#ifndef _CHARDEV_H_
-#define _CHARDEV_H_
-
-#include <libarch/types.h>
-#include <async.h>
-
-ssize_t chardev_read(async_exch_t *, void *, size_t);
-ssize_t chardev_write(async_exch_t *, const void *, size_t);
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/char/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/char/xtkbd/xtkbd.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/drv/char/xtkbd/xtkbd.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -36,9 +36,9 @@
 #include <ddf/log.h>
 #include <io/keycode.h>
+#include <io/chardev.h>
 #include <io/console.h>
 #include <ipc/kbdev.h>
 #include <abi/ipc/methods.h>
 
-#include "chardev.h"
 #include "xtkbd.h"
 
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/lib/c/Makefile	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -92,4 +92,6 @@
 	generic/io/input.c \
 	generic/io/io.c \
+	generic/io/chardev.c \
+	generic/io/chardev_srv.c \
 	generic/io/chargrid.c \
 	generic/io/output.c \
Index: uspace/lib/c/generic/bd_srv.c
===================================================================
--- uspace/lib/c/generic/bd_srv.c	(revision 312e5ff64a7e4151a05801b65b38da2bbe914da0)
+++ uspace/lib/c/generic/bd_srv.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -209,5 +209,5 @@
 	bd_srv_t *srv;
 
-	srv = calloc(1, sizeof(srv));
+	srv = calloc(1, sizeof(bd_srv_t));
 	if (srv == NULL)
 		return NULL;
Index: uspace/lib/c/generic/io/chardev.c
===================================================================
--- uspace/lib/c/generic/io/chardev.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
+++ uspace/lib/c/generic/io/chardev.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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.
+ */
+
+#include <errno.h>
+#include <mem.h>
+#include <io/chardev.h>
+#include <ipc/chardev.h>
+
+ssize_t chardev_read(async_exch_t *exch, void *data, size_t size)
+{
+	if (!exch)
+		return EBADMEM;
+	if (size > 4 * sizeof(sysarg_t))
+		return ELIMIT;
+
+	sysarg_t message[4] = { 0 };
+	const ssize_t ret = async_req_1_4(exch, CHARDEV_READ, size,
+	    &message[0], &message[1], &message[2], &message[3]);
+	if (ret > 0 && (size_t)ret <= size)
+		memcpy(data, message, size);
+	return ret;
+}
+
+ssize_t chardev_write(async_exch_t *exch, const void *data, size_t size)
+{
+	if (!exch)
+		return EBADMEM;
+	if (size > 3 * sizeof(sysarg_t))
+		return ELIMIT;
+
+	sysarg_t message[3] = { 0 };
+	memcpy(message, data, size);
+	return async_req_4_0(exch, CHARDEV_WRITE, size,
+	    message[0], message[1], message[2]);
+}
Index: uspace/lib/c/generic/io/chardev_srv.c
===================================================================
--- uspace/lib/c/generic/io/chardev_srv.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
+++ uspace/lib/c/generic/io/chardev_srv.c	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014 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 libc
+ * @{
+ */
+/**
+ * @file
+ * @brief Character device server stub
+ */
+#include <errno.h>
+#include <io/chardev_srv.h>
+#include <ipc/chardev.h>
+#include <macros.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+static chardev_srv_t *chardev_srv_create(chardev_srvs_t *);
+
+static void chardev_read_srv(chardev_srv_t *srv, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	size_t size = IPC_GET_ARG1(*call);
+	int rc;
+
+	if (srv->srvs->ops->read == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	if (size <= 4 * sizeof(sysarg_t)) {
+		sysarg_t message[4] = {};
+
+		rc = srv->srvs->ops->read(srv, (char *)message, size);
+		async_answer_4(callid, rc, message[0], message[1],
+		    message[2], message[3]);
+	} else {
+		async_answer_0(callid, ELIMIT);
+	}
+}
+
+static void chardev_write_srv(chardev_srv_t *srv, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	size_t size = IPC_GET_ARG1(*call);
+	int rc;
+
+	if (srv->srvs->ops->write == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	if (size <= 3 * sizeof(sysarg_t)) {
+		const sysarg_t message[3] = {
+			IPC_GET_ARG2(*call),
+			IPC_GET_ARG3(*call),
+			IPC_GET_ARG4(*call)
+		};
+
+		rc = srv->srvs->ops->write(srv, (char *)message, size);
+		async_answer_0(callid, rc);
+	} else {
+		async_answer_0(callid, ELIMIT);
+	}
+}
+
+static chardev_srv_t *chardev_srv_create(chardev_srvs_t *srvs)
+{
+	chardev_srv_t *srv;
+
+	srv = calloc(1, sizeof(chardev_srv_t));
+	if (srv == NULL)
+		return NULL;
+
+	srv->srvs = srvs;
+	return srv;
+}
+
+void chardev_srvs_init(chardev_srvs_t *srvs)
+{
+	srvs->ops = NULL;
+	srvs->sarg = NULL;
+}
+
+int chardev_conn(ipc_callid_t iid, ipc_call_t *icall, chardev_srvs_t *srvs)
+{
+	chardev_srv_t *srv;
+	int rc;
+
+	/* Accept the connection */
+	async_answer_0(iid, EOK);
+
+	srv = chardev_srv_create(srvs);
+	if (srv == NULL)
+		return ENOMEM;
+
+	if (srvs->ops->open != NULL) {
+		rc = srvs->ops->open(srvs, srv);
+		if (rc != EOK)
+			return rc;
+	}
+
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		sysarg_t method = IPC_GET_IMETHOD(call);
+
+		if (!method) {
+			/* The other side has hung up */
+			async_answer_0(callid, EOK);
+			break;
+		}
+
+		switch (method) {
+		case CHARDEV_READ:
+			chardev_read_srv(srv, callid, &call);
+			break;
+		case CHARDEV_WRITE:
+			chardev_write_srv(srv, callid, &call);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
+
+	if (srvs->ops->close != NULL)
+		rc = srvs->ops->close(srv);
+	else
+		rc = EOK;
+
+	free(srv);
+
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/io/chardev.h
===================================================================
--- uspace/lib/c/include/io/chardev.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
+++ uspace/lib/c/include/io/chardev.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libc
+ * @{
+ */
+
+#ifndef LIBC_IO_CHARDEV_H_
+#define LIBC_IO_CHARDEV_H_
+
+#include <libarch/types.h>
+#include <async.h>
+
+ssize_t chardev_read(async_exch_t *, void *, size_t);
+ssize_t chardev_write(async_exch_t *, const void *, size_t);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/c/include/io/chardev_srv.h
===================================================================
--- uspace/lib/c/include/io/chardev_srv.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
+++ uspace/lib/c/include/io/chardev_srv.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IO_CHARDEV_SRV_H_
+#define LIBC_IO_CHARDEV_SRV_H_
+
+#include <adt/list.h>
+#include <async.h>
+#include <fibril_synch.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+typedef struct chardev_ops chardev_ops_t;
+
+/** Service setup (per sevice) */
+typedef struct {
+	chardev_ops_t *ops;
+	void *sarg;
+} chardev_srvs_t;
+
+/** Server structure (per client session) */
+typedef struct {
+	chardev_srvs_t *srvs;
+	void *carg;
+} chardev_srv_t;
+
+struct chardev_ops {
+	int (*open)(chardev_srvs_t *, chardev_srv_t *);
+	int (*close)(chardev_srv_t *);
+	int (*read)(chardev_srv_t *, void *, size_t);
+	int (*write)(chardev_srv_t *, const void *, size_t);
+};
+
+extern void chardev_srvs_init(chardev_srvs_t *);
+
+extern int chardev_conn(ipc_callid_t, ipc_call_t *, chardev_srvs_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/chardev.h
===================================================================
--- uspace/lib/c/include/ipc/chardev.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
+++ uspace/lib/c/include/ipc/chardev.h	(revision 75751db6c5c6834a6695072a6087289dd2c538f6)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014 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
+ * @brief Character device interface.
+ */
+
+#ifndef LIBC_IPC_CHARDEV_H_
+#define LIBC_IPC_CHARDEV_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	CHARDEV_READ = IPC_FIRST_USER_METHOD,
+	CHARDEV_WRITE
+} chardev_request_t;
+
+#endif
+
+/** @}
+ */
