Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/isa/isa.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -73,10 +73,4 @@
 #define CHILD_FUN_CONF_PATH "/drv/isa/isa.dev"
 
-/** Obtain soft-state from device node */
-#define ISA_BUS(dev) ((isa_bus_t *) ((dev)->driver_data))
-
-/** Obtain soft-state from function node */
-#define ISA_FUN(fun) ((isa_fun_t *) ((fun)->driver_data))
-
 #define ISA_MAX_HW_RES 5
 
@@ -95,7 +89,19 @@
 } isa_fun_t;
 
+/** Obtain soft-state from device node */
+static isa_bus_t *isa_bus(ddf_dev_t *dev)
+{
+	return ddf_dev_data_get(dev);
+}
+
+/** Obtain soft-state from function node */
+static isa_fun_t *isa_fun(ddf_fun_t *fun)
+{
+	return ddf_fun_data_get(fun);
+}
+
 static hw_resource_list_t *isa_get_fun_resources(ddf_fun_t *fnode)
 {
-	isa_fun_t *fun = ISA_FUN(fnode);
+	isa_fun_t *fun = isa_fun(fnode);
 	assert(fun != NULL);
 
@@ -107,5 +113,5 @@
 	/* This is an old ugly way, copied from pci driver */
 	assert(fnode);
-	isa_fun_t *isa_fun = fnode->driver_data;
+	isa_fun_t *fun = isa_fun(fnode);
 
 	sysarg_t apic;
@@ -123,6 +129,5 @@
 		return false;
 
-	assert(isa_fun);
-	const hw_resource_list_t *res = &isa_fun->hw_resources;
+	const hw_resource_list_t *res = &fun->hw_resources;
 	assert(res);
 	for (size_t i = 0; i < res->count; ++i) {
@@ -150,6 +155,6 @@
 {
 	assert(fnode);
-	isa_fun_t *isa_fun = fnode->driver_data;
-	const hw_resource_list_t *res = &isa_fun->hw_resources;
+	isa_fun_t *fun = isa_fun(fnode);
+	const hw_resource_list_t *res = &fun->hw_resources;
 	assert(res);
 	
@@ -339,5 +344,5 @@
 
 		ddf_msg(LVL_NOTE, "Added irq 0x%x to function %s", irq,
-		    fun->fnode->name);
+		    ddf_fun_get_name(fun->fnode));
 	}
 }
@@ -355,5 +360,5 @@
 			fun->hw_resources.count++;
 			ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
-			    fun->fnode->name);
+			    ddf_fun_get_name(fun->fnode));
 			
 			return;
@@ -366,5 +371,5 @@
 			fun->hw_resources.count++;
 			ddf_msg(LVL_NOTE, "Added dma 0x%x to function %s", dma,
-			    fun->fnode->name);
+			    ddf_fun_get_name(fun->fnode));
 			
 			return;
@@ -372,5 +377,5 @@
 		
 		ddf_msg(LVL_WARN, "Skipped dma 0x%x for function %s", dma,
-		    fun->fnode->name);
+		    ddf_fun_get_name(fun->fnode));
 	}
 }
@@ -391,5 +396,5 @@
 		ddf_msg(LVL_NOTE, "Added io range (addr=0x%x, size=0x%x) to "
 		    "function %s", (unsigned int) addr, (unsigned int) len,
-		    fun->fnode->name);
+		    ddf_fun_get_name(fun->fnode));
 	}
 }
@@ -463,5 +468,5 @@
 	if (val == end) {
 		ddf_msg(LVL_ERROR, "Cannot read match score for function "
-		    "%s.", fun->fnode->name);
+		    "%s.", ddf_fun_get_name(fun->fnode));
 		return;
 	}
@@ -471,10 +476,10 @@
 	if (id == NULL) {
 		ddf_msg(LVL_ERROR, "Cannot read match ID for function %s.",
-		    fun->fnode->name);
+		    ddf_fun_get_name(fun->fnode));
 		return;
 	}
 
 	ddf_msg(LVL_DEBUG, "Adding match id '%s' with score %d to "
-	    "function %s", id, score, fun->fnode->name);
+	    "function %s", id, score, ddf_fun_get_name(fun->fnode));
 
 	rc = ddf_fun_add_match_id(fun->fnode, id, score);
@@ -579,7 +584,7 @@
 
 	/* Set device operations to the device. */
-	fun->fnode->ops = &isa_fun_ops;
-
-	ddf_msg(LVL_DEBUG, "Binding function %s.", fun->fnode->name);
+	ddf_fun_set_ops(fun->fnode, &isa_fun_ops);
+
+	ddf_msg(LVL_DEBUG, "Binding function %s.", ddf_fun_get_name(fun->fnode));
 
 	/* XXX Handle error */
@@ -614,5 +619,5 @@
 
 	ddf_msg(LVL_DEBUG, "isa_dev_add, device handle = %d",
-	    (int) dev->handle);
+	    (int) ddf_dev_get_handle(dev));
 
 	isa = ddf_dev_data_alloc(dev, sizeof(isa_bus_t));
@@ -652,5 +657,5 @@
 static int isa_dev_remove(ddf_dev_t *dev)
 {
-	isa_bus_t *isa = ISA_BUS(dev);
+	isa_bus_t *isa = isa_bus(dev);
 	int rc;
 
@@ -664,5 +669,5 @@
 		if (rc != EOK) {
 			fibril_mutex_unlock(&isa->mutex);
-			ddf_msg(LVL_ERROR, "Failed offlining %s", fun->fnode->name);
+			ddf_msg(LVL_ERROR, "Failed offlining %s", ddf_fun_get_name(fun->fnode));
 			return rc;
 		}
@@ -671,5 +676,5 @@
 		if (rc != EOK) {
 			fibril_mutex_unlock(&isa->mutex);
-			ddf_msg(LVL_ERROR, "Failed unbinding %s", fun->fnode->name);
+			ddf_msg(LVL_ERROR, "Failed unbinding %s", ddf_fun_get_name(fun->fnode));
 			return rc;
 		}
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -50,6 +50,4 @@
 #include <ddf/driver.h>
 #include <ddf/log.h>
-#include <devman.h>
-#include <ipc/devman.h>
 #include <ipc/dev_iface.h>
 #include <ipc/irc.h>
@@ -71,11 +69,22 @@
 
 /** Obtain PCI function soft-state from DDF function node */
-#define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data)
+static pci_fun_t *pci_fun(ddf_fun_t *fnode)
+{
+	return ddf_fun_data_get(fnode);
+}
 
 /** Obtain PCI bus soft-state from DDF device node */
-#define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data)
+#if 0
+static pci_bus_t *pci_bus(ddf_dev_t *dnode)
+{
+	return ddf_dev_data_get(dnode);
+}
+#endif
 
 /** Obtain PCI bus soft-state from function soft-state */
-#define PCI_BUS_FROM_FUN(fun) ((fun)->busptr)
+static pci_bus_t *pci_bus_from_fun(pci_fun_t *fun)
+{
+	return fun->busptr;
+}
 
 /** Max is 47, align to something nice. */
@@ -84,5 +93,5 @@
 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode)
 {
-	pci_fun_t *fun = PCI_FUN(fnode);
+	pci_fun_t *fun = pci_fun(fnode);
 	
 	if (fun == NULL)
@@ -95,5 +104,5 @@
 	/* This is an old ugly way */
 	assert(fnode);
-	pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
+	pci_fun_t *dev_data = pci_fun(fnode);
 	
 	sysarg_t apic;
@@ -138,5 +147,5 @@
 	if (address > 252)
 		return EINVAL;
-	pci_conf_write_32(PCI_FUN(fun), address, data);
+	pci_conf_write_32(pci_fun(fun), address, data);
 	return EOK;
 }
