Index: uspace/drv/ohci/batch.c
===================================================================
--- uspace/drv/ohci/batch.c	(revision b854e5642c101b1b85a54dd5f411ebb73e242ad0)
+++ uspace/drv/ohci/batch.c	(revision e42dd3245c842ab3531270c8dd0c423f20cc2bd2)
@@ -49,5 +49,6 @@
 } ohci_batch_t;
 
-static void batch_control(usb_transfer_batch_t *instance);
+static void batch_control(usb_transfer_batch_t *instance,
+    usb_direction_t data_dir, usb_direction_t status_dir);
 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance);
 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance);
@@ -135,5 +136,5 @@
 	    instance->buffer_size);
 	instance->next_step = batch_call_out_and_dispose;
-	batch_control(instance);
+	batch_control(instance, USB_DIRECTION_OUT, USB_DIRECTION_IN);
 	usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
 }
@@ -143,5 +144,5 @@
 	assert(instance);
 	instance->next_step = batch_call_in_and_dispose;
-	batch_control(instance);
+	batch_control(instance, USB_DIRECTION_IN, USB_DIRECTION_OUT);
 	usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
 }
@@ -194,5 +195,6 @@
 }
 /*----------------------------------------------------------------------------*/
-static void batch_control(usb_transfer_batch_t *instance)
+void batch_control(usb_transfer_batch_t *instance,
+    usb_direction_t data_dir, usb_direction_t status_dir)
 {
 	assert(instance);
@@ -200,4 +202,43 @@
 	assert(data);
 	ed_init(data->ed, instance->ep);
+	ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);
+	usb_log_debug("Created ED: %x:%x:%x:%x.\n", data->ed->status,
+	    data->ed->td_tail, data->ed->td_head, data->ed->next);
+	int toggle = 0;
+	/* setup stage */
+	td_init(&data->tds[0], USB_DIRECTION_BOTH, instance->setup_buffer,
+		instance->setup_size, toggle);
+	td_set_next(&data->tds[0], &data->tds[1]);
+	usb_log_debug("Created SETUP TD: %x:%x:%x:%x.\n", data->tds[0].status,
+	    data->tds[0].cbp, data->tds[0].next, data->tds[0].be);
+
+	/* data stage */
+	size_t td_current = 1;
+	size_t remain_size = instance->buffer_size;
+	char *transfer_buffer = instance->transport_buffer;
+	while (remain_size > 0) {
+		size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?
+		    OHCI_TD_MAX_TRANSFER : remain_size;
+		toggle = 1 - toggle;
+
+		td_init(&data->tds[td_current], data_dir, transfer_buffer,
+		    transfer_size, toggle);
+		td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);
+		usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
+		    data->tds[td_current].status, data->tds[td_current].cbp,
+		    data->tds[td_current].next, data->tds[td_current].be);
+
+		transfer_buffer += transfer_size;
+		remain_size -= transfer_size;
+		assert(td_current < data->td_count - 2);
+		++td_current;
+	}
+
+	/* status stage */
+	assert(td_current == data->td_count - 2);
+	td_init(&data->tds[td_current], status_dir, NULL, 0, 1);
+	usb_log_debug("Created STATUS TD: %x:%x:%x:%x.\n",
+	    data->tds[td_current].status, data->tds[td_current].cbp,
+	    data->tds[td_current].next, data->tds[td_current].be);
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/ohci/hw_struct/endpoint_descriptor.h
===================================================================
--- uspace/drv/ohci/hw_struct/endpoint_descriptor.h	(revision b854e5642c101b1b85a54dd5f411ebb73e242ad0)
+++ uspace/drv/ohci/hw_struct/endpoint_descriptor.h	(revision e42dd3245c842ab3531270c8dd0c423f20cc2bd2)
@@ -41,4 +41,5 @@
 
 #include "utils/malloc32.h"
+#include "transfer_descriptor.h"
 
 #include "completion_codes.h"
@@ -49,7 +50,7 @@
 #define ED_STATUS_FA_SHIFT (0)
 #define ED_STATUS_EN_MASK (0xf)    /* USB endpoint address */
-#define ED_STATUS_EN_SHIFT (6)
+#define ED_STATUS_EN_SHIFT (7)
 #define ED_STATUS_D_MASK (0x3)     /* direction */
-#define ED_STATUS_D_SHIFT (10)
+#define ED_STATUS_D_SHIFT (11)
 #define ED_STATUS_D_IN (0x1)
 #define ED_STATUS_D_OUT (0x2)
@@ -80,9 +81,9 @@
 void ed_init(ed_t *instance, endpoint_t *ep);
 
-static inline void ed_add_tds(ed_t *instance, uint32_t head, uint32_t tail)
+static inline void ed_add_tds(ed_t *instance, td_t *head, td_t *tail)
 {
 	assert(instance);
-	instance->td_head = head & ED_TDHEAD_PTR_MASK;
-	instance->td_tail = tail & ED_TDTAIL_PTR_MASK;
+	instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK;
+	instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK;
 }
 
Index: uspace/drv/ohci/hw_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/ohci/hw_struct/transfer_descriptor.h	(revision b854e5642c101b1b85a54dd5f411ebb73e242ad0)
+++ uspace/drv/ohci/hw_struct/transfer_descriptor.h	(revision e42dd3245c842ab3531270c8dd0c423f20cc2bd2)
@@ -36,4 +36,5 @@
 
 #include <stdint.h>
+#include "utils/malloc32.h"
 
 #include "completion_codes.h"
@@ -55,7 +56,6 @@
 #define TD_STATUS_T_MASK (0x3)  /* data toggle 1x = use ED toggle carry */
 #define TD_STATUS_T_SHIFT (24)
-#define TD_STATUS_T_0 (0x0)
-#define TD_STATUS_T_1 (0x1)
-#define TD_STATUS_T_USE_EP (0x1)
+#define TD_STATUS_T_0 (0x2)
+#define TD_STATUS_T_1 (0x3)
 #define TD_STATUS_EC_MASK (0x3) /* error count */
 #define TD_STATUS_EC_SHIFT (26)
@@ -74,8 +74,8 @@
     td_t *instance, usb_direction_t dir, void *buffer, size_t size, int toggle);
 
-inline static void td_set_next(td_t *instance, uint32_t next)
+inline static void td_set_next(td_t *instance, td_t *next)
 {
 	assert(instance);
-	instance->next = next & TD_NEXT_PTR_MASK;
+	instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK;
 }
 #endif
