Index: uspace/drv/ohci/root_hub.c
===================================================================
--- uspace/drv/ohci/root_hub.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/drv/ohci/root_hub.c	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -249,5 +249,5 @@
 		opResult = EINVAL;
 	}
-	usb_transfer_batch_finish(request, opResult);
+	usb_transfer_batch_finish_error(request, opResult);
 	return EOK;
 }
@@ -863,7 +863,4 @@
 }
 
-
-
-
 /**
  * @}
Index: uspace/drv/uhci-hcd/hc.c
===================================================================
--- uspace/drv/uhci-hcd/hc.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/drv/uhci-hcd/hc.c	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -332,8 +332,4 @@
 	    instance->transfers[batch->speed][batch->transfer_type];
 	assert(list);
-	if (batch->transfer_type == USB_TRANSFER_CONTROL) {
-		usb_device_keeper_use_control(
-		    &instance->manager, batch->target);
-	}
 	transfer_list_add_batch(list, batch);
 
@@ -373,27 +369,5 @@
 			usb_transfer_batch_t *batch =
 			    list_get_instance(item, usb_transfer_batch_t, link);
-			switch (batch->transfer_type)
-			{
-			case USB_TRANSFER_CONTROL:
-				usb_device_keeper_release_control(
-				    &instance->manager, batch->target);
-				break;
-			case USB_TRANSFER_INTERRUPT:
-			case USB_TRANSFER_ISOCHRONOUS: {
-/*
-				int ret = bandwidth_free(&instance->bandwidth,
-				    batch->target.address,
-				    batch->target.endpoint,
-				    batch->direction);
-				if (ret != EOK)
-					usb_log_warning("Failed(%d) to free "
-					    "reserved bw: %s.\n", ret,
-					    str_error(ret));
-*/
-				}
-			default:
-				break;
-			}
-			batch->next_step(batch);
+			usb_transfer_batch_finish(batch);
 		}
 	}
Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -132,12 +132,8 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Check list for finished batches.
- *
- * @param[in] instance List to use.
- * @return Error code
- *
- * Creates a local list of finished batches and calls next_step on each and
- * every one. This is safer because next_step may theoretically access
- * this transfer list leading to the deadlock if its done inline.
+/** Create list for finished batches.
+ *
+ * @param[in] instance List to use.
+ * @param[in] done list to fill
  */
 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
@@ -161,5 +157,4 @@
 	}
 	fibril_mutex_unlock(&instance->guard);
-
 }
 /*----------------------------------------------------------------------------*/
@@ -176,5 +171,5 @@
 		    list_get_instance(current, usb_transfer_batch_t, link);
 		transfer_list_remove_batch(instance, batch);
-		usb_transfer_batch_finish(batch, EIO);
+		usb_transfer_batch_finish_error(batch, EIO);
 	}
 	fibril_mutex_unlock(&instance->guard);
