Index: uspace/drv/hid/ps2mouse/main.c
===================================================================
--- uspace/drv/hid/ps2mouse/main.c	(revision d420b22fe09893c1b4117473e6787a4295055001)
+++ uspace/drv/hid/ps2mouse/main.c	(revision 15c5418e4090a071bc8da1b205870222f20e574e)
@@ -30,5 +30,5 @@
  */
 /** @file
- * @brief ps/2 mouse driver
+ * @brief PS/2 mouse driver
  */
 
Index: uspace/drv/hid/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/hid/ps2mouse/ps2mouse.c	(revision d420b22fe09893c1b4117473e6787a4295055001)
+++ uspace/drv/hid/ps2mouse/ps2mouse.c	(revision 15c5418e4090a071bc8da1b205870222f20e574e)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2017 Jiri Svoboda
  * All rights reserved.
  *
@@ -30,5 +31,5 @@
  */
 /** @file
- * @brief ps2 mouse driver.
+ * @brief PS/2 mouse driver.
  */
 
@@ -70,9 +71,9 @@
 #define PS2_BUTTON_MASK(button) (1 << button)
 
-#define MOUSE_READ_BYTE_TEST(sess, value_) \
+#define MOUSE_READ_BYTE_TEST(mouse, value_) \
 do { \
 	uint8_t value = (value_); \
 	uint8_t data = 0; \
-	const ssize_t size = chardev_read(sess, &data, 1); \
+	const ssize_t size = chardev_read((mouse)->chardev, &data, 1); \
 	if (size != 1) { \
 		ddf_msg(LVL_ERROR, "Failed reading byte: %zd)", size);\
@@ -86,9 +87,9 @@
 } while (0)
 
-#define MOUSE_WRITE_BYTE(sess, value_) \
+#define MOUSE_WRITE_BYTE(mouse, value_) \
 do { \
 	uint8_t value = (value_); \
 	uint8_t data = (value); \
-	const ssize_t size = chardev_write(sess, &data, 1); \
+	const ssize_t size = chardev_write((mouse)->chardev, &data, 1); \
 	if (size < 0 ) { \
 		ddf_msg(LVL_ERROR, "Failed writing byte: %hhx", value); \
@@ -99,5 +100,5 @@
 static int polling_ps2(void *);
 static int polling_intellimouse(void *);
-static int probe_intellimouse(async_exch_t *, bool);
+static int probe_intellimouse(ps2_mouse_t *, bool);
 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
 
@@ -108,72 +109,101 @@
 
 /** Initialize mouse driver structure.
+ *
+ * Connects to parent, creates keyboard function, starts polling fibril.
+ *
  * @param kbd Mouse driver structure to initialize.
  * @param dev DDF device structure.
  *
- * Connects to parent, creates keyboard function, starts polling fibril.
+ * @return EOK on success or non-zero error code
  */
 int ps2_mouse_init(ps2_mouse_t *mouse, ddf_dev_t *dev)
 {
+	async_sess_t *parent_sess;
+	bool bound = false;
+	int rc;
+
 	mouse->client_sess = NULL;
-	mouse->parent_sess = ddf_dev_parent_sess_get(dev);
-	if (!mouse->parent_sess)
-		return ENOMEM;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL) {
+		ddf_msg(LVL_ERROR, "Failed getting parent session.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = chardev_open(parent_sess, &mouse->chardev);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed opening character device.");
+		goto error;
+	}
 
 	mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse");
-	if (!mouse->mouse_fun) {
-		return ENOMEM;
-	}
+	if (mouse->mouse_fun == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating mouse function.");
+		rc = ENOMEM;
+		goto error;
+	}
+
 	ddf_fun_set_ops(mouse->mouse_fun, &mouse_ops);
 
-	int ret = ddf_fun_bind(mouse->mouse_fun);
-	if (ret != EOK) {
-		ddf_fun_destroy(mouse->mouse_fun);
-		return ENOMEM;
-	}
-
-	ret = ddf_fun_add_to_category(mouse->mouse_fun, "mouse");
-	if (ret != EOK) {
-		ddf_fun_unbind(mouse->mouse_fun);
-		ddf_fun_destroy(mouse->mouse_fun);
-		return ENOMEM;
-	}
+	rc = ddf_fun_bind(mouse->mouse_fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding mouse function.");
+		goto error;
+	}
+
+	bound = true;
+
+	rc = ddf_fun_add_to_category(mouse->mouse_fun, "mouse");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding mouse function to category.");
+		goto error;
+	}
+
 	/* Probe IntelliMouse extensions. */
 	int (*polling_f)(void*) = polling_ps2;
-	async_exch_t *exch = async_exchange_begin(mouse->parent_sess);
-	if (probe_intellimouse(exch, false) == EOK) {
+	if (probe_intellimouse(mouse, false) == EOK) {
 		ddf_msg(LVL_NOTE, "Enabled IntelliMouse extensions");
 		polling_f = polling_intellimouse;
-		if (probe_intellimouse(exch, true) == EOK)
+		if (probe_intellimouse(mouse, true) == EOK)
 			ddf_msg(LVL_NOTE, "Enabled 4th and 5th button.");
 	}
+
 	/* Enable mouse data reporting. */
 	uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
-	ssize_t size = chardev_write(exch, &report, 1);
+	ssize_t size = chardev_write(mouse->chardev, &report, 1);
 	if (size != 1) {
 		ddf_msg(LVL_ERROR, "Failed to enable data reporting.");
-		async_exchange_end(exch);
-		ddf_fun_unbind(mouse->mouse_fun);
-		ddf_fun_destroy(mouse->mouse_fun);
-		return EIO;
-	}
-
-	size = chardev_read(exch, &report, 1);
-	async_exchange_end(exch);
+		rc = EIO;
+		goto error;
+	}
+
+	size = chardev_read(mouse->chardev, &report, 1);
 	if (size != 1 || report != PS2_MOUSE_ACK) {
 		ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.",
 		    report);
-		ddf_fun_unbind(mouse->mouse_fun);
-		ddf_fun_destroy(mouse->mouse_fun);
-		return EIO;
+		rc = EIO;
+		goto error;
 	}
 
 	mouse->polling_fibril = fibril_create(polling_f, mouse);
-	if (!mouse->polling_fibril) {
-		ddf_fun_unbind(mouse->mouse_fun);
-		ddf_fun_destroy(mouse->mouse_fun);
-		return ENOMEM;
-	}
+	if (mouse->polling_fibril == 0) {
+		rc = ENOMEM;
+		goto error;
+	}
+
 	fibril_add_ready(mouse->polling_fibril);
 	return EOK;
+error:
+	if (bound)
+		ddf_fun_unbind(mouse->mouse_fun);
+	if (mouse->mouse_fun != NULL) {
+		ddf_fun_destroy(mouse->mouse_fun);
+		mouse->mouse_fun = NULL;
+	}
+
+	chardev_close(mouse->chardev);
+	mouse->chardev = NULL;
+	return rc;
 }
 
