Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -193,5 +193,5 @@
 	instance->rh.address = 1;
 	rc = usb_device_manager_request_address(
-	    &instance->generic.dev_manager, &instance->rh.address, false,
+	    &instance->generic->dev_manager, &instance->rh.address, false,
 	    USB_SPEED_FULL);
 	if (rc != EOK) {
@@ -204,5 +204,5 @@
 
 	rc = usb_endpoint_manager_add_ep(
-	    &instance->generic.ep_manager, instance->rh.address, 0,
+	    &instance->generic->ep_manager, instance->rh.address, 0,
 	    USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
 	    0, NULL, NULL);
@@ -231,5 +231,5 @@
 	fun_bound = true;
 
-	rc = usb_device_manager_bind_address(&instance->generic.dev_manager,
+	rc = usb_device_manager_bind_address(&instance->generic->dev_manager,
 	    instance->rh.address, ddf_fun_get_handle(hub_fun));
 	if (rc != EOK) {
@@ -244,10 +244,10 @@
 	if (ep_added) {
 		usb_endpoint_manager_remove_ep(
-		    &instance->generic.ep_manager, instance->rh.address, 0,
+		    &instance->generic->ep_manager, instance->rh.address, 0,
 		    USB_DIRECTION_BOTH, NULL, NULL);
 	}
 	if (addr_reqd) {
 		usb_device_manager_release_address(
-		    &instance->generic.dev_manager, instance->rh.address);
+		    &instance->generic->dev_manager, instance->rh.address);
 	}
 	return rc;
@@ -257,9 +257,10 @@
  *
  * @param[in] instance Memory place for the structure.
+ * @param[in] HC function node
  * @param[in] regs Device's I/O registers range.
  * @param[in] interrupts True if w interrupts should be used
  * @return Error code
  */
-int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts)
+int hc_init(hc_t *instance, ddf_fun_t *fun, addr_range_t *regs, bool interrupts)
 {
 	assert(instance);
@@ -274,10 +275,16 @@
 	list_initialize(&instance->pending_batches);
 
-	hcd_init(&instance->generic, USB_SPEED_FULL,
+	instance->generic = ddf_fun_data_alloc(fun, sizeof(hcd_t));
+	if (instance->generic == NULL) {
+		usb_log_error("Out of memory.\n");
+		return ENOMEM;
+	}
+
+	hcd_init(instance->generic, USB_SPEED_FULL,
 	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
-	instance->generic.private_data = instance;
-	instance->generic.schedule = hc_schedule;
-	instance->generic.ep_add_hook = ohci_endpoint_init;
-	instance->generic.ep_remove_hook = ohci_endpoint_fini;
+	instance->generic->private_data = instance;
+	instance->generic->schedule = hc_schedule;
+	instance->generic->ep_add_hook = ohci_endpoint_init;
+	instance->generic->ep_remove_hook = ohci_endpoint_fini;
 
 	rc = hc_init_memory(instance);
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -35,4 +35,5 @@
 #define DRV_OHCI_HC_H
 
+#include <ddf/driver.h>
 #include <ddf/interrupt.h>
 #include <fibril.h>
@@ -53,5 +54,5 @@
 typedef struct hc {
 	/** Generic USB hc driver */
-	hcd_t generic;
+	hcd_t *generic;
 
 	/** Memory mapped I/O registers area */
@@ -79,6 +80,6 @@
 int hc_register_irq_handler(ddf_dev_t *, addr_range_t *, int,
     interrupt_handler_t);
-int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
-int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts);
+int hc_register_hub(hc_t *, ddf_fun_t *);
+int hc_init(hc_t *, ddf_fun_t *, addr_range_t *, bool);
 
 /** Safely dispose host controller internal structures
Index: uspace/drv/bus/usb/ohci/ohci.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/ohci/ohci.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -34,7 +34,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <errno.h>
 #include <str_error.h>
@@ -165,5 +162,4 @@
 
 	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");
@@ -214,5 +210,5 @@
 	}
 
-	rc = hc_init(&instance->hc, &regs, interrupts);
+	rc = hc_init(&instance->hc, instance->hc_fun, &regs, interrupts);
 	if (rc != EOK) {
 		usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -230,4 +230,5 @@
  *
  * @param[in] instance Memory place to initialize.
+ * @param[in] HC function node
  * @param[in] regs Range of device's I/O control registers.
  * @param[in] interrupts True if hw interrupts should be used.
@@ -238,5 +239,5 @@
  * interrupt fibrils.
  */
-int hc_init(hc_t *instance, addr_range_t *regs, bool interrupts)
+int hc_init(hc_t *instance, ddf_fun_t *fun, addr_range_t *regs, bool interrupts)
 {
 	assert(regs->size >= sizeof(uhci_regs_t));
@@ -266,10 +267,16 @@
 	}
 
-	hcd_init(&instance->generic, USB_SPEED_FULL,
+	instance->generic = ddf_fun_data_alloc(fun, sizeof(hcd_t));
+	if (instance->generic == NULL) {
+		usb_log_error("Out of memory.\n");
+		return ENOMEM;
+	}
+
+	hcd_init(instance->generic, USB_SPEED_FULL,
 	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
 
-	instance->generic.private_data = instance;
-	instance->generic.schedule = hc_schedule;
-	instance->generic.ep_add_hook = NULL;
+	instance->generic->private_data = instance;
+	instance->generic->schedule = hc_schedule;
+	instance->generic->ep_add_hook = NULL;
 
 	hc_init_hw(instance);
Index: uspace/drv/bus/usb/uhci/hc.h
===================================================================
--- uspace/drv/bus/usb/uhci/hc.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/uhci/hc.h	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -36,4 +36,5 @@
 #define DRV_UHCI_HC_H
 
+#include <ddf/driver.h>
 #include <ddf/interrupt.h>
 #include <device/hw_res_parsed.h>
@@ -93,5 +94,5 @@
 typedef struct hc {
 	/** Generic HCD driver structure */
-	hcd_t generic;
+	hcd_t *generic;
 
 	/** Addresses of I/O registers */
@@ -126,5 +127,5 @@
     addr_range_t *);
 void hc_interrupt(hc_t *instance, uint16_t status);
-int hc_init(hc_t *instance, addr_range_t *regs, bool interupts);
+int hc_init(hc_t *, ddf_fun_t *, addr_range_t *, bool);
 
 /** Safely dispose host controller internal structures
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -34,7 +34,4 @@
  */
 
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
-
 #include <errno.h>
 #include <stdbool.h>
@@ -62,5 +59,5 @@
 	hc_t hc;
 	/** Internal driver's representation of UHCI root hub */
-	rh_t rh;
+	rh_t *rh;
 } uhci_t;
 
@@ -186,5 +183,4 @@
 
 	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");
@@ -196,5 +192,5 @@
 
 	ddf_fun_set_ops(instance->rh_fun, &rh_ops);
-	ddf_fun_data_implant(instance->rh_fun, &instance->rh);
+	instance->rh = ddf_fun_data_alloc(instance->rh_fun, sizeof(rh_t));
 
 	addr_range_t regs;
@@ -236,5 +232,5 @@
 	}
 
-	rc = hc_init(&instance->hc, &regs, interrupts);
+	rc = hc_init(&instance->hc, instance->hc_fun, &regs, interrupts);
 	if (rc != EOK) {
 		usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc));
@@ -260,5 +256,5 @@
 	}
 
-	rc = rh_init(&instance->rh, instance->rh_fun, &regs, 0x10, 4);
+	rc = rh_init(instance->rh, instance->rh_fun, &regs, 0x10, 4);
 	if (rc != EOK) {
 		usb_log_error("Failed to setup UHCI root hub: %s.\n",
Index: uspace/drv/bus/usb/uhcirh/port.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/uhcirh/port.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -269,8 +269,22 @@
 	int ret, count = MAX_ERROR_COUNT;
 	do {
-		ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
+		port->attached_device.fun = ddf_fun_create(port->rh, fun_inner,
+		    NULL);
+		if (port->attached_device.fun == NULL) {
+			ret = ENOMEM;
+			continue;
+		}
+
+		ret = usb_hc_new_device_wrapper(port->rh,
+		    port->attached_device.fun,
+		    &port->hc_connection,
 		    speed, uhci_port_reset_enable, port,
-		    &port->attached_device.address, NULL, NULL,
-		    &port->attached_device.fun);
+		    &port->attached_device.address, NULL);
+
+		if (ret != EOK) {
+			ddf_fun_destroy(port->attached_device.fun);
+			port->attached_device.fun = NULL;
+		}
+
 	} while (ret != EOK && count-- > 0);
 
Index: uspace/drv/bus/usb/usbhid/usbhid.c
===================================================================
--- uspace/drv/bus/usb/usbhid/usbhid.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/usbhid/usbhid.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -415,14 +415,5 @@
 	}
 
-	/*
-	 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
-	 *    do nej.
-	 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 
-	 *    vyplnenu strukturu usbhid_iface_t.
-	 * 3) klientska aplikacia - musi si rucne vytvorit telefon
-	 *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 
-	 *    k tej fcii.
-	 *    pouzit usb/classes/hid/iface.h - prvy int je telefon
-	 */
+	/* Initialize subdrivers */
 	bool ok = false;
 	for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) {
Index: uspace/drv/bus/usb/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -424,7 +424,12 @@
 	ddf_fun_t *child_fun;
 
+	child_fun = ddf_fun_create(data->hub->usb_device->ddf_dev,
+	    fun_inner, NULL);
+	if (child_fun == NULL)
+		return ENOMEM;
+
 	const int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,
-	    &data->hub->usb_device->hc_conn, data->speed, enable_port_callback,
-	    data->port, &new_address, NULL, NULL, &child_fun);
+	    child_fun, &data->hub->usb_device->hc_conn, data->speed,
+	    enable_port_callback, data->port, &new_address, NULL);
 
 	if (rc == EOK) {
@@ -440,4 +445,5 @@
 		    ddf_fun_get_handle(child_fun));
 	} else {
+		ddf_fun_destroy(child_fun);
 		usb_log_error("Failed registering device on port %zu: %s.\n",
 		    data->port->port_number, str_error(rc));
Index: uspace/drv/bus/usb/usbmid/explore.c
===================================================================
--- uspace/drv/bus/usb/usbmid/explore.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/usbmid/explore.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -34,4 +34,5 @@
  * Exploration of available interfaces in the USB device.
  */
+#include <ddf/driver.h>
 #include <errno.h>
 #include <str_error.h>
@@ -70,7 +71,8 @@
  * @param config_descriptor_size Size of configuration descriptor in bytes.
  * @param list List where to add the interfaces.
- */
-static void create_interfaces(const uint8_t *config_descriptor,
-    size_t config_descriptor_size, list_t *list)
+ * @return EOK on success, ENOMEM if out of memory.
+ */
+static int create_interfaces(usb_mid_t *mid, const uint8_t *config_descriptor,
+    size_t config_descriptor_size)
 {
 	const usb_dp_parser_data_t data = {
@@ -101,22 +103,40 @@
 
 		/* Skip alternate interfaces. */
-		if (interface_in_list(list, interface->interface_number)) {
+		if (interface_in_list(&mid->interface_list,
+		    interface->interface_number)) {
 			/* TODO: add the alternatives and create match ids
 			 * for them. */
 			continue;
 		}
-		usbmid_interface_t *iface = malloc(sizeof(usbmid_interface_t));
-		if (iface == NULL) {
-			//TODO: Do something about that failure.
-			break;
-		}
+
+		/* Create the function */
+		ddf_fun_t *fun = ddf_fun_create(mid->dev, fun_inner, NULL);
+		if (fun == NULL)
+			goto error;
+
+		usbmid_interface_t *iface = ddf_fun_data_alloc(fun,
+		    sizeof(usbmid_interface_t));
+		if (iface == NULL)
+			goto error;
 
 		link_initialize(&iface->link);
-		iface->fun = NULL;
+		iface->fun = fun;
 		iface->interface_no = interface->interface_number;
 		iface->interface = interface;
 
-		list_append(&iface->link, list);
-	}
+		list_append(&iface->link, &mid->interface_list);
+	}
+
+	return EOK;
+error:
+	while (!list_empty(&mid->interface_list)) {
+		link_t *link = list_first(&mid->interface_list);
+		usbmid_interface_t *iface = list_get_instance(link,
+		    usbmid_interface_t, link);
+
+		ddf_fun_destroy(iface->fun);
+	}
+
+	return ENOMEM;
 }
 
@@ -165,4 +185,6 @@
 	}
 
