Index: uspace/drv/bus/usb/usbdiag/main.c
===================================================================
--- uspace/drv/bus/usb/usbdiag/main.c	(revision 71f211f6909eb71f441da24a2ff90c3ecefd18fd)
+++ uspace/drv/bus/usb/usbdiag/main.c	(revision 91173333ffad8030d872b4bac54acc3311e9e3c1)
@@ -77,4 +77,13 @@
 }
 
+static int device_cleanup(usbdiag_dev_t *diag_dev)
+{
+	/* TODO: Join some fibrils? */
+
+	/* Free memory. */
+	usbdiag_dev_destroy(diag_dev);
+	return EOK;
+}
+
 static int device_remove(usb_device_t *dev)
 {
@@ -91,25 +100,9 @@
 	}
 
-	return EOK;
+	usb_log_info("Device '%s' removed.", usb_device_get_name(dev));
+	return device_cleanup(diag_dev);
 
 err:
 	return rc;
-}
-
-static int device_cleanup(usbdiag_dev_t *diag_dev)
-{
-	/* TODO: Join some fibrils? */
-
-	/* Free memory. */
-	usbdiag_dev_destroy(diag_dev);
-	return EOK;
-}
-
-static int device_removed(usb_device_t *dev)
-{
-	usb_log_info("Device '%s' removed.", usb_device_get_name(dev));
-
-	usbdiag_dev_t *diag_dev = usb_device_to_usbdiag_dev(dev);
-	return device_cleanup(diag_dev);
 }
 
@@ -207,5 +200,4 @@
 	.device_add = device_add,
 	.device_remove = device_remove,
-	.device_removed = device_removed,
 	.device_gone = device_gone,
 	.function_online = function_online,
Index: uspace/drv/bus/usb/usbflbk/main.c
===================================================================
--- uspace/drv/bus/usb/usbflbk/main.c	(revision 71f211f6909eb71f441da24a2ff90c3ecefd18fd)
+++ uspace/drv/bus/usb/usbflbk/main.c	(revision 91173333ffad8030d872b4bac54acc3311e9e3c1)
@@ -69,11 +69,4 @@
 {
 	assert(dev);
-	usb_log_info("Device '%s' will be removed.", usb_device_get_name(dev));
-	return EOK;
-}
-
-static int usbfallback_device_removed(usb_device_t *dev)
-{
-	assert(dev);
 	usb_log_info("Device '%s' removed.", usb_device_get_name(dev));
 	return EOK;
@@ -84,5 +77,4 @@
 	.device_add = usbfallback_device_add,
 	.device_remove = usbfallback_device_remove,
-	.device_removed = usbfallback_device_removed,
 	.device_gone = usbfallback_device_gone,
 };
Index: uspace/drv/bus/usb/usbhub/main.c
===================================================================
--- uspace/drv/bus/usb/usbhub/main.c	(revision 71f211f6909eb71f441da24a2ff90c3ecefd18fd)
+++ uspace/drv/bus/usb/usbhub/main.c	(revision 91173333ffad8030d872b4bac54acc3311e9e3c1)
@@ -49,5 +49,4 @@
 	.device_add = usb_hub_device_add,
 	.device_remove = usb_hub_device_remove,
-	.device_removed = usb_hub_device_removed,
 	.device_gone = usb_hub_device_gone,
 };
Index: uspace/drv/bus/usb/usbhub/usbhub.c
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.c	(revision 71f211f6909eb71f441da24a2ff90c3ecefd18fd)
+++ uspace/drv/bus/usb/usbhub/usbhub.c	(revision 91173333ffad8030d872b4bac54acc3311e9e3c1)
@@ -99,5 +99,5 @@
 
 	/* Continue polling until the device is about to be removed. */
-	return hub->running && !hub->poll_stop;
+	return hub->running;
 }
 
@@ -123,9 +123,6 @@
 	hub_dev->pending_ops_count = 0;
 	hub_dev->running = false;
-	hub_dev->poll_stop = false;
 	fibril_mutex_initialize(&hub_dev->pending_ops_mutex);
-	fibril_mutex_initialize(&hub_dev->poll_guard);
 	fibril_condvar_initialize(&hub_dev->pending_ops_cv);
-	fibril_condvar_initialize(&hub_dev->poll_cv);
 
 	/* Set hub's first configuration. (There should be only one) */
@@ -197,23 +194,4 @@
 }
 
-/**
- * Turn off power to all ports.
- *
- * @param usb_dev generic usb device information
- * @return error code
- */
-int usb_hub_device_remove(usb_device_t *usb_dev)
-{
-	assert(usb_dev);
-	usb_hub_dev_t *hub = usb_device_data_get(usb_dev);
-	assert(hub);
-
-	usb_log_info("(%p) USB hub will be removed.", hub);
-
-	/* Instruct the hub to stop once endpoints are unregistered. */
-	hub->poll_stop = true;
-	return EOK;
-}
-
 static int usb_hub_cleanup(usb_hub_dev_t *hub)
 {
@@ -241,5 +219,11 @@
 }
 