@@ -184,15 +214,11 @@
 int polling_ps2(void *arg)
 {
-	assert(arg);
-	const ps2_mouse_t *mouse = arg;
-
-	assert(mouse->parent_sess);
+	ps2_mouse_t *mouse = (ps2_mouse_t *) arg;
+
 	bool buttons[PS2_BUTTON_COUNT] = {};
-	async_exch_t *parent_exch = async_exchange_begin(mouse->parent_sess);
 	while (1) {
-
 		uint8_t packet[PS2_BUFSIZE] = {};
 		const ssize_t size =
-		    chardev_read(parent_exch, packet, PS2_BUFSIZE);
+		    chardev_read(mouse->chardev, packet, PS2_BUFSIZE);
 
 		if (size != PS2_BUFSIZE) {
@@ -232,5 +258,6 @@
 		async_exchange_end(exch);
 	}
-	async_exchange_end(parent_exch);
+
+	return 0;
 }
 
@@ -241,17 +268,11 @@
 static int polling_intellimouse(void *arg)
 {
-	assert(arg);
-	const ps2_mouse_t *mouse = arg;
-
-	assert(mouse->parent_sess);
+	ps2_mouse_t *mouse = (ps2_mouse_t *) arg;
+
 	bool buttons[INTELLIMOUSE_BUTTON_COUNT] = {};
-	async_exch_t *parent_exch = NULL;
 	while (1) {
-		if (!parent_exch)
-			parent_exch = async_exchange_begin(mouse->parent_sess);
-
 		uint8_t packet[INTELLIMOUSE_BUFSIZE] = {};
 		const ssize_t size = chardev_read(
-		    parent_exch, packet, INTELLIMOUSE_BUFSIZE);
+		    mouse->chardev, packet, INTELLIMOUSE_BUFSIZE);
 
 		if (size != INTELLIMOUSE_BUFSIZE) {
@@ -310,5 +331,6 @@
 		async_exchange_end(exch);
 	}
-	async_exchange_end(parent_exch);
+
+	return 0;
 }
 
@@ -319,26 +341,24 @@
  * See http://www.computer-engineering.org/ps2mouse/ for details.
  */
-static int probe_intellimouse(async_exch_t *exch, bool buttons)
+static int probe_intellimouse(ps2_mouse_t *mouse, bool buttons)
 {
-	assert(exch);
-
-	MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-	MOUSE_WRITE_BYTE(exch, 200);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-
-	MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-	MOUSE_WRITE_BYTE(exch, buttons ? 200 : 100);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-
-	MOUSE_WRITE_BYTE(exch, PS2_MOUSE_SET_SAMPLE_RATE);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-	MOUSE_WRITE_BYTE(exch, 80);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-
-	MOUSE_WRITE_BYTE(exch, PS2_MOUSE_GET_DEVICE_ID);
-	MOUSE_READ_BYTE_TEST(exch, PS2_MOUSE_ACK);
-	MOUSE_READ_BYTE_TEST(exch, buttons ? 4 : 3);
+	MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+	MOUSE_WRITE_BYTE(mouse, 200);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+
+	MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+	MOUSE_WRITE_BYTE(mouse, buttons ? 200 : 100);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+
+	MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_SET_SAMPLE_RATE);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+	MOUSE_WRITE_BYTE(mouse, 80);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+
+	MOUSE_WRITE_BYTE(mouse, PS2_MOUSE_GET_DEVICE_ID);
+	MOUSE_READ_BYTE_TEST(mouse, PS2_MOUSE_ACK);
+	MOUSE_READ_BYTE_TEST(mouse, buttons ? 4 : 3);
 
 	return EOK;
Index: uspace/drv/hid/ps2mouse/ps2mouse.h
===================================================================
--- uspace/drv/hid/ps2mouse/ps2mouse.h	(revision d420b22fe09893c1b4117473e6787a4295055001)
+++ uspace/drv/hid/ps2mouse/ps2mouse.h	(revision 15c5418e4090a071bc8da1b205870222f20e574e)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2017 Jiri Svoboda
  * All rights reserved.
  *
@@ -30,24 +31,30 @@
  */
 /** @file
- * @brief ps/2 mouse driver.
+ * @brief PS/2 mouse driver.
  */
 
-#ifndef _PS2MOUSE_H_
-#define _PS2MOUSE_H_
+#ifndef PS2MOUSE_H_
+#define PS2MOUSE_H_
 
 #include <ddf/driver.h>
 #include <fibril.h>
+#include <io/chardev.h>
 
 /** PS/2 mouse driver structure. */
 typedef struct {
-	ddf_fun_t *mouse_fun;      /**< Mouse function. */
-	async_sess_t *parent_sess; /**< Connection to device providing data. */
-	async_sess_t *client_sess;  /**< Callback connection to client. */
-	fid_t polling_fibril;      /**< Fibril retrieving an parsing data. */
+	/** Mouse function. */
+	ddf_fun_t *mouse_fun;
+	/** Device providing mouse connection */
+	chardev_t *chardev;
+	/** Callback connection to client. */
+	async_sess_t *client_sess;
+	/** Fibril retrieving an parsing data. */
+	fid_t polling_fibril;
 } ps2_mouse_t;
 
-int ps2_mouse_init(ps2_mouse_t *, ddf_dev_t *);
+extern int ps2_mouse_init(ps2_mouse_t *, ddf_dev_t *);
 
 #endif
+
 /**
  * @}
