Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/i8042/i8042.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -39,5 +39,4 @@
  */
 
-#include <devman.h>
 #include <device/hw_res.h>
 #include <ddi.h>
@@ -140,4 +139,10 @@
 };
 
+/** 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)
@@ -159,8 +164,5 @@
     ipc_call_t *call)
 {
-	if ((!dev) || (!dev->driver_data))
-		return;
-	
-	i8042_t *controller = dev->driver_data;
+	i8042_t *controller = dev_i8042(dev);
 	
 	const uint8_t status = IPC_GET_ARG1(*call);
@@ -188,40 +190,49 @@
     int irq_mouse, ddf_dev_t *ddf_dev)
 {
-	assert(ddf_dev);
-	assert(dev);
-	
-	if (reg_size < sizeof(i8042_regs_t))
-		return EINVAL;
-	
-	if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0)
-		return -1;
+	const size_t range_count = sizeof(i8042_ranges) /
+	    sizeof(irq_pio_range_t);
+	irq_pio_range_t ranges[range_count];
+	const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
+	irq_cmd_t cmds[cmd_count];
+
+	int rc;
+	bool kbd_bound = false;
+	bool aux_bound = false;
+
+	dev->kbd_fun = NULL;
+	dev->aux_fun = NULL;
+	
+	if (reg_size < sizeof(i8042_regs_t)) {
+		rc = EINVAL;
+		goto error;
+	}
+	
+	if (pio_enable(regs, sizeof(i8042_regs_t), (void **) &dev->regs) != 0) {
+		rc = EIO;
+		goto error;
+	}
 	
 	dev->kbd_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2a");
-	if (!dev->kbd_fun)
-		return ENOMEM;
-	
-	int ret = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
-	if (ret != EOK) {
-		ddf_fun_destroy(dev->kbd_fun);
-		return ret;
-	}
+	if (dev->kbd_fun == NULL) {
+		rc = ENOMEM;
+		goto error;
+	};
+	
+	rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90);
+	if (rc != EOK)
+		goto error;
 	
 	dev->aux_fun = ddf_fun_create(ddf_dev, fun_inner, "ps2b");
-	if (!dev->aux_fun) {
-		ddf_fun_destroy(dev->kbd_fun);
-		return ENOMEM;
-	}
-	
-	ret = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90);
-	if (ret != EOK) {
-		ddf_fun_destroy(dev->kbd_fun);
-		ddf_fun_destroy(dev->aux_fun);
-		return ret;
-	}
-	
-	dev->kbd_fun->ops = &ops;
-	dev->aux_fun->ops = &ops;
-	dev->kbd_fun->driver_data = dev;
-	dev->aux_fun->driver_data = dev;
+	if (dev->aux_fun == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+	
+	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);
 	
 	buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE);
@@ -229,11 +240,19 @@
 	fibril_mutex_initialize(&dev->write_guard);
 	
-	ret = ddf_fun_bind(dev->kbd_fun);
-	CHECK_RET_DESTROY(ret, "Failed to bind keyboard function: %s.",
-	    str_error(ret));
-	
-	ret = ddf_fun_bind(dev->aux_fun);
-	CHECK_RET_DESTROY(ret, "Failed to bind mouse function: %s.",
-	    str_error(ret));
+	rc = ddf_fun_bind(dev->kbd_fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to bind keyboard function: %s.",
+		    ddf_fun_get_name(dev->kbd_fun));
+		goto error;
+	}
+	kbd_bound = true;
+	
+	rc = ddf_fun_bind(dev->aux_fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to bind aux function: %s.",
+		    ddf_fun_get_name(dev->aux_fun));
+		goto error;
+	}
+	aux_bound = true;
 	
 	/* Disable kbd and aux */
@@ -247,12 +266,7 @@
 		(void) pio_read_8(&dev->regs->data);
 
-	const size_t range_count = sizeof(i8042_ranges) /
-	    sizeof(irq_pio_range_t);
-	irq_pio_range_t ranges[range_count];
 	memcpy(ranges, i8042_ranges, sizeof(i8042_ranges));
 	ranges[0].base = (uintptr_t) regs;
 
-	const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
-	irq_cmd_t cmds[cmd_count];
 	memcpy(cmds, i8042_cmds, sizeof(i8042_cmds));
 	cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status);
@@ -266,25 +280,31 @@
 	};
 	
