Index: uspace/drv/hid/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/hid/xtkbd/xtkbd.c	(revision d420b22fe09893c1b4117473e6787a4295055001)
+++ uspace/drv/hid/xtkbd/xtkbd.c	(revision 15c5418e4090a071bc8da1b205870222f20e574e)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2017 Jiri Svoboda
  * All rights reserved.
  *
@@ -206,20 +207,12 @@
 static int polling(void *arg)
 {
-	const xt_kbd_t *kbd = arg;
-	
-	assert(kbd);
-	assert(kbd->parent_sess);
-	
-	async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess);
+	xt_kbd_t *kbd = arg;
 	
 	while (true) {
-		if (!parent_exch)
-			parent_exch = async_exchange_begin(kbd->parent_sess);
-		
 		const unsigned int *map = scanmap_simple;
 		size_t map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
 		
 		uint8_t code = 0;
-		ssize_t size = chardev_read(parent_exch, &code, 1);
+		ssize_t size = chardev_read(kbd->chardev, &code, 1);
 		if (size != 1)
 			return EIO;
@@ -234,5 +227,5 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 			
-			size = chardev_read(parent_exch, &code, 1);
+			size = chardev_read(kbd->chardev, &code, 1);
 			if (size != 1)
 				return EIO;
@@ -241,5 +234,5 @@
 			
 			if (code == 0x2a) {  /* Print Screen */
-				size = chardev_read(parent_exch, &code, 1);
+				size = chardev_read(kbd->chardev, &code, 1);
 				if (size != 1)
 					return EIO;
@@ -248,5 +241,5 @@
 					continue;
 				
-				size = chardev_read(parent_exch, &code, 1);
+				size = chardev_read(kbd->chardev, &code, 1);
 				if (size != 1)
 					return EIO;
@@ -259,5 +252,5 @@
 			
 			if (code == 0x46) {  /* Break */
-				size = chardev_read(parent_exch, &code, 1);
+				size = chardev_read(kbd->chardev, &code, 1);
 				if (size != 1)
 					return EIO;
@@ -266,5 +259,5 @@
 					continue;
 				
-				size = chardev_read(parent_exch, &code, 1);
+				size = chardev_read(kbd->chardev, &code, 1);
 				if (size != 1)
 					return EIO;
@@ -279,5 +272,5 @@
 		/* Extended special set */
 		if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			size = chardev_read(parent_exch, &code, 1);
+			size = chardev_read(kbd->chardev, &code, 1);
 			if (size != 1)
 				return EIO;
@@ -286,5 +279,5 @@
 				continue;
 			
-			size = chardev_read(parent_exch, &code, 1);
+			size = chardev_read(kbd->chardev, &code, 1);
 			if (size != 1)
 				return EIO;
@@ -293,5 +286,5 @@
 				continue;
 			
-			size = chardev_read(parent_exch, &code, 1);
+			size = chardev_read(kbd->chardev, &code, 1);
 			if (size != 1)
 				return EIO;
@@ -300,5 +293,5 @@
 				continue;
 			
-			size = chardev_read(parent_exch, &code, 1);
+			size = chardev_read(kbd->chardev, &code, 1);
 			if (size != 1)
 				return EIO;
@@ -307,5 +300,5 @@
 				continue;
 			
-			size = chardev_read(parent_exch, &code, 1);
+			size = chardev_read(kbd->chardev, &code, 1);
 			if (size != 1)
 				return EIO;
@@ -357,7 +350,5 @@
 		uint8_t cmds[] = { KBD_CMD_SET_LEDS, status };
 		
-		async_exch_t *exch = async_exchange_begin(kbd->parent_sess);
-		const ssize_t size = chardev_write(exch, cmds, sizeof(cmds));
-		async_exchange_end(exch);
+		ssize_t size = chardev_write(kbd->chardev, cmds, sizeof(cmds));
 		
 		async_answer_0(icallid, size < 0 ? size : EOK);
@@ -413,48 +404,60 @@
 int xt_kbd_init(xt_kbd_t *kbd, ddf_dev_t *dev)
 {
-	assert(kbd);
-	assert(dev);
+	async_sess_t *parent_sess;
+	bool bound = false;
+	int rc;
 	
 	kbd->client_sess = NULL;
-	kbd->parent_sess = ddf_dev_parent_sess_get(dev);
-	
-	if (!kbd->parent_sess) {
+	
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL) {
 		ddf_msg(LVL_ERROR, "Failed creating parent session.");
-		return EIO;
+		rc = EIO;
+		goto error;
+	}
+	
+	rc = chardev_open(parent_sess, &kbd->chardev);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed opening character device.");
+		goto error;
 	}
 	
 	kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd");
-	if (!kbd->kbd_fun) {
+	if (kbd->kbd_fun == NULL) {
 		ddf_msg(LVL_ERROR, "Failed creating function 'kbd'.");
-		return ENOMEM;
+		rc = ENOMEM;
+		goto error;
 	}
 	
 	ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops);
 	
-	int ret = ddf_fun_bind(kbd->kbd_fun);
-	if (ret != EOK) {
+	rc = ddf_fun_bind(kbd->kbd_fun);
+	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed binding function 'kbd'.");
-		ddf_fun_destroy(kbd->kbd_fun);
-		return EEXIST;
-	}
-	
-	ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard");
-	if (ret != EOK) {
+		goto error;
+	}
+	
+	rc = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard");
+	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed adding function 'kbd' to category "
 		    "'keyboard'.");
-		ddf_fun_unbind(kbd->kbd_fun);
-		ddf_fun_destroy(kbd->kbd_fun);
-		return ENOMEM;
+		goto error;
 	}
 	
 	kbd->polling_fibril = fibril_create(polling, kbd);
-	if (!kbd->polling_fibril) {
+	if (kbd->polling_fibril == 0) {
 		ddf_msg(LVL_ERROR, "Failed creating polling fibril.");
-		ddf_fun_unbind(kbd->kbd_fun);
-		ddf_fun_destroy(kbd->kbd_fun);
-		return ENOMEM;
+		rc = ENOMEM;
+		goto error;
 	}
 	
 	fibril_add_ready(kbd->polling_fibril);
 	return EOK;
+error:
+	if (bound)
+		ddf_fun_unbind(kbd->kbd_fun);
+	if (kbd->kbd_fun != NULL)
+		ddf_fun_destroy(kbd->kbd_fun);
+	chardev_close(kbd->chardev);
+	return rc;
 }
