Index: uspace/drv/ohci/Makefile
===================================================================
--- uspace/drv/ohci/Makefile	(revision 2759c52b46ddb4e1c20ca262cae954df7d30797a)
+++ uspace/drv/ohci/Makefile	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
@@ -34,4 +34,5 @@
 SOURCES = \
 	batch.c \
+	endpoint_list.c \
 	hc.c \
 	hcd_endpoint.c \
@@ -41,5 +42,4 @@
 	pci.c \
 	root_hub.c \
-	transfer_list.c \
 	hw_struct/endpoint_descriptor.c \
 	hw_struct/transfer_descriptor.c
Index: uspace/drv/ohci/endpoint_list.c
===================================================================
--- uspace/drv/ohci/endpoint_list.c	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
+++ uspace/drv/ohci/endpoint_list.c	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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.
+ */
+/** @addtogroup drvusbohci
+ * @{
+ */
+/** @file
+ * @brief OHCI driver transfer list implementation
+ */
+#include <errno.h>
+#include <usb/debug.h>
+
+#include "endpoint_list.h"
+
+/** Initialize transfer list structures.
+ *
+ * @param[in] instance Memory place to use.
+ * @param[in] name Name of the new list.
+ * @return Error code
+ *
+ * Allocates memory for internal qh_t structure.
+ */
+int endpoint_list_init(endpoint_list_t *instance, const char *name)
+{
+	assert(instance);
+	instance->name = name;
+	instance->list_head = malloc32(sizeof(ed_t));
+	if (!instance->list_head) {
+		usb_log_error("Failed to allocate list head.\n");
+		return ENOMEM;
+	}
+	instance->list_head_pa = addr_to_phys(instance->list_head);
+	usb_log_debug2("Transfer list %s setup with ED: %p(%p).\n",
+	    name, instance->list_head, instance->list_head_pa);
+
+	ed_init(instance->list_head, NULL);
+	list_initialize(&instance->endpoint_list);
+	fibril_mutex_initialize(&instance->guard);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Set the next list in transfer list chain.
+ *
+ * @param[in] instance List to lead.
+ * @param[in] next List to append.
+ * @return Error code
+ *
+ * Does not check whether this replaces an existing list .
+ */
+void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next)
+{
+	assert(instance);
+	assert(next);
+	ed_append_ed(instance->list_head, next->list_head);
+}
+/*----------------------------------------------------------------------------*/
+/** Submit transfer endpoint to the list and queue.
+ *
+ * @param[in] instance List to use.
+ * @param[in] endpoint Transfer endpoint to submit.
+ * @return Error code
+ *
+ * The endpoint is added to the end of the list and queue.
+ */
+void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
+{
+	assert(instance);
+	assert(hcd_ep);
+	usb_log_debug2("Queue %s: Adding endpoint(%p).\n",
+	    instance->name, hcd_ep);
+
+	fibril_mutex_lock(&instance->guard);
+
+	ed_t *last_ed = NULL;
+	/* Add to the hardware queue. */
+	if (list_empty(&instance->endpoint_list)) {
+		/* There is nothing scheduled */
+		last_ed = instance->list_head;
+	} else {
+		/* There is something scheduled */
+		hcd_endpoint_t *last = list_get_instance(
+		    instance->endpoint_list.prev, hcd_endpoint_t, link);
+		last_ed = last->ed;
+	}
+	/* keep link */
+	hcd_ep->ed->next = last_ed->next;
+	ed_append_ed(last_ed, hcd_ep->ed);
+
+	asm volatile ("": : :"memory");
+
+	/* Add to the driver list */
+	list_append(&hcd_ep->link, &instance->endpoint_list);
+
+	hcd_endpoint_t *first = list_get_instance(
+	    instance->endpoint_list.next, hcd_endpoint_t, link);
+	usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n",
+		hcd_ep, instance->name, first, first->ed);
+	if (last_ed == instance->list_head) {
+		usb_log_debug2("%s head ED(%p-%p): %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);
+	}
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+#if 0
+/** Create list for finished endpoints.
+ *
+ * @param[in] instance List to use.
+ * @param[in] done list to fill
+ */
+void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done)
+{
+	assert(instance);
+	assert(done);
+
+	fibril_mutex_lock(&instance->guard);
+	usb_log_debug2("Checking list %s for completed endpointes(%d).\n",
+	    instance->name, list_count(&instance->endpoint_list));
+	link_t *current = instance->endpoint_list.next;
+	while (current != &instance->endpoint_list) {
+		link_t *next = current->next;
+		hcd_endpoint_t *endpoint =
+		    list_get_instance(current, hcd_endpoint_t, link);
+
+		if (endpoint_is_complete(endpoint)) {
+			/* Save for post-processing */
+			endpoint_list_remove_endpoint(instance, endpoint);
+			list_append(current, done);
+		}
+		current = next;
+	}
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+/** Walk the list and abort all endpointes.
+ *
+ * @param[in] instance List to use.
+ */
+void endpoint_list_abort_all(endpoint_list_t *instance)
+{
+	fibril_mutex_lock(&instance->guard);
+	while (!list_empty(&instance->endpoint_list)) {
+		link_t *current = instance->endpoint_list.next;
+		hcd_endpoint_t *endpoint =
+		    list_get_instance(current, hcd_endpoint_t, link);
+		endpoint_list_remove_endpoint(instance, endpoint);
+		hcd_endpoint_finish_error(endpoint, EIO);
+	}
+	fibril_mutex_unlock(&instance->guard);
+}
+#endif
+/*----------------------------------------------------------------------------*/
+/** Remove a transfer endpoint from the list and queue.
+ *
+ * @param[in] instance List to use.
+ * @param[in] endpoint Transfer endpoint to remove.
+ * @return Error code
+ *
+ * Does not lock the transfer list, caller is responsible for that.
+ */
+void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)
+{
+	assert(instance);
+	assert(instance->list_head);
+	assert(hcd_ep);
+	assert(hcd_ep->ed);
+	assert(fibril_mutex_is_locked(&instance->guard));
+
+	usb_log_debug2(
+	    "Queue %s: removing endpoint(%p).\n", instance->name, hcd_ep);
+
+	const char *qpos = NULL;
+	ed_t *prev_ed;
+	/* Remove from the hardware queue */
+	if (instance->endpoint_list.next == &hcd_ep->link) {
+		/* I'm the first one here */
+		prev_ed = instance->list_head;
+		qpos = "FIRST";
+	} else {
+		hcd_endpoint_t *prev =
+		    list_get_instance(hcd_ep->link.prev, hcd_endpoint_t, link);
+		prev_ed = prev->ed;
+		qpos = "NOT FIRST";
+	}
+	assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed));
+	prev_ed->next = hcd_ep->ed->next;
+
+	asm volatile ("": : :"memory");
+	usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n",
+	    hcd_ep, qpos, instance->name, hcd_ep->ed->next);
+
+	/* Remove from the endpoint list */
+	list_remove(&hcd_ep->link);
+}
+/**
+ * @}
+ */
Index: uspace/drv/ohci/endpoint_list.h
===================================================================
--- uspace/drv/ohci/endpoint_list.h	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
+++ uspace/drv/ohci/endpoint_list.h	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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.
+ */
+/** @addtogroup drvusbohci
+ * @{
+ */
+/** @file
+ * @brief OHCI driver transfer list structure
+ */
+#ifndef DRV_OHCI_ENDPOINT_LIST_H
+#define DRV_OHCI_ENDPOINT_LIST_H
+
+#include <fibril_synch.h>
+
+#include "hcd_endpoint.h"
+#include "hw_struct/endpoint_descriptor.h"
+#include "utils/malloc32.h"
+
+typedef struct endpoint_list
+{
+	fibril_mutex_t guard;
+	ed_t *list_head;
+	uint32_t list_head_pa;
+	const char *name;
+	link_t endpoint_list;
+} endpoint_list_t;
+
+/** Dispose transfer list structures.
+ *
+ * @param[in] instance Memory place to use.
+ *
+ * Frees memory for internal qh_t structure.
+ */
+static inline void endpoint_list_fini(endpoint_list_t *instance)
+{
+	assert(instance);
+	free32(instance->list_head);
+}
+
+int endpoint_list_init(endpoint_list_t *instance, const char *name);
+
+void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next);
+
+void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
+
+void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);
+#if 0
+void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done);
+
+void endpoint_list_abort_all(endpoint_list_t *instance);
+#endif
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/ohci/hc.c
===================================================================
--- uspace/drv/ohci/hc.c	(revision 2759c52b46ddb4e1c20ca262cae954df7d30797a)
+++ uspace/drv/ohci/hc.c	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
@@ -155,10 +155,37 @@
 		return ENOMEM;
 	}
