Index: uspace/drv/bus/usb/ehci/ehci_endpoint.h
===================================================================
--- uspace/drv/bus/usb/ehci/ehci_endpoint.h	(revision a24d68251578222a03414d0b81434d7d480c7519)
+++ uspace/drv/bus/usb/ehci/ehci_endpoint.h	(revision 3de7a6235f59404fe29b5e6146634adbfaf9e3bf)
@@ -66,4 +66,9 @@
 }
 
+static inline ehci_endpoint_t * ehci_endpoint_list_instance(link_t *l)
+{
+	return list_get_instance(l, ehci_endpoint_t, link);
+}
+
 #endif
 /**
Index: uspace/drv/bus/usb/ehci/endpoint_list.c
===================================================================
--- uspace/drv/bus/usb/ehci/endpoint_list.c	(revision a24d68251578222a03414d0b81434d7d480c7519)
+++ uspace/drv/bus/usb/ehci/endpoint_list.c	(revision 3de7a6235f59404fe29b5e6146634adbfaf9e3bf)
@@ -64,5 +64,5 @@
 	    name, instance->list_head, instance->list_head_pa);
 
-//	qh_init(instance->list_head, NULL, NULL);
+	qh_init(instance->list_head, NULL);
 	list_initialize(&instance->endpoint_list);
 	fibril_mutex_initialize(&instance->guard);
@@ -70,5 +70,5 @@
 }
 
-/** Add endpoint to the list and queue.
+/** Add endpoint to the end of the list and queue.
  *
  * @param[in] instance List to use.
@@ -77,32 +77,32 @@
  * The endpoint is added to the end of the list and queue.
  */
-void endpoint_list_add_ep(endpoint_list_t *instance, ehci_endpoint_t *ep)
+void endpoint_list_append_ep(endpoint_list_t *instance, ehci_endpoint_t *ep)
 {
 	assert(instance);
 	assert(ep);
+	assert(ep->qh);
 	usb_log_debug2("Queue %s: Adding endpoint(%p).\n", instance->name, ep);
 
 	fibril_mutex_lock(&instance->guard);
 
-#if 0
-	//TODO Implement this
-	ed_t *last_ed = NULL;
+	qh_t *last_qh = NULL;
 	/* Add to the hardware queue. */
 	if (list_empty(&instance->endpoint_list)) {
 		/* There are no active EDs */
-		last_ed = instance->list_head;
+		last_qh = instance->list_head;
 	} else {
 		/* There are active EDs, get the last one */
-		ehci_endpoint_t *last = list_get_instance(
-		    list_last(&instance->endpoint_list), ehci_endpoint_t, link);
-		last_ed = last->ed;
+		ehci_endpoint_t *last = ehci_endpoint_list_instance(
+		    list_last(&instance->endpoint_list));
+		last_qh = last->qh;
 	}
+	assert(last_qh);
 	/* Keep link */
-	ep->ed->next = last_ed->next;
-	/* Make sure ED is written to the memory */
+	ep->qh->horizontal = last_qh->horizontal;
+	/* Make sure QH update is written to the memory */
 	write_barrier();
 
 	/* Add ed to the hw queue */
-	ed_append_ed(last_ed, ep->ed);
+	qh_append_qh(last_qh, ep->qh);
 	/* Make sure ED is updated */
 	write_barrier();
@@ -110,15 +110,13 @@
 	list_append(&ep->link, &instance->endpoint_list);
 
-	ehci_endpoint_t *first = list_get_instance(
-	    list_first(&instance->endpoint_list), ehci_endpoint_t, link);
+	ehci_endpoint_t *first = ehci_endpoint_list_instance(
+	    list_first(&instance->endpoint_list));
 	usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n",
-		ep, instance->name, first, first->ed);
-	if (last_ed == instance->list_head) {
-		usb_log_debug2("%s head ED(%p-0x%0" PRIx32 "): %x:%x:%x:%x.\n",
-		    instance->name, last_ed, instance->list_head_pa,
-		    last_ed->status, last_ed->td_tail, last_ed->td_head,
-		    last_ed->next);
+		ep, instance->name, first, first->qh);
+	if (last_qh == instance->list_head) {
+		usb_log_debug2("%s head ED(%p-0x%0" PRIx32 "): %x:%x.\n",
+		    instance->name, last_qh, instance->list_head_pa,
+		    last_qh->status, last_qh->horizontal);
 	}
-#endif
 	fibril_mutex_unlock(&instance->guard);
 }
@@ -153,5 +151,5 @@
 		qpos = "NOT FIRST";
 	}
-//	assert(ed_next(prev_qh) == addr_to_phys(ep->eq));
+	assert(qh_next(prev_qh) == addr_to_phys(ep->qh));
 	prev_qh->next = ep->qh->next;
 	/* Make sure ED is updated */
Index: uspace/drv/bus/usb/ehci/endpoint_list.h
===================================================================
--- uspace/drv/bus/usb/ehci/endpoint_list.h	(revision a24d68251578222a03414d0b81434d7d480c7519)
+++ uspace/drv/bus/usb/ehci/endpoint_list.h	(revision 3de7a6235f59404fe29b5e6146634adbfaf9e3bf)
@@ -69,10 +69,9 @@
 	free32(instance->list_head);
 	instance->list_head = NULL;
+	instance->list_head_pa = 0;
 }
 
 int endpoint_list_init(endpoint_list_t *instance, const char *name);
-void endpoint_list_set_next(
-    const endpoint_list_t *instance, const endpoint_list_t *next);
-void endpoint_list_add_ep(endpoint_list_t *instance, ehci_endpoint_t *ep);
+void endpoint_list_append_ep(endpoint_list_t *instance, ehci_endpoint_t *ep);
 void endpoint_list_remove_ep(endpoint_list_t *instance, ehci_endpoint_t *ep);
 #endif
Index: uspace/drv/bus/usb/ehci/hw_struct/queue_head.h
===================================================================
--- uspace/drv/bus/usb/ehci/hw_struct/queue_head.h	(revision a24d68251578222a03414d0b81434d7d480c7519)
+++ uspace/drv/bus/usb/ehci/hw_struct/queue_head.h	(revision 3de7a6235f59404fe29b5e6146634adbfaf9e3bf)
@@ -40,4 +40,5 @@
 
 #include "link_pointer.h"
+#include "mem_access.h"
 
 /** This structure is defined in EHCI design guide p. 46 */
@@ -140,4 +141,19 @@
 } qh_t;
 
+static inline void qh_append_qh(qh_t *qh, const qh_t *next)
+{
+	assert(qh);
+	assert(next);
+	const uint32_t pa = addr_to_phys(next);
+	assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
+	EHCI_MEM32_WR(qh->horizontal, LINK_POINTER_QH(pa));
+}
+
+static inline uintptr_t qh_next(const qh_t *qh)
+{
+	assert(qh);
+	return (qh->horizontal & LINK_POINTER_ADDRESS_MASK);
+}
+
 void qh_init(qh_t *instance, const endpoint_t *ep);
 #endif