-int usb_hub_device_removed(usb_device_t *usb_dev)
+/**
+ * Turn off power to all ports.
+ *
+ * @param usb_dev generic usb device information
+ * @return error code
+ */
+int usb_hub_device_remove(usb_device_t *usb_dev)
 {
 	assert(usb_dev);
@@ -247,12 +231,8 @@
 	assert(hub);
 
-	usb_log_info("(%p) USB hub was removed, joining polling fibril.", hub);
+	usb_log_info("(%p) USB hub removed, joining polling fibril.", hub);
 
 	/* Join polling fibril. */
-	fibril_mutex_lock(&hub->poll_guard);
-	while (hub->running)
-		fibril_condvar_wait(&hub->poll_cv, &hub->poll_guard);
-	fibril_mutex_unlock(&hub->poll_guard);
-
+	usb_device_poll_join(hub->polling);
 	usb_log_info("(%p) USB hub polling stopped, freeing memory.", hub);
 
@@ -272,12 +252,9 @@
 	assert(hub);
 
-	hub->poll_stop = true;
 	usb_log_info("(%p) USB hub gone, joining polling fibril.", hub);
 
 	/* Join polling fibril. */
-	fibril_mutex_lock(&hub->poll_guard);
-	while (hub->running)
-		fibril_condvar_wait(&hub->poll_cv, &hub->poll_guard);
-	fibril_mutex_unlock(&hub->poll_guard);
+	usb_device_poll_join(hub->polling);
+	usb_log_info("(%p) USB hub polling stopped, freeing memory.", hub);
 
 	/* Destroy hub. */
@@ -592,10 +569,6 @@
 	fibril_mutex_unlock(&hub->pending_ops_mutex);
 	hub->running = false;
-
-	/* Signal polling end to joining thread. */
-	fibril_mutex_lock(&hub->poll_guard);
-	fibril_condvar_signal(&hub->poll_cv);
-	fibril_mutex_unlock(&hub->poll_guard);
-}
+}
+
 /**
  * @}
Index: uspace/drv/bus/usb/usbhub/usbhub.h
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.h	(revision 71f211f6909eb71f441da24a2ff90c3ecefd18fd)
+++ uspace/drv/bus/usb/usbhub/usbhub.h	(revision 91173333ffad8030d872b4bac54acc3311e9e3c1)
@@ -39,4 +39,5 @@
 
 #include <ddf/driver.h>
+#include <fibril_synch.h>
 
 #include <usb/classes/hub.h>
@@ -45,6 +46,4 @@
 #include <usb/dev/driver.h>
 #include <usb/dev/poll.h>
-
-#include <fibril_synch.h>
 
 #define NAME "usbhub"
@@ -81,8 +80,4 @@
 	/** Each port is switched individually. */
 	bool per_port_power;
-	/** True if the device should stop running as soon as possible. */
-	volatile bool poll_stop;
-	fibril_mutex_t poll_guard;
-	fibril_condvar_t poll_cv;
 };
 
@@ -91,5 +86,4 @@
 extern int usb_hub_device_add(usb_device_t *);
 extern int usb_hub_device_remove(usb_device_t *);
-extern int usb_hub_device_removed(usb_device_t *);
 extern int usb_hub_device_gone(usb_device_t *);
 
Index: uspace/drv/bus/usb/usbmid/main.c
===================================================================
--- uspace/drv/bus/usb/usbmid/main.c	(revision 71f211f6909eb71f441da24a2ff90c3ecefd18fd)
+++ uspace/drv/bus/usb/usbmid/main.c	(revision 91173333ffad8030d872b4bac54acc3311e9e3c1)
@@ -56,4 +56,25 @@
 }
 
+static int destroy_interfaces(usb_mid_t *usb_mid)
+{
+	int ret = EOK;
+
+	while (!list_empty(&usb_mid->interface_list)) {
+		link_t *item = list_first(&usb_mid->interface_list);
+		list_remove(item);
+
+		usbmid_interface_t *iface = usbmid_interface_from_link(item);
+
+		const int pret = usbmid_interface_destroy(iface);
+		if (pret != EOK) {
+			usb_log_error("Failed to remove child `%s': %s\n",
+			    ddf_fun_get_name(iface->fun), str_error(pret));
+			ret = pret;
+		}
+	}
+
+	return ret;
+}
+
 /** Callback when a MID device is about to be removed from the host.
  *
@@ -90,35 +111,4 @@
 	}
 
-	return ret;
-}
-
-static int destroy_interfaces(usb_mid_t *usb_mid)
-{
-	int ret = EOK;
-
-	while (!list_empty(&usb_mid->interface_list)) {
-		link_t *item = list_first(&usb_mid->interface_list);
-		list_remove(item);
-
-		usbmid_interface_t *iface = usbmid_interface_from_link(item);
-
-		const int pret = usbmid_interface_destroy(iface);
-		if (pret != EOK) {
-			usb_log_error("Failed to remove child `%s': %s\n",
-			    ddf_fun_get_name(iface->fun), str_error(pret));
-			ret = pret;
-		}
-	}
-
-	return ret;
-}
-
-static int usbmid_device_removed(usb_device_t *dev)
-{
-	assert(dev);
-	usb_mid_t *usb_mid = usb_device_data_get(dev);
-	assert(usb_mid);
-
-	/* Children are offline. Destroy them now. */
 	return destroy_interfaces(usb_mid);
 }
@@ -166,5 +156,4 @@
 	.device_add = usbmid_device_add,
 	.device_remove = usbmid_device_remove,
-	.device_removed = usbmid_device_removed,
 	.device_gone = usbmid_device_gone,
 	.function_online = usbmid_function_online,