-	// TODO: enqueue hcd_ep here!
 
 	ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size);
 	if (ret != EOK) {
 		endpoint_destroy(ep);
-	}
+		return ret;
+	}
+
+	/* Enqueue hcd_ep */
+	switch (ep->transfer_type) {
+	case USB_TRANSFER_CONTROL:
+		instance->registers->control &= ~C_CLE;
+		endpoint_list_add_ep(
+		    &instance->lists[ep->transfer_type], hcd_ep);
+		instance->registers->control_current = 0;
+		instance->registers->control |= C_CLE;
+		break;
+	case USB_TRANSFER_BULK:
+		instance->registers->control &= ~C_BLE;
+		endpoint_list_add_ep(
+		    &instance->lists[ep->transfer_type], hcd_ep);
+		instance->registers->control |= C_BLE;
+		break;
+	case USB_TRANSFER_ISOCHRONOUS:
+	case USB_TRANSFER_INTERRUPT:
+		instance->registers->control &= (~C_PLE & ~C_IE);
+		endpoint_list_add_ep(
+		    &instance->lists[ep->transfer_type], hcd_ep);
+		instance->registers->control |= C_PLE | C_IE;
+		break;
+	default:
+		break;
+	}
+
 	return ret;
 }
@@ -176,5 +203,29 @@
 	hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);
 	if (hcd_ep) {
-		// TODO: dequeue hcd_ep here!
+		/* Dequeue hcd_ep */
+		switch (ep->transfer_type) {
+		case USB_TRANSFER_CONTROL:
+			instance->registers->control &= ~C_CLE;
+			endpoint_list_remove_ep(
+			    &instance->lists[ep->transfer_type], hcd_ep);
+			instance->registers->control_current = 0;
+			instance->registers->control |= C_CLE;
+			break;
+		case USB_TRANSFER_BULK:
+			instance->registers->control &= ~C_BLE;
+			endpoint_list_remove_ep(
+			    &instance->lists[ep->transfer_type], hcd_ep);
+			instance->registers->control |= C_BLE;
+			break;
+		case USB_TRANSFER_ISOCHRONOUS:
+		case USB_TRANSFER_INTERRUPT:
+			instance->registers->control &= (~C_PLE & ~C_IE);
+			endpoint_list_remove_ep(
+			    &instance->lists[ep->transfer_type], hcd_ep);
+			instance->registers->control |= C_PLE | C_IE;
+			break;
+		default:
+			break;
+		}
 		hcd_endpoint_clear(ep);
 	} else {
@@ -195,5 +246,5 @@
 		return rh_request(&instance->rh, batch);
 	}