@@ -147,5 +156,5 @@
 	if (address > 254)
 		return EINVAL;
-	pci_conf_write_16(PCI_FUN(fun), address, data);
+	pci_conf_write_16(pci_fun(fun), address, data);
 	return EOK;
 }
@@ -156,5 +165,5 @@
 	if (address > 255)
 		return EINVAL;
-	pci_conf_write_8(PCI_FUN(fun), address, data);
+	pci_conf_write_8(pci_fun(fun), address, data);
 	return EOK;
 }
@@ -165,5 +174,5 @@
 	if (address > 252)
 		return EINVAL;
-	*data = pci_conf_read_32(PCI_FUN(fun), address);
+	*data = pci_conf_read_32(pci_fun(fun), address);
 	return EOK;
 }
@@ -174,5 +183,5 @@
 	if (address > 254)
 		return EINVAL;
-	*data = pci_conf_read_16(PCI_FUN(fun), address);
+	*data = pci_conf_read_16(pci_fun(fun), address);
 	return EOK;
 }
@@ -183,5 +192,5 @@
 	if (address > 255)
 		return EINVAL;
-	*data = pci_conf_read_8(PCI_FUN(fun), address);
+	*data = pci_conf_read_8(pci_fun(fun), address);
 	return EOK;
 }
@@ -225,5 +234,5 @@
 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
 {
-	pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
+	pci_bus_t *bus = pci_bus_from_fun(fun);
 	
 	fibril_mutex_lock(&bus->conf_mutex);
@@ -252,5 +261,5 @@
 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len)
 {
-	pci_bus_t *bus = PCI_BUS_FROM_FUN(fun);
+	pci_bus_t *bus = pci_bus_from_fun(fun);
 	
 	fibril_mutex_lock(&bus->conf_mutex);
@@ -480,5 +489,5 @@
 	if (range_addr != 0) {
 		ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64
-		    ", size = %x", fun->fnode->name, range_addr,
+		    ", size = %x", ddf_fun_get_name(fun->fnode), range_addr,
 		    (unsigned int) range_size);
 	}
@@ -506,5 +515,5 @@
 	hw_res_list->count++;
 	
-	ddf_msg(LVL_NOTE, "Function %s uses irq %x.", fun->fnode->name, irq);
+	ddf_msg(LVL_NOTE, "Function %s uses irq %x.", ddf_fun_get_name(fun->fnode), irq);
 }
 
@@ -523,6 +532,6 @@
 void pci_bus_scan(pci_bus_t *bus, int bus_num) 
 {
-	ddf_fun_t *fnode;
 	pci_fun_t *fun;
+	int rc;
 	
 	int child_bus = 0;
@@ -531,11 +540,12 @@
 	uint8_t header_type;
 	
-	fun = pci_fun_new(bus);
-	
 	for (dnum = 0; dnum < 32; dnum++) {
 		multi = true;
 		for (fnum = 0; multi && fnum < 8; fnum++) {
+			fun = pci_fun_new(bus);
+			
 			pci_fun_init(fun, bus_num, dnum, fnum);
 			if (fun->vendor_id == 0xffff) {
+				pci_fun_delete(fun);
 				/*
 				 * The device is not present, go on scanning the
@@ -559,15 +569,15 @@
 			if (fun_name == NULL) {
 				ddf_msg(LVL_ERROR, "Out of memory.");
+				pci_fun_delete(fun);
 				return;
 			}
 			
-			fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
+			rc = ddf_fun_set_name(fun->fnode, fun_name);
 			free(fun_name);
-			if (fnode == NULL) {
-				ddf_msg(LVL_ERROR, "Failed creating function.");
+			if (rc != EOK) {
+				ddf_msg(LVL_ERROR, "Failed setting function name.");
+				pci_fun_delete(fun);
 				return;
 			}
-			
-			fun->fnode = fnode;
 			
 			pci_alloc_resource_list(fun);
@@ -575,17 +585,14 @@
 			pci_read_interrupt(fun);
 			
-			fnode->ops = &pci_fun_ops;
-			fnode->driver_data = fun;
+			ddf_fun_set_ops(fun->fnode, &pci_fun_ops);
 			
 			ddf_msg(LVL_DEBUG, "Adding new function %s.",
-			    fnode->name);
+			    ddf_fun_get_name(fun->fnode));
 			
 			pci_fun_create_match_ids(fun);
 			
-			if (ddf_fun_bind(fnode) != EOK) {
+			if (ddf_fun_bind(fun->fnode) != EOK) {
 				pci_clean_resource_list(fun);
-				clean_match_ids(&fnode->match_ids);
-				free((char *) fnode->name);
-				fnode->name = NULL;
+				pci_fun_delete(fun);
 				continue;
 			}
@@ -601,12 +608,5 @@
 					pci_bus_scan(bus, child_bus);
 			}
-			
-			fun = pci_fun_new(bus);
 		}
-	}
-	
-	if (fun->vendor_id == 0xffff) {
-		/* Free the auxiliary function structure. */
-		pci_fun_delete(fun);
 	}
 }
@@ -617,8 +617,8 @@
 	ddf_fun_t *ctl = NULL;
 	bool got_res = false;
+	async_sess_t *sess;
 	int rc;
 	
 	ddf_msg(LVL_DEBUG, "pci_dev_add");
-	dnode->parent_sess = NULL;
 	
 	bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t));
@@ -631,9 +631,7 @@
 
 	bus->dnode = dnode;
-	dnode->driver_data = bus;
-	
-	dnode->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
-	    dnode->handle, IPC_FLAG_BLOCKING);
-	if (!dnode->parent_sess) {
+	
+	sess = ddf_dev_parent_sess_create(dnode, EXCHANGE_SERIALIZE);
+	if (sess == NULL) {
 		ddf_msg(LVL_ERROR, "pci_dev_add failed to connect to the "
 		    "parent driver.");
@@ -644,5 +642,5 @@
 	hw_resource_list_t hw_resources;
 	
-	rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources);
+	rc = hw_res_get_resource_list(sess, &hw_resources);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "pci_dev_add failed to get hw resources "
@@ -708,7 +706,4 @@
 	
 fail:
-	if (dnode->parent_sess)
-		async_hangup(dnode->parent_sess);
-	
 	if (got_res)
 		hw_res_clean_resource_list(&hw_resources);
@@ -742,10 +737,16 @@
 {
 	pci_fun_t *fun;
-	
-	fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t));
+	ddf_fun_t *fnode;
+	
+	fnode = ddf_fun_create(bus->dnode, fun_inner, NULL);
+	if (fnode == NULL)
+		return NULL;
+
+	fun = ddf_fun_data_alloc(fnode, sizeof(pci_fun_t));
 	if (fun == NULL)
 		return NULL;
 
 	fun->busptr = bus;
