Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/batch.c	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -100,8 +100,8 @@
 	bzero(instance, sizeof(batch_t));
 
-	instance->qh = malloc32(sizeof(queue_head_t));
+	instance->qh = malloc32(sizeof(qh_t));
 	CHECK_NULL_DISPOSE_RETURN(instance->qh,
 	    "Failed to allocate batch queue head.\n");
-	queue_head_init(instance->qh);
+	qh_init(instance->qh);
 
 	instance->packets = (size + max_packet_size - 1) / max_packet_size;
@@ -114,6 +114,4 @@
 	    instance->tds, "Failed to allocate transfer descriptors.\n");
 	bzero(instance->tds, sizeof(td_t) * instance->packets);
-
-//	const size_t transport_size = max_packet_size * instance->packets;
 
 	if (size > 0) {
@@ -143,11 +141,8 @@
 	instance->speed = speed;
 	instance->manager = manager;
-
-	if (func_out)
-		instance->callback_out = func_out;
-	if (func_in)
-		instance->callback_in = func_in;
-
-	queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds));
+	instance->callback_out = func_out;
+	instance->callback_in = func_in;
+
+	qh_set_element_td(instance->qh, addr_to_phys(instance->tds));
 
 	usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
Index: uspace/drv/uhci-hcd/batch.h
===================================================================
--- uspace/drv/uhci-hcd/batch.h	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/batch.h	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -50,8 +50,6 @@
 	usb_target_t target;
 	usb_transfer_type_t transfer_type;
-	union {
-		usbhc_iface_transfer_in_callback_t callback_in;
-		usbhc_iface_transfer_out_callback_t callback_out;
-	};
+	usbhc_iface_transfer_in_callback_t callback_in;
+	usbhc_iface_transfer_out_callback_t callback_out;
 	void *arg;
 	char *transport_buffer;
@@ -65,5 +63,5 @@
 	int error;
 	ddf_fun_t *fun;
-	queue_head_t *qh;
+	qh_t *qh;
 	td_t *tds;
 	void (*next_step)(struct batch*);
Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -47,12 +47,11 @@
  * @return Error code
  *
- * Allocates memory for internat queue_head_t structure.
+ * Allocates memory for internal qh_t structure.
  */
 int transfer_list_init(transfer_list_t *instance, const char *name)
 {
 	assert(instance);
-	instance->next = NULL;
 	instance->name = name;
-	instance->queue_head = malloc32(sizeof(queue_head_t));
+	instance->queue_head = malloc32(sizeof(qh_t));
 	if (!instance->queue_head) {
 		usb_log_error("Failed to allocate queue head.\n");
@@ -61,5 +60,5 @@
 	instance->queue_head_pa = addr_to_phys(instance->queue_head);
 
-	queue_head_init(instance->queue_head);
+	qh_init(instance->queue_head);
 	list_initialize(&instance->batch_list);
 	fibril_mutex_initialize(&instance->guard);
@@ -72,4 +71,6 @@
  * @param[in] next List to append.
  * @return Error code
+ *
+ * Does not check whether there was a next list already.
  */
 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
@@ -79,6 +80,7 @@
 	if (!instance->queue_head)
 		return;
-	queue_head_append_qh(instance->queue_head, next->queue_head_pa);
-	instance->queue_head->element = instance->queue_head->next_queue;
+	/* set both next and element to point to the same QH */
+	qh_set_next_qh(instance->queue_head, next->queue_head_pa);
+	qh_set_element_qh(instance->queue_head, next->queue_head_pa);
 }
 /*----------------------------------------------------------------------------*/
@@ -93,43 +95,42 @@
 	assert(instance);
 	assert(batch);
-	usb_log_debug2(
-	    "Adding batch(%p) to queue %s.\n", batch, instance->name);
+	usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
 
-	uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
+	const uint32_t pa = addr_to_phys(batch->qh);
 	assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
-	pa |= LINK_POINTER_QUEUE_HEAD_FLAG;
 
-	batch->qh->next_queue = instance->queue_head->next_queue;
+	/* New batch will be added to the end of the current list
+	 * so set the link accordingly */
+	qh_set_next_qh(batch->qh, instance->queue_head->next);
 
 	fibril_mutex_lock(&instance->guard);
 
-	if (instance->queue_head->element == instance->queue_head->next_queue) {
-		/* there is nothing scheduled */
-		list_append(&batch->link, &instance->batch_list);
-		instance->queue_head->element = pa;
-		usb_log_debug("Batch(%p) added to queue %s first.\n",
-			batch, instance->name);
-		fibril_mutex_unlock(&instance->guard);
-		return;
+	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);
+	} else {
+		/* There is something scheduled */
+		batch_t *last = list_get_instance(
+		    instance->batch_list.prev, batch_t, link);
+		qh_set_next_qh(last->qh, pa);
 	}