-
+#if 0
 	fibril_mutex_lock(&instance->guard);
 	switch (batch->ep->transfer_type) {
@@ -230,4 +281,5 @@
 	}
 	fibril_mutex_unlock(&instance->guard);
+#endif
 	return EOK;
 }
@@ -249,4 +301,5 @@
 		usb_log_debug2("Periodic current: %p.\n",
 		    instance->registers->periodic_current);
+#if 0
 		LIST_INITIALIZE(done);
 		transfer_list_remove_finished(
@@ -267,4 +320,5 @@
 		}
 		fibril_mutex_unlock(&instance->guard);
+#endif
 	}
 }
@@ -358,14 +412,15 @@
 
 	/* Use queues */
-	instance->registers->bulk_head = instance->transfers_bulk.list_head_pa;
+	instance->registers->bulk_head =
+	    instance->lists[USB_TRANSFER_BULK].list_head_pa;
 	usb_log_debug2("Bulk HEAD set to: %p(%p).\n",
-	    instance->transfers_bulk.list_head,
-	    instance->transfers_bulk.list_head_pa);
+	    instance->lists[USB_TRANSFER_BULK].list_head,
+	    instance->lists[USB_TRANSFER_BULK].list_head_pa);
 
 	instance->registers->control_head =
-	    instance->transfers_control.list_head_pa;
+	    instance->lists[USB_TRANSFER_CONTROL].list_head_pa;
 	usb_log_debug2("Control HEAD set to: %p(%p).\n",
-	    instance->transfers_control.list_head,
-	    instance->transfers_control.list_head_pa);
+	    instance->lists[USB_TRANSFER_CONTROL].list_head,
+	    instance->lists[USB_TRANSFER_CONTROL].list_head_pa);
 
 	/* Enable queues */