+	fun->fnode = fnode;
 	return fun;
 }
@@ -766,7 +767,7 @@
 void pci_fun_delete(pci_fun_t *fun)
 {
-	assert(fun != NULL);
 	hw_res_clean_resource_list(&fun->hw_resources);
-	free(fun);
+	if (fun->fnode != NULL)
+		ddf_fun_destroy(fun->fnode);
 }
 
Index: uspace/drv/bus/usb/ehci/main.c
===================================================================
--- uspace/drv/bus/usb/ehci/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ehci/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -84,5 +84,5 @@
 	CHECK_RET_RETURN(ret,
 	    "Failed to get memory addresses for %" PRIun ": %s.\n",
-	    device->handle, str_error(ret));
+	    ddf_dev_get_handle(device), str_error(ret));
 	usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
 	    reg_base, reg_size, irq);
@@ -104,5 +104,5 @@
 	/* High Speed, no bandwidth */
 	hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL);
-	hc_fun->ops = &hc_ops;
+	ddf_fun_set_ops(hc_fun,  &hc_ops);
 
 	ret = ddf_fun_bind(hc_fun);
@@ -116,5 +116,5 @@
 
 	usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
-	    device->name, device->handle);
+	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
 
 	return EOK;
Index: uspace/drv/bus/usb/ehci/res.c
===================================================================
--- uspace/drv/bus/usb/ehci/res.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ehci/res.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -76,5 +76,5 @@
  * @return Error code.
  */
