Index: uspace/lib/usb/src/hub.c
===================================================================
--- uspace/lib/usb/src/hub.c	(revision 96b8f3222438a558cf7926a03934e7e6e0ca3f20)
+++ uspace/lib/usb/src/hub.c	(revision 87906500fff813e7fa98e3c24caafe7911fef646)
@@ -178,6 +178,11 @@
  * error codes than those listed as return codes by this function itself).
  *
+ * The @p connection representing connection with host controller does not
+ * need to be started.
+ * This function duplicates the connection to allow simultaneous calls of
+ * this function (i.e. from different fibrils).
+ *
  * @param[in] parent Parent device (i.e. the hub device).
- * @param[in] connection Opened connection to host controller.
+ * @param[in] connection Connection to host controller.
  * @param[in] dev_speed New device speed.
  * @param[in] enable_port Function for enabling signaling through the port the
@@ -206,20 +211,33 @@
     ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
 {
-	CHECK_CONNECTION(connection);
+	assert(connection != NULL);
+	// FIXME: this is awful, we are accessing directly the structure.
+	usb_hc_connection_t hc_conn = {
+		.hc_handle = connection->hc_handle,
+		.hc_phone = -1
+	};
+
+	int rc;
+
+	rc = usb_hc_connection_open(&hc_conn);
+	if (rc != EOK) {
+		return rc;
+	}
+
 
 	/*
 	 * Request new address.
 	 */
-	usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
+	usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
 	if (dev_addr < 0) {
+		usb_hc_connection_close(&hc_conn);
 		return EADDRNOTAVAIL;
 	}
 
-	int rc;
 
 	/*
 	 * Reserve the default address.
 	 */
-	rc = usb_hc_reserve_default_address(connection, dev_speed);
+	rc = usb_hc_reserve_default_address(&hc_conn, dev_speed);
 	if (rc != EOK) {
 		rc = EBUSY;
@@ -241,5 +259,5 @@
 	usb_device_connection_t dev_conn;
 	rc = usb_device_connection_initialize_on_default_address(&dev_conn,
-	    connection);
+	    &hc_conn);
 	if (rc != EOK) {
 		rc = ENOTCONN;
@@ -258,5 +276,5 @@
 	 * endpoint.
 	 */
-	rc = usb_pipe_register(&ctrl_pipe, 0, connection);
+	rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
 	if (rc != EOK) {
 		rc = EREFUSED;
@@ -286,5 +304,5 @@
 	 * Register the control endpoint for the new device.
 	 */
-	rc = usb_pipe_register(&ctrl_pipe, 0, connection);
+	rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
 	if (rc != EOK) {
 		rc = EREFUSED;
@@ -295,10 +313,10 @@
 	 * Release the original endpoint.
 	 */
-	unregister_control_endpoint_on_default_address(connection);
+	unregister_control_endpoint_on_default_address(&hc_conn);
 
 	/*
 	 * Once the address is changed, we can return the default address.
 	 */
-	usb_hc_release_default_address(connection);
+	usb_hc_release_default_address(&hc_conn);
 
 
@@ -325,5 +343,5 @@
 		.handle = child_handle
 	};
-	rc = usb_hc_register_device(connection, &new_device);
+	rc = usb_hc_register_device(&hc_conn, &new_device);
 	if (rc != EOK) {
 		rc = EDESTADDRREQ;
@@ -354,11 +372,13 @@
 
 leave_unregister_endpoint:
-	usb_pipe_unregister(&ctrl_pipe, connection);
+	usb_pipe_unregister(&ctrl_pipe, &hc_conn);
 
 leave_release_default_address:
-	usb_hc_release_default_address(connection);
+	usb_hc_release_default_address(&hc_conn);
 
 leave_release_free_address:
-	usb_hc_unregister_device(connection, dev_addr);
+	usb_hc_unregister_device(&hc_conn, dev_addr);
+
+	usb_hc_connection_close(&hc_conn);
 
 	return rc;