@@ -398,34 +453,25 @@
 	assert(instance);
 
-#define SETUP_TRANSFER_LIST(type, name) \
+#define SETUP_ENDPOINT_LIST(type) \
 do { \
-	int ret = transfer_list_init(&instance->type, name); \
+	const char *name = usb_str_transfer_type(type); \
+	int ret = endpoint_list_init(&instance->lists[type], name); \
 	if (ret != EOK) { \
-		usb_log_error("Failed(%d) to setup %s transfer list.\n", \
+		usb_log_error("Failed(%d) to setup %s endpoint list.\n", \
 		    ret, name); \
-		transfer_list_fini(&instance->transfers_isochronous); \
-		transfer_list_fini(&instance->transfers_interrupt); \
-		transfer_list_fini(&instance->transfers_control); \
-		transfer_list_fini(&instance->transfers_bulk); \
+		endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \
+		endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \
+		endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \
+		endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \
 	} \
 } while (0)
 
-	SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS");
-	SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT");
-	SETUP_TRANSFER_LIST(transfers_control, "CONTROL");
-	SETUP_TRANSFER_LIST(transfers_bulk, "BULK");
-#undef SETUP_TRANSFER_LIST
-	transfer_list_set_next(&instance->transfers_interrupt,
-	    &instance->transfers_isochronous);
-
-	/* Assign pointers to be used during scheduling */
-	instance->transfers[USB_TRANSFER_INTERRUPT] =
-	  &instance->transfers_interrupt;
-	instance->transfers[USB_TRANSFER_ISOCHRONOUS] =
-	  &instance->transfers_interrupt;
-	instance->transfers[USB_TRANSFER_CONTROL] =
-	  &instance->transfers_control;
-	instance->transfers[USB_TRANSFER_BULK] =
-	  &instance->transfers_bulk;
+	SETUP_ENDPOINT_LIST(USB_TRANSFER_ISOCHRONOUS);
+	SETUP_ENDPOINT_LIST(USB_TRANSFER_INTERRUPT);
+	SETUP_ENDPOINT_LIST(USB_TRANSFER_CONTROL);
+	SETUP_ENDPOINT_LIST(USB_TRANSFER_BULK);
+#undef SETUP_ENDPOINT_LIST
+	endpoint_list_set_next(&instance->lists[USB_TRANSFER_INTERRUPT],
+	    &instance->lists[USB_TRANSFER_ISOCHRONOUS]);
 
 	return EOK;
@@ -448,9 +494,9 @@
 	for (; i < 32; ++i) {
 		instance->hcca->int_ep[i] =
-		    instance->transfers_interrupt.list_head_pa;
+		    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa;
 	}
 	usb_log_debug2("Interrupt HEADs set to: %p(%p).\n",
-	    instance->transfers_interrupt.list_head,
-	    instance->transfers_interrupt.list_head_pa);
+	    instance->lists[USB_TRANSFER_INTERRUPT].list_head,
+	    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
 
 	return EOK;
Index: uspace/drv/ohci/hc.h
===================================================================
--- uspace/drv/ohci/hc.h	(revision 2759c52b46ddb4e1c20ca262cae954df7d30797a)
+++ uspace/drv/ohci/hc.h	(revision 5a2c42bd0e02f21ac673b0897cc3c6cd7816158b)
@@ -48,5 +48,5 @@
 #include "ohci_regs.h"
 #include "root_hub.h"
-#include "transfer_list.h"
+#include "endpoint_list.h"
 #include "hw_struct/hcca.h"
 
@@ -58,10 +58,5 @@
 	hcca_t *hcca;
 
-	transfer_list_t transfers_isochronous;
-	transfer_list_t transfers_interrupt;
-	transfer_list_t transfers_control;
-	transfer_list_t transfers_bulk;
-
-	transfer_list_t *transfers[4];
+	endpoint_list_t lists[4];
 
 	ddf_fun_t *ddf_instance;
Index: uspace/drv/ohci/transfer_list.c
===================================================================
--- uspace/drv/ohci/transfer_list.c	(revision 2759c52b46ddb4e1c20ca262cae954df7d30797a)
+++ 	(revision )
@@ -1,226 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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.
- */
-/** @addtogroup drvusbohci
- * @{
- */
-/** @file
- * @brief OHCI driver transfer list implementation
- */
-#include <errno.h>
-#include <usb/debug.h>
-
-#include "transfer_list.h"
-
-static void transfer_list_remove_batch(
-    transfer_list_t *instance, usb_transfer_batch_t *batch);
-/*----------------------------------------------------------------------------*/
-/** Initialize transfer list structures.
- *
- * @param[in] instance Memory place to use.
- * @param[in] name Name of the new list.
- * @return Error code
- *
- * Allocates memory for internal qh_t structure.
- */
-int transfer_list_init(transfer_list_t *instance, const char *name)
-{
-	assert(instance);
-	instance->name = name;
-	instance->list_head = malloc32(sizeof(ed_t));
-	if (!instance->list_head) {
-		usb_log_error("Failed to allocate list head.\n");
-		return ENOMEM;
-	}
-	instance->list_head_pa = addr_to_phys(instance->list_head);
-	usb_log_debug2("Transfer list %s setup with ED: %p(%p).\n",
-	    name, instance->list_head, instance->list_head_pa);
-
-	ed_init(instance->list_head, NULL);
-	list_initialize(&instance->batch_list);
-	fibril_mutex_initialize(&instance->guard);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Set the next list in transfer list chain.
- *
- * @param[in] instance List to lead.
- * @param[in] next List to append.
- * @return Error code
- *
- * Does not check whether this replaces an existing list .
- */
-void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
-{
-	assert(instance);
-	assert(next);
-	ed_append_ed(instance->list_head, next->list_head);
-}
-/*----------------------------------------------------------------------------*/
-/** Submit transfer batch to the list and queue.
- *
- * @param[in] instance List to use.
- * @param[in] batch Transfer batch to submit.
- * @return Error code
- *
- * The batch is added to the end of the list and queue.
- */
-void transfer_list_add_batch(
-    transfer_list_t *instance, usb_transfer_batch_t *batch)
-{
-	assert(instance);
-	assert(batch);
-	usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);
-
-	fibril_mutex_lock(&instance->guard);
-
-	ed_t *last_ed = NULL;
-	/* Add to the hardware queue. */
-	if (list_empty(&instance->batch_list)) {
-		/* There is nothing scheduled */
-		last_ed = instance->list_head;
-	} else {
-		/* There is something scheduled */
-		usb_transfer_batch_t *last = list_get_instance(
-		    instance->batch_list.prev, usb_transfer_batch_t, link);
-		last_ed = batch_ed(last);
-	}
-	/* keep link */
-	batch_ed(batch)->next = last_ed->next;
-	ed_append_ed(last_ed, batch_ed(batch));
-
-	asm volatile ("": : :"memory");
-
-	/* Add to the driver list */
-	list_append(&batch->link, &instance->batch_list);
-
-	usb_transfer_batch_t *first = list_get_instance(
-	    instance->batch_list.next, usb_transfer_batch_t, link);
-	usb_log_debug("Batch(%p) added to list %s, first is %p(%p).\n",
-		batch, instance->name, first, batch_ed(first));
-	if (last_ed == instance->list_head) {
-		usb_log_debug2("%s head ED(%p-%p): %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);
-	}
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Create list for finished batches.
- *
- * @param[in] instance List to use.
- * @param[in] done list to fill
- */
-void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
-{
-	assert(instance);
-	assert(done);
-
-	fibril_mutex_lock(&instance->guard);
-	usb_log_debug2("Checking list %s for completed batches(%d).\n",
-	    instance->name, list_count(&instance->batch_list));
-	link_t *current = instance->batch_list.next;
-	while (current != &instance->batch_list) {
-		link_t *next = current->next;
-		usb_transfer_batch_t *batch =
-		    list_get_instance(current, usb_transfer_batch_t, link);
-
-		if (batch_is_complete(batch)) {
-			/* Save for post-processing */
-			transfer_list_remove_batch(instance, batch);
-			list_append(current, done);
-		}
-		current = next;
-	}
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Walk the list and abort all batches.
- *
- * @param[in] instance List to use.
- */
-void transfer_list_abort_all(transfer_list_t *instance)
-{
-	fibril_mutex_lock(&instance->guard);
-	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);
-		transfer_list_remove_batch(instance, batch);
-		usb_transfer_batch_finish_error(batch, EIO);
-	}
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Remove 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, usb_transfer_batch_t *batch)
-{
-	assert(instance);
-	assert(instance->list_head);
-	assert(batch);
-	assert(batch_ed(batch));
-	assert(fibril_mutex_is_locked(&instance->guard));
-
-	usb_log_debug2(
-	    "Queue %s: removing batch(%p).\n", instance->name, batch);
-
-	const char *qpos = NULL;
-	/* Remove from the hardware queue */
-	if (instance->batch_list.next == &batch->link) {
-		/* I'm the first one here */
-		assert((instance->list_head->next & ED_NEXT_PTR_MASK)
-		    == addr_to_phys(batch_ed(batch)));
-		instance->list_head->next = batch_ed(batch)->next;
-		qpos = "FIRST";
-	} else {
-		usb_transfer_batch_t *prev =
-		    list_get_instance(
-		        batch->link.prev, usb_transfer_batch_t, link);
-		assert((batch_ed(prev)->next & ED_NEXT_PTR_MASK)
-		    == addr_to_phys(batch_ed(batch)));
-		batch_ed(prev)->next = batch_ed(batch)->next;
-		qpos = "NOT FIRST";
-	}
-	asm volatile ("": : :"memory");
-	usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",
-	    batch, qpos, instance->name, batch_ed(batch)->next);
-
-	/* Remove from the batch list */
-	list_remove(&batch->link);
-}
-/**
- * @}
- */
Index: uspace/drv/ohci/transfer_list.h
===================================================================
--- uspace/drv/ohci/transfer_list.h	(revision 2759c52b46ddb4e1c20ca262cae954df7d30797a)
+++ 	(revision )
@@ -1,76 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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.
- */
-/** @addtogroup drvusbohci
- * @{
- */
-/** @file
- * @brief OHCI driver transfer list structure
- */
-#ifndef DRV_OHCI_TRANSFER_LIST_H
-#define DRV_OHCI_TRANSFER_LIST_H
-
-#include <fibril_synch.h>
-
-#include "batch.h"
-#include "hw_struct/endpoint_descriptor.h"
-#include "utils/malloc32.h"
-
-typedef struct transfer_list
-{
-	fibril_mutex_t guard;
-	ed_t *list_head;
-	uint32_t list_head_pa;
-	const char *name;
-	link_t batch_list;
-} transfer_list_t;
-
-/** Dispose transfer list structures.
- *
- * @param[in] instance Memory place to use.
- *
- * Frees memory for internal qh_t structure.
- */
-static inline void transfer_list_fini(transfer_list_t *instance)
-{
-	assert(instance);
-	free32(instance->list_head);
-}
-
-int transfer_list_init(transfer_list_t *instance, const char *name);
-
-void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);
-
-void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
-
-void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
-
-void transfer_list_abort_all(transfer_list_t *instance);
-#endif
-/**
- * @}
- */