-int get_my_registers(const ddf_dev_t *dev,
+int get_my_registers(ddf_dev_t *dev,
     uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
 {
@@ -82,5 +82,5 @@
 	
 	async_sess_t *parent_sess = devman_parent_device_connect(
-	    EXCHANGE_SERIALIZE, dev->handle, IPC_FLAG_BLOCKING);
+	    EXCHANGE_SERIALIZE, ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
@@ -115,8 +115,8 @@
  * @return Error code.
  */
-int enable_interrupts(const ddf_dev_t *device)
+int enable_interrupts(ddf_dev_t *device)
 {
 	async_sess_t *parent_sess = devman_parent_device_connect(
-	    EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING);
+	    EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
@@ -134,5 +134,5 @@
  * @return Error code.
  */
-static int disable_extended_caps(const ddf_dev_t *device, unsigned eecp)
+static int disable_extended_caps(ddf_dev_t *device, unsigned eecp)
 {
 	/* nothing to do */
@@ -141,5 +141,5 @@
 
 	async_sess_t *parent_sess = devman_parent_device_connect(
-	    EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING);
+	    EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
@@ -234,5 +234,5 @@
 }
 
-int disable_legacy(const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size)
+int disable_legacy(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size)
 {
 	assert(device);
Index: uspace/drv/bus/usb/ehci/res.h
===================================================================
--- uspace/drv/bus/usb/ehci/res.h	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ehci/res.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -38,7 +38,7 @@
 #include <ddf/driver.h>
 
-int get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int enable_interrupts(const ddf_dev_t *);
-int disable_legacy(const ddf_dev_t *, uintptr_t, size_t);
+int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
+int enable_interrupts(ddf_dev_t *);
+int disable_legacy(ddf_dev_t *, uintptr_t, size_t);
 
 #endif
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -187,5 +187,5 @@
 
 	ret = usb_device_manager_bind_address(&instance->generic.dev_manager,
-	    instance->rh.address, hub_fun->handle);
+	    instance->rh.address, ddf_fun_get_handle(hub_fun));
 	if (ret != EOK)
 		usb_log_warning("Failed to bind root hub address: %s.\n",
Index: uspace/drv/bus/usb/ohci/main.c
===================================================================
--- uspace/drv/bus/usb/ohci/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ohci/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -59,5 +59,5 @@
 		return ret;
 	}
-	usb_log_info("Controlling new OHCI device '%s'.\n", device->name);
+	usb_log_info("Controlling new OHCI device '%s'.\n", ddf_dev_get_name(device));
 
 	return EOK;
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -33,4 +33,8 @@
  * @brief OHCI driver
  */
+
+/* XXX Fix this */
+#define _DDF_DATA_IMPLANT
+
 #include <errno.h>
 #include <str_error.h>
@@ -52,8 +56,7 @@
 } ohci_t;
 
-static inline ohci_t * dev_to_ohci(ddf_dev_t *dev)
-{
-	assert(dev);
-	return dev->driver_data;
+static inline ohci_t *dev_to_ohci(ddf_dev_t *dev)
+{
+	return ddf_dev_data_get(dev);
 }
 /** IRQ handling callback, identifies device
@@ -87,5 +90,5 @@
 
 	if (address != NULL) {
-		*address = dev_to_ohci(fun->dev)->hc.rh.address;
+		*address = dev_to_ohci(ddf_fun_get_dev(fun))->hc.rh.address;
 	}
 
@@ -103,9 +106,9 @@
 {
 	assert(fun);
-	ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun;
+	ddf_fun_t *hc_fun = dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun;
 	assert(hc_fun);
 
 	if (handle != NULL)
-		*handle = hc_fun->handle;
+		*handle = ddf_fun_get_handle(hc_fun);
 	return EOK;
 }
@@ -152,9 +155,7 @@
 if (ret != EOK) { \
 	if (instance->hc_fun) { \
-		instance->hc_fun->driver_data = NULL; \
 		ddf_fun_destroy(instance->hc_fun); \
 	} \
 	if (instance->rh_fun) { \
-		instance->rh_fun->driver_data = NULL; \
 		ddf_fun_destroy(instance->rh_fun); \
 	} \
@@ -167,6 +168,6 @@
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to create OHCI HC function: %s.\n", str_error(ret));
-	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc;
+	ddf_fun_set_ops(instance->hc_fun, &hc_ops);
+	ddf_fun_data_implant(instance->hc_fun, &instance->hc);
 
 	instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
@@ -174,5 +175,5 @@
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to create OHCI RH function: %s.\n", str_error(ret));
-	instance->rh_fun->ops = &rh_ops;
+	ddf_fun_set_ops(instance->rh_fun, &rh_ops);
 
 	uintptr_t reg_base = 0;
@@ -183,5 +184,5 @@
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to get register memory addresses for %" PRIun ": %s.\n",
-	    device->handle, str_error(ret));
+	    ddf_dev_get_handle(device), str_error(ret));
 	usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
 	    (void *) reg_base, reg_size, irq);
Index: uspace/drv/bus/usb/ohci/res.c
===================================================================
--- uspace/drv/bus/usb/ohci/res.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ohci/res.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -53,5 +53,5 @@
  * @return Error code.
  */
-int get_my_registers(const ddf_dev_t *dev,
+int get_my_registers(ddf_dev_t *dev,
     uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
 {
@@ -59,6 +59,6 @@
 
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
@@ -94,9 +94,9 @@
  * @return Error code.
  */
-int enable_interrupts(const ddf_dev_t *device)
+int enable_interrupts(ddf_dev_t *device)
 {
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
Index: uspace/drv/bus/usb/ohci/res.h
===================================================================
--- uspace/drv/bus/usb/ohci/res.h	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/ohci/res.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -37,6 +37,6 @@
 #include <ddf/driver.h>
 
-int get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int enable_interrupts(const ddf_dev_t *);
+int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
+int enable_interrupts(ddf_dev_t *);
 
 #endif
Index: uspace/drv/bus/usb/uhci/main.c
===================================================================
--- uspace/drv/bus/usb/uhci/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/uhci/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -70,5 +70,5 @@
 	} else {
 		usb_log_info("Controlling new UHCI device '%s'.\n",
-		    device->name);
+		    ddf_dev_get_name(device));
 	}
 
Index: uspace/drv/bus/usb/uhci/res.c
===================================================================
--- uspace/drv/bus/usb/uhci/res.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/uhci/res.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -51,5 +51,5 @@
  * @return Error code.
  */
-int get_my_registers(const ddf_dev_t *dev,
+int get_my_registers(ddf_dev_t *dev,
     uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
 {
@@ -57,6 +57,6 @@
 
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
@@ -92,9 +92,9 @@
  * @return Error code.
  */
-int enable_interrupts(const ddf_dev_t *device)
+int enable_interrupts(ddf_dev_t *device)
 {
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
@@ -111,10 +111,10 @@
  * @return Error code.
  */
-int disable_legacy(const ddf_dev_t *device)
+int disable_legacy(ddf_dev_t *device)
 {
 	assert(device);
 
 	async_sess_t *parent_sess = devman_parent_device_connect(
-	    EXCHANGE_SERIALIZE, device->handle, IPC_FLAG_BLOCKING);
+	    EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
Index: uspace/drv/bus/usb/uhci/res.h
===================================================================
--- uspace/drv/bus/usb/uhci/res.h	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/uhci/res.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -38,7 +38,7 @@
 #include <ddf/driver.h>
 
-int get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int enable_interrupts(const ddf_dev_t *);
-int disable_legacy(const ddf_dev_t *);
+int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *);
+int enable_interrupts(ddf_dev_t *);
+int disable_legacy(ddf_dev_t *);
 
 #endif
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -33,4 +33,8 @@
  * @brief UHCI driver
  */
+
+/* XXX Fix this */
+#define _DDF_DATA_IMPLANT
+
 #include <errno.h>
 #include <str_error.h>
@@ -60,8 +64,7 @@
 } uhci_t;
 
-static inline uhci_t * dev_to_uhci(const ddf_dev_t *dev)
-{
-	assert(dev);
-	return dev->driver_data;
+static inline uhci_t *dev_to_uhci(ddf_dev_t *dev)
+{
+	return ddf_dev_data_get(dev);
 }
 
@@ -97,10 +100,9 @@
 static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
 {
-	assert(fun);
-	ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
+	ddf_fun_t *hc_fun = dev_to_uhci(ddf_fun_get_dev(fun))->hc_fun;
 	assert(hc_fun);
 
 	if (handle != NULL)
-		*handle = hc_fun->handle;
+		*handle = ddf_fun_get_handle(hc_fun);
 	return EOK;
 }
@@ -118,6 +120,5 @@
 static hw_resource_list_t *get_resource_list(ddf_fun_t *fun)
 {
-	assert(fun);
-	rh_t *rh = fun->driver_data;
+	rh_t *rh = ddf_fun_data_get(fun);
 	assert(rh);
 	return &rh->resource_list;
@@ -160,8 +161,6 @@
 if (ret != EOK) { \
 	if (instance->hc_fun) \
-		instance->hc_fun->driver_data = NULL; \
 		ddf_fun_destroy(instance->hc_fun); \
 	if (instance->rh_fun) {\
-		instance->rh_fun->driver_data = NULL; \
 		ddf_fun_destroy(instance->rh_fun); \
 	} \
@@ -174,12 +173,12 @@
 	int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
 	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
-	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc.generic;
+	ddf_fun_set_ops(instance->hc_fun, &hc_ops);
+	ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic);
 
 	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
 	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
 	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
-	instance->rh_fun->ops = &rh_ops;
-	instance->rh_fun->driver_data = &instance->rh;
+	ddf_fun_set_ops(instance->rh_fun, &rh_ops);
+	ddf_fun_data_implant(instance->rh_fun, &instance->rh);
 
 	uintptr_t reg_base = 0;
@@ -190,5 +189,5 @@
 	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to get I/O addresses for %" PRIun ": %s.\n",
-	    device->handle, str_error(ret));
+	    ddf_dev_get_handle(device), str_error(ret));
 	usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
 	    (void *) reg_base, reg_size, irq);
Index: uspace/drv/bus/usb/uhcirh/main.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/uhcirh/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -48,5 +48,5 @@
 #define NAME "uhcirh"
 
-static int hc_get_my_registers(const ddf_dev_t *dev,
+static int hc_get_my_registers(ddf_dev_t *dev,
     uintptr_t *io_reg_address, size_t *io_reg_size);
 
@@ -88,5 +88,5 @@
 
 	usb_log_debug2("uhci_rh_dev_add(handle=%" PRIun ")\n",
-	    device->handle);
+	    ddf_dev_get_handle(device));
 
 	uintptr_t io_regs = 0;
@@ -98,6 +98,4 @@
 if (ret != EOK) { \
 	usb_log_error(message); \
-	if (rh) \
-		free(rh); \
 	return ret; \
 } else (void)0
@@ -109,5 +107,5 @@
 	    (void *) io_regs, io_size);
 
-	rh = malloc(sizeof(uhci_root_hub_t));
+	rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t));
 	ret = (rh == NULL) ? ENOMEM : EOK;
 	CHECK_RET_FREE_RH_RETURN(ret,
@@ -119,7 +117,6 @@
 	    ret, str_error(ret));
 
-	device->driver_data = rh;
 	usb_log_info("Controlling root hub '%s' (%" PRIun ").\n",
-	    device->name, device->handle);
+	    ddf_dev_get_name(device), ddf_dev_get_handle(device));
 	return EOK;
 }
@@ -133,11 +130,9 @@
  */
 int hc_get_my_registers(
-    const ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
+    ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
 {
-	assert(dev);
-
 	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE,
+	    ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING);
 	if (!parent_sess)
 		return ENOMEM;
Index: uspace/drv/bus/usb/uhcirh/port.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/uhcirh/port.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -279,5 +279,5 @@
 	usb_log_info("%s: New device, address %d (handle %" PRIun ").\n",
 	    port->id_string, port->attached_device.address,
-	    port->attached_device.fun->handle);
+	    ddf_fun_get_handle(port->attached_device.fun));
 	return EOK;
 }
Index: uspace/drv/bus/usb/usbflbk/main.c
===================================================================
--- uspace/drv/bus/usb/usbflbk/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbflbk/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -69,5 +69,5 @@
 	    " (node `%s', handle %" PRIun ").\n",
 	    dev->interface_no < 0 ? "device" : "interface",
-	    dev->ddf_dev->name, fun_name, dev->ddf_dev->handle);
+	    ddf_dev_get_name(dev->ddf_dev), fun_name, ddf_dev_get_handle(dev->ddf_dev));
 
 	return EOK;
@@ -85,5 +85,5 @@
 	const int ret = ddf_fun_unbind(ctl_fun);
 	if (ret != EOK) {
-		usb_log_error("Failed to unbind %s.\n", ctl_fun->name);
+		usb_log_error("Failed to unbind %s.\n", ddf_fun_get_name(ctl_fun));
 		return ret;
 	}