-	ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
+	rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
 	    &irq_code);
-	CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for kbd: %s.",
-	    str_error(ret));
-	
-	ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.",
+		    ddf_dev_get_name(ddf_dev));
+		goto error;
+	}
+	
+	rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
 	    &irq_code);
-	CHECK_RET_UNBIND_DESTROY(ret, "Failed set handler for mouse: %s.",
-	    str_error(ret));
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.",
+		    ddf_dev_get_name(ddf_dev));
+		goto error;
+	}
 	
 	/* Enable interrupts */
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, ddf_dev->handle,
-	    IPC_FLAG_BLOCKING);
-	ret = parent_sess ? EOK : ENOMEM;
-	CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection.");
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(ddf_dev);
+	assert(parent_sess != NULL);
 	
 	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-	ret = enabled ? EOK : EIO;
-	CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.");
+	if (!enabled) {
+		log_msg(LVL_ERROR, "Failed to enable interrupts: %s.",
+		    ddf_dev_get_name(ddf_dev));
+		rc = EIO;
+		goto error;
+	}
 	
 	/* Enable port interrupts. */
@@ -296,4 +316,15 @@
 	
 	return EOK;
+error:
+	if (kbd_bound)
+		ddf_fun_unbind(dev->kbd_fun);
+	if (aux_bound)
+		ddf_fun_unbind(dev->aux_fun);
+	if (dev->kbd_fun != NULL)
+		ddf_fun_destroy(dev->kbd_fun);
+	if (dev->aux_fun != NULL)
+		ddf_fun_destroy(dev->aux_fun);
+
+	return rc;
 }
 
@@ -315,8 +346,5 @@
 static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size)
 {
-	assert(fun);
-	assert(fun->driver_data);
-	
-	i8042_t *controller = fun->driver_data;
+	i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun));
 	fibril_mutex_lock(&controller->write_guard);
 	
@@ -347,8 +375,5 @@
 static int i8042_read(ddf_fun_t *fun, char *data, size_t size)
 {
-	assert(fun);
-	assert(fun->driver_data);
-	
-	i8042_t *controller = fun->driver_data;
+	i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun));
 	buffer_t *buffer = (fun == controller->aux_fun) ?
 	    &controller->aux_buffer : &controller->kbd_buffer;
Index: uspace/drv/char/i8042/main.c
===================================================================
--- uspace/drv/char/i8042/main.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/i8042/main.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -37,5 +37,4 @@
 #include <libarch/inttypes.h>
 #include <ddf/driver.h>
-#include <devman.h>
 #include <device/hw_res_parsed.h>
 #include <errno.h>
@@ -64,13 +63,12 @@
  *
  */
-static int get_my_registers(const ddf_dev_t *dev, uintptr_t *io_reg_address,
+static int get_my_registers(ddf_dev_t *dev, uintptr_t *io_reg_address,
     size_t *io_reg_size, int *kbd_irq, int *mouse_irq)
 {
 	assert(dev);
 	
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
+	async_sess_t *parent_sess = ddf_dev_parent_sess_create(
+	    dev, EXCHANGE_SERIALIZE);
+	if (parent_sess == NULL)
 		return ENOMEM;
 	
@@ -78,5 +76,4 @@
 	hw_res_list_parsed_init(&hw_resources);
 	const int ret = hw_res_get_list_parsed(parent_sess, &hw_resources, 0);
-	async_hangup(parent_sess);
 	if (ret != EOK)
 		return ret;
@@ -136,5 +133,5 @@
 	
 	ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
-	    device->name, device->handle);
+	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
 	return EOK;
 }
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/ns8250/ns8250.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -58,7 +58,5 @@
 #include <ops/char_dev.h>
 
-#include <devman.h>
 #include <ns.h>
-#include <ipc/devman.h>
 #include <ipc/services.h>
 #include <ipc/irc.h>
@@ -127,10 +125,4 @@
 #define	NS8250_MSR_SIGNALS	(NS8250_MSR_CTS | NS8250_MSR_DSR \
     | NS8250_MSR_RI | NS8250_MSR_DCD)
-
-/** Obtain soft-state structure from function node */
-#define NS8250(fnode) ((ns8250_t *) ((fnode)->dev->driver_data))
-
-/** Obtain soft-state structure from device node */
-#define NS8250_FROM_DEV(dnode) ((ns8250_t *) ((dnode)->driver_data))
 
 /** The number of bits of one data unit send by the serial port. */
