Index: uspace/drv/ohci/batch.c
===================================================================
--- uspace/drv/ohci/batch.c	(revision 344925c56b57570f6db6c3fce2f2c373adf649d9)
+++ uspace/drv/ohci/batch.c	(revision 06c552c4ee679c41b5947ad94101dfb74192fb9c)
@@ -40,4 +40,14 @@
 #include "batch.h"
 #include "utils/malloc32.h"
+#include "hw_struct/endpoint_descriptor.h"
+#include "hw_struct/transfer_descriptor.h"
+
+#define OHCI_MAX_TRANSFER (8 * 1024) /* OHCI TDs can handle up to 8KB buffers */
+
+typedef struct ohci_batch {
+	ed_t *ed;
+	td_t *tds;
+	size_t td_count;
+} ohci_batch_t;
 
 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
@@ -68,4 +78,24 @@
 	    func_in, func_out, arg, fun, ep, NULL);
 
+	ohci_batch_t *data = malloc(sizeof(ohci_batch_t));
+	CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
+	bzero(data, sizeof(ohci_batch_t));
+	instance->private_data = data;
+
+	data->td_count =
+	    (buffer_size + OHCI_MAX_TRANSFER - 1) / OHCI_MAX_TRANSFER;
+	if (ep->transfer_type == USB_TRANSFER_CONTROL) {
+		data->td_count += 2;
+	}
+
+	data->tds = malloc32(sizeof(td_t) * data->td_count);
+	CHECK_NULL_DISPOSE_RETURN(data->tds,
+	    "Failed to allocate transfer descriptors.\n");
+	bzero(data->tds, sizeof(td_t) * data->td_count);
+
+	data->ed = malloc32(sizeof(ed_t));
+	CHECK_NULL_DISPOSE_RETURN(data->ed,
+	    "Failed to allocate endpoint descriptor.\n");
+
         if (buffer_size > 0) {
                 instance->transport_buffer = malloc32(buffer_size);
@@ -81,5 +111,4 @@
         }
 
-
 	return instance;
 }
Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 344925c56b57570f6db6c3fce2f2c373adf649d9)
+++ uspace/drv/uhci-hcd/batch.c	(revision 06c552c4ee679c41b5947ad94101dfb74192fb9c)
@@ -103,13 +103,11 @@
 	usb_target_t target =
 	    { .address = ep->address, .endpoint = ep->endpoint };
-	usb_transfer_batch_init(instance, target,
-	    ep->transfer_type, ep->speed, ep->max_packet_size,
-	    buffer, NULL, buffer_size, NULL, setup_size, func_in,
-	    func_out, arg, fun, ep, NULL);
+	usb_transfer_batch_init(instance, target, ep->transfer_type, ep->speed,
+	    ep->max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
+	    func_in, func_out, arg, fun, ep, NULL);
 
 
 	uhci_batch_t *data = malloc(sizeof(uhci_batch_t));
-	CHECK_NULL_DISPOSE_RETURN(instance,
-	    "Failed to allocate batch instance.\n");
+	CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
 	bzero(data, sizeof(uhci_batch_t));
 	instance->private_data = data;