+	usb_mid->dev = dev->ddf_dev;
+
 	/* Create control function. */
 	usb_mid->ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl");
@@ -182,9 +204,7 @@
 	}
 
-
 	/* Create interface children. */
 	list_initialize(&usb_mid->interface_list);
-	create_interfaces(config_descriptor_raw, config_descriptor_size,
-	    &usb_mid->interface_list);
+	create_interfaces(usb_mid, config_descriptor_raw, config_descriptor_size);
 
 	/* Start child function for every interface. */
Index: uspace/drv/bus/usb/usbmid/usbmid.c
===================================================================
--- uspace/drv/bus/usb/usbmid/usbmid.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/usbmid/usbmid.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -30,7 +30,4 @@
  * @{
  */
-
-/* XXX Fix this */
-#define _DDF_DATA_IMPLANT
 
 /**
@@ -102,5 +99,4 @@
     const usb_standard_interface_descriptor_t *interface_descriptor)
 {
-	ddf_fun_t *child = NULL;
 	char *child_name = NULL;
 	int rc;
@@ -114,14 +110,11 @@
 	    usb_str_class(interface_descriptor->interface_class),
 	    interface_descriptor->interface_number);
-	if (rc < 0) {
+	if (rc < 0)
 		return ENOMEM;
-	}
 
-	/* Create the device. */
-	child = ddf_fun_create(parent->ddf_dev, fun_inner, child_name);
+	rc = ddf_fun_set_name(iface->fun, child_name);
 	free(child_name);
-	if (child == NULL) {
+	if (rc != EOK)
 		return ENOMEM;
-	}
 
 	match_id_list_t match_ids;
@@ -130,14 +123,11 @@
 	rc = usb_device_create_match_ids_from_interface(device_descriptor,
 	    interface_descriptor, &match_ids);
-	if (rc != EOK) {
-		ddf_fun_destroy(child);
+	if (rc != EOK)
 		return rc;
-	}
 
 	list_foreach(match_ids.ids, link, match_id_t, match_id) {
-		rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
+		rc = ddf_fun_add_match_id(iface->fun, match_id->id, match_id->score);
 		if (rc != EOK) {
 			clean_match_ids(&match_ids);
-			ddf_fun_destroy(child);
 			return rc;
 		}
@@ -145,14 +135,9 @@
 	clean_match_ids(&match_ids);
 
-	rc = ddf_fun_bind(child);
-	if (rc != EOK) {
-		/* This takes care of match_id deallocation as well. */
-		ddf_fun_destroy(child);
+	ddf_fun_set_ops(iface->fun, &child_device_ops);
+
+	rc = ddf_fun_bind(iface->fun);
+	if (rc != EOK)
 		return rc;
-	}
-
-	iface->fun = child;
-	ddf_fun_data_implant(child, iface);
-	ddf_fun_set_ops(child, &child_device_ops);
 
 	return EOK;
Index: uspace/drv/bus/usb/usbmid/usbmid.h
===================================================================
--- uspace/drv/bus/usb/usbmid/usbmid.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/usbmid/usbmid.h	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -60,4 +60,5 @@
 /** Container to hold all the function pointers */
 typedef struct usb_mid {
+	ddf_dev_t *dev;
 	ddf_fun_t *ctl_fun;
 	list_t interface_list;
Index: uspace/drv/bus/usb/vhc/hub.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/bus/usb/vhc/hub.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -94,15 +94,4 @@
 {
 	ddf_fun_t *hc_dev = (ddf_fun_t *) arg;
-
-	/*
-	 * Wait until parent device is properly initialized.
-	 */
-	async_sess_t *sess;
-	do {
-		sess = devman_device_connect(EXCHANGE_SERIALIZE,
-		    ddf_fun_get_handle(hc_dev), 0);
-	} while (!sess);
-	async_hangup(sess);
-
 	int rc;
 
@@ -114,9 +103,19 @@
 
 	ddf_fun_t *hub_dev;
-	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);
+
+	hub_dev = ddf_fun_create(ddf_fun_get_dev(hc_dev), fun_inner, NULL);
+	if (hub_dev == NULL) {
+		rc = ENOMEM;
+		usb_log_fatal("Failed to create root hub: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+
+	rc = usb_hc_new_device_wrapper(ddf_fun_get_dev(hc_dev), hub_dev,
+	    &hc_conn, USB_SPEED_FULL, pretend_port_rest, NULL, NULL, &rh_ops);
 	if (rc != EOK) {
 		usb_log_fatal("Failed to create root hub: %s.\n",
 		    str_error(rc));
+		ddf_fun_destroy(hub_dev);
 	}
 
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/nic/e1k/e1k.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -71,5 +71,5 @@
 /** ddf_fun_t * -> nic_driver_data_t* cast */
 #define NIC_DATA_FUN(fun) \
-	((nic_t *) ddf_fun_data_get(fun))
+	((nic_t *) ddf_dev_data_get(ddf_fun_get_dev(fun)))
 
 /** ddf_dev_t * -> nic_driver_data_t* cast */
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/drv/nic/rtl8169/driver.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -439,5 +439,5 @@
 	nic_set_ddf_fun(nic_data, fun);
 	ddf_fun_set_ops(fun, &rtl8169_dev_ops);
-	ddf_fun_data_implant(fun, nic_data);
+//	ddf_fun_data_implant(fun, nic_data);
 
 	rc = ddf_fun_bind(fun);
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/drv/generic/driver.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -36,6 +36,4 @@
 /** @file
  */
-
-#define _DDF_DATA_IMPLANT
 
 #include <assert.h>
@@ -596,15 +594,4 @@
 }
 
-/** Implant foreign driver-specific device data.
- *
- * XXX This is used to transition USB to new interface. Do not use
- * in new code. Use of this function must be removed.
- */
-void ddf_fun_data_implant(ddf_fun_t *fun, void *data)
-{
-	assert(fun->driver_data == NULL);
-	fun->driver_data = data;
-}
-
 /** Return driver-specific device data. */
 void *ddf_dev_data_get(ddf_dev_t *dev)
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/drv/include/ddf/driver.h	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -111,9 +111,4 @@
 } driver_t;
 
-/** XXX Only to transition USB */
-#ifdef _DDF_DATA_IMPLANT
-extern void ddf_fun_data_implant(ddf_fun_t *, void *);
-#endif
-
 extern int ddf_driver_main(const driver_t *);
 
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/nic/src/nic_driver.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -47,4 +47,6 @@
 #include <ops/nic.h>
 #include <errno.h>
+
+#include <io/log.h>
 
 #include "nic_driver.h"
@@ -436,4 +438,6 @@
 		int rc = nic_ev_addr_changed(nic_data->client_session,
 		    address);
+		log_msg(LOG_DEFAULT, LVL_WARN, "rc=%d", rc);
+
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&nic_data->main_lock);
Index: uspace/lib/nic/src/nic_impl.c
===================================================================
--- uspace/lib/nic/src/nic_impl.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/nic/src/nic_impl.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -179,4 +179,5 @@
 
 	nic_data->send_frame(nic_data, data, size);
+	fibril_rwlock_read_unlock(&nic_data->main_lock);
 	return EOK;
 }
Index: uspace/lib/usbdev/include/usb/dev/hub.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/hub.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/usbdev/include/usb/dev/hub.h	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -44,7 +44,7 @@
 #include <usb/hc.h>
 
-extern int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
-    int (*)(void *), void *, usb_address_t *, ddf_dev_ops_t *, void *,
-    ddf_fun_t **);
+extern int usb_hc_new_device_wrapper(ddf_dev_t *, ddf_fun_t *,
+    usb_hc_connection_t *, usb_speed_t, int (*)(void *), void *,
+    usb_address_t *, ddf_dev_ops_t *);
 
 /** Info about device attached to host controller.
Index: uspace/lib/usbdev/include/usb/dev/recognise.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/recognise.h	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/usbdev/include/usb/dev/recognise.h	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -52,5 +52,5 @@
 
 extern int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
-    ddf_dev_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
+    ddf_dev_t *, ddf_fun_t *, ddf_dev_ops_t *);
 
 #endif
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/usbdev/src/hub.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -155,10 +155,10 @@
  *	request or requests for descriptors when creating match ids).
  */