Index: uspace/drv/bus/usb/usbhid/generic/hiddev.c
===================================================================
--- uspace/drv/bus/usb/usbhid/generic/hiddev.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhid/generic/hiddev.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -35,4 +35,7 @@
  */
 
+/* XXX Fix this */
+#define _DDF_DATA_IMPLANT
+
 #include <usb/debug.h>
 #include <usb/classes/classes.h>
@@ -81,14 +84,20 @@
 };
 
+/** Return hid_dev_t * for generic HID function node.
+ *
+ * For the generic HID subdriver the 'hid' function has usb_hid_gen_fun_t
+ * as soft state. Through that we can get to the usb_hid_dev_t.
+ */
+static usb_hid_dev_t *fun_hid_dev(ddf_fun_t *fun)
+{
+	return ((usb_hid_gen_fun_t *)ddf_fun_data_get(fun))->hid_dev;
+}
+
 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
 {
 	usb_log_debug2("Generic HID: Get event length (fun: %p, "
-	    "fun->driver_data: %p.\n", fun, fun->driver_data);
-
-	if (fun == NULL || fun->driver_data == NULL) {
-		return 0;
-	}
-
-	const usb_hid_dev_t *hid_dev = fun->driver_data;
+	    "fun->driver_data: %p.\n", fun, ddf_fun_data_get(fun));
+
+	const usb_hid_dev_t *hid_dev = fun_hid_dev(fun);
 
 	usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n",
@@ -103,11 +112,10 @@
 	usb_log_debug2("Generic HID: Get event.\n");
 
-	if (fun == NULL || fun->driver_data == NULL || buffer == NULL
-	    || act_size == NULL || event_nr == NULL) {
+	if (buffer == NULL || act_size == NULL || event_nr == NULL) {
 		usb_log_debug("No function");
 		return EINVAL;
 	}
 
-	const usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
+	const usb_hid_dev_t *hid_dev = fun_hid_dev(fun);
 
 	if (hid_dev->input_report_size > size) {
@@ -132,10 +140,5 @@
 	usb_log_debug("Generic HID: Get report descriptor length.\n");
 
-	if (fun == NULL || fun->driver_data == NULL) {
-		usb_log_debug("No function");
-		return EINVAL;
-	}
-
-	const usb_hid_dev_t *hid_dev = fun->driver_data;
+	const usb_hid_dev_t *hid_dev = fun_hid_dev(fun);
 
 	usb_log_debug2("hid_dev->report_desc_size = %zu\n",
@@ -150,10 +153,5 @@
 	usb_log_debug2("Generic HID: Get report descriptor.\n");
 
-	if (fun == NULL || fun->driver_data == NULL) {
-		usb_log_debug("No function");
-		return EINVAL;
-	}
-
-	const usb_hid_dev_t *hid_dev = fun->driver_data;
+	const usb_hid_dev_t *hid_dev = fun_hid_dev(fun);
 
 	if (hid_dev->report_desc_size > size) {
@@ -183,8 +181,5 @@
 		return;
 	}
-	usb_log_debug2("%s unbound.\n", fun->name);
-	/* We did not allocate this, so leave this alone
-	 * the device would take care of it */
-	fun->driver_data = NULL;
+	usb_log_debug2("%s unbound.\n", ddf_fun_get_name(fun));
 	ddf_fun_destroy(fun);
 }
@@ -192,4 +187,6 @@
 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data)
 {
+	usb_hid_gen_fun_t *hid_fun;
+
 	if (hid_dev == NULL) {
 		return EINVAL;
@@ -205,8 +202,8 @@
 	}
 
-	/* This is nasty, both device and this function have the same
-	 * driver data, thus destruction causes to double free */
-	fun->driver_data = hid_dev;
-	fun->ops = &usb_generic_hid_ops;
+	/* Create softstate */
+	hid_fun = ddf_fun_data_alloc(fun, sizeof(usb_hid_gen_fun_t));
+	hid_fun->hid_dev = hid_dev;
+	ddf_fun_set_ops(fun, &usb_generic_hid_ops);
 
 	int rc = ddf_fun_bind(fun);
@@ -214,10 +211,10 @@
 		usb_log_error("Could not bind DDF function: %s.\n",
 		    str_error(rc));
-		fun->driver_data = NULL;
 		ddf_fun_destroy(fun);
 		return rc;
 	}
 
-	usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle);
+	usb_log_debug("HID function created. Handle: %" PRIun "\n",
+	    ddf_fun_get_handle(fun));
 	*data = fun;
 
Index: uspace/drv/bus/usb/usbhid/generic/hiddev.h
===================================================================
--- uspace/drv/bus/usb/usbhid/generic/hiddev.h	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhid/generic/hiddev.h	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -47,5 +47,8 @@
 const char *HID_GENERIC_CLASS_NAME;
 
-
+/** The USB HID generic 'hid' function softstate */
+typedef struct {
+	struct usb_hid_dev *hid_dev;
+} usb_hid_gen_fun_t;
 
 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data);
Index: uspace/drv/bus/usb/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/bus/usb/usbhid/kbd/kbddev.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhid/kbd/kbddev.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -34,4 +34,7 @@
  * USB HID keyboard device structure and API.
  */
+
+/* XXX Fix this */
+#define _DDF_DATA_IMPLANT
 
 #include <errno.h>
@@ -162,12 +165,6 @@
     ipc_callid_t icallid, ipc_call_t *icall)
 {
-	if (fun == NULL || fun->driver_data == NULL) {
-		usb_log_error("%s: Missing parameter.\n", __FUNCTION__);
-		async_answer_0(icallid, EINVAL);
-		return;
-	}
-
 	const sysarg_t method = IPC_GET_IMETHOD(*icall);
-	usb_kbd_t *kbd_dev = fun->driver_data;
+	usb_kbd_t *kbd_dev = ddf_fun_data_get(fun);
 
 	switch (method) {
@@ -501,6 +498,6 @@
 	/* Store the initialized HID device and HID ops
 	 * to the DDF function. */
-	fun->ops = &kbdops;
-	fun->driver_data = kbd_dev;
+	ddf_fun_set_ops(fun, &kbdops);
+	ddf_fun_data_implant(fun, kbd_dev);
 
 	int rc = ddf_fun_bind(fun);
@@ -508,5 +505,4 @@
 		usb_log_error("Could not bind DDF function: %s.\n",
 		    str_error(rc));
-		fun->driver_data = NULL; /* We did not allocate this. */
 		ddf_fun_destroy(fun);
 		return rc;
@@ -514,5 +510,5 @@
 
 	usb_log_debug("%s function created. Handle: %" PRIun "\n",
-	    HID_KBD_FUN_NAME, fun->handle);
+	    HID_KBD_FUN_NAME, ddf_fun_get_handle(fun));
 
 	usb_log_debug("Adding DDF function to category %s...\n",
@@ -524,10 +520,9 @@
 		    HID_KBD_CLASS_NAME, str_error(rc));
 		if (ddf_fun_unbind(fun) == EOK) {
-			fun->driver_data = NULL; /* We did not allocate this. */
 			ddf_fun_destroy(fun);
 		} else {
 			usb_log_error(
 			    "Failed to unbind `%s', will not destroy.\n",
-			    fun->name);
+			    ddf_fun_get_name(fun));
 		}
 		return rc;