-	/* now we can be sure that there is someting scheduled */
-	assert(!list_empty(&instance->batch_list));
-	batch_t *first = list_get_instance(
-	          instance->batch_list.next, batch_t, link);
-	batch_t *last = list_get_instance(
-	    instance->batch_list.prev, batch_t, link);
-	queue_head_append_qh(last->qh, pa);
 	list_append(&batch->link, &instance->batch_list);
 
-	usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n",
+	batch_t *first = list_get_instance(
+	    instance->batch_list.next, batch_t, link);
+	usb_log_debug("Batch(%p) added to queue %s, first is %p.\n",
 		batch, instance->name, first);
 	fibril_mutex_unlock(&instance->guard);
 }
 /*----------------------------------------------------------------------------*/
-/** Removes a transfer batch from list and queue.
+/** Removes a transfer batch from the list and queue.
  *
  * @param[in] instance List to use.
  * @param[in] batch Transfer batch to remove.
  * @return Error code
+ *
+ * Does not lock the transfer list, caller is responsible for that.
  */
 void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch)
@@ -140,24 +141,23 @@
 	assert(batch->qh);
 	usb_log_debug2(
-	    "Removing batch(%p) from queue %s.\n", batch, instance->name);
+	    "Queue %s: removing batch(%p).\n", instance->name, batch);
 
+	const char * pos = NULL;
 	if (batch->link.prev == &instance->batch_list) {
 		/* I'm the first one here */
-		usb_log_debug(
-		    "Batch(%p) removed (FIRST) from %s, next element %x.\n",
-		    batch, instance->name, batch->qh->next_queue);
-		instance->queue_head->element = batch->qh->next_queue;
+		qh_set_element_qh(instance->queue_head, batch->qh->next);
+		pos = "FIRST";
 	} else {
-		usb_log_debug(
-		    "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n",
-		    batch, instance->name, batch->qh->next_queue);
 		batch_t *prev =
 		    list_get_instance(batch->link.prev, batch_t, link);
-		prev->qh->next_queue = batch->qh->next_queue;
+		qh_set_next_qh(prev->qh, batch->qh->next);
+		pos = "NOT FIRST";
 	}
 	list_remove(&batch->link);
+	usb_log_debug("Batch(%p) removed (%s) from %s, next element %x.\n",
+	    batch, pos, instance->name, batch->qh->next);
 }
 /*----------------------------------------------------------------------------*/
