Index: uspace/app/test_serial/test_serial.c
===================================================================
--- uspace/app/test_serial/test_serial.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/app/test_serial/test_serial.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -56,10 +56,6 @@
 
 #define NAME 		"test serial"
-#define MYROOM 		2
-#define UpSection1 	25
-#define DwnSection1 26
-#define UpSection2 	27
-#define DwnSection2 28
-
+
+/*
 static int device_get_handle(const char *name, dev_handle_t *handle);
 static void print_usage();
@@ -105,7 +101,5 @@
 
 
-/*
- * The name of a serial device must be between 'com0' and 'com9'.
- */ 
+// The name of a serial device must be between 'com0' and 'com9'.
 static bool is_com_dev(const char *dev_name) 
 {
@@ -168,5 +162,71 @@
 	
 	return 0;
-}
+}*/
+
+
+#include <ipc/devman.h>
+#include <devman.h>
+#include <device/char.h>
+
+
+static void print_usage()
+{
+	printf("Usage: \n test_serial count \n where count is a number of characters to be read\n");	
+}
+
+
+int main(int argc, char *argv[])
+{
+	if (argc != 2) {
+		printf(NAME ": incorrect number of arguments.\n");
+		print_usage();
+		return 0;		
+	}
+	
+	long int cnt = strtol(argv[1], NULL, 10);
+	
+	int res;
+	res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
+	device_handle_t handle;
+	
+	if (EOK != (res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle, IPC_FLAG_BLOCKING))) {
+		printf(NAME ": could not get the device handle, errno = %d.\n", -res);
+		return 1;
+	}
+	
+	printf(NAME ": device handle is %d.\n", handle);	
+	
+	int phone;
+	if (0 >= (phone = devman_device_connect(handle, IPC_FLAG_BLOCKING))) {
+		printf(NAME ": could not connect to the device, errno = %d.\n", -res);
+		devman_hangup_phone(DEVMAN_CLIENT);		
+		return 2;
+	}
+	
+	char *buf = (char *)malloc(cnt+1);
+	if (NULL == buf) {
+		printf(NAME ": failed to allocate the input buffer\n");
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return 3;
+	}
+	
+	int read = read_dev(phone, buf, cnt);
+	if (0 > read) {
+		printf(NAME ": failed read from device, errno = %d.\n", -read);
+		ipc_hangup(phone);
+		devman_hangup_phone(DEVMAN_CLIENT);
+		return 4;
+	}
+	
+	buf[cnt+1] = 0;
+	printf(NAME ": read data: '%s'.", buf);
+	
+	devman_hangup_phone(DEVMAN_CLIENT);
+	ipc_hangup(phone);
+	
+	return 0;
+}
+
 
 /** @}
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 f6584584155369fb64be36eb3432e8a2081ac094)
@@ -38,4 +38,5 @@
 #include <async.h>
 #include <malloc.h>
+#include <stdio.h>
 
 
@@ -46,4 +47,5 @@
 	async_serialize_start();
 	
+	printf("calling interface %d\n", DEV_IFACE_ID(CHAR_DEV_IFACE));
 	aid_t req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_READ_DEV, &answer);
 	
Index: uspace/lib/libc/generic/devman.c
===================================================================
--- uspace/lib/libc/generic/devman.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libc/generic/devman.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -230,4 +230,41 @@
 }
 
+int devman_device_get_handle(const char *pathname, device_handle_t *handle, unsigned int flags)
+{
+	int phone = devman_get_phone(DEVMAN_CLIENT, flags);
+	
+	if (phone < 0)
+		return phone;
+	
+	async_serialize_start();
+	
+	ipc_call_t answer;
+	aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0,
+	    &answer);
+	
+	ipcarg_t retval = async_data_write_start(phone, pathname, str_size(pathname));
+	if (retval != EOK) {
+		async_wait_for(req, NULL);
+		async_serialize_end();
+		return retval;
+	}
+	
+	async_wait_for(req, &retval);
+	
+	async_serialize_end();
+	
+	if (retval != EOK) {
+		if (handle != NULL)
+			*handle = (device_handle_t) -1;
+		return retval;
+	}
+	
+	if (handle != NULL)
+		*handle = (device_handle_t) IPC_GET_ARG1(answer);
+	
+	return retval;
+}
+
+
 /** @}
  */
Index: uspace/lib/libc/include/devman.h
===================================================================
--- uspace/lib/libc/include/devman.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libc/include/devman.h	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -51,4 +51,6 @@
 int devman_parent_device_connect(device_handle_t handle, unsigned int flags);
 
+int devman_device_get_handle(const char *pathname, device_handle_t *handle, unsigned int flags);
+
 
 #endif
Index: uspace/lib/libc/include/ipc/devman.h
===================================================================
--- uspace/lib/libc/include/ipc/devman.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libc/include/ipc/devman.h	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -138,4 +138,8 @@
 } devman_to_driver_t;
 
+typedef enum {
+	DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD
+} client_to_devman_t;
+
 #endif
 