@@ -757,12 +752,11 @@
 		if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
 			usb_log_warning("Failed to unbind %s.\n",
-			    kbd_dev->fun->name);
+			    ddf_fun_get_name(kbd_dev->fun));
 		} else {
-			usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);
-			kbd_dev->fun->driver_data = NULL;
+			usb_log_debug2("%s unbound.\n",
+			    ddf_fun_get_name(kbd_dev->fun));
 			ddf_fun_destroy(kbd_dev->fun);
 		}
 	}
-	free(kbd_dev);
 }
 
Index: uspace/drv/bus/usb/usbhid/main.c
===================================================================
--- uspace/drv/bus/usb/usbhid/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhid/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -103,5 +103,5 @@
 	if (rc != EOK) {
 		usb_log_error("Failed to start polling fibril for `%s'.\n",
-		    dev->ddf_dev->name);
+		    ddf_dev_get_name(dev->ddf_dev));
 		usb_hid_deinit(hid_dev);
 		return rc;
@@ -109,5 +109,6 @@
 	hid_dev->running = true;
 
-	usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name);
+	usb_log_info("HID device `%s' ready to use.\n",
+	    ddf_dev_get_name(dev->ddf_dev));
 
 	return EOK;
@@ -149,5 +150,5 @@
 
 	usb_hid_deinit(hid_dev);
-	usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name);
+	usb_log_debug2("%s destruction complete.\n", ddf_dev_get_name(dev->ddf_dev));
 	return EOK;
 }
Index: uspace/drv/bus/usb/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/bus/usb/usbhid/mouse/mousedev.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhid/mouse/mousedev.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -34,4 +34,7 @@
  * USB Mouse driver API.
  */
+
+/* XXX Fix this */
+#define _DDF_DATA_IMPLANT
 
 #include <usb/debug.h>
@@ -115,5 +118,5 @@
     ipc_callid_t icallid, ipc_call_t *icall)
 {
-	usb_mouse_t *mouse_dev = fun->driver_data;
+	usb_mouse_t *mouse_dev = ddf_fun_data_get(fun);
 
 	if (mouse_dev == NULL) {
@@ -123,5 +126,5 @@
 	}
 
-	usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name);
+	usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, ddf_fun_get_name(fun));
 	usb_log_debug("%s: mouse_sess: %p\n",
 	    __FUNCTION__, mouse_dev->mouse_sess);
@@ -133,9 +136,9 @@
 			mouse_dev->mouse_sess = sess;
 			usb_log_debug("Console session to %s set ok (%p).\n",
-			    fun->name, sess);
+			    ddf_fun_get_name(fun), sess);
 			async_answer_0(icallid, EOK);
 		} else {
 			usb_log_error("Console session to %s already set.\n",
-			    fun->name);
+			    ddf_fun_get_name(fun));
 			async_answer_0(icallid, ELIMIT);
 			async_hangup(sess);
@@ -249,9 +252,8 @@
 if (fun) { \
 	if (ddf_fun_unbind((fun)) == EOK) { \
-		(fun)->driver_data = NULL; \
 		ddf_fun_destroy((fun)); \
 	} else { \
 		usb_log_error("Could not unbind function `%s', it " \
-		    "will not be destroyed.\n", (fun)->name); \
+		    "will not be destroyed.\n", ddf_fun_get_name(fun)); \
 	} \
 } else (void)0
@@ -272,12 +274,11 @@
 	}
 
-	fun->ops = &ops;
-	fun->driver_data = mouse;
+	ddf_fun_set_ops(fun, &ops);
+	ddf_fun_data_implant(fun, mouse);
 
 	int rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
 		usb_log_error("Could not bind DDF function `%s': %s.\n",
-		    fun->name, str_error(rc));
-		fun->driver_data = NULL;
+		    ddf_fun_get_name(fun), str_error(rc));
 		ddf_fun_destroy(fun);
 		return rc;
@@ -285,5 +286,5 @@
 
 	usb_log_debug("Adding DDF function `%s' to category %s...\n",
-	    fun->name, HID_MOUSE_CATEGORY);
+	    ddf_fun_get_name(fun), HID_MOUSE_CATEGORY);
 	rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
 	if (rc != EOK) {
@@ -419,5 +420,4 @@
 
 	free(mouse_dev->buttons);
-	free(mouse_dev);
 }
 
Index: uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
===================================================================
--- uspace/drv/bus/usb/usbhid/multimedia/multimedia.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhid/multimedia/multimedia.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -86,10 +86,6 @@
 {
 	usb_log_debug(NAME " default_connection_handler()\n");
-	if (fun == NULL || fun->driver_data == NULL) {
-		async_answer_0(icallid, EINVAL);
-		return;
-	}
-
-	usb_multimedia_t *multim_dev = fun->driver_data;
+
+	usb_multimedia_t *multim_dev = ddf_fun_data_get(fun);
 
 	async_sess_t *sess =
@@ -172,5 +168,5 @@
 	}
 
-	fun->ops = &multimedia_ops;
+	ddf_fun_set_ops(fun, &multimedia_ops);
 
 	usb_multimedia_t *multim_dev =
@@ -194,5 +190,5 @@
 
 	usb_log_debug(NAME " function created (handle: %" PRIun ").\n",
-	    fun->handle);
+	    ddf_fun_get_handle(fun));
 
 	rc = ddf_fun_add_to_category(fun, "keyboard");