-/** Checks list for finished transfers.
+/** Checks list for finished batches.
  *
  * @param[in] instance List to use.
Index: uspace/drv/uhci-hcd/transfer_list.h
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.h	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/transfer_list.h	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -44,7 +44,6 @@
 {
 	fibril_mutex_t guard;
-	queue_head_t *queue_head;
+	qh_t *queue_head;
 	uint32_t queue_head_pa;
-	struct transfer_list *next;
 	const char *name;
 	link_t batch_list;
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -437,5 +437,6 @@
 		int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff;
 
-		uintptr_t expected_pa = instance->frame_list[frnum] & (~0xf);
+		uintptr_t expected_pa = instance->frame_list[frnum]
+		    & LINK_POINTER_ADDRESS_MASK;
 		uintptr_t real_pa = addr_to_phys(QH(interrupt));
 		if (expected_pa != real_pa) {
@@ -444,5 +445,5 @@
 		}
 
-		expected_pa = QH(interrupt)->next_queue & (~0xf);
+		expected_pa = QH(interrupt)->next & LINK_POINTER_ADDRESS_MASK;
 		real_pa = addr_to_phys(QH(control_slow));
 		if (expected_pa != real_pa) {
@@ -451,5 +452,5 @@
 		}
 
-		expected_pa = QH(control_slow)->next_queue & (~0xf);
+		expected_pa = QH(control_slow)->next & LINK_POINTER_ADDRESS_MASK;
 		real_pa = addr_to_phys(QH(control_full));
 		if (expected_pa != real_pa) {
@@ -458,5 +459,5 @@
 		}
 
-		expected_pa = QH(control_full)->next_queue & (~0xf);
+		expected_pa = QH(control_full)->next & LINK_POINTER_ADDRESS_MASK;
 		real_pa = addr_to_phys(QH(bulk_full));
 		if (expected_pa != real_pa ) {
Index: uspace/drv/uhci-hcd/uhci_struct/link_pointer.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/link_pointer.h	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/uhci_struct/link_pointer.h	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -46,4 +46,7 @@
 #define LINK_POINTER_ADDRESS_MASK 0xfffffff0 /* upper 28 bits */
 
+#define LINK_POINTER_QH(address) \
+	((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG)
+
 #endif
 /**
Index: uspace/drv/uhci-hcd/uhci_struct/queue_head.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/queue_head.h	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/uhci_struct/queue_head.h	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -43,36 +43,44 @@
 
 typedef struct queue_head {
-	volatile link_pointer_t next_queue;
+	volatile link_pointer_t next;
 	volatile link_pointer_t element;
-} __attribute__((packed)) queue_head_t;
-
-static inline void queue_head_init(queue_head_t *instance)
+} __attribute__((packed)) qh_t;
+/*----------------------------------------------------------------------------*/
+static inline void qh_init(qh_t *instance)
 {
 	assert(instance);
 
 	instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
-	instance->next_queue = 0 | LINK_POINTER_TERMINATE_FLAG;
+	instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
 }
-
-static inline void queue_head_append_qh(queue_head_t *instance, uint32_t pa)
+/*----------------------------------------------------------------------------*/
+static inline void qh_set_next_qh(qh_t *instance, uint32_t pa)
 {
-	if (pa) {
-		instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK)
+	/* 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;
+	} else {
+		instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
 	}
 }
-
-static inline void queue_head_element_qh(queue_head_t *instance, uint32_t pa)
+/*----------------------------------------------------------------------------*/
+static inline void qh_set_element_qh(qh_t *instance, uint32_t pa)
 {
-	if (pa) {
-		instance->next_queue = (pa & LINK_POINTER_ADDRESS_MASK)
+	/* 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;
+	} else {
+		instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
 	}
 }
-
-static inline void queue_head_set_element_td(queue_head_t *instance, uint32_t pa)
+/*----------------------------------------------------------------------------*/
+static inline void qh_set_element_td(qh_t *instance, uint32_t pa)
 {
-	if (pa) {
+	if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {
 		instance->element = (pa & LINK_POINTER_ADDRESS_MASK);
+	} else {
+		instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
 	}
 }
Index: uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h	(revision eb0dc587ae7da417930cae6d0a65bb86fea11513)
+++ uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h	(revision 6143ce3dd41a81c40c456be33f077730bcddf32f)
@@ -49,5 +49,4 @@
 #define TD_STATUS_ERROR_COUNT_POS ( 27 )
 #define TD_STATUS_ERROR_COUNT_MASK ( 0x3 )
-#define TD_STATUS_ERROR_COUNT_DEFAULT 3
 #define TD_STATUS_LOW_SPEED_FLAG ( 1 << 26 )
 #define TD_STATUS_ISOCHRONOUS_FLAG ( 1 << 25 )
