Index: uspace/lib/usb/include/usb/port.h
===================================================================
--- uspace/lib/usb/include/usb/port.h	(revision a9fcd73c9a825936be7838244fd03da4f23bf1e7)
+++ uspace/lib/usb/include/usb/port.h	(revision 5bccec32a6aa53d91c35fe402041aae3e14d0209)
@@ -56,4 +56,5 @@
 	PORT_ENUMERATED,/* Device enumerated. Fibril finished succesfully. */
 	PORT_CONNECTING,/* A connected event received, fibril running. */
+	PORT_DISCONNECTING,/* A disconnected event received, fibril running. */
 	PORT_ERROR,	/* An error "in-progress". Fibril still running. */
 } usb_port_state_t;
Index: uspace/lib/usb/src/port.c
===================================================================
--- uspace/lib/usb/src/port.c	(revision a9fcd73c9a825936be7838244fd03da4f23bf1e7)
+++ uspace/lib/usb/src/port.c	(revision 5bccec32a6aa53d91c35fe402041aae3e14d0209)
@@ -102,5 +102,5 @@
 
 	if (port->state != PORT_DISABLED) {
-		usb_log_warning("A connected event come for port that is not disabled.");
+		usb_log_warning("a connected event come for port that is not disabled.");
 		ret = EINVAL;
 		goto out;
@@ -137,4 +137,46 @@
 }
 
+struct remove_worker_args {
+	usb_port_t *port;
+	usb_port_remove_t handler;
+};
+
+static int remove_worker(void *arg)
+{
+	struct remove_worker_args * const args = arg;
+	usb_port_t *port = args->port;
+	usb_port_remove_t handler = args->handler;
+	free(args);
+
+	fibril_mutex_lock(&port->guard);
+	assert(port->state == PORT_DISCONNECTING);
+
+	handler(port);
+
+	port->state = PORT_DISABLED;
+	fibril_condvar_broadcast(&port->finished_cv);
+	fibril_mutex_unlock(&port->guard);
+	return EOK;
+}
+
+static void fork_remove_worker(usb_port_t *port, usb_port_remove_t handler)
+{
+	struct remove_worker_args *args = malloc(sizeof(*args));
+	if (!args)
+		return;
+
+	fid_t fibril = fibril_create(&remove_worker, args);
+	if (!fibril) {
+		free(args);
+		return;
+	}
+
+	args->port = port;
+	args->handler = handler;
+
+	port->state = PORT_DISCONNECTING;
+	fibril_add_ready(fibril);
+}
+
 void usb_port_disabled(usb_port_t *port, usb_port_remove_t handler)
 {
@@ -144,6 +186,5 @@
 	switch (port->state) {
 	case PORT_ENUMERATED:
-		handler(port);
-		port->state = PORT_DISABLED;
+		fork_remove_worker(port, handler);
 		break;
 
@@ -154,9 +195,10 @@
 		fibril_condvar_wait(&port->finished_cv, &port->guard);
 		/* fallthrough */
+	case PORT_DISCONNECTING:
 	case PORT_DISABLED:
 		break;
 	}
 
-	assert(port->state == PORT_DISABLED);
+	assert(port->state == PORT_DISABLED || port->state == PORT_DISCONNECTING);
 	fibril_mutex_unlock(&port->guard);
 }
@@ -190,4 +232,5 @@
 		/* fallthrough */
 	case PORT_ERROR:
+	case PORT_DISCONNECTING:
 		fibril_condvar_wait(&port->finished_cv, &port->guard);
 		break;
