Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision a72620d844b2def11ca79c28d58a9dfca9e925d0)
+++ uspace/drv/uhci-hcd/iface.c	(revision f241b05bc59edac56b06c29f8b6c93daaa705206)
@@ -136,5 +136,13 @@
     usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
-	return ENOTSUP;
+	size_t max_packet_size = size;
+	dev_speed_t speed = FULL_SPEED;
+
+	tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
+	    max_packet_size, speed, data, size, NULL, callback, arg);
+	if (!tracker)
+		return ENOMEM;
+	tracker_control_write(tracker, setup_data, setup_size);
+	return EOK;
 }
 /*----------------------------------------------------------------------------*/
@@ -143,5 +151,13 @@
     usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
-	return ENOTSUP;
+	size_t max_packet_size = size;
+	dev_speed_t speed = FULL_SPEED;
+
+	tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
+	    max_packet_size, speed, data, size, callback, NULL, arg);
+	if (!tracker)
+		return ENOMEM;
+	tracker_control_read(tracker, setup_data, setup_size);
+	return EOK;
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci-hcd/tracker.c
===================================================================
--- uspace/drv/uhci-hcd/tracker.c	(revision a72620d844b2def11ca79c28d58a9dfca9e925d0)
+++ uspace/drv/uhci-hcd/tracker.c	(revision f241b05bc59edac56b06c29f8b6c93daaa705206)
@@ -109,17 +109,18 @@
 }
 /*----------------------------------------------------------------------------*/
-void tracker_control_write(tracker_t *instance)
+void tracker_control_write(
+    tracker_t *instance, char* setup_buffer, size_t setup_size)
 {
 	assert(instance);
 	assert(instance->buffer_offset == 0);
-
-	instance->packet_size = SETUP_PACKET_DATA_SIZE;
-	memcpy(instance->packet, instance->buffer, SETUP_PACKET_DATA_SIZE);
-
-	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
-	    SETUP_PACKET_DATA_SIZE, instance->toggle++, false, instance->target,
+	assert(setup_size == 8);
+
+	instance->packet_size = 0;
+	memcpy(instance->packet, setup_buffer, setup_size);
+
+	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
+	    setup_size, instance->toggle++, false, instance->target,
 	    USB_PID_SETUP, instance->packet);
 
-	instance->buffer_offset += SETUP_PACKET_DATA_SIZE;
 	instance->next_step = tracker_control_write_data;
 
@@ -127,14 +128,15 @@
 }
 /*----------------------------------------------------------------------------*/
-void tracker_control_read(tracker_t *instance)
+void tracker_control_read(
+    tracker_t *instance, char* setup_buffer, size_t setup_size)
 {
 	assert(instance);
 	assert(instance->buffer_offset == 0);
-
-	instance->packet_size = SETUP_PACKET_DATA_SIZE;
-	memcpy(instance->packet, instance->buffer, SETUP_PACKET_DATA_SIZE);
-
-	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
-	    SETUP_PACKET_DATA_SIZE, instance->toggle++, false, instance->target,
+	assert(setup_size == 8);
+
+	memcpy(instance->packet, setup_buffer, setup_size);
+
+	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
+	    setup_size, instance->toggle++, false, instance->target,
 	    USB_PID_SETUP, instance->packet);
 
@@ -157,6 +159,8 @@
 
 	/* we are data in, we want data from our device */
-	memcpy(instance->buffer + instance->buffer_offset, instance->packet,
-	    instance->packet_size);
+	if (instance->packet_size) {
+		memcpy(instance->buffer + instance->buffer_offset, instance->packet,
+		    instance->packet_size);
+	}
 	instance->buffer_offset += instance->packet_size;
 
@@ -190,5 +194,5 @@
 	}
 
-	/* we are data out, we down't want data from our device */
+	/* we are data out, we don't want data from our device */
 	instance->buffer_offset += instance->packet_size;
 
@@ -233,5 +237,5 @@
 	instance->packet_size =	0;
 	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
