Index: uspace/drv/bus/usb/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision 3875af6590a4482f2b057fc9df39681c9545f726)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision a825eeb05c1e010a5e73089de2df743ccc767e34)
@@ -55,6 +55,5 @@
 };
 
-static void usb_hub_port_removed_device(usb_hub_port_t *port,
-    usb_hub_dev_t *hub);
+static int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub);
 static void usb_hub_port_reset_completed(usb_hub_port_t *port,
     usb_port_status_t status);
@@ -65,11 +64,17 @@
     usb_speed_t speed);
 
+int usb_hub_port_fini(usb_hub_port_t *port, usb_hub_dev_t *hub)
+{
+	assert(port);
+	if (port->attached_device.fun)
+		return usb_hub_port_device_gone(port, hub);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
 /**
  * Clear feature on hub port.
  *
- * @param hc Host controller telephone
- * @param address Hub address
- * @param port_index Port
- * @param feature Feature selector
+ * @param port Port structure.
+ * @param feature Feature selector.
  * @return Operation result
  */
@@ -78,5 +83,5 @@
 {
 	assert(port);
-	usb_device_request_setup_packet_t clear_request = {
+	const usb_device_request_setup_packet_t clear_request = {
 		.request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
 		.request = USB_DEVREQ_CLEAR_FEATURE,
@@ -90,10 +95,8 @@
 /*----------------------------------------------------------------------------*/
 /**
- * Clear feature on hub port.
- *
- * @param hc Host controller telephone
- * @param address Hub address
- * @param port_index Port
- * @param feature Feature selector
+ * Set feature on hub port.
+ *
+ * @param port Port structure.
+ * @param feature Feature selector.
  * @return Operation result
  */
@@ -102,5 +105,5 @@
 {
 	assert(port);
-	usb_device_request_setup_packet_t clear_request = {
+	const usb_device_request_setup_packet_t clear_request = {
 		.request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE,
 		.request = USB_DEVREQ_SET_FEATURE,
@@ -113,4 +116,9 @@
 }
 /*----------------------------------------------------------------------------*/
+/**
+ * Mark reset process as failed due to external reasons
+ *
+ * @param port Port structure
+ */
 void usb_hub_port_reset_fail(usb_hub_port_t *port)
 {
@@ -124,9 +132,9 @@
 /*----------------------------------------------------------------------------*/
 /**
- * Process interrupts on given hub port
+ * Process interrupts on given port
  *
  * Accepts connection, over current and port reset change.
+ * @param port port structure
  * @param hub hub representation
- * @param port port number, starting from 1
  */
 void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub)
@@ -171,5 +179,5 @@
 			 * to that handler, it shall ACK the change too. */
 			if (!(status & USB_HUB_PORT_C_STATUS_ENABLED)) {
-				usb_hub_port_removed_device(port, hub);
+				usb_hub_port_device_gone(port, hub);
 			}
 		}
@@ -180,5 +188,5 @@
 		usb_log_info("Port %zu, disabled because of errors.\n",
 		   port->port_number);
-		usb_hub_port_removed_device(port, hub);
+		usb_hub_port_device_gone(port, hub);
 		const int rc = usb_hub_port_clear_feature(port,
 		        USB_HUB_FEATURE_C_PORT_ENABLE);
@@ -238,5 +246,5 @@
 	    port->port_number, status);
 }
-
+/*----------------------------------------------------------------------------*/
 /**
  * routine called when a device on port has been removed
@@ -245,37 +253,12 @@
  * Otherwise does not do anything, because DDF does not allow to remove device
  * from it`s device tree.
+ * @param port port structure
  * @param hub hub representation
- * @param port port number, starting from 1
- */
-static void usb_hub_port_removed_device(usb_hub_port_t *port,
-    usb_hub_dev_t *hub)
+ */
+int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub)
 {
 	assert(port);
 	assert(hub);
-	if (port->attached_device.address >= 0) {
-		fibril_mutex_lock(&port->mutex);
-		usb_log_debug("Removing device on port %zu.\n",
-		    port->port_number);
-		const int ret = ddf_fun_unbind(port->attached_device.fun);
-		if (ret == EOK) {
-			ddf_fun_destroy(port->attached_device.fun);
-			const int ret =
-			    usb_hc_unregister_device(&hub->connection,
-			        port->attached_device.address);
-			if (ret != EOK) {
-				usb_log_error("Failed to unregister "
-				   "address of removed device: %s.\n",
-				   str_error(ret));
-			}
-		} else {
-			usb_log_error("Failed to unbind child function on port"
-			   " %zu: %s.\n", port->port_number, str_error(ret));
-		}
-		port->attached_device.address = -1;
-		port->attached_device.fun = NULL;
-		fibril_mutex_unlock(&port->mutex);
-		usb_log_info("Removed device on port %zu.\n",
-		    port->port_number);
-	} else {
+	if (port->attached_device.address < 0) {
 		usb_log_warning(
 		    "Device on port %zu removed before being registered.\n",
@@ -288,7 +271,33 @@
 		 */
 		usb_hub_port_reset_fail(port);
-	}
-}
-
+		return EOK;
+	}
+
+	fibril_mutex_lock(&port->mutex);
+	assert(port->attached_device.fun);
+	usb_log_debug("Removing device on port %zu.\n", port->port_number);
+	int ret = ddf_fun_unbind(port->attached_device.fun);
+	if (ret != EOK) {
+		usb_log_error("Failed to unbind child function on port"
+		    " %zu: %s.\n", port->port_number, str_error(ret));
+		fibril_mutex_unlock(&port->mutex);
+		return ret;
+	}
+
+	ddf_fun_destroy(port->attached_device.fun);
+	port->attached_device.fun = NULL;
+
+	ret = usb_hc_unregister_device(&hub->connection,
+	    port->attached_device.address);
+	if (ret != EOK) {
+		usb_log_warning("Failed to unregister address of the removed "
+		    "device: %s.\n", str_error(ret));
+	}
+	port->attached_device.address = -1;
+	fibril_mutex_unlock(&port->mutex);
+	usb_log_info("Removed device on port %zu.\n", port->port_number);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
 /**
  * Process port reset change
@@ -296,9 +305,8 @@
  * After this change port should be enabled, unless some problem occurred.
  * This functions triggers second phase of enabling new device.
- * @param hub
- * @param port
- * @param status
- */
-static void usb_hub_port_reset_completed(usb_hub_port_t *port,
+ * @param port Port structure
+ * @param status Port status mask
+ */
+void usb_hub_port_reset_completed(usb_hub_port_t *port,
     usb_port_status_t status)
 {
@@ -330,6 +338,5 @@
 /** Retrieve port status.
  *
- * @param[in] ctrl_pipe Control pipe to use.
- * @param[in] port Port number (starting at 1).
+ * @param[in] port Port structure
  * @param[out] status Where to store the port status.
  * @return Error code.
@@ -397,11 +404,7 @@
 	fibril_mutex_unlock(&port->mutex);
 
-	if (port->reset_okay) {
-		return EOK;
-	} else {
-		return ESTALL;
-	}
-}
-
+	return port->reset_okay ? EOK : ESTALL;
+}
+/*----------------------------------------------------------------------------*/
 /** Fibril for adding a new device.
  *
@@ -412,5 +415,5 @@
  * @return 0 Always.
  */
-static int add_device_phase1_worker_fibril(void *arg)
+int add_device_phase1_worker_fibril(void *arg)
 {
 	struct add_device_phase1 *data = arg;
@@ -449,7 +452,7 @@
 	free(arg);
 
-	return EOK;
-}
-
+	return rc;
+}
+/*----------------------------------------------------------------------------*/
 /** Start device adding when connection change is detected.
  *
Index: uspace/drv/bus/usb/usbhub/port.h
===================================================================
--- uspace/drv/bus/usb/usbhub/port.h	(revision 3875af6590a4482f2b057fc9df39681c9545f726)
+++ uspace/drv/bus/usb/usbhub/port.h	(revision a825eeb05c1e010a5e73089de2df743ccc767e34)
@@ -76,11 +76,11 @@
 	fibril_condvar_initialize(&port->reset_cv);
 }
-
-void usb_hub_port_reset_fail(usb_hub_port_t *port);
-void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub);
+int usb_hub_port_fini(usb_hub_port_t *port, usb_hub_dev_t *hub);
 int usb_hub_port_clear_feature(
     usb_hub_port_t *port, usb_hub_class_feature_t feature);
 int usb_hub_port_set_feature(
     usb_hub_port_t *port, usb_hub_class_feature_t feature);
+void usb_hub_port_reset_fail(usb_hub_port_t *port);
+void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub);
 
 #endif
Index: uspace/drv/bus/usb/usbhub/usbhub.c
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.c	(revision 3875af6590a4482f2b057fc9df39681c9545f726)
+++ uspace/drv/bus/usb/usbhub/usbhub.c	(revision a825eeb05c1e010a5e73089de2df743ccc767e34)
@@ -98,4 +98,15 @@
 
 	assert(!hub->running);
+
+	for (size_t port = 0; port < hub->port_count; ++port) {
+		if (hub->ports[port].attached_device.fun) {
+			const int ret =
+			    usb_hub_port_fini(&hub->ports[port], hub);
+			if (ret != EOK)
+				return ret;
+		}
+	}
+	free(hub->ports);
+
 	const int ret = ddf_fun_unbind(hub->hub_fun);
 	if (ret != EOK) {
@@ -105,5 +116,5 @@
 	}
 	ddf_fun_destroy(hub->hub_fun);
-	free(hub->ports);
+
 	free(hub);
 	usb_dev->driver_data = NULL;