@@ -203,5 +199,5 @@
 		if (ddf_fun_unbind(fun) != EOK) {
 			usb_log_error("Failed to unbind %s, won't destroy.\n",
-			    fun->name);
+			    ddf_fun_get_name(fun));
 		} else {
 			ddf_fun_destroy(fun);
@@ -220,21 +216,18 @@
 {
 	ddf_fun_t *fun = data;
-	if (fun != NULL && fun->driver_data != NULL) {
-		usb_multimedia_t *multim_dev = fun->driver_data;
-		/* Hangup session to the console */
-		if (multim_dev->console_sess)
-			async_hangup(multim_dev->console_sess);
-		if (ddf_fun_unbind(fun) != EOK) {
-			usb_log_error("Failed to unbind %s, won't destroy.\n",
-			    fun->name);
-		} else {
-			usb_log_debug2("%s unbound.\n", fun->name);
-			/* This frees multim_dev too as it was stored in
-			 * fun->data */
-			ddf_fun_destroy(fun);
-		}
+
+	usb_multimedia_t *multim_dev = ddf_fun_data_get(fun);
+
+	/* Hangup session to the console */
+	if (multim_dev->console_sess)
+		async_hangup(multim_dev->console_sess);
+	if (ddf_fun_unbind(fun) != EOK) {
+		usb_log_error("Failed to unbind %s, won't destroy.\n",
+		    ddf_fun_get_name(fun));
 	} else {
-		usb_log_error(
-		    "Failed to deinit multimedia subdriver, data missing.\n");
+		usb_log_debug2("%s unbound.\n", ddf_fun_get_name(fun));
+		/* This frees multim_dev too as it was stored in
+		 * fun->data */
+		ddf_fun_destroy(fun);
 	}
 }
@@ -244,9 +237,9 @@
 	// TODO: checks
 	ddf_fun_t *fun = data;
-	if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) {
+	if (hid_dev == NULL) {
 		return false;
 	}
 
-	usb_multimedia_t *multim_dev = fun->driver_data;
+	usb_multimedia_t *multim_dev = ddf_fun_data_get(fun);
 
 	usb_hid_report_path_t *path = usb_hid_report_path();
Index: uspace/drv/bus/usb/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -436,6 +436,7 @@
 		usb_log_info("Detected new device on `%s' (port %zu), "
 		    "address %d (handle %" PRIun ").\n",
-		    data->hub->usb_device->ddf_dev->name,
-		    data->port->port_number, new_address, child_fun->handle);
+		    ddf_dev_get_name(data->hub->usb_device->ddf_dev),
+		    data->port->port_number, new_address,
+		    ddf_fun_get_handle(child_fun));
 	} else {
 		usb_log_error("Failed registering device on port %zu: %s.\n",
Index: uspace/drv/bus/usb/usbhub/usbhub.c
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbhub/usbhub.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -160,5 +160,5 @@
 	hub_dev->running = true;
 	usb_log_info("Controlling hub '%s' (%zu ports).\n",
-	    hub_dev->usb_device->ddf_dev->name, hub_dev->port_count);
+	    ddf_dev_get_name(hub_dev->usb_device->ddf_dev), hub_dev->port_count);
 
 	usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
Index: uspace/drv/bus/usb/usbmast/main.c
===================================================================
--- uspace/drv/bus/usb/usbmast/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbmast/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -160,5 +160,5 @@
 	mdev->usb_dev = dev;
 
-	usb_log_info("Initializing mass storage `%s'.\n", dev->ddf_dev->name);
+	usb_log_info("Initializing mass storage `%s'.\n", ddf_dev_get_name(dev->ddf_dev));
 	usb_log_debug("Bulk in endpoint: %d [%zuB].\n",
 	    dev->pipes[BULK_IN_EP].pipe.endpoint_no,
@@ -245,5 +245,5 @@
 
 	/* Set up a connection handler. */
-	fun->conn_handler = usbmast_bd_connection;
+	ddf_fun_set_conn_handler(fun, usbmast_bd_connection);
 
 	usb_log_debug("Inquire...\n");
@@ -252,5 +252,5 @@
 	if (rc != EOK) {
 		usb_log_warning("Failed to inquire device `%s': %s.\n",
-		    mdev->ddf_dev->name, str_error(rc));
+		    ddf_dev_get_name(mdev->ddf_dev), str_error(rc));
 		rc = EIO;
 		goto error;
@@ -259,5 +259,5 @@
 	usb_log_info("Mass storage `%s' LUN %u: " \
 	    "%s by %s rev. %s is %s (%s).\n",
-	    mdev->ddf_dev->name,
+	    ddf_dev_get_name(mdev->ddf_dev),
 	    lun,
 	    inquiry.product,
@@ -272,5 +272,5 @@
 	if (rc != EOK) {
 		usb_log_warning("Failed to read capacity, device `%s': %s.\n",
-		    mdev->ddf_dev->name, str_error(rc));
+		    ddf_dev_get_name(mdev->ddf_dev), str_error(rc));
 		rc = EIO;
 		goto error;
@@ -310,5 +310,5 @@
 	usbmast_fun_t *mfun;
 
-	mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
+	mfun = (usbmast_fun_t *) ddf_fun_data_get((ddf_fun_t *)arg);
 	bd_conn(iid, icall, &mfun->bds);
 }
Index: uspace/drv/bus/usb/usbmast/scsi_ms.c
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi_ms.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbmast/scsi_ms.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -88,5 +88,5 @@
 		if (rc != EOK) {
 			usb_log_error("Inquiry transport failed, device %s: %s.\n",
-			   mfun->mdev->ddf_dev->name, str_error(rc));
+			   ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc));
 			return rc;
 		}
@@ -96,5 +96,5 @@
 
 		usb_log_error("SCSI command failed, device %s.\n",
-		    mfun->mdev->ddf_dev->name);
+		    ddf_dev_get_name(mfun->mdev->ddf_dev));
 
 		rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf));
@@ -147,5 +147,5 @@
 	if (rc != EOK) {
 		usb_log_error("Inquiry transport failed, device %s: %s.\n",
-		   mfun->mdev->ddf_dev->name, str_error(rc));
+		   ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc));
 		return rc;
 	}
@@ -153,5 +153,5 @@
 	if (cmd.status != CMDS_GOOD) {
 		usb_log_error("Inquiry command failed, device %s.\n",
-		   mfun->mdev->ddf_dev->name);
+		   ddf_dev_get_name(mfun->mdev->ddf_dev));
 		return EIO;
 	}
@@ -215,5 +215,5 @@
         if (rc != EOK || cmd.status != CMDS_GOOD) {
 		usb_log_error("Request Sense failed, device %s: %s.\n",
-		   mfun->mdev->ddf_dev->name, str_error(rc));
+		   ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc));
 		return rc;
 	}
@@ -257,5 +257,5 @@
         if (rc != EOK) {
 		usb_log_error("Read Capacity (10) transport failed, device %s: %s.\n",
-		   mfun->mdev->ddf_dev->name, str_error(rc));
+		   ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc));
 		return rc;
 	}
@@ -263,5 +263,5 @@
 	if (cmd.status != CMDS_GOOD) {
 		usb_log_error("Read Capacity (10) command failed, device %s.\n",
-		   mfun->mdev->ddf_dev->name);
+		   ddf_dev_get_name(mfun->mdev->ddf_dev));
 		return EIO;
 	}
@@ -314,5 +314,5 @@
         if (rc != EOK) {
 		usb_log_error("Read (10) transport failed, device %s: %s.\n",
-		   mfun->mdev->ddf_dev->name, str_error(rc));
+		   ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc));
 		return rc;
 	}
@@ -320,5 +320,5 @@
 	if (cmd.status != CMDS_GOOD) {
 		usb_log_error("Read (10) command failed, device %s.\n",
-		   mfun->mdev->ddf_dev->name);
+		   ddf_dev_get_name(mfun->mdev->ddf_dev));
 		return EIO;
 	}
@@ -370,5 +370,5 @@
         if (rc != EOK) {
 		usb_log_error("Write (10) transport failed, device %s: %s.\n",
-		   mfun->mdev->ddf_dev->name, str_error(rc));
+		   ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc));
 		return rc;
 	}
@@ -376,5 +376,5 @@
 	if (cmd.status != CMDS_GOOD) {
 		usb_log_error("Write (10) command failed, device %s.\n",
-		   mfun->mdev->ddf_dev->name);
+		   ddf_dev_get_name(mfun->mdev->ddf_dev));
 		return EIO;
 	}
Index: uspace/drv/bus/usb/usbmid/explore.c
===================================================================
--- uspace/drv/bus/usb/usbmid/explore.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbmid/explore.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -172,5 +172,5 @@
 		return false;
 	}
-	usb_mid->ctl_fun->ops = &mid_device_ops;
+	ddf_fun_set_ops(usb_mid->ctl_fun, &mid_device_ops);
 
 	/* Bind control function. */
