Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision e099f264aa055ac645611d5b7f9a7720a42190af)
@@ -79,7 +79,6 @@
 	if (!instance->queue_head)
 		return;
-	/* Set both next and element to point to the same QH */
+	/* Set both queue_head.next to point to the follower */
 	qh_set_next_qh(instance->queue_head, next->queue_head_pa);
-	qh_set_element_qh(instance->queue_head, next->queue_head_pa);
 }
 /*----------------------------------------------------------------------------*/
@@ -98,25 +97,24 @@
 	usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
 
-	const uint32_t pa = addr_to_phys(batch_qh(batch));
-	assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
-
-	/* New batch will be added to the end of the current list
-	 * so set the link accordingly */
-	qh_set_next_qh(batch_qh(batch), instance->queue_head->next);
-
 	fibril_mutex_lock(&instance->guard);
 
+	qh_t *last_qh = NULL;
 	/* Add to the hardware queue. */
 	if (list_empty(&instance->batch_list)) {
 		/* There is nothing scheduled */
-		qh_t *qh = instance->queue_head;
-		assert(qh->element == qh->next);
-		qh_set_element_qh(qh, pa);
+		last_qh = instance->queue_head;
 	} else {
 		/* There is something scheduled */
 		usb_transfer_batch_t *last = list_get_instance(
 		    instance->batch_list.prev, usb_transfer_batch_t, link);
-		qh_set_next_qh(batch_qh(last), pa);
-	}
+		last_qh = batch_qh(last);
+	}
+	const uint32_t pa = addr_to_phys(batch->qh);
+	assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
+
+	/* keep link */
+	batch_qh(batch)->next = last_qh->next;
+	qh_set_next_qh(last_qh, pa);
+
 	/* Add to the driver list */
 	list_append(&batch->link, &instance->batch_list);
@@ -174,5 +172,5 @@
 {
 	fibril_mutex_lock(&instance->guard);
-	while (list_empty(&instance->batch_list)) {
+	while (!list_empty(&instance->batch_list)) {
 		link_t *current = instance->batch_list.next;
 		usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link);
@@ -197,22 +195,28 @@
 	assert(batch);
 	assert(batch_qh(batch));
+	assert(fibril_mutex_is_locked(&instance->guard));
+
 	usb_log_debug2(
 	    "Queue %s: removing batch(%p).\n", instance->name, batch);
 
-	const char * pos = NULL;
+	const char *qpos = NULL;
 	/* Remove from the hardware queue */
-	if (batch->link.prev == &instance->batch_list) {
+	if (instance->batch_list.next == &batch->link) {
 		/* I'm the first one here */
-		qh_set_element_qh(instance->queue_head, batch_qh(batch)->next);
-		pos = "FIRST";
+		assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK)
+		    == addr_to_phys(bathc_qh(batch)));
+		instance->queue_head->next = batch_qh(batch)->next;
+		qpos = "FIRST";
 	} else {
 		usb_transfer_batch_t *prev =
 		    list_get_instance(batch->link.prev, usb_transfer_batch_t, link);
-		qh_set_next_qh(batch_qh(prev), batch_qh(batch)->next);
-		pos = "NOT FIRST";
-	}
-	/* Remove from the driver list */
+		assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK)
+		    == addr_to_phys(batch_qh(batch)));
+		batch_qh(prev)->next = batch_qh(batch)->next;
+		qpos = "NOT FIRST";
+	}
+	/* Remove from the batch list */
 	list_remove(&batch->link);
-	usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n",
+	usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",
 	    batch, pos, instance->name, batch_qh(batch)->next);
 }
