Index: uspace/lib/usbdev/include/usb/dev/request.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/request.h	(revision 07a7a97d2fd3576a7118fdd4b06fd18fbeb3a4f7)
+++ uspace/lib/usbdev/include/usb/dev/request.h	(revision 3238506cbb730ad7eb43c2168531ab063f6dcf63)
@@ -115,7 +115,6 @@
 int usb_request_set_feature(usb_pipe_t *, usb_request_type_t,
     usb_request_recipient_t, uint16_t, uint16_t);
-int usb_request_set_address(usb_pipe_t *, usb_address_t);
 int usb_request_get_descriptor(usb_pipe_t *, usb_request_type_t,
-    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 
+    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t,
     size_t *);
 int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t,
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision 07a7a97d2fd3576a7118fdd4b06fd18fbeb3a4f7)
+++ uspace/lib/usbdev/src/hub.c	(revision 3238506cbb730ad7eb43c2168531ab063f6dcf63)
@@ -133,22 +133,50 @@
 }
 
-
-static void unregister_control_endpoint_on_default_address(
-    usb_hc_connection_t *connection)
+/** Change address of connected device.
+ * This function automatically updates the backing connection to point to
+ * the new address. It also unregisterrs the old endpoint and registers
+ * a new one.
+ * This creates whole bunch of problems:
+ *  1. All pipes using this wire are broken because they are not
+ *     registered for new address
+ *  2. All other pipes for this device are using wrong address,
+ *     possibly targeting completely different device
+ *
+ * @param pipe Control endpoint pipe (session must be already started).
+ * @param new_address New USB address to be set (in native endianness).
+ * @return Error code.
+ */
+static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address,
+    usb_hc_connection_t *hc_conn)
 {
-	usb_device_connection_t dev_conn;
-	int rc = usb_device_connection_initialize_on_default_address(&dev_conn,
-	    connection);
-	if (rc != EOK) {
-		return;
-	}
-
-	usb_pipe_t ctrl_pipe;
-	rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
-	if (rc != EOK) {
-		return;
-	}
-
-	usb_pipe_unregister(&ctrl_pipe, connection);
+	if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
+		return EINVAL;
+	}
+	assert(pipe);
+	assert(hc_conn);
+	assert(pipe->wire != NULL);
+
+	const uint16_t addr = uint16_host2usb((uint16_t)new_address);
+
+	int rc = usb_control_request_set(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_SET_ADDRESS, addr, 0, NULL, 0);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* TODO: prevent others from accessing the wire now. */
+	if (usb_pipe_unregister(pipe, hc_conn) != EOK) {
+		usb_log_warning(
+		    "Failed to unregister the old pipe on address change.\n");
+	}
+	/* The address is already changed so set it in the wire */
+	pipe->wire->address = new_address;
+	rc = usb_pipe_register(pipe, 0, hc_conn);
+	if (rc != EOK)
+		return EADDRNOTAVAIL;
+
+	return EOK;
 }
 
@@ -225,5 +253,5 @@
 	 */
 	usb_address_t dev_addr =