-	    0, 1, false, instance->target, USB_PID_OUT, NULL);
+	    instance->packet_size, 1, false, instance->target, USB_PID_OUT, NULL);
 
 	tracker_schedule(instance);
@@ -253,4 +257,6 @@
 
 	/* we are data in, we want data from our device */
+	assert(
+	    instance->buffer_offset + instance->packet_size <= instance->buffer_size);
 	memcpy(instance->buffer + instance->buffer_offset, instance->packet,
 	    instance->packet_size);
@@ -261,5 +267,5 @@
 	instance->packet_size =	0;
 	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
-	    0, 1, false, instance->target, USB_PID_OUT, NULL);
+	    instance->packet_size, 1, false, instance->target, USB_PID_IN, NULL);
 
 	tracker_schedule(instance);
@@ -290,4 +296,5 @@
 	instance->packet_size =	MIN(instance->max_packet_size,
 			instance->buffer_size - instance->buffer_offset);
+	assert(instance->packet_size <= instance->max_packet_size);
 
 	transfer_descriptor_init(instance->td, DEFAULT_ERROR_COUNT,
@@ -351,5 +358,6 @@
 	}
 	instance->buffer_offset += instance->packet_size;
-	usb_log_debug("Callback IN: %d, %zu.\n", err, instance->buffer_offset);
+	usb_log_debug("Callback IN(%d): %d, %zu.\n", instance->transfer_type,
+	    err, instance->buffer_offset);
 	instance->callback_in(instance->dev,
 	    err ? USB_OUTCOME_CRCERROR : USB_OUTCOME_OK, instance->buffer_offset,
@@ -364,5 +372,6 @@
 	/* check for errors */
 	int err = transfer_descriptor_status(instance->td);
-	usb_log_debug("Callback OUT: %d, %zu.\n", err, instance->buffer_offset);
+	usb_log_debug("Callback OUT(%d): %d, %zu.\n", instance->transfer_type,
+	    err, instance->buffer_offset);
 	instance->callback_out(instance->dev,
 	    err ? USB_OUTCOME_CRCERROR : USB_OUTCOME_OK, instance->arg);
Index: uspace/drv/uhci-hcd/tracker.h
===================================================================
--- uspace/drv/uhci-hcd/tracker.h	(revision a72620d844b2def11ca79c28d58a9dfca9e925d0)
+++ uspace/drv/uhci-hcd/tracker.h	(revision f241b05bc59edac56b06c29f8b6c93daaa705206)
@@ -77,7 +77,9 @@
     usbhc_iface_transfer_out_callback_t func_out, void *arg);
 
-void tracker_control_write(tracker_t *instance);
+void tracker_control_write(
+    tracker_t *instance, char* setup_buffer, size_t setup_size);
 
-void tracker_control_read(tracker_t *instance);
+void tracker_control_read(
+    tracker_t *instance, char* setup_buffer, size_t setup_size);
 
 void tracker_interrupt_in(tracker_t *instance);
Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision a72620d844b2def11ca79c28d58a9dfca9e925d0)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision f241b05bc59edac56b06c29f8b6c93daaa705206)
@@ -83,7 +83,7 @@
 
 	/* check again, may be use atomic compare and swap */
-	if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
-		instance->queue_head->element = pa;
-	}
+//	if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
+//		instance->queue_head->element = pa;
+//	}
 }
 /**
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision a72620d844b2def11ca79c28d58a9dfca9e925d0)
+++ uspace/drv/uhci-hcd/uhci.c	(revision f241b05bc59edac56b06c29f8b6c93daaa705206)
@@ -186,5 +186,10 @@
 			link_t *next = current->next;
 			tracker_t *tracker = list_get_instance(current, tracker_t, link);
+
 			assert(current == &tracker->link);
+			assert(tracker);
+			assert(tracker->next_step);
+			assert(tracker->td);
+
 			if (!transfer_descriptor_is_active(tracker->td)) {
 				usb_log_info("Found inactive tracker with status: %x.\n",
