Index: uspace/drv/bus/usb/uhcirh/port.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.c	(revision b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/drv/bus/usb/uhcirh/port.c	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -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/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -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/vhc/hub.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub.c	(revision b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/drv/bus/usb/vhc/hub.c	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -114,9 +114,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/lib/usbdev/include/usb/dev/hub.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/hub.h	(revision b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/lib/usbdev/include/usb/dev/hub.h	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -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 b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/lib/usbdev/include/usb/dev/recognise.h	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -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 b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/lib/usbdev/src/hub.c	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -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 b5111c46021cac567ff85e5ffa9f39811311f805)
+++ uspace/lib/usbdev/src/recognise.c	(revision ffa96c243f74449ac2805eb79c0595d3a4d5f9ba)
@@ -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;
 }
