Index: uspace/drv/bus/usb/ohci/endpoint_list.c
===================================================================
--- uspace/drv/bus/usb/ohci/endpoint_list.c	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/endpoint_list.c	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -108,5 +108,5 @@
 		/* There are active EDs, get the last one */
 		ohci_endpoint_t *last = list_get_instance(
-		    list_last(&instance->endpoint_list), ohci_endpoint_t, link);
+		    list_last(&instance->endpoint_list), ohci_endpoint_t, eplist_link);
 		last_ed = last->ed;
 	}
@@ -122,8 +122,8 @@
 
 	/* Add to the sw list */
-	list_append(&ep->link, &instance->endpoint_list);
+	list_append(&ep->eplist_link, &instance->endpoint_list);
 
 	ohci_endpoint_t *first = list_get_instance(
-	    list_first(&instance->endpoint_list), ohci_endpoint_t, link);
+	    list_first(&instance->endpoint_list), ohci_endpoint_t, eplist_link);
 	usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).",
 		ep, instance->name, first, first->ed);
@@ -156,5 +156,5 @@
 	ed_t *prev_ed;
 	/* Remove from the hardware queue */
-	if (list_first(&instance->endpoint_list) == &ep->link) {
+	if (list_first(&instance->endpoint_list) == &ep->eplist_link) {
 		/* I'm the first one here */
 		prev_ed = instance->list_head;
@@ -162,5 +162,5 @@
 	} else {
 		ohci_endpoint_t *prev =
-		    list_get_instance(ep->link.prev, ohci_endpoint_t, link);
+		    list_get_instance(ep->eplist_link.prev, ohci_endpoint_t, eplist_link);
 		prev_ed = prev->ed;
 		qpos = "NOT FIRST";
@@ -175,5 +175,5 @@
 
 	/* Remove from the endpoint list */
-	list_remove(&ep->link);
+	list_remove(&ep->eplist_link);
 	fibril_mutex_unlock(&instance->guard);
 }
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -168,5 +168,5 @@
 	    hw_res->mem_ranges.ranges[0].size);
 
-	list_initialize(&instance->pending_batches);
+	list_initialize(&instance->pending_endpoints);
 	fibril_mutex_initialize(&instance->guard);
 
@@ -304,7 +304,14 @@
 		return err;
 
-	fibril_mutex_lock(&hc->guard);
-	list_append(&ohci_batch->link, &hc->pending_batches);
+	endpoint_t *ep = batch->ep;
+	ohci_endpoint_t * const ohci_ep = ohci_endpoint_get(ep);
+
+	/* creating local reference */
+	endpoint_add_ref(ep);
+
+	fibril_mutex_lock(&ep->guard);
+	endpoint_activate_locked(ep, batch);
 	ohci_transfer_batch_commit(ohci_batch);
+	fibril_mutex_unlock(&ep->guard);
 
 	/* Control and bulk schedules need a kick to start working */
@@ -320,5 +327,9 @@
 		break;
 	}
+
+	fibril_mutex_lock(&hc->guard);
+	list_append(&ohci_ep->pending_link, &hc->pending_endpoints);
 	fibril_mutex_unlock(&hc->guard);
+
 	return EOK;
 }
@@ -353,16 +364,20 @@
 		    OHCI_RD(hc->registers->periodic_current));
 