Index: pace/drv/uhci-hcd/transfers.c
===================================================================
--- uspace/drv/uhci-hcd/transfers.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ 	(revision )
@@ -1,160 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <usb/hcdhubd.h>
-#include <errno.h>
-
-#include "uhci.h"
-
-static int enqueue_transfer_out(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer OUT [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-static int enqueue_transfer_setup(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer SETUP [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-static int enqueue_transfer_in(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer IN [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-
-static int get_address(device_t *dev, devman_handle_t handle,
-    usb_address_t *address)
-{
-	return ENOTSUP;
-}
-
-static int interrupt_out(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
-	    data, size,
-	    callback, arg);
-}
-
-static int interrupt_in(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_setup(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_data(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
-static int control_read_setup(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_data(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
-
-usbhc_iface_t uhci_iface = {
-	.tell_address = get_address,
-	.interrupt_out = interrupt_out,
-	.interrupt_in = interrupt_in,
-	.control_write_setup = control_write_setup,
-	.control_write_data = control_write_data,
-	.control_write_status = control_write_status,
-	.control_read_setup = control_read_setup,
-	.control_read_data = control_read_data,
-	.control_read_status = control_read_status
-};
Index: uspace/lib/usb/include/usb/host/batch.h
===================================================================
--- uspace/lib/usb/include/usb/host/batch.h	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/lib/usb/include/usb/host/batch.h	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -92,5 +92,13 @@
 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
-void usb_transfer_batch_finish(usb_transfer_batch_t *instance, int error);
+void usb_transfer_batch_finish(usb_transfer_batch_t *instance);
+
+static inline void usb_transfer_batch_finish_error(
+    usb_transfer_batch_t *instance, int error)
+{
+	assert(instance);
+	instance->error = error;
+	usb_transfer_batch_finish(instance);
+}
 
 #endif
Index: uspace/lib/usb/include/usb/host/device_keeper.h
===================================================================
--- uspace/lib/usb/include/usb/host/device_keeper.h	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/lib/usb/include/usb/host/device_keeper.h	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -96,11 +96,4 @@
 usb_speed_t usb_device_keeper_get_speed(usb_device_keeper_t *instance,
     usb_address_t address);
-
-void usb_device_keeper_use_control(usb_device_keeper_t *instance,
-    usb_target_t target);
-
-void usb_device_keeper_release_control(usb_device_keeper_t *instance,
-    usb_target_t target);
-
 #endif
 /**
Index: uspace/lib/usb/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usb/include/usb/host/endpoint.h	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/lib/usb/include/usb/host/endpoint.h	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -39,4 +39,6 @@
 #include <bool.h>
 #include <adt/list.h>
+#include <fibril_synch.h>
+
 #include <usb/usb.h>
 
@@ -48,6 +50,8 @@
 	usb_speed_t speed;
 	size_t max_packet_size;
-	bool active;
 	unsigned toggle:1;
+	fibril_mutex_t guard;
+	fibril_condvar_t avail;
+	volatile bool active;
 	link_t same_device_eps;
 } endpoint_t;
@@ -58,4 +62,8 @@
 
 void endpoint_destroy(endpoint_t *instance);
+
+void endpoint_use(endpoint_t *instance);
+
+void endpoint_release(endpoint_t *instance);
 
 int endpoint_toggle_get(endpoint_t *instance);
Index: uspace/lib/usb/src/host/batch.c
===================================================================
--- uspace/lib/usb/src/host/batch.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/lib/usb/src/host/batch.c	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -79,4 +79,5 @@
 	instance->error = EOK;
 	instance->ep = ep;
+	endpoint_use(instance->ep);
 }
 /*----------------------------------------------------------------------------*/
@@ -86,8 +87,9 @@
  *
  */
-void usb_transfer_batch_finish(usb_transfer_batch_t *instance, int error)
+void usb_transfer_batch_finish(usb_transfer_batch_t *instance)
 {
 	assert(instance);
-	instance->error = error;
+	assert(instance->ep);
+	endpoint_release(instance->ep);
 	instance->next_step(instance);
 }
Index: uspace/lib/usb/src/host/device_keeper.c
===================================================================
--- uspace/lib/usb/src/host/device_keeper.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/lib/usb/src/host/device_keeper.c	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -264,29 +264,4 @@
 	return instance->devices[address].speed;
 }
-/*----------------------------------------------------------------------------*/
-void usb_device_keeper_use_control(
-    usb_device_keeper_t *instance, usb_target_t target)
-{
-	assert(instance);
-	const uint16_t ep = 1 << target.endpoint;
-	fibril_mutex_lock(&instance->guard);
-	while (instance->devices[target.address].control_used & ep) {
-		fibril_condvar_wait(&instance->change, &instance->guard);
-	}
-	instance->devices[target.address].control_used |= ep;
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-void usb_device_keeper_release_control(
-    usb_device_keeper_t *instance, usb_target_t target)
-{
-	assert(instance);
-	const uint16_t ep = 1 << target.endpoint;
-	fibril_mutex_lock(&instance->guard);
-	assert((instance->devices[target.address].control_used & ep) != 0);
-	instance->devices[target.address].control_used &= ~ep;
-	fibril_mutex_unlock(&instance->guard);
-	fibril_condvar_signal(&instance->change);
-}
 /**
  * @}
Index: uspace/lib/usb/src/host/endpoint.c
===================================================================
--- uspace/lib/usb/src/host/endpoint.c	(revision 8b74997f71d062c07d27d7b964e1b778df3c993b)
+++ uspace/lib/usb/src/host/endpoint.c	(revision 4b39af4e2319d61edaccfb315cbd126aed47101d)
@@ -34,4 +34,5 @@
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <usb/host/endpoint.h>
@@ -49,4 +50,7 @@
 	instance->max_packet_size = max_packet_size;
 	instance->toggle = 0;
+	instance->active = false;
+	fibril_mutex_initialize(&instance->guard);
+	fibril_condvar_initialize(&instance->avail);
 	link_initialize(&instance->same_device_eps);
 	return EOK;
@@ -56,6 +60,26 @@
 {
 	assert(instance);
+	assert(!instance->active);
 	list_remove(&instance->same_device_eps);
 	free(instance);
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_use(endpoint_t *instance)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	while (instance->active)
+		fibril_condvar_wait(&instance->avail, &instance->guard);
+	instance->active = true;
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_release(endpoint_t *instance)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	instance->active = false;
+	fibril_mutex_unlock(&instance->guard);
+	fibril_condvar_signal(&instance->avail);
 }
 /*----------------------------------------------------------------------------*/