-int usb_hc_new_device_wrapper(ddf_dev_t *parent,
+int usb_hc_new_device_wrapper(ddf_dev_t *parent, ddf_fun_t *fun,
     usb_hc_connection_t *hc_conn, usb_speed_t dev_speed,
     int (*enable_port)(void *arg), void *arg, usb_address_t *assigned_address,
-    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
+    ddf_dev_ops_t *dev_ops)
 {
-	if ((new_fun == NULL) || (hc_conn == NULL))
+	if (hc_conn == NULL)
 		return EINVAL;
 
@@ -271,7 +271,6 @@
 	/* Register the device with devman. */
 	/* FIXME: create device_register that will get opened ctrl pipe. */
-	ddf_fun_t *child_fun;
 	rc = usb_device_register_child_in_devman(&ctrl_pipe,
-	    parent, dev_ops, new_dev_data, &child_fun);
+	    parent, fun, dev_ops);
 	if (rc != EOK) {
 		goto leave_release_free_address;
@@ -280,5 +279,5 @@
 	const usb_hub_attached_device_t new_device = {
 		.address = dev_addr,
-		.fun = child_fun,
+		.fun = fun,
 	};
 
@@ -288,5 +287,4 @@
 	if (rc != EOK) {
 		/* The child function is already created. */
-		ddf_fun_destroy(child_fun);
 		rc = EDESTADDRREQ;
 		goto leave_release_free_address;
@@ -296,6 +294,4 @@
 		*assigned_address = dev_addr;
 	}
-
-	*new_fun = child_fun;
 
 	rc = EOK;
Index: uspace/lib/usbdev/src/recognise.c
===================================================================
--- uspace/lib/usbdev/src/recognise.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/lib/usbdev/src/recognise.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -33,7 +33,4 @@
  * Functions for recognition of attached devices.
  */
-
-/** XXX Fix this */
-#define _DDF_DATA_IMPLANT
 
 #include <sys/types.h>
@@ -318,11 +315,10 @@
  */
 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
-    ddf_dev_t *parent, ddf_dev_ops_t *dev_ops, void *dev_data,
-    ddf_fun_t **child_fun)
-{
-	if (child_fun == NULL || ctrl_pipe == NULL)
+    ddf_dev_t *parent, ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
+{
+	if (ctrl_pipe == NULL)
 		return EINVAL;
 	
-	if (!dev_ops && dev_data) {
+	if (!dev_ops && ddf_fun_data_get(fun) != NULL) {
 		usb_log_warning("Using standard fun ops with arbitrary "
 		    "driver data. This does not have to work.\n");
@@ -334,5 +330,4 @@
 	    (size_t) atomic_preinc(&device_name_index);
 	
-	ddf_fun_t *child = NULL;
 	int rc;
 	
@@ -348,16 +343,12 @@
 	}
 	
-	child = ddf_fun_create(parent, fun_inner, child_name);
-	if (child == NULL) {
-		rc = ENOMEM;
+	rc = ddf_fun_set_name(fun, child_name);
+	if (rc != EOK)
 		goto failure;
-	}
 	
 	if (dev_ops != NULL)
-		ddf_fun_set_ops(child, dev_ops);
+		ddf_fun_set_ops(fun, dev_ops);
 	else
-		ddf_fun_set_ops(child, &child_ops);
-	
-	ddf_fun_data_implant(child, dev_data);
+		ddf_fun_set_ops(fun, &child_ops);
 	
 	/*
@@ -365,7 +356,7 @@
 	 * driver data if there is no other data
 	 */
-	if (!dev_data) {
+	if (ddf_fun_data_get(fun) == NULL) {
 		usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
-		    child, sizeof(usb_hub_attached_device_t));
+		    fun, sizeof(usb_hub_attached_device_t));
 		if (!new_device) {
 			rc = ENOMEM;
@@ -374,5 +365,5 @@
 		
 		new_device->address = ctrl_pipe->wire->address;
-		new_device->fun = child;
+		new_device->fun = fun;
 	}
 	
@@ -384,5 +375,5 @@
 	
 	list_foreach(match_ids.ids, link, match_id_t, match_id) {
-		rc = ddf_fun_add_match_id(child, match_id->id, match_id->score);
+		rc = ddf_fun_add_match_id(fun, match_id->id, match_id->score);
 		if (rc != EOK) {
 			clean_match_ids(&match_ids);
@@ -393,17 +384,11 @@
 	clean_match_ids(&match_ids);
 	
-	rc = ddf_fun_bind(child);
+	rc = ddf_fun_bind(fun);
 	if (rc != EOK)
 		goto failure;
 	
-	*child_fun = child;
 	return EOK;
 	
 failure:
-	if (child != NULL) {
-		/* This takes care of match_id deallocation as well. */
-		ddf_fun_destroy(child);
-	}
-	
 	return rc;
 }
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision cbfece72626dbcd93661ce58b0575c5602ad9660)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision 1f1fa6420a71dbef5d82ed476f6f5411487e7144)
@@ -231,6 +231,20 @@
     ipc_call_t *call)
 {
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_changed()");
-	async_answer_0(callid, ENOTSUP);
+	uint8_t *addr;
+	size_t size;
+	int rc;
+
+	rc = async_data_write_accept((void **)&addr, false, 0, 0, 0, &size);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "data_write_accept() failed");
+		return;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_changed(): "
+	    "new addr=%02x:%02x:%02x:%02x:%02x:%02x",
+	    addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+
+	free(addr);
+	async_answer_0(callid, EOK);
 }
 
@@ -295,4 +309,5 @@
 			break;
 		default:
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %d", IPC_GET_IMETHOD(call));
 			async_answer_0(callid, ENOTSUP);
 		}
