Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision 90d7033846a8edda8717433838bf02e35cf19f72)
+++ uspace/lib/usbdev/src/hub.c	(revision 59c163c4895f8831dfc9f2c695c66139130bc011)
@@ -179,5 +179,6 @@
  * @param[in] dev_ops Child device ops. Will use default if not provided.
  * @param[in] new_dev_data Arbitrary pointer to be stored in the child
- *	as @c driver_data.
+ *	as @c driver_data. Will allocate and assign usb_hub_attached_device_t
+ *	structure if NULL.
  * @param[out] new_fun Storage where pointer to allocated child function
  *	will be written. Must be non-null.
@@ -219,5 +220,4 @@
 	}
 
-
 	/*
 	 * Request new address.
@@ -328,15 +328,19 @@
 	}
 
-	/*
-	 * And now inform the host controller about the handle.
-	 */
 	const usb_hub_attached_device_t new_device = {
 		.address = dev_addr,
 		.fun = child_fun,
 	};
+
+
+	/*
+	 * And now inform the host controller about the handle.
+	 */
 	rc = usb_hc_register_device(&hc_conn, &new_device);
 	if (rc != EOK) {
+		/* We know nothing about that data. */
+		if (new_dev_data)
+			child_fun->driver_data = NULL;
 		/* The child function is already created. */
-		child_fun->driver_data = NULL;
 		ddf_fun_destroy(child_fun);
 		rc = EDESTADDRREQ;
Index: uspace/lib/usbdev/src/recognise.c
===================================================================
--- uspace/lib/usbdev/src/recognise.c	(revision 90d7033846a8edda8717433838bf02e35cf19f72)
+++ uspace/lib/usbdev/src/recognise.c	(revision 59c163c4895f8831dfc9f2c695c66139130bc011)
@@ -35,4 +35,6 @@
 #include <sys/types.h>
 #include <fibril_synch.h>
+#include <usb/debug.h>
+#include <usb/dev/hub.h>
 #include <usb/dev/pipes.h>
 #include <usb/dev/recognise.h>
@@ -353,4 +355,9 @@
 		return EINVAL;
 
+	if (!dev_ops && dev_data) {
+		usb_log_warning("Using standard fun ops with arbitrary "
+		    "driver data. This does not have to work.\n");
+	}
+
 	size_t this_device_name_index;
 
@@ -366,11 +373,11 @@
 	usb_pipe_t ctrl_pipe;
 
-	rc = usb_device_connection_initialize(&dev_connection, hc_handle, address);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	rc = usb_pipe_initialize_default_control(&ctrl_pipe,
-	    &dev_connection);
+	rc = usb_device_connection_initialize(
+	    &dev_connection, hc_handle, address);
+	if (rc != EOK) {
+		goto failure;
+	}
+
+	rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_connection);
 	if (rc != EOK) {
 		goto failure;
@@ -405,4 +412,17 @@
 
 	child->driver_data = dev_data;
+	/* Store the attached device in fun driver data if there is no
+	 * other data */
+	if (!dev_data) {
+		usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
+		    child, sizeof(usb_hub_attached_device_t));
+		if (!new_device) {
+			rc = ENOMEM;
+			goto failure;
+		}
+		new_device->address = address;
+		new_device->fun = child;
+	}
+
 
 	rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
@@ -421,7 +441,8 @@
 failure:
 	if (child != NULL) {
-		/* This was not malloced by us, does not even have to be
-		 * on heap. */
-		child->driver_data = NULL;
+		/* We know nothing about the data if it came from outside. */
+		if (dev_data) {
+			child->driver_data = NULL;
+		}
 		/* This takes care of match_id deallocation as well. */
 		ddf_fun_destroy(child);
