Index: uspace/lib/libc/Makefile
===================================================================
--- uspace/lib/libc/Makefile	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/lib/libc/Makefile	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -55,4 +55,5 @@
 	generic/devman.c \
 	generic/device/hw_res.c \
+	generic/device/char.c \
 	generic/event.c \
 	generic/errno.c \
Index: uspace/lib/libc/generic/device/char.c
===================================================================
--- uspace/lib/libc/generic/device/char.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libc/generic/device/char.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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
+ */
+
+#include <ipc/dev_iface.h>
+#include <device/char.h>
+#include <errno.h>
+#include <async.h>
+#include <malloc.h>
+
+
+int read_dev(int dev_phone, void *buf, size_t len)
+{	
+	ipc_call_t answer;
+	
+	async_serialize_start();
+	
+	aid_t req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_READ_DEV, &answer);
+	
+	int rc = async_data_read_start(dev_phone, buf, len);
+	if (rc != EOK) {
+		ipcarg_t rc_orig;
+		async_wait_for(req, &rc_orig);
+		async_serialize_end();
+		if (rc_orig == EOK) {
+			return rc;
+		}
+		else {
+			return (int) rc_orig;
+		}
+	}
+	
+	async_wait_for(req, &rc);
+	async_serialize_end();
+	
+	if (EOK != rc) {
+		return rc;
+	}
+	
+	return IPC_GET_ARG1(answer);
+}
+
+int write_dev(int dev_phone, void *buf, size_t len)
+{
+	// TODO
+	return 0;
+}
+
+  
+ /** @}
+ */
Index: uspace/lib/libc/include/device/char.h
===================================================================
--- uspace/lib/libc/include/device/char.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libc/include/device/char.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * 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_DEVICE_HW_RES_H_
+#define LIBC_DEVICE_HW_RES_H_
+
+typedef enum {
+	CHAR_READ_DEV = 0,
+	CHAR_WRITE_DEV	
+} hw_res_funcs_t;
+
+int read_dev(int dev_phone, void *buf, size_t len);
+int write_dev(int dev_phone, void *buf, size_t len);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/libc/include/ipc/dev_iface.h	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/lib/libc/include/ipc/dev_iface.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -37,4 +37,5 @@
 typedef enum {	
 	HW_RES_DEV_IFACE = 0,	
+	CHAR_DEV_IFACE,
 	// TODO add more interfaces
 	DEV_IFACE_MAX
Index: uspace/lib/libdrv/Makefile
===================================================================
--- uspace/lib/libdrv/Makefile	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/lib/libdrv/Makefile	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -37,5 +37,6 @@
 	generic/driver.c \
 	generic/dev_iface.c \
-	generic/remote_res.h
+	generic/remote_res.c \
+	generic/remote_char.c
 
 include ../Makefile.common
Index: uspace/lib/libdrv/generic/dev_iface.c
===================================================================
--- uspace/lib/libdrv/generic/dev_iface.c	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/lib/libdrv/generic/dev_iface.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -38,8 +38,10 @@
 #include "dev_iface.h"
 #include "remote_res.h"
+#include "remote_char.h"
  
 static iface_dipatch_table_t remote_ifaces = {
 	.ifaces = {
-		&remote_res_iface
+		&remote_res_iface,
+		&remote_char_iface
 	}
 };
Index: uspace/lib/libdrv/generic/driver.c
===================================================================
--- uspace/lib/libdrv/generic/driver.c	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/lib/libdrv/generic/driver.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -224,7 +224,11 @@
 	// TODO - if the client is not a driver, check whether it is allowed to use the device
 
-	// TODO open the device (introduce some callbacks for opening and closing devices registered by the driver)
-	
-	ipc_answer_0(iid, EOK);	
+	int ret = EOK;
+	// open the device
+	if (NULL != dev->class && NULL != dev->class->open) {
+		ret = (*dev->class->open)(dev);
+	}
+	
+	ipc_answer_0(iid, ret);	
 
 	while (1) {
@@ -236,8 +240,9 @@
 		
 		switch  (method) {
-		case IPC_M_PHONE_HUNGUP:
-		
-			// TODO close the device
-			
+		case IPC_M_PHONE_HUNGUP:		
+			// close the device
+			if (NULL != dev->class && NULL != dev->class->close) {
+				(*dev->class->close)(dev);
+			}			
 			ipc_answer_0(callid, EOK);
 			return;
Index: uspace/lib/libdrv/generic/remote_char.c
===================================================================
--- uspace/lib/libdrv/generic/remote_char.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libdrv/generic/remote_char.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova 
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+#include "char.h"
+#include "driver.h"
+
+#define MAX_CHAR_RW_COUNT 256
+
+static void remote_char_read(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call);
+static void remote_char_write(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call);
+
+static remote_iface_func_ptr_t remote_char_iface_ops [] = {
+	&remote_char_read,
+	&remote_char_write	
+}; 
+ 
+remote_iface_t remote_char_iface = {
+	.method_count = sizeof(remote_char_iface_ops) / sizeof(remote_iface_func_ptr_t),
+	.methods = remote_char_iface_ops
+};
+
+static void remote_char_read(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	char_iface_t *char_iface = (char_iface_t *)iface;
+	if (!char_iface->read) {
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+	
+	size_t len;
+	if (!async_data_read_receive(&callid, &len)) {
+		// TODO handle protocol error
+		return;
+	}
+	
+	if (len > MAX_CHAR_RW_COUNT) {
+		len = MAX_CHAR_RW_COUNT;
+	}
+	
+	char buf[MAX_CHAR_RW_COUNT];
+	int ret = (*char_iface->read)(dev, buf, len);
+	
+	if (ret < 0) { // some error occured
+		async_data_read_finalize(callid, buf, 0);
+		ipc_answer_0(callid, ret);
+		return;
+	}
+	
+	async_data_read_finalize(callid, buf, ret);
+	ipc_answer_0(callid, EOK);	
+}
+
+static void remote_char_write(device_t *dev, void *iface, ipc_callid_t callid, ipc_call_t *call)
+{
+	char_iface_t *char_iface = (char_iface_t *)iface;
+	if (!char_iface->write) {
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}	
+	
+	size_t len;
+	if (!async_data_write_receive(&callid, &len)) {
+		// TODO handle protocol error
+		return;
+    }
+	
+	if (len > MAX_CHAR_RW_COUNT) {
+		len = MAX_CHAR_RW_COUNT;
+	}
+	
+	char buf[MAX_CHAR_RW_COUNT];
+	
+	async_data_write_finalize(callid, buf, len);
+	
+	int ret = (*char_iface->write)(dev, buf, len);
+	if (ret < 0) { // some error occured
+		ipc_answer_0(callid, ret);
+	} else {
+		ipc_answer_0(callid, EOK);
+	}
+}
+
+ /**
+ * @}
+ */
Index: uspace/lib/libdrv/include/char.h
===================================================================
--- uspace/lib/libdrv/include/char.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libdrv/include/char.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova 
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+#ifndef LIBDRV_CHAR_H_
+#define LIBDRV_CHAR_H_
+
+#include "driver.h"
+
+typedef struct char_iface {
+	int (*read)(device_t *dev, char *buf, size_t count);
+	int (*write)(device_t *dev, char *buf, size_t count);	
+} char_iface_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/libdrv/include/driver.h
===================================================================
--- uspace/lib/libdrv/include/driver.h	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/lib/libdrv/include/driver.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -41,4 +41,5 @@
 #include <ipc/dev_iface.h>
 #include <device/hw_res.h>
+#include <device/char.h>
 #include <assert.h>
 #include <ddi.h>
@@ -81,4 +82,8 @@
 	/** Unique identification of the class. */
 	int id;
+	/** Optional callback function called when a client is connecting to the device. */
+	int (*open)(device_t *dev);
+	/** Optional callback function called when a client is disconnecting from the device. */
+	void (*close)(device_t *dev);
 	/** The table of interfaces implemented by the device. */
 	void *interfaces[DEV_IFACE_COUNT];	
Index: uspace/lib/libdrv/include/remote_char.h
===================================================================
--- uspace/lib/libdrv/include/remote_char.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libdrv/include/remote_char.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova 
+ * 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 libdrv
+ * @{
+ */
+/** @file
+ */
+#ifndef LIBDRV_REMOTE_CHAR_H_
+#define LIBDRV_REMOTE_CHAR_H_
+
+remote_iface_t remote_char_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/drivers/serial/serial.c
===================================================================
--- uspace/srv/drivers/serial/serial.c	(revision dafe675664c7a1289511a0a93f9c29ad327ec554)
+++ uspace/srv/drivers/serial/serial.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
@@ -269,5 +269,4 @@
 	int res;
 	// enable interrupt globally	
-	printf(NAME ": call  enable_interrupt\n");
 	if (EOK != (res = interrupt_enable(data->irq))) {
 		return res;
@@ -385,8 +384,60 @@
 }
 
+/** Open the device.
+ * 
+ * This is a callback function called when a client tries to connect to the device.
+ * 
+ * @param dev the device.
+ */
+static int serial_open(device_t *dev)
+{
+	serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data;
+	int res;
+	
+	fibril_mutex_lock(&data->mutex);	
+	
+	if (data->client_connected) {
+		res = ELIMIT;
+	} else {
+		res = EOK;
+		data->client_connected = true;
+	}
+	
+	fibril_mutex_unlock(&data->mutex);
+
+	return res;
+}
+
+/** Close the device.
+ * 
+ *  This is a callback function called when a client tries to disconnect from the device.
+ * 
+ * @param dev the device. 
+ */
+static void serial_close(device_t *dev)
+{
+	serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data;
+	
+	fibril_mutex_lock(&data->mutex);
+	
+	assert(data->client_connected);	
+	
+	data->client_connected = false;
+	buf_clear(&data->input_buffer);
+	
+	fibril_mutex_unlock(&data->mutex);	 
+}
+
+/** Initialize the serial port driver.
+ * 
+ * Initialize class structures with callback methods for handling 
+ * client requests to the serial port devices.
+ */
 static void serial_init() 
 {
 	// TODO
 	serial_dev_class.id = 0;
+	serial_dev_class.open = &serial_open;
+	serial_dev_class.close = &serial_close;	
 }
 
