Index: uspace/lib/usb/src/hcdhubd.c
===================================================================
--- uspace/lib/usb/src/hcdhubd.c	(revision ba7f6717aa5c46dc46b07495cac2ae3d548369d6)
+++ uspace/lib/usb/src/hcdhubd.c	(revision c39544a2e3b6eaaf8e16c596a73f657acb325cd4)
@@ -113,5 +113,5 @@
 	}
 
-	rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id);
+	rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id, true);
 	if (rc != EOK) {
 		free(id);
@@ -153,7 +153,10 @@
 	add_match_id(&child->match_ids, match_id);
 
+	printf("%s: adding child device `%s' with match \"%s\"\n",
+	    hc_driver->name, child->name, match_id->id);
 	rc = child_device_register(child, child_info->parent);
-	printf("%s: adding child device with match \"%s\" (%s)\n",
-	    hc_driver->name, match_id->id, str_error(rc));
+	printf("%s: child device `%s' registration: %s\n",
+	    hc_driver->name, child->name, str_error(rc));
+
 	if (rc != EOK) {
 		goto failure;
@@ -175,5 +178,5 @@
 leave:
 	free(arg);
-	return rc;
+	return EOK;
 }
 
@@ -182,13 +185,19 @@
  * driven by the same task, the child adding is done in separate fibril.
  * Not optimal, but it works.
+ * Update: not under all circumstances the new fibril is successful either.
+ * Thus the last parameter to let the caller choose.
  *
  * @param parent Parent device.
  * @param name Device name.
  * @param match_id Match id.
+ * @param create_fibril Whether to run the addition in new fibril.
  * @return Error code.
  */
 int usb_hc_add_child_device(device_t *parent, const char *name,
-    const char *match_id)
-{
+    const char *match_id, bool create_fibril)
+{
+	printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
+	    name, match_id);
+
 	struct child_device_info *child_info
 	    = malloc(sizeof(struct child_device_info));
@@ -198,9 +207,13 @@
 	child_info->match_id = match_id;
 
-	fid_t fibril = fibril_create(fibril_add_child_device, child_info);
-	if (!fibril) {
-		return ENOMEM;
-	}
-	fibril_add_ready(fibril);
+	if (create_fibril) {
+		fid_t fibril = fibril_create(fibril_add_child_device, child_info);
+		if (!fibril) {
+			return ENOMEM;
+		}
+		fibril_add_ready(fibril);
+	} else {
+		fibril_add_child_device(child_info);
+	}
 
 	return EOK;
Index: uspace/lib/usb/src/hcdrv.c
===================================================================
--- uspace/lib/usb/src/hcdrv.c	(revision ba7f6717aa5c46dc46b07495cac2ae3d548369d6)
+++ uspace/lib/usb/src/hcdrv.c	(revision c39544a2e3b6eaaf8e16c596a73f657acb325cd4)
@@ -54,8 +54,10 @@
 };
 
-int usb_add_hc_device(device_t *dev)
-{
+static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
 	usb_hc_device_t *hc_dev = malloc(sizeof (usb_hc_device_t));
+
 	list_initialize(&hc_dev->link);
+	list_initialize(&hc_dev->hubs);
+	list_initialize(&hc_dev->attached_devices);
 	hc_dev->transfer_ops = NULL;
 
@@ -63,4 +65,11 @@
 	dev->ops = &usb_device_ops;
 	hc_dev->generic->driver_data = hc_dev;
+
+	return hc_dev;
+}
+
+int usb_add_hc_device(device_t *dev)
+{
+	usb_hc_device_t *hc_dev = usb_hc_device_create(dev);
 
 	int rc = hc_driver->add_hc(hc_dev);
@@ -85,5 +94,5 @@
 	 */
 	printf("%s: trying to add USB HID child device...\n", hc_driver->name);
-	rc = usb_hc_add_child_device(dev, USB_KBD_DEVICE_NAME, "usb&hid");
+	rc = usb_hc_add_child_device(dev, USB_KBD_DEVICE_NAME, "usb&hid", false);
 	if (rc != EOK) {
 		printf("%s: adding USB HID child failed...\n", hc_driver->name);
