Index: uspace/drv/bus/usb/uhci/batch.c
===================================================================
--- uspace/drv/bus/usb/uhci/batch.c	(revision df8f3fa39d5ad84bba1218333a405b8109775286)
+++ uspace/drv/bus/usb/uhci/batch.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
@@ -45,4 +45,21 @@
 #define DEFAULT_ERROR_COUNT 3
 
+static void batch_setup_control(usb_transfer_batch_t *batch)
+{
+	// TODO Find a better way to do this
+	if (batch->setup_buffer[0] & (1 << 7))
+		batch_control_read(batch);
+	else
+		batch_control_write(batch);
+}
+
+void (*batch_setup[4][3])(usb_transfer_batch_t*) =
+{
+	{ NULL, NULL, batch_setup_control },
+	{ NULL, NULL, NULL },
+	{ batch_bulk_in, batch_bulk_out, NULL },
+	{ batch_interrupt_in, batch_interrupt_out, NULL },
+};
+ // */
 /** UHCI specific data required for USB transfer */
 typedef struct uhci_transfer_batch {
@@ -68,5 +85,5 @@
  * @param[in] uhci_batch Instance to destroy.
  */
-static void uhci_transfer_batch_dispose(void *uhci_batch)
+void uhci_transfer_batch_dispose(void *uhci_batch)
 {
 	uhci_transfer_batch_t *instance = uhci_batch;
@@ -74,4 +91,59 @@
 	free32(instance->device_buffer);
 	free(instance);
+}
+/*----------------------------------------------------------------------------*/
+void * uhci_transfer_batch_create(usb_transfer_batch_t *batch)
+{
+#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
+	if (ptr == NULL) { \
+		usb_log_error(message); \
+		if (uhci_data) { \
+			uhci_transfer_batch_dispose(uhci_data); \
+		} \
+		return NULL; \
+	} else (void)0
+
+	uhci_transfer_batch_t *uhci_data =
+	    calloc(1, sizeof(uhci_transfer_batch_t));
+	CHECK_NULL_DISPOSE_RETURN(uhci_data,
+	    "Failed to allocate UHCI batch.\n");
+
+	uhci_data->td_count =
+	    (batch->buffer_size + batch->ep->max_packet_size - 1)
+	    / batch->ep->max_packet_size;
+	if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
+		uhci_data->td_count += 2;
+	}
+
+	assert((sizeof(td_t) % 16) == 0);
+	const size_t total_size = (sizeof(td_t) * uhci_data->td_count)
+	    + sizeof(qh_t) + batch->setup_size + batch->buffer_size;
+	uhci_data->device_buffer = malloc32(total_size);
+	CHECK_NULL_DISPOSE_RETURN(uhci_data->device_buffer,
+	    "Failed to allocate UHCI buffer.\n");
+	bzero(uhci_data->device_buffer, total_size);
+
+	uhci_data->tds = uhci_data->device_buffer;
+	uhci_data->qh =
+	    (uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count));
+
+	qh_init(uhci_data->qh);
+	qh_set_element_td(uhci_data->qh, uhci_data->tds);
+
+	void *setup =
+	    uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count)
+	    + sizeof(qh_t);
+	/* Copy SETUP packet data to device buffer */
+	memcpy(setup, batch->setup_buffer, batch->setup_size);
+	/* Set generic data buffer pointer */
+	batch->data_buffer = setup + batch->setup_size;
+	batch->private_data = uhci_data;
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
+	    " memory structures ready.\n", batch,
+	    USB_TRANSFER_BATCH_ARGS(*batch));
+	assert(batch_setup[batch->ep->transfer_type][batch->ep->direction]);
+	batch_setup[batch->ep->transfer_type][batch->ep->direction](batch);
+
+	return uhci_data;
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/bus/usb/uhci/batch.h
===================================================================
--- uspace/drv/bus/usb/uhci/batch.h	(revision df8f3fa39d5ad84bba1218333a405b8109775286)
+++ uspace/drv/bus/usb/uhci/batch.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
@@ -46,4 +46,7 @@
     void *arg);
 
+void * uhci_transfer_batch_create(usb_transfer_batch_t *batch);
+void uhci_transfer_batch_dispose(void *uhci_batch);
+
 void batch_dispose(usb_transfer_batch_t *instance);
 
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision df8f3fa39d5ad84bba1218333a405b8109775286)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
@@ -41,4 +41,5 @@
 
 #include "hc.h"
+#include "batch.h"
 
 #define UHCI_INTR_ALLOW_INTERRUPTS \
@@ -46,4 +47,10 @@
 #define UHCI_STATUS_USED_INTERRUPTS \
     (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
+
+static int schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
+{
+	assert(hcd);
+	return hc_schedule(hcd->private_data, batch);
+}
 
 static const irq_cmd_t uhci_irq_commands[] =
@@ -131,4 +138,9 @@
 	usb_log_debug(
 	    "Device registers at %p (%zuB) accessible.\n", io, reg_size);
+	hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11);
+	instance->generic.private_data = instance;
+	instance->generic.schedule = schedule;
+	instance->generic.batch_private_ctor = uhci_transfer_batch_create;
+	instance->generic.batch_private_dtor = uhci_transfer_batch_dispose;
 
 	ret = hc_init_mem_structures(instance);
Index: uspace/drv/bus/usb/uhci/hc.h
===================================================================
--- uspace/drv/bus/usb/uhci/hc.h	(revision df8f3fa39d5ad84bba1218333a405b8109775286)
+++ uspace/drv/bus/usb/uhci/hc.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
@@ -42,4 +42,5 @@
 #include <usb/host/usb_endpoint_manager.h>
 #include <usb/host/batch.h>
+#include <usb/host/hcd.h>
 
 #include "transfer_list.h"
@@ -94,4 +95,5 @@
 /** Main UHCI driver structure */
 typedef struct hc {
+	hcd_t generic;
 	/** USB bus driver, devices and addresses */
 	usb_device_keeper_t manager;
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision df8f3fa39d5ad84bba1218333a405b8109775286)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
@@ -87,5 +87,5 @@
 /** Operations supported by the HC driver */
 static ddf_dev_ops_t hc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
+	.interfaces[USBHC_DEV_IFACE] = &hcd_iface, /* see iface.h/c */
 };
 /*----------------------------------------------------------------------------*/
@@ -100,5 +100,5 @@
 {
 	assert(fun);
-	usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
+	usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.generic.dev_manager;
 	usb_address_t addr = usb_device_keeper_find(manager, handle);
 
@@ -202,5 +202,5 @@
 	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
 	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc;
+	instance->hc_fun->driver_data = &instance->hc.generic;
 
 	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