@@ -187,4 +179,16 @@
 } ns8250_t;
 
+/** Obtain soft-state structure from device node */
+static ns8250_t *dev_ns8250(ddf_dev_t *dev)
+{
+	return ddf_dev_data_get(dev);
+}
+
+/** Obtain soft-state structure from function node */
+static ns8250_t *fun_ns8250(ddf_fun_t *fun)
+{
+	return dev_ns8250(ddf_fun_get_dev(fun));
+}
+
 /** Find out if there is some incomming data available on the serial port.
  *
@@ -241,5 +245,5 @@
 static int ns8250_read(ddf_fun_t *fun, char *buf, size_t count)
 {
-	ns8250_t *ns = NS8250(fun);
+	ns8250_t *ns = fun_ns8250(fun);
 	int ret = 0;
 	
@@ -279,5 +283,5 @@
 static int ns8250_write(ddf_fun_t *fun, char *buf, size_t count)
 {
-	ns8250_t *ns = NS8250(fun);
+	ns8250_t *ns = fun_ns8250(fun);
 	size_t idx;
 	
@@ -317,8 +321,4 @@
 static void ns8250_dev_cleanup(ns8250_t *ns)
 {
-	if (ns->dev->parent_sess) {
-		async_hangup(ns->dev->parent_sess);
-		ns->dev->parent_sess = NULL;
-	}
 }
 
@@ -330,5 +330,5 @@
 static bool ns8250_pio_enable(ns8250_t *ns)
 {
-	ddf_msg(LVL_DEBUG, "ns8250_pio_enable %s", ns->dev->name);
+	ddf_msg(LVL_DEBUG, "ns8250_pio_enable %s", ddf_dev_get_name(ns->dev));
 	
 	/* Gain control over port's registers. */
@@ -336,5 +336,5 @@
 	    (void **) &ns->port)) {
 		ddf_msg(LVL_ERROR, "Cannot map the port %#" PRIx32
-		    " for device %s.", ns->io_addr, ns->dev->name);
+		    " for device %s.", ns->io_addr, ddf_dev_get_name(ns->dev));
 		return false;
 	}
@@ -352,5 +352,5 @@
 static bool ns8250_dev_probe(ns8250_t *ns)
 {
-	ddf_msg(LVL_DEBUG, "ns8250_dev_probe %s", ns->dev->name);
+	ddf_msg(LVL_DEBUG, "ns8250_dev_probe %s", ddf_dev_get_name(ns->dev));
 	
 	bool res = true;
@@ -372,5 +372,5 @@
 	if (!res) {
 		ddf_msg(LVL_DEBUG, "Device %s is not present.",
-		    ns->dev->name);
+		    ddf_dev_get_name(ns->dev));
 	}
 	
@@ -385,7 +385,8 @@
 static int ns8250_dev_initialize(ns8250_t *ns)
 {
-	ddf_msg(LVL_DEBUG, "ns8250_dev_initialize %s", ns->dev->name);
-	
+	async_sess_t *parent_sess;
 	int ret = EOK;
+	
+	ddf_msg(LVL_DEBUG, "ns8250_dev_initialize %s", ddf_dev_get_name(ns->dev));
 	
 	hw_resource_list_t hw_resources;
@@ -393,9 +394,8 @@
 	
 	/* Connect to the parent's driver. */
-	ns->dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
-	    ns->dev->handle, IPC_FLAG_BLOCKING);
-	if (!ns->dev->parent_sess) {
+	parent_sess = ddf_dev_parent_sess_create(ns->dev, EXCHANGE_SERIALIZE);
+	if (parent_sess == NULL) {
 		ddf_msg(LVL_ERROR, "Failed to connect to parent driver of "
-		    "device %s.", ns->dev->name);
+		    "device %s.", ddf_dev_get_name(ns->dev));
 		ret = ENOENT;
 		goto failed;
@@ -403,8 +403,8 @@
 	
 	/* Get hw resources. */
-	ret = hw_res_get_resource_list(ns->dev->parent_sess, &hw_resources);
+	ret = hw_res_get_resource_list(parent_sess, &hw_resources);
 	if (ret != EOK) {
 		ddf_msg(LVL_ERROR, "Failed to get HW resources for device "
-		    "%s.", ns->dev->name);
+		    "%s.", ddf_dev_get_name(ns->dev));
 		goto failed;
 	}