Index: uspace/lib/libdrv/generic/driver.c
===================================================================
--- uspace/lib/libdrv/generic/driver.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libdrv/generic/driver.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -254,5 +254,5 @@
 			if (!is_valid_iface_idx(iface_idx)) {
 				// this is not device's interface
-				printf("%s: driver_connection_gen error - invalid interface id %x.", driver->name, method);
+				printf("%s: driver_connection_gen error - invalid interface id %d.", driver->name, iface_idx);
 				ipc_answer_0(callid, ENOTSUP);
 				break;
@@ -265,5 +265,5 @@
 			if (NULL == iface) {
 				printf("%s: driver_connection_gen error - ", driver->name);
-				printf("device with handle %x has no interface with id %x.\n", handle, method);
+				printf("device with handle %d has no interface with id %d.\n", handle, iface_idx);
 				ipc_answer_0(callid, ENOTSUP);
 				break;
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 f6584584155369fb64be36eb3432e8a2081ac094)
@@ -56,14 +56,17 @@
 
 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
+		ipc_answer_0(callid, EINVAL);
+		return;
+	}
+	
+	if (!char_iface->read) {
+		async_data_read_finalize(callid, NULL, 0);
+		ipc_answer_0(callid, ENOTSUP);
 		return;
 	}
Index: uspace/lib/libdrv/include/driver.h
===================================================================
--- uspace/lib/libdrv/include/driver.h	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/lib/libdrv/include/driver.h	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -163,5 +163,7 @@
 {
 	assert(is_valid_iface_idx(idx));	
-
+	if (NULL == dev->class) {
+		return NULL;
+	}
 	return dev->class->interfaces[idx];	
 }
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/srv/devman/devman.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -679,4 +679,5 @@
 {
 	node_t *dev = tree->root_node;
+	// relative path to the device from its parent (but with '/' at the beginning)
 	char *rel_path = path;
 	char *next_path_elem = NULL;
@@ -685,5 +686,5 @@
 	
 	while (cont && NULL != dev) {		
-		next_path_elem  = get_path_elem_end(rel_path+1);		
+		next_path_elem  = get_path_elem_end(rel_path + 1);		
 		if ('/' == next_path_elem[0]) {
 			cont = true;
@@ -693,7 +694,8 @@
 		}
 		
-		dev = find_node_child(dev, rel_path);		
+		dev = find_node_child(dev, rel_path + 1);		
 		
 		if (cont) {
+			// restore the original path
 			next_path_elem[0] = '/';
 		}
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/srv/devman/main.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -291,4 +291,56 @@
 }
 
+/** Find handle for the device instance identified by the device's path in the device tree.
+ */
+static void devman_device_get_handle(ipc_callid_t iid, ipc_call_t *icall)
+{
+	char *pathname;
+	
+	/* Get fqdn */
+	int rc = async_string_receive(&pathname, 0, NULL);
+	if (rc != EOK) {
+		ipc_answer_0(iid, rc);
+		return;
+	}
+	
+	node_t * dev = find_dev_node_by_path(&device_tree, pathname); 
+	
+	free(pathname);
+
+	if (NULL == dev) {
+		ipc_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	ipc_answer_1(iid, EOK, dev->handle);
+}
+
+
+/** Function for handling connections from a client to the device manager.
+ */
+static void devman_connection_client(ipc_callid_t iid, ipc_call_t *icall)
+{
+	/* Accept connection */
+	ipc_answer_0(iid, EOK);
+	
+	bool cont = true;
+	while (cont) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			cont = false;
+			continue;
+		case DEVMAN_DEVICE_GET_HANDLE:
+			devman_device_get_handle(callid, &call);
+			break;
+		default:
+			if (!(callid & IPC_CALLID_NOTIFICATION))
+				ipc_answer_0(callid, ENOENT);
+		}
+	}	
+}
+
 static void devman_forward(ipc_callid_t iid, ipc_call_t *icall, bool drv_to_parent) {	
 	
@@ -346,7 +398,7 @@
 		devman_connection_driver(iid, icall);
 		break;
-	/*case DEVMAN_CLIENT:
-		devmap_connection_client(iid, icall);
-		break;*/
+	case DEVMAN_CLIENT:
+		devman_connection_client(iid, icall);
+		break;
 	case DEVMAN_CONNECT_TO_DEVICE:
 		// Connect client to selected device
Index: uspace/srv/drivers/serial/serial.c
===================================================================
--- uspace/srv/drivers/serial/serial.c	(revision 25a7e11d68ec284b83b483e3d4e486419ef52218)
+++ uspace/srv/drivers/serial/serial.c	(revision f6584584155369fb64be36eb3432e8a2081ac094)
@@ -53,4 +53,5 @@
 
 #include <driver.h>
+#include <char.h>
 #include <resource.h>
 
@@ -91,5 +92,23 @@
 }
 
+static int serial_read(device_t *dev, char *buf, size_t count) 
+{
+	printf(NAME ": serial_read %s\n", dev->name);
+	// TODO
+	return 0;
+}
+
+static int serial_write(device_t *dev, char *buf, size_t count) 
+{
+	// TODO
+	return 0;
+}
+
 static device_class_t serial_dev_class;
+
+static char_iface_t serial_char_iface = {
+	.read = &serial_read,
+	.write = &serial_write
+};
 
 static int serial_add_device(device_t *dev);
@@ -377,5 +396,7 @@
 		serial_unregister_interrupt_handler(dev);
 		return res;
-	}		
+	}	
+	
+	dev->class = &serial_dev_class;
 	
 	printf(NAME ": the %s device has been successfully initialized.\n", dev->name);
@@ -440,4 +461,6 @@
 	serial_dev_class.open = &serial_open;
 	serial_dev_class.close = &serial_close;	
+	
+	serial_dev_class.interfaces[CHAR_DEV_IFACE] = &serial_char_iface;
 }
 
