Index: uspace/drv/bus/usb/ohci/batch.c
===================================================================
--- uspace/drv/bus/usb/ohci/batch.c	(revision 27873be11b67d6fc3a8680b49efedc697ae908fd)
+++ uspace/drv/bus/usb/ohci/batch.c	(revision e2976bbb4ebc8d239237d89b873dd15b927568ea)
@@ -66,5 +66,5 @@
  * @param[in] ohci_batch Instance to destroy.
  */
-static void ohci_transfer_batch_dispose(void *ohci_batch)
+static void ohci_batch_dispose(void *ohci_batch)
 {
 	ohci_transfer_batch_t *instance = ohci_batch;
@@ -83,4 +83,66 @@
 }
 /*----------------------------------------------------------------------------*/
+int batch_init_ohci(usb_transfer_batch_t *batch)
+{
+	assert(batch);
+#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
+        if (ptr == NULL) { \
+                usb_log_error(message); \
+		if (data) { \
+			ohci_batch_dispose(data); \
+		} \
+                return ENOMEM; \
+        } else (void)0
+
+	const hcd_endpoint_t *hcd_ep = hcd_endpoint_get(batch->ep);
+	assert(hcd_ep);
+
+	ohci_transfer_batch_t *data = calloc(sizeof(ohci_transfer_batch_t), 1);
+	CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
+
+	data->td_count = ((batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1)
+	    / OHCI_TD_MAX_TRANSFER);
+	/* Control transfer need Setup and Status stage */
+	if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
+		data->td_count += 2;
+	}
+
+	/* We need an extra place for TD that is currently assigned to hcd_ep*/
+	data->tds = calloc(sizeof(td_t*), data->td_count + 1);
+	CHECK_NULL_DISPOSE_RETURN(data->tds,
+	    "Failed to allocate transfer descriptors.\n");
+
+	/* Add TD left over by the previous transfer */
+	data->tds[0] = hcd_ep->td;
+	data->leave_td = 0;
+	unsigned i = 1;
+	for (; i <= data->td_count; ++i) {
+		data->tds[i] = malloc32(sizeof(td_t));
+		CHECK_NULL_DISPOSE_RETURN(data->tds[i],
+		    "Failed to allocate TD %d.\n", i );
+	}
+
+	data->ed = hcd_ep->ed;
+	batch->private_data = data;
+	batch->private_data_dtor = ohci_batch_dispose;
+
+	/* NOTE: OHCI is capable of handling buffer that crosses page boundaries
+	 * it is, however, not capable of handling buffer that occupies more
+	 * than two pages (the first page is computed using start pointer, the
+	 * other using the end pointer) */
+        if (batch->setup_size + batch->buffer_size > 0) {
+		data->device_buffer =
+		    malloc32(batch->setup_size + batch->buffer_size);
+                CHECK_NULL_DISPOSE_RETURN(data->device_buffer,
+                    "Failed to allocate device accessible buffer.\n");
+                memcpy(data->device_buffer, batch->setup_buffer,
+		    batch->setup_size);
+		batch->data_buffer = data->device_buffer + batch->setup_size;
+        }
+
+	return EOK;
+#undef CHECK_NULL_DISPOSE_RETURN
+}
+/*----------------------------------------------------------------------------*/
 /** Allocate memory initialize internal structures
  *
@@ -119,5 +181,5 @@
 	usb_transfer_batch_init(instance, ep, buffer, NULL, buffer_size,
 	    NULL, setup_size, func_in, func_out, arg, fun, NULL,
-	    ohci_transfer_batch_dispose);
+	    ohci_batch_dispose);
 
 	const hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
Index: uspace/drv/bus/usb/ohci/batch.h
===================================================================
--- uspace/drv/bus/usb/ohci/batch.h	(revision 27873be11b67d6fc3a8680b49efedc697ae908fd)
+++ uspace/drv/bus/usb/ohci/batch.h	(revision e2976bbb4ebc8d239237d89b873dd15b927568ea)
@@ -48,5 +48,7 @@
     void *arg);
 
-bool batch_is_complete(usb_transfer_batch_t *instance);
+int batch_init_ohci(usb_transfer_batch_t *batch);
+
+bool batch_is_complete(usb_transfer_batch_t *batch);
 
 void batch_commit(usb_transfer_batch_t *instance);
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 27873be11b67d6fc3a8680b49efedc697ae908fd)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision e2976bbb4ebc8d239237d89b873dd15b927568ea)
@@ -193,4 +193,9 @@
 	CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
 	    str_error(ret));
+
+	ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11);
+	instance->generic.schedule = NULL;
+	instance->generic.batch_init_hook = batch_init_ohci;
+	instance->generic.ep_add_hook = NULL;
 
 	ret = hc_init_memory(instance);
Index: uspace/drv/bus/usb/ohci/hc.h
===================================================================
--- uspace/drv/bus/usb/ohci/hc.h	(revision 27873be11b67d6fc3a8680b49efedc697ae908fd)
+++ uspace/drv/bus/usb/ohci/hc.h	(revision e2976bbb4ebc8d239237d89b873dd15b927568ea)
@@ -43,5 +43,5 @@
 #include <usb/host/device_keeper.h>
 #include <usb/host/usb_endpoint_manager.h>
-#include <usbhc_iface.h>
+#include <usb/host/hcd.h>
 
 #include "batch.h"
@@ -57,4 +57,7 @@
 	/** USB bus driver, endpoints */
 	usb_endpoint_manager_t ep_manager;
+
+	/** Generic USB hc driver */
+	hcd_t generic;
 
 	/** Memory mapped I/O registers area */