@@ -422,5 +422,5 @@
 			irq = true;
 			ddf_msg(LVL_NOTE, "Device %s was asigned irq = 0x%x.",
-			    ns->dev->name, ns->irq);
+			    ddf_dev_get_name(ns->dev), ns->irq);
 			break;
 			
@@ -429,5 +429,5 @@
 			if (res->res.io_range.size < REG_COUNT) {
 				ddf_msg(LVL_ERROR, "I/O range assigned to "
-				    "device %s is too small.", ns->dev->name);
+				    "device %s is too small.", ddf_dev_get_name(ns->dev));
 				ret = ELIMIT;
 				goto failed;
@@ -435,5 +435,5 @@
 			ioport = true;
 			ddf_msg(LVL_NOTE, "Device %s was asigned I/O address = "
-			    "0x%x.", ns->dev->name, ns->io_addr);
+			    "0x%x.", ddf_dev_get_name(ns->dev), ns->io_addr);
     			break;
 			
@@ -445,5 +445,5 @@
 	if (!irq || !ioport) {
 		ddf_msg(LVL_ERROR, "Missing HW resource(s) for device %s.",
-		    ns->dev->name);
+		    ddf_dev_get_name(ns->dev));
 		ret = ENOENT;
 		goto failed;
@@ -613,4 +613,7 @@
 	*parity = ((val >> NS8250_LCR_PARITY) & 7);
 	
+	/* Silence warnings */
+	*word_length = 0;
+
 	switch (val & 3) {
 	case WORD_LENGTH_5:
@@ -755,10 +758,10 @@
 				if (!buf_push_back(&ns->input_buffer, val)) {
 					ddf_msg(LVL_WARN, "Buffer overflow on "
-					    "%s.", ns->dev->name);
+					    "%s.", ddf_dev_get_name(ns->dev));
 					break;
 				} else {
 					ddf_msg(LVL_DEBUG2, "Character %c saved "
 					    "to the buffer of %s.",
-					    val, ns->dev->name);
+					    val, ddf_dev_get_name(ns->dev));
 					if (buf_was_empty)
 						fibril_condvar_broadcast(&ns->input_buffer_available);
@@ -782,5 +785,5 @@
     ipc_call_t *icall)
 {
-	ns8250_t *ns = NS8250_FROM_DEV(dev);
+	ns8250_t *ns = dev_ns8250(dev);
 
 	uint8_t iir = pio_read_8(&ns->regs->iid);
@@ -788,5 +791,5 @@
 		uint8_t lsr = pio_read_8(&ns->regs->lsr);
 		if (lsr & NS8250_LSR_OE) {
-			ddf_msg(LVL_WARN, "Overrun error on %s", ns->dev->name);
+			ddf_msg(LVL_WARN, "Overrun error on %s", ddf_dev_get_name(ns->dev));
 		}
 	}
@@ -828,5 +831,5 @@
 	
 	ddf_msg(LVL_DEBUG, "ns8250_dev_add %s (handle = %d)",
-	    dev->name, (int) dev->handle);
+	    ddf_dev_get_name(dev), (int) ddf_dev_get_handle(dev));
 	
 	/* Allocate soft-state for the device */
@@ -883,5 +886,5 @@
 	
 	/* Set device operations. */
-	fun->ops = &ns8250_dev_ops;
+	ddf_fun_set_ops(fun, &ns8250_dev_ops);
 	rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
@@ -895,5 +898,5 @@
 	
 	ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
-	    dev->name);
+	    ddf_dev_get_name(dev));
 	
 	return EOK;
