Index: uspace/drv/uhci-hcd/hc.c
===================================================================
--- uspace/drv/uhci-hcd/hc.c	(revision 8123695a05edc85df5433b25264e0e8c0cbf18a2)
+++ uspace/drv/uhci-hcd/hc.c	(revision d8987b19dcb446b3842662825b1f9727cde5dae9)
@@ -239,4 +239,8 @@
 	usb_log_debug("Initialized device manager.\n");
 
+	ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
+	    bandwidth_count_usb11);
+	assert(ret == true);
+
 	return EOK;
 #undef CHECK_RET_DEST_CMDS_RETURN
@@ -325,11 +329,20 @@
 	if (!usb_is_allowed(
 	    low_speed, batch->transfer_type, batch->max_packet_size)) {
-		usb_log_warning(
-		    "Invalid USB transfer specified %s SPEED %d %zu.\n",
-		    low_speed ? "LOW" : "FULL" , batch->transfer_type,
+		usb_log_error("Invalid USB transfer specified %s %d %zu.\n",
+		    usb_str_speed(batch->speed), batch->transfer_type,
 		    batch->max_packet_size);
 		return ENOTSUP;
 	}
-	/* TODO: check available bandwidth here */
+	/* Check available bandwidth */
+	if (batch->transfer_type == USB_TRANSFER_INTERRUPT ||
+	    batch->transfer_type == USB_TRANSFER_ISOCHRONOUS) {
+		int ret =
+		    bandwidth_use(&instance->bandwidth, batch->target.address,
+		    batch->target.endpoint, batch->direction);
+		if (ret != EOK) {
+			usb_log_warning("Failed(%d) to use reserved bw: %s.\n",
+			    ret, str_error(ret));
+		}
+	}
 
 	transfer_list_t *list =
@@ -338,5 +351,5 @@
 	if (batch->transfer_type == USB_TRANSFER_CONTROL) {
 		usb_device_keeper_use_control(
-		    &instance->manager, batch->target.address);
+		    &instance->manager, batch->target);
 	}
 	transfer_list_add_batch(list, batch);
@@ -358,4 +371,5 @@
 {
 	assert(instance);
+//	status |= 1; //Uncomment to work around qemu hang
 	/* TODO: Resume interrupts are not supported */
 	/* Lower 2 bits are transaction error and transaction complete */
@@ -376,7 +390,23 @@
 			usb_transfer_batch_t *batch =
 			    list_get_instance(item, usb_transfer_batch_t, link);
-			if (batch->transfer_type == USB_TRANSFER_CONTROL) {
+			switch (batch->transfer_type)
+			{
+			case USB_TRANSFER_CONTROL:
 				usb_device_keeper_release_control(
-				    &instance->manager, batch->target.address);
+				    &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);
Index: uspace/drv/uhci-hcd/hc.h
===================================================================
--- uspace/drv/uhci-hcd/hc.h	(revision 8123695a05edc85df5433b25264e0e8c0cbf18a2)
+++ uspace/drv/uhci-hcd/hc.h	(revision d8987b19dcb446b3842662825b1f9727cde5dae9)
@@ -43,4 +43,5 @@
 #include <usbhc_iface.h>
 #include <usb/host/device_keeper.h>
+#include <usb/host/bandwidth.h>
 
 #include "batch.h"
@@ -84,4 +85,5 @@
 typedef struct hc {
 	usb_device_keeper_t manager;
+	bandwidth_t bandwidth;
 
 	regs_t *registers;
Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 8123695a05edc85df5433b25264e0e8c0cbf18a2)
+++ uspace/drv/uhci-hcd/iface.c	(revision d8987b19dcb446b3842662825b1f9727cde5dae9)
@@ -128,4 +128,33 @@
 }
 /*----------------------------------------------------------------------------*/
+static int register_endpoint(
+    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
+    usb_transfer_type_t transfer_type, usb_direction_t direction,
+    size_t max_packet_size, unsigned int interval)
+{
+	hc_t *hc = fun_to_hc(fun);
+	assert(hc);
+	const usb_speed_t speed =
+	    usb_device_keeper_get_speed(&hc->manager, address);
+	size_t size = max_packet_size;
+
+	usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
+	    address, endpoint, usb_str_transfer_type(transfer_type),
+	    usb_str_speed(speed), direction, size, max_packet_size, interval);
+	return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,
+	    speed, transfer_type, max_packet_size, size, interval);
+}
+/*----------------------------------------------------------------------------*/
+static int unregister_endpoint(
+    ddf_fun_t *fun, usb_address_t address,
+    usb_endpoint_t endpoint, usb_direction_t direction)
+{
+	hc_t *hc = fun_to_hc(fun);
+	assert(hc);
+	usb_log_debug("Unregister endpoint %d:%d %d.\n",
+	    address, endpoint, direction);
+	return bandwidth_release(&hc->bandwidth, address, endpoint, direction);
+}
+/*----------------------------------------------------------------------------*/
 /** Interrupt out transaction interface function
  *
@@ -365,4 +394,7 @@
 	.release_address = release_address,
 
+	.register_endpoint = register_endpoint,
+	.unregister_endpoint = unregister_endpoint,
+
 	.interrupt_out = interrupt_out,
 	.interrupt_in = interrupt_in,
