Index: uspace/drv/bus/usb/ohci/batch.c
===================================================================
--- uspace/drv/bus/usb/ohci/batch.c	(revision 09ace19264532b52287b4ee10cb23e6d9c1dcff8)
+++ uspace/drv/bus/usb/ohci/batch.c	(revision 08150005d227615e0b790ddb93c8092fe3f32919)
@@ -61,5 +61,5 @@
                 batch_control_write(batch);
 }
-
+/*----------------------------------------------------------------------------*/
 void (*batch_setup[4][3])(usb_transfer_batch_t*) =
 {
@@ -98,5 +98,4 @@
 	if (!instance)
 		return;
-	free32(instance->device_buffer);
 	unsigned i = 0;
 	if (instance->tds) {
@@ -107,4 +106,5 @@
 		free(instance->tds);
 	}
+	free32(instance->device_buffer);
 	free(instance);
 }
@@ -122,7 +122,4 @@
         } else (void)0
 
-	const ohci_endpoint_t *ohci_ep = ohci_endpoint_get(batch->ep);
-	assert(ohci_ep);
-
 	ohci_transfer_batch_t *data = calloc(sizeof(ohci_transfer_batch_t), 1);
 	CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");
@@ -135,5 +132,5 @@
 	}
 
-	/* We need an extra place for TD that is assigned to ohci_ep */
+	/* We need an extra place for TD that was left at ED */
 	data->tds = calloc(sizeof(td_t*), data->td_count + 1);
 	CHECK_NULL_DISPOSE_RETURN(data->tds,
@@ -141,5 +138,6 @@
 
 	/* Add TD left over by the previous transfer */
-	data->tds[0] = ohci_ep->td;
+	data->ed = ohci_endpoint_get(batch->ep)->ed;
+	data->tds[0] = ohci_endpoint_get(batch->ep)->td;
 	data->leave_td = 0;
 	unsigned i = 1;
@@ -150,7 +148,4 @@
 	}
 
-	data->ed = ohci_ep->ed;
-	batch->private_data = data;
-	batch->private_data_dtor = ohci_batch_dispose;
 
 	/* NOTE: OHCI is capable of handling buffer that crosses page boundaries
@@ -163,8 +158,12 @@
                 CHECK_NULL_DISPOSE_RETURN(data->device_buffer,
                     "Failed to allocate device accessible buffer.\n");
+		/* Copy setup data */
                 memcpy(data->device_buffer, batch->setup_buffer,
 		    batch->setup_size);
 		batch->data_buffer = data->device_buffer + batch->setup_size;
         }
+
+	batch->private_data = data;
+	batch->private_data_dtor = ohci_batch_dispose;
 
         assert(batch_setup[batch->ep->transfer_type][batch->ep->direction]);
@@ -221,5 +220,5 @@
 	ohci_endpoint_t *ohci_ep = ohci_endpoint_get(instance->ep);
 	assert(ohci_ep);
-	ohci_ep->td = data->tds[i];
+	ohci_ep->td = data->tds[data->leave_td];
 	assert(i > 0);
 	for (--i;i < data->td_count; ++i)
@@ -363,6 +362,7 @@
 		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);
+	usb_log_debug("Created CONTROL 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 */
@@ -378,5 +378,5 @@
 		    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",
+		usb_log_debug("Created CONTROL 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);
@@ -392,5 +392,5 @@
 	td_init(data->tds[td_current], status_dir, NULL, 0, 1);
 	td_set_next(data->tds[td_current], data->tds[td_current + 1]);
-	usb_log_debug("Created STATUS TD: %x:%x:%x:%x.\n",
+	usb_log_debug("Created CONTROL 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/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 09ace19264532b52287b4ee10cb23e6d9c1dcff8)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 08150005d227615e0b790ddb93c8092fe3f32919)
@@ -139,7 +139,10 @@
 	    &instance->generic.dev_manager, hub_address, hub_fun->handle);
 
-#define CHECK_RET_RELEASE(ret, message...) \
+#define CHECK_RET_DESTROY(ret, message...) \
 if (ret != EOK) { \
 	usb_log_error(message); \
+	endpoint_destroy(ep); \
+	usb_endpoint_manager_unregister_ep(&instance->generic.ep_manager, \
+	    hub_address, 0, USB_DIRECTION_BOTH); \
 	return ret; \
 } else (void)0
@@ -151,28 +154,17 @@
 
 	int ret = ohci_endpoint_init(&instance->generic, ep);
-	if (ret != EOK) {
-		endpoint_destroy(ep);
-		return ret;
-	}
-
-	ret = usb_endpoint_manager_register_ep(&instance->generic.ep_manager, ep, 0);
-	if (ret != EOK) {
-		endpoint_destroy(ep);
-		return ret;
-	}
-	hc_enqueue_endpoint(instance, ep);
-
-
-//	int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL,
-//	    USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0);
-//	CHECK_RET_RELEASE(ret,
-//	    "Failed to add OHCI root hub endpoint 0: %s.\n", str_error(ret));
+	CHECK_RET_DESTROY(ret, "Failed to initialize rh OHCI ep structures.\n");
+
+	ret = usb_endpoint_manager_register_ep(
+	    &instance->generic.ep_manager, ep, 0);
+	CHECK_RET_DESTROY(ret, "Failed to initialize rh control ep.\n");
+	ep = NULL;
 
 	ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
-	CHECK_RET_RELEASE(ret,
+	CHECK_RET_DESTROY(ret,
 	    "Failed to add root hub match-id: %s.\n", str_error(ret));
 
 	ret = ddf_fun_bind(hub_fun);
-	CHECK_RET_RELEASE(ret,
+	CHECK_RET_DESTROY(ret,
 	    "Failed to bind root hub function: %s.\n", str_error(ret));
 
@@ -248,6 +240,5 @@
 	case USB_TRANSFER_BULK:
 		instance->registers->control &= ~C_BLE;
-		endpoint_list_add_ep(
-		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
+		endpoint_list_add_ep(list, ohci_ep);
 		instance->registers->control |= C_BLE;
 		break;
@@ -255,6 +246,5 @@
 	case USB_TRANSFER_INTERRUPT:
 		instance->registers->control &= (~C_PLE & ~C_IE);
-		endpoint_list_add_ep(
-		    &instance->lists[ep->transfer_type], ohci_endpoint_get(ep));
+		endpoint_list_add_ep(list, ohci_ep);
 		instance->registers->control |= C_PLE | C_IE;
 		break;
@@ -368,4 +358,5 @@
 
 	if (status & I_UE) {
+		usb_log_fatal("Error like no other!\n");
 		hc_start(instance);
 	}