@@ -908,5 +911,5 @@
 static int ns8250_dev_remove(ddf_dev_t *dev)
 {
-	ns8250_t *ns = NS8250_FROM_DEV(dev);
+	ns8250_t *ns = dev_ns8250(dev);
 	int rc;
 	
@@ -942,5 +945,5 @@
 static int ns8250_open(ddf_fun_t *fun)
 {
-	ns8250_t *ns = NS8250(fun);
+	ns8250_t *ns = fun_ns8250(fun);
 	int res;
 	
@@ -968,5 +971,5 @@
 static void ns8250_close(ddf_fun_t *fun)
 {
-	ns8250_t *data = (ns8250_t *) fun->dev->driver_data;
+	ns8250_t *data = fun_ns8250(fun);
 	
 	fibril_mutex_lock(&data->mutex);
@@ -993,5 +996,5 @@
     unsigned int *word_length, unsigned int* stop_bits)
 {
-	ns8250_t *data = (ns8250_t *) dev->driver_data;
+	ns8250_t *data = dev_ns8250(dev);
 	ns8250_regs_t *regs = data->regs;
 	
@@ -1024,5 +1027,5 @@
 	    stop_bits);
 	
-	ns8250_t *data = (ns8250_t *) dev->driver_data;
+	ns8250_t *data = dev_ns8250(dev);
 	ns8250_regs_t *regs = data->regs;
 	int ret;
@@ -1053,5 +1056,5 @@
 	switch (method) {
 	case SERIAL_GET_COM_PROPS:
-		ns8250_get_props(fun->dev, &baud_rate, &parity, &word_length,
+		ns8250_get_props(ddf_fun_get_dev(fun), &baud_rate, &parity, &word_length,
 		    &stop_bits);
 		async_answer_4(callid, EOK, baud_rate, parity, word_length,
@@ -1064,5 +1067,5 @@
 		word_length = IPC_GET_ARG3(*call);
 		stop_bits = IPC_GET_ARG4(*call);
-		ret = ns8250_set_props(fun->dev, baud_rate, parity, word_length,
+		ret = ns8250_set_props(ddf_fun_get_dev(fun), baud_rate, parity, word_length,
 		    stop_bits);
 		async_answer_0(callid, ret);
Index: uspace/drv/char/ps2mouse/main.c
===================================================================
--- uspace/drv/char/ps2mouse/main.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/ps2mouse/main.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -98,5 +98,5 @@
 
 	ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
-	    device->name, device->handle);
+	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
 	return EOK;
 }
Index: uspace/drv/char/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/char/ps2mouse/ps2mouse.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/ps2mouse/ps2mouse.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -35,5 +35,4 @@
 #include <bool.h>
 #include <errno.h>
-#include <devman.h>
 #include <ddf/log.h>
 #include <io/keycode.h>
@@ -114,9 +113,6 @@
 int ps2_mouse_init(ps2_mouse_t *mouse, ddf_dev_t *dev)
 {
-	assert(mouse);
-	assert(dev);
 	mouse->client_sess = NULL;
-	mouse->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
-	    dev->handle, IPC_FLAG_BLOCKING);
+	mouse->parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
 	if (!mouse->parent_sess)
 		return ENOMEM;
@@ -124,14 +120,10 @@
 	mouse->mouse_fun = ddf_fun_create(dev, fun_exposed, "mouse");
 	if (!mouse->mouse_fun) {
-		async_hangup(mouse->parent_sess);
-		return ENOMEM;
-	}
-	mouse->mouse_fun->ops = &mouse_ops;
-	mouse->mouse_fun->driver_data = mouse;
+		return ENOMEM;
+	}
+	ddf_fun_set_ops(mouse->mouse_fun, &mouse_ops);
 
 	int ret = ddf_fun_bind(mouse->mouse_fun);
 	if (ret != EOK) {
-		async_hangup(mouse->parent_sess);
-		mouse->mouse_fun->driver_data = NULL;
 		ddf_fun_destroy(mouse->mouse_fun);
 		return ENOMEM;
@@ -140,7 +132,5 @@
 	ret = ddf_fun_add_to_category(mouse->mouse_fun, "mouse");
 	if (ret != EOK) {
-		async_hangup(mouse->parent_sess);
 		ddf_fun_unbind(mouse->mouse_fun);
-		mouse->mouse_fun->driver_data = NULL;
 		ddf_fun_destroy(mouse->mouse_fun);
 		return ENOMEM;
@@ -161,7 +151,5 @@
 		ddf_msg(LVL_ERROR, "Failed to enable data reporting.");
 		async_exchange_end(exch);
-		async_hangup(mouse->parent_sess);
 		ddf_fun_unbind(mouse->mouse_fun);
-		mouse->mouse_fun->driver_data = NULL;
 		ddf_fun_destroy(mouse->mouse_fun);
 		return EIO;
@@ -173,7 +161,5 @@
 		ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.",
 		    report);
-		async_hangup(mouse->parent_sess);
 		ddf_fun_unbind(mouse->mouse_fun);
-		mouse->mouse_fun->driver_data = NULL;
 		ddf_fun_destroy(mouse->mouse_fun);
 		return EIO;
@@ -182,7 +168,5 @@
 	mouse->polling_fibril = fibril_create(polling_f, mouse);
 	if (!mouse->polling_fibril) {
-		async_hangup(mouse->parent_sess);
 		ddf_fun_unbind(mouse->mouse_fun);
-		mouse->mouse_fun->driver_data = NULL;
 		ddf_fun_destroy(mouse->mouse_fun);
 		return ENOMEM;
@@ -368,12 +352,6 @@
     ipc_callid_t icallid, ipc_call_t *icall)
 {
-	if (fun == NULL || fun->driver_data == NULL) {
-		ddf_msg(LVL_ERROR, "%s: Missing parameter.", __FUNCTION__);
-		async_answer_0(icallid, EINVAL);
-		return;
-	}
-
 	const sysarg_t method = IPC_GET_IMETHOD(*icall);
-	ps2_mouse_t *mouse = fun->driver_data;
+	ps2_mouse_t *mouse = ddf_dev_data_get(ddf_fun_get_dev(fun));
 
 	switch (method) {
Index: uspace/drv/char/xtkbd/main.c
===================================================================
--- uspace/drv/char/xtkbd/main.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/xtkbd/main.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -98,5 +98,5 @@
 
 	ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
-	    device->name, device->handle);
+	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
 	return EOK;
 }
Index: uspace/drv/char/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/char/xtkbd/xtkbd.c	(revision c92e30fd4c782868f0f4d1b8087da611f1efa90a)
+++ uspace/drv/char/xtkbd/xtkbd.c	(revision 6f445a67491000572da4fa7897f93fdff426b03f)
@@ -34,5 +34,4 @@
 
 #include <errno.h>
-#include <devman.h>
 #include <ddf/log.h>
 #include <io/keycode.h>
@@ -207,6 +206,5 @@
 	assert(dev);
 	kbd->client_sess = NULL;
-	kbd->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
-	    dev->handle, IPC_FLAG_BLOCKING);
+	kbd->parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
 	if (!kbd->parent_sess)
 		return ENOMEM;
@@ -214,14 +212,10 @@
 	kbd->kbd_fun = ddf_fun_create(dev, fun_exposed, "kbd");
 	if (!kbd->kbd_fun) {
-		async_hangup(kbd->parent_sess);
-		return ENOMEM;
-	}
-	kbd->kbd_fun->ops = &kbd_ops;
-	kbd->kbd_fun->driver_data = kbd;
+		return ENOMEM;
+	}
+	ddf_fun_set_ops(kbd->kbd_fun, &kbd_ops);
 
 	int ret = ddf_fun_bind(kbd->kbd_fun);
 	if (ret != EOK) {
-		async_hangup(kbd->parent_sess);
-		kbd->kbd_fun->driver_data = NULL;
 		ddf_fun_destroy(kbd->kbd_fun);
 		return ENOMEM;
@@ -230,7 +224,5 @@
 	ret = ddf_fun_add_to_category(kbd->kbd_fun, "keyboard");
 	if (ret != EOK) {
-		async_hangup(kbd->parent_sess);
 		ddf_fun_unbind(kbd->kbd_fun);
-		kbd->kbd_fun->driver_data = NULL;
 		ddf_fun_destroy(kbd->kbd_fun);
 		return ENOMEM;
@@ -239,7 +231,5 @@
 	kbd->polling_fibril = fibril_create(polling, kbd);
 	if (!kbd->polling_fibril) {
-		async_hangup(kbd->parent_sess);
 		ddf_fun_unbind(kbd->kbd_fun);
-		kbd->kbd_fun->driver_data = NULL;
 		ddf_fun_destroy(kbd->kbd_fun);
 		return ENOMEM;
@@ -319,12 +309,6 @@
     ipc_callid_t icallid, ipc_call_t *icall)
 {
-	if (fun == NULL || fun->driver_data == NULL) {
-		ddf_msg(LVL_ERROR, "%s: Missing parameter.", __FUNCTION__);
-		async_answer_0(icallid, EINVAL);
-		return;
-	}
-
 	const sysarg_t method = IPC_GET_IMETHOD(*icall);
-	xt_kbd_t *kbd = fun->driver_data;
+	xt_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));
 
 	switch (method) {