-		link_t *current = list_first(&hc->pending_batches);
-		while (current && current != &hc->pending_batches.head) {
-			link_t *next = current->next;
-			ohci_transfer_batch_t *batch =
-			    ohci_transfer_batch_from_link(current);
+		list_foreach_safe(hc->pending_endpoints, current, next) {
+			ohci_endpoint_t *ep
+				= list_get_instance(current, ohci_endpoint_t, pending_link);
+
+			fibril_mutex_lock(&ep->base.guard);
+			ohci_transfer_batch_t *batch
+				= ohci_transfer_batch_get(ep->base.active_batch);
+			assert(batch);
 
 			if (ohci_transfer_batch_check_completed(batch)) {
+				endpoint_deactivate_locked(&ep->base);
 				list_remove(current);
+				endpoint_del_ref(&ep->base);
 				usb_transfer_batch_finish(&batch->base);
 			}
-
-			current = next;
+			fibril_mutex_unlock(&ep->base.guard);
 		}
 		fibril_mutex_unlock(&hc->guard);
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -70,6 +70,6 @@
 	endpoint_list_t lists[4];
 
-	/** List of active transfers */
-	list_t pending_batches;
+	/** List of active endpoints */
+	list_t pending_endpoints;
 
 	/** Guards schedule and endpoint manipulation */
Index: uspace/drv/bus/usb/ohci/main.c
===================================================================
--- uspace/drv/bus/usb/ohci/main.c	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/main.c	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -39,4 +39,5 @@
 #include <errno.h>
 #include <io/log.h>
+#include <io/logctl.h>
 #include <str_error.h>
 
@@ -72,4 +73,5 @@
 {
 	log_init(NAME);
+	logctl_set_log_level(NAME, LVL_DEBUG2);
 	return hc_driver_main(&ohci_driver);
 }
Index: uspace/drv/bus/usb/ohci/ohci_batch.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_batch.c	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/ohci_batch.c	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -88,5 +88,4 @@
 
 	usb_transfer_batch_init(&ohci_batch->base, ep);
-	link_initialize(&ohci_batch->link);
 
 	return ohci_batch;
Index: uspace/drv/bus/usb/ohci/ohci_batch.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_batch.h	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/ohci_batch.h	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -47,6 +47,4 @@
 	usb_transfer_batch_t base;
 
-	/** Link */
-	link_t link;
 	/** Endpoint descriptor of the target endpoint. */
 	ed_t *ed;
@@ -65,10 +63,4 @@
 void ohci_transfer_batch_destroy(ohci_transfer_batch_t *ohci_batch);
 
-static inline ohci_transfer_batch_t *ohci_transfer_batch_from_link(link_t *l)
-{
-	assert(l);
-	return list_get_instance(l, ohci_transfer_batch_t, link);
-}
-
 static inline ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *usb_batch)
 {
Index: uspace/drv/bus/usb/ohci/ohci_bus.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.c	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/ohci_bus.c	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -82,5 +82,6 @@
 	}
 
-	link_initialize(&ohci_ep->link);
+	link_initialize(&ohci_ep->eplist_link);
+	link_initialize(&ohci_ep->pending_link);
 	return &ohci_ep->base;
 }
@@ -120,9 +121,38 @@
 static void ohci_unregister_ep(endpoint_t *ep)
 {
-	ohci_bus_t *bus = (ohci_bus_t *) endpoint_get_bus(ep);
+	ohci_bus_t * const bus = (ohci_bus_t *) endpoint_get_bus(ep);
+	hc_t * const hc = bus->hc;
 	assert(ep);
 
 	usb2_bus_ops.endpoint_unregister(ep);
 	hc_dequeue_endpoint(bus->hc, ep);
+
+	ohci_endpoint_t * const ohci_ep = ohci_endpoint_get(ep);
+
+	/*
+	 * Now we can be sure the active transfer will not be completed. But first,
+	 * make sure that the handling fibril won't use its link in pending list.
+	 */
+	fibril_mutex_lock(&hc->guard);
+	if (link_in_use(&ohci_ep->pending_link))
+		/* pending list reference */
+		endpoint_del_ref(ep);
+	list_remove(&ohci_ep->pending_link);
+	fibril_mutex_unlock(&hc->guard);
+
+	/*
+	 * Finally, the endpoint shall not be used anywhere else. Finish the
+	 * pending batch.
+	 */
+	fibril_mutex_lock(&ep->guard);
+	usb_transfer_batch_t * const batch = ep->active_batch;
+	endpoint_deactivate_locked(ep);
+	fibril_mutex_unlock(&ep->guard);
+
+	if (batch) {
+		batch->error = EINTR;
+		batch->transfered_size = 0;
+		usb_transfer_batch_finish(batch);
+	}
 }
 
Index: uspace/drv/bus/usb/ohci/ohci_bus.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.h	(revision ed8575f8584c50f2fbc1f481eede55f9dc3e86a8)
+++ uspace/drv/bus/usb/ohci/ohci_bus.h	(revision d60115a5571c1d7a5330d0cd74e3abdef172ec0c)
@@ -51,6 +51,8 @@
 	/** Currently enqueued transfer descriptor */
 	td_t *td;
-	/** Linked list used by driver software */
-	link_t link;
+	/** Link in endpoint_list*/
+	link_t eplist_link;
+	/** Link in pending_endpoints */
+	link_t pending_link;
 } ohci_endpoint_t;
 
