Index: uspace/drv/usbhub/ports.c
===================================================================
--- uspace/drv/usbhub/ports.c	(revision 0d59d0e99709ef15e7ba51b20f1f96a86e8c7a45)
+++ uspace/drv/usbhub/ports.c	(revision 3fb5a3eb79e89579c13ef4806f8f1daf70895f3f)
@@ -407,4 +407,11 @@
 	free(arg);
 
+	fibril_mutex_lock(&data->hub->pending_ops_mutex);
+	assert(data->hub->pending_ops_count > 0);
+	data->hub->pending_ops_count--;
+	fibril_condvar_signal(&data->hub->pending_ops_cv);
+	fibril_mutex_unlock(&data->hub->pending_ops_mutex);
+
+
 	return EOK;
 }
@@ -452,4 +459,7 @@
 		return ENOMEM;
 	}
+	fibril_mutex_lock(&hub->pending_ops_mutex);
+	hub->pending_ops_count++;
+	fibril_mutex_unlock(&hub->pending_ops_mutex);
 	fibril_add_ready(fibril);
 
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision 0d59d0e99709ef15e7ba51b20f1f96a86e8c7a45)
+++ uspace/drv/usbhub/usbhub.c	(revision 3fb5a3eb79e89579c13ef4806f8f1daf70895f3f)
@@ -72,5 +72,5 @@
 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
 
-static void usb_hub_polling_terminted_callback(usb_device_t * device,
+static void usb_hub_polling_terminated_callback(usb_device_t * device,
     bool was_error, void * data);
 
@@ -200,4 +200,8 @@
 	result->control_pipe = &usb_dev->ctrl_pipe;
 	result->is_default_address_used = false;
+
+	fibril_mutex_initialize(&result->pending_ops_mutex);
+	fibril_condvar_initialize(&result->pending_ops_cv);
+	result->pending_ops_count = 0;
 	return result;
 }
@@ -340,5 +344,5 @@
 	rc = usb_device_auto_poll(hub_info->usb_device, 0,
 	    hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1,
-	    usb_hub_polling_terminted_callback, hub_info);
+	    usb_hub_polling_terminated_callback, hub_info);
 	if (rc != EOK) {
 		usb_log_error("Failed to create polling fibril: %s.\n",
@@ -473,10 +477,18 @@
  * @param data pointer to usb_hub_info_t structure
  */
-static void usb_hub_polling_terminted_callback(usb_device_t * device,
+static void usb_hub_polling_terminated_callback(usb_device_t * device,
     bool was_error, void * data){
-	usb_hub_info_t * hub_info = data;
-	if(!hub_info) return;
-	free(hub_info->ports);
-	free(hub_info);
+	usb_hub_info_t * hub = data;
+	assert(hub);
+
+	fibril_mutex_lock(&hub->pending_ops_mutex);
+	while (hub->pending_ops_count > 0) {
+		fibril_condvar_wait(&hub->pending_ops_cv,
+		    &hub->pending_ops_mutex);
+	}
+	fibril_mutex_unlock(&hub->pending_ops_mutex);
+
+	free(hub->ports);
+	free(hub);
 }
 
Index: uspace/drv/usbhub/usbhub.h
===================================================================
--- uspace/drv/usbhub/usbhub.h	(revision 0d59d0e99709ef15e7ba51b20f1f96a86e8c7a45)
+++ uspace/drv/usbhub/usbhub.h	(revision 3fb5a3eb79e89579c13ef4806f8f1daf70895f3f)
@@ -89,4 +89,17 @@
 	/** generic usb device data*/
 	usb_device_t * usb_device;
+
+	/** Number of pending operations on the mutex to prevent shooting
+	 * ourselves in the foot.
+	 * When the hub is disconnected but we are in the middle of some
+	 * operation, we cannot destroy this structure right away because
+	 * the pending operation might use it.
+	 */
+	size_t pending_ops_count;
+	/** Guard for pending_ops_count. */
+	fibril_mutex_t pending_ops_mutex;
+	/** Condition variable for pending_ops_count. */
+	fibril_condvar_t pending_ops_cv;
+
 };
 