Index: uspace/drv/bus/usb/usbmid/main.c
===================================================================
--- uspace/drv/bus/usb/usbmid/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbmid/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -51,5 +51,5 @@
 static int usbmid_device_add(usb_device_t *dev)
 {
-	usb_log_info("Taking care of new MID `%s'.\n", dev->ddf_dev->name);
+	usb_log_info("Taking care of new MID `%s'.\n", ddf_dev_get_name(dev->ddf_dev));
 
 	const bool accept = usbmid_explore_device(dev);
@@ -127,5 +127,5 @@
 	assert(usb_mid);
 
-	usb_log_info("USB MID gone: `%s'.\n", dev->ddf_dev->name);
+	usb_log_info("USB MID gone: `%s'.\n", ddf_dev_get_name(dev->ddf_dev));
 
 	/* Remove ctl function */
Index: uspace/drv/bus/usb/usbmid/usbmid.c
===================================================================
--- uspace/drv/bus/usb/usbmid/usbmid.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/usbmid/usbmid.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -30,4 +30,8 @@
  * @{
  */
+
+/* XXX Fix this */
+#define _DDF_DATA_IMPLANT
+
 /**
  * @file
@@ -47,7 +51,5 @@
 static int usb_iface_get_interface_impl(ddf_fun_t *fun, int *iface_no)
 {
-	assert(fun);
-
-	usbmid_interface_t *iface = fun->driver_data;
+	usbmid_interface_t *iface = ddf_fun_data_get(fun);
 	assert(iface);
 
@@ -123,10 +125,24 @@
 	}
 
+	match_id_list_t match_ids;
+	init_match_ids(&match_ids);
+
 	rc = usb_device_create_match_ids_from_interface(device_descriptor,
-	    interface_descriptor, &child->match_ids);
+	    interface_descriptor, &match_ids);
 	if (rc != EOK) {
 		ddf_fun_destroy(child);
 		return rc;
 	}
+
+	list_foreach(match_ids.ids, link) {
+		match_id_t *match_id = list_get_instance(link, match_id_t, link);
+		rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
+		if (rc != EOK) {
+			clean_match_ids(&match_ids);
+			ddf_fun_destroy(child);
+			return rc;
+		}
+	}
+	clean_match_ids(&match_ids);
 
 	rc = ddf_fun_bind(child);
@@ -138,6 +154,6 @@
 
 	iface->fun = child;
-	child->driver_data = iface;
-	child->ops = &child_device_ops;
+	ddf_fun_data_implant(child, iface);
+	ddf_fun_set_ops(child, &child_device_ops);
 
 	return EOK;
Index: uspace/drv/bus/usb/vhc/conndev.c
===================================================================
--- uspace/drv/bus/usb/vhc/conndev.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/vhc/conndev.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -94,5 +94,5 @@
     ipc_call_t *icall)
 {
-	vhc_data_t *vhc = fun->dev->driver_data;
+	vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	
 	async_sess_t *callback =
@@ -125,5 +125,5 @@
 void on_client_close(ddf_fun_t *fun)
 {
-	vhc_data_t *vhc = fun->dev->driver_data;
+	vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun));
 
 	if (plugged_device_handle != 0) {
Index: uspace/drv/bus/usb/vhc/connhost.c
===================================================================
--- uspace/drv/bus/usb/vhc/connhost.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/vhc/connhost.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -42,5 +42,5 @@
 
 #define GET_VHC_DATA(fun) \
-	((vhc_data_t *)fun->dev->driver_data)
+	((vhc_data_t *)ddf_dev_data_get(ddf_fun_get_dev(fun)))
 #define VHC_DATA(vhc, fun) \
 	vhc_data_t *vhc = GET_VHC_DATA(fun); assert(vhc->magic == 0xdeadbeef)
@@ -483,5 +483,5 @@
 	VHC_DATA(vhc, root_hub_fun);
 
-	*handle = vhc->hc_fun->handle;
+	*handle = ddf_fun_get_handle(vhc->hc_fun);
 
 	return EOK;
@@ -492,5 +492,5 @@
 	VHC_DATA(vhc, root_hub_fun);
 
-	devman_handle_t handle = root_hub_fun->handle;
+	devman_handle_t handle = ddf_fun_get_handle(root_hub_fun);
 
 	usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle);
Index: uspace/drv/bus/usb/vhc/hub.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/vhc/hub.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -100,5 +100,6 @@
 	async_sess_t *sess;
 	do {
-		sess = devman_device_connect(EXCHANGE_SERIALIZE, hc_dev->handle, 0);
+		sess = devman_device_connect(EXCHANGE_SERIALIZE,
+		    ddf_fun_get_handle(hc_dev), 0);
 	} while (!sess);
 	async_hangup(sess);
@@ -107,5 +108,5 @@
 
 	usb_hc_connection_t hc_conn;
-	usb_hc_connection_initialize(&hc_conn, hc_dev->handle);
+	usb_hc_connection_initialize(&hc_conn, ddf_fun_get_handle(hc_dev));
 
 	rc = usb_hc_connection_open(&hc_conn);
@@ -113,5 +114,5 @@
 
 	ddf_fun_t *hub_dev;
-	rc = usb_hc_new_device_wrapper(hc_dev->dev, &hc_conn, USB_SPEED_FULL,
+	rc = usb_hc_new_device_wrapper(ddf_fun_get_dev(hc_dev), &hc_conn, USB_SPEED_FULL,
 	    pretend_port_rest, NULL, NULL, &rh_ops, hc_dev, &hub_dev);
 	if (rc != EOK) {
@@ -123,5 +124,5 @@
 
 	usb_log_info("Created root hub function (handle %zu).\n",
-	    (size_t) hub_dev->handle);
+	    (size_t) ddf_fun_get_handle(hub_dev));
 
 	return 0;
Index: uspace/drv/bus/usb/vhc/main.c
===================================================================
--- uspace/drv/bus/usb/vhc/main.c	(revision 135486df91381258aa51c130b7b463fc4ff5e0a8)
+++ uspace/drv/bus/usb/vhc/main.c	(revision 56fd7cf53b8ee7af3e78e2237e566926562e0291)
@@ -67,5 +67,5 @@
 	}
 
-	vhc_data_t *data = malloc(sizeof(vhc_data_t));
+	vhc_data_t *data = ddf_dev_data_alloc(dev, sizeof(vhc_data_t));
 	if (data == NULL) {
 		usb_log_fatal("Failed to allocate memory.\n");
@@ -89,11 +89,9 @@
 	}
 
-	hc->ops = &vhc_ops;
+	ddf_fun_set_ops(hc, &vhc_ops);
 	list_initialize(&data->devices);
 	fibril_mutex_initialize(&data->guard);
 	data->hub = &virtual_hub_device;
 	data->hc_fun = hc;
-
-	dev->driver_data = data;
 
 	rc = ddf_fun_bind(hc);
@@ -116,7 +114,5 @@
 
 	usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
-	    (size_t) dev->handle, (size_t) hc->handle);
-
-
+	    (size_t) ddf_dev_get_handle(dev), (size_t) ddf_fun_get_handle(hc));
 
 	rc = vhc_virtdev_plug_hub(data, data->hub, NULL);