-	    usb_hc_request_address(&hc_conn, 1, false, dev_speed);
+	    usb_hc_request_address(&hc_conn, 0, false, dev_speed);
 	if (dev_addr < 0) {
 		rc = EADDRNOTAVAIL;
@@ -246,6 +274,5 @@
 
 	usb_pipe_t ctrl_pipe;
-	rc = usb_pipe_initialize_default_control(&ctrl_pipe,
-	    &dev_conn);
+	rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
 	if (rc != EOK) {
 		rc = ENOTCONN;
@@ -256,13 +283,14 @@
 		rc = usb_hc_request_address(&hc_conn, USB_ADDRESS_DEFAULT,
 		    true, dev_speed);
-		if (rc != USB_ADDRESS_DEFAULT) {
+		if (rc == ENOENT) {
 			/* Do not overheat the CPU ;-). */
 			async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
 		}
 	} while (rc == ENOENT);
-	if (rc != EOK) {
+	if (rc < 0) {
 		goto leave_release_free_address;
 	}
 
+	/* Register control pipe on default address. */
 	rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
 	if (rc != EOK) {
@@ -283,13 +311,10 @@
 	 * above might use much of this time so we should only wait to fill
 	 * up the 100ms quota*/
-	suseconds_t elapsed = tv_sub(&end_time, &start_time);
+	const suseconds_t elapsed = tv_sub(&end_time, &start_time);
 	if (elapsed < 100000) {
 		async_usleep(100000 - elapsed);
 	}
 
-	/*
-	 * Endpoint is registered. We can enable the port and change
-	 * device address.
-	 */
+	/* Endpoint is registered. We can enable the port and change address. */
 	rc = enable_port(arg);
 	if (rc != EOK) {
@@ -303,4 +328,5 @@
 	async_usleep(10000);
 
+	/* Get max_packet_size value. */
 	rc = usb_pipe_probe_default_control(&ctrl_pipe);
 	if (rc != EOK) {
@@ -309,5 +335,5 @@
 	}
 
-	rc = usb_request_set_address(&ctrl_pipe, dev_addr);
+	rc = usb_request_set_address(&ctrl_pipe, dev_addr, &hc_conn);
 	if (rc != EOK) {
 		rc = ESTALL;
@@ -315,22 +341,9 @@
 	}
 
-	/*
-	 * Address changed. We can release the original endpoint, thus
-	 * allowing other to access the default address.
-	 */
-	unregister_control_endpoint_on_default_address(&hc_conn);
+	/* Address changed. We can release the default, thus
+	 * allowing other to access the default address. */
 	usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT);
 
-	/*
-	 * Time to register the new endpoint.
-	 */
-	rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
-	if (rc != EOK) {
-		goto leave_release_free_address;
-	}
-
-	/*
-	 * It is time to register the device with devman.
-	 */
+	/* Register the device with devman. */
 	/* FIXME: create device_register that will get opened ctrl pipe. */
 	ddf_fun_t *child_fun;
@@ -347,7 +360,5 @@
 
 
-	/*
-	 * And now inform the host controller about the handle.
-	 */
+	/* Inform the host controller about the handle. */
 	rc = usb_hc_register_device(&hc_conn, &new_device);
 	if (rc != EOK) {
@@ -361,13 +372,9 @@
 	}
 
-	/*
-	 * And we are done.
-	 */
 	if (assigned_address != NULL) {
 		*assigned_address = dev_addr;
 	}
-	if (new_fun != NULL) {
-		*new_fun = child_fun;
-	}
+
+	*new_fun = child_fun;
 
 	rc = EOK;
@@ -382,7 +389,4 @@
 
 leave_release_free_address:
-	if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK)
-		usb_log_warning("%s: Failed to unregister device.\n",
-		    __FUNCTION__);
 	/* This might be either 0:0 or dev_addr:0 */
 	if (usb_pipe_unregister(&ctrl_pipe, &hc_conn) != EOK)
@@ -390,7 +394,11 @@
 		    __FUNCTION__);
 
+	if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK)
+		usb_log_warning("%s: Failed to unregister device.\n",
+		    __FUNCTION__);
+
 close_connection:
 	if (usb_hc_connection_close(&hc_conn) != EOK)
-		usb_log_warning("%s: Failed to close connection.\n",
+		usb_log_warning("%s: Failed to close hc connection.\n",
 		    __FUNCTION__);
 
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision 07a7a97d2fd3576a7118fdd4b06fd18fbeb3a4f7)
+++ uspace/lib/usbdev/src/request.c	(revision 3238506cbb730ad7eb43c2168531ab063f6dcf63)
@@ -250,38 +250,4 @@
 }
 
-/** Change address of connected device.
- * This function automatically updates the backing connection to point to
- * the new address.
- *
- * @param pipe Control endpoint pipe (session must be already started).
- * @param new_address New USB address to be set (in native endianness).
- * @return Error code.
- */
-int usb_request_set_address(usb_pipe_t *pipe,
-    usb_address_t new_address)
-{
-	if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
-		return EINVAL;
-	}
-
-	uint16_t addr = uint16_host2usb((uint16_t)new_address);
-
-	int rc = usb_control_request_set(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DEVREQ_SET_ADDRESS,
-	    addr, 0,
-	    NULL, 0);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	assert(pipe->wire != NULL);
-	/* TODO: prevent other from accessing wire now. */
-	pipe->wire->address = new_address;
-
-	return EOK;
-}
-
 /** Retrieve USB descriptor of a USB device.
  *
