Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 2ab687502fa30dee1542b61009d24ea2e502f9f4)
+++ uspace/drv/uhci-hcd/batch.c	(revision bcaefe3d6f7ed5d92fdff4b8478ffc5baa75ae99)
@@ -98,8 +98,8 @@
 	bzero(instance->tds, sizeof(td_t) * instance->packets);
 
-	const size_t transport_size = max_packet_size * instance->packets;
+//	const size_t transport_size = max_packet_size * instance->packets;
 
 	if (size > 0) {
-		instance->transport_buffer = malloc32(transport_size);
+		instance->transport_buffer = malloc32(size);
 		CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
 		    "Failed to allocate device accessible buffer.\n");
@@ -156,6 +156,6 @@
 			    instance, i, instance->tds[i].status);
 
-			device_keeper_set_toggle(instance->manager, instance->target,
-			    td_toggle(&instance->tds[i]));
+			device_keeper_set_toggle(instance->manager,
+			    instance->target, td_toggle(&instance->tds[i]));
 			if (i > 0)
 				goto substract_ret;
@@ -204,4 +204,5 @@
 {
 	assert(instance);
+	/* we are data out, we are supposed to provide data */
 	memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
 	batch_data(instance, USB_PID_OUT);
@@ -234,5 +235,6 @@
 	assert(instance);
 	const bool low_speed = instance->speed == USB_SPEED_LOW;
-	int toggle = device_keeper_get_toggle(instance->manager, instance->target);
+	int toggle =
+	    device_keeper_get_toggle(instance->manager, instance->target);
 	assert(toggle == 0 || toggle == 1);
 
@@ -244,24 +246,25 @@
 		    - remain_size;
 
-
 		const size_t packet_size =
 		    (instance->max_packet_size > remain_size) ?
 		    remain_size : instance->max_packet_size;
 
-		td_init(&instance->tds[packet],
-		    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
-		    instance->target, pid, data,
-		    &instance->tds[packet + 1]);
+		td_t *next_packet = (packet + 1 < instance->packets)
+		    ? &instance->tds[packet + 1] : NULL;
+
+		assert(packet < instance->packets);
+		assert(packet_size <= remain_size);
+
+		td_init(
+		    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
+		    toggle, false, low_speed, instance->target, pid, data,
+		    next_packet);
+
 
 		toggle = 1 - toggle;
+		remain_size -= packet_size;
 		++packet;
-		assert(packet <= instance->packets);
-		assert(packet_size <= remain_size);
-		remain_size -= packet_size;
 	}
 	device_keeper_set_toggle(instance->manager, instance->target, toggle);
-
-	instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
-	instance->tds[packet - 1].next = 0 | LINK_POINTER_TERMINATE_FLAG;
 }
 /*----------------------------------------------------------------------------*/
@@ -292,8 +295,8 @@
 		    remain_size : instance->max_packet_size;
 
-		td_init(&instance->tds[packet],
-		    DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
-		    instance->target, data_stage, data,
-		    &instance->tds[packet + 1]);
+		td_init(
+		    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
+		    toggle, false, low_speed, instance->target, data_stage,
+		    data, &instance->tds[packet + 1]);
 
 		++packet;
@@ -319,4 +322,5 @@
 	assert(instance->callback_in);
 
+	/* we are data in, we need data */
 	memcpy(instance->buffer, instance->transport_buffer, instance->buffer_size);
 
@@ -326,7 +330,6 @@
 	    instance->transfered_size);
 
-	instance->callback_in(instance->fun,
-	    err, instance->transfered_size,
-	    instance->arg);
+	instance->callback_in(
+	    instance->fun, err, instance->transfered_size, instance->arg);
 }
 /*----------------------------------------------------------------------------*/
@@ -361,4 +364,5 @@
 	assert(instance);
 	usb_log_debug("Batch(%p) disposing.\n", instance);
+	/* free32 is NULL safe */
 	free32(instance->tds);
 	free32(instance->qh);