Index: uspace/drv/uhci-hcd/transfers.c
===================================================================
--- uspace/drv/uhci-hcd/transfers.c	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ 	(revision )
@@ -1,160 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <usb/hcdhubd.h>
-#include <errno.h>
-
-#include "uhci.h"
-
-static int enqueue_transfer_out(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer OUT [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-static int enqueue_transfer_setup(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer SETUP [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-static int enqueue_transfer_in(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	printf(NAME ": transfer IN [%d.%d (%s); %zu]\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	return ENOTSUP;
-}
-
-
-static int get_address(device_t *dev, devman_handle_t handle,
-    usb_address_t *address)
-{
-	return ENOTSUP;
-}
-
-static int interrupt_out(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
-	    data, size,
-	    callback, arg);
-}
-
-static int interrupt_in(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_setup(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_data(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
-static int control_read_setup(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_data(device_t *dev, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
-
-usbhc_iface_t uhci_iface = {
-	.tell_address = get_address,
-	.interrupt_out = interrupt_out,
-	.interrupt_in = interrupt_in,
-	.control_write_setup = control_write_setup,
-	.control_write_data = control_write_data,
-	.control_write_status = control_write_status,
-	.control_read_setup = control_read_setup,
-	.control_read_data = control_read_data,
-	.control_read_status = control_read_status
-};
Index: uspace/drv/uhci-hcd/uhci_hc.c
===================================================================
--- uspace/drv/uhci-hcd/uhci_hc.c	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ uspace/drv/uhci-hcd/uhci_hc.c	(revision e099f264aa055ac645611d5b7f9a7720a42190af)
@@ -125,6 +125,7 @@
 	}
 
-	instance->debug_checker = fibril_create(uhci_hc_debug_checker, instance);
-	fibril_add_ready(instance->debug_checker);
+	instance->debug_checker =
+	    fibril_create(uhci_hc_debug_checker, instance);
+//	fibril_add_ready(instance->debug_checker);
 
 	return EOK;
Index: uspace/drv/uhci-hcd/uhci_struct/link_pointer.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/link_pointer.h	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ uspace/drv/uhci-hcd/uhci_struct/link_pointer.h	(revision e099f264aa055ac645611d5b7f9a7720a42190af)
@@ -49,4 +49,10 @@
 	((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG)
 
+#define LINK_POINTER_TD(address) \
+	(address & LINK_POINTER_ADDRESS_MASK)
+
+#define LINK_POINTER_TERM \
+	((link_pointer_t)LINK_POINTER_TERMINATE_FLAG)
+
 #endif
 /**
Index: uspace/drv/uhci-hcd/uhci_struct/queue_head.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/queue_head.h	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ uspace/drv/uhci-hcd/uhci_struct/queue_head.h	(revision e099f264aa055ac645611d5b7f9a7720a42190af)
@@ -72,8 +72,7 @@
 	/* Address is valid and not terminal */
 	if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
-		instance->next = (pa & LINK_POINTER_ADDRESS_MASK)
-		    | LINK_POINTER_QUEUE_HEAD_FLAG;
+		instance->next = LINK_POINTER_QH(pa);
 	} else {
-		instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
+		instance->next = LINK_POINTER_TERM;
 	}
 }
@@ -91,8 +90,7 @@
 	/* Address is valid and not terminal */
 	if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
-		instance->element = (pa & LINK_POINTER_ADDRESS_MASK)
-		    | LINK_POINTER_QUEUE_HEAD_FLAG;
+		instance->element = LINK_POINTER_QH(pa);
 	} else {
-		instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
+		instance->element = LINK_POINTER_TERM;
 	}
 }
@@ -109,7 +107,7 @@
 {
 	if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
-		instance->element = (pa & LINK_POINTER_ADDRESS_MASK);
+		instance->element = LINK_POINTER_TD(pa);
 	} else {
-		instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
+		instance->element = LINK_POINTER_TERM;
 	}
 }
Index: uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c	(revision e099f264aa055ac645611d5b7f9a7720a42190af)
@@ -69,7 +69,10 @@
 	    || (pid == USB_PID_OUT));
 
+	const uint32_t next_pa = addr_to_phys(next);
+	assert((next_pa & LINK_POINTER_ADDRESS_MASK) == next_pa);
+
 	instance->next = 0
 	    | LINK_POINTER_VERTICAL_FLAG
-	    | ((next != NULL) ? addr_to_phys(next) : LINK_POINTER_TERMINATE_FLAG);
+	    | (next_pa ? next_pa : LINK_POINTER_TERMINATE_FLAG);
 
 	instance->status = 0
@@ -90,9 +93,5 @@
 	    | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
 
-	instance->buffer_ptr = 0;
-
-	if (size) {
-		instance->buffer_ptr = (uintptr_t)addr_to_phys(buffer);
-	}
+	instance->buffer_ptr = addr_to_phys(buffer);
 
 	usb_log_debug2("Created TD(%p): %X:%X:%X:%X(%p).\n",
@@ -115,21 +114,29 @@
 	assert(instance);
 
-	if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
-		return ESTALL;
+	/* this is hc internal error it should never be reported */
+	if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0)
+		return EAGAIN;
 
+	/* CRC or timeout error, like device not present or bad data,
+	 * it won't be reported unless err count reached zero */
 	if ((instance->status & TD_STATUS_ERROR_CRC) != 0)
 		return EBADCHECKSUM;
 
-	if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
+	/* hc does not end transaction on these, it should never be reported */
+	if ((instance->status & TD_STATUS_ERROR_NAK) != 0)
 		return EAGAIN;
 
+	/* buffer overrun or underrun */
+	if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
+		return ERANGE;
+
+	/* device babble is something serious */
 	if ((instance->status & TD_STATUS_ERROR_BABBLE) != 0)
 		return EIO;
 
-	if ((instance->status & TD_STATUS_ERROR_NAK) != 0)
-		return EAGAIN;
-
-	if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0)
-		return EAGAIN;
+	/* stall might represent err count reaching zero or stall response from
+	 * the device, is err count reached zero, one of the above is reported*/
+	if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
+		return ESTALL;
 
 	return EOK;
Index: uspace/drv/uhci-hcd/utils/malloc32.h
===================================================================
--- uspace/drv/uhci-hcd/utils/malloc32.h	(revision fbefd0ef38a280edbe1fd4144105f99fd72ed083)
+++ uspace/drv/uhci-hcd/utils/malloc32.h	(revision e099f264aa055ac645611d5b7f9a7720a42190af)
@@ -50,4 +50,7 @@
 static inline uintptr_t addr_to_phys(void *addr)
 {
+	if (addr == NULL)
+		return 0;
+
 	uintptr_t result;
 	int ret = as_get_physical_mapping(addr, &result);
