Index: uspace/drv/bus/usb/uhci/Makefile
===================================================================
--- uspace/drv/bus/usb/uhci/Makefile	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/Makefile	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -42,5 +42,4 @@
 
 SOURCES = \
-	iface.c \
 	main.c \
 	transfer_list.c \
Index: uspace/drv/bus/usb/uhci/batch.c
===================================================================
--- uspace/drv/bus/usb/uhci/batch.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/batch.c	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -44,4 +44,12 @@
 
 #define DEFAULT_ERROR_COUNT 3
+static void batch_control_write(usb_transfer_batch_t *instance);
+static void batch_control_read(usb_transfer_batch_t *instance);
+
+static void batch_interrupt_in(usb_transfer_batch_t *instance);
+static void batch_interrupt_out(usb_transfer_batch_t *instance);
+
+static void batch_bulk_in(usb_transfer_batch_t *instance);
+static void batch_bulk_out(usb_transfer_batch_t *instance);
 
 static void batch_setup_control(usb_transfer_batch_t *batch)
@@ -93,4 +101,22 @@
 }
 /*----------------------------------------------------------------------------*/
+/** Allocate memory and initialize internal data structure.
+ *
+ * @param[in] fun DDF function to pass to callback.
+ * @param[in] ep Communication target
+ * @param[in] buffer Data source/destination.
+ * @param[in] buffer_size Size of the buffer.
+ * @param[in] setup_buffer Setup data source (if not NULL)
+ * @param[in] setup_size Size of setup_buffer (should be always 8)
+ * @param[in] func_in function to call on inbound transfer completion
+ * @param[in] func_out function to call on outbound transfer completion
+ * @param[in] arg additional parameter to func_in or func_out
+ * @return Valid pointer if all structures were successfully created,
+ * NULL otherwise.
+ *
+ * Determines the number of needed transfer descriptors (TDs).
+ * Prepares a transport buffer (that is accessible by the hardware).
+ * Initializes parameters needed for the transfer and callback.
+ */
 void * uhci_transfer_batch_create(usb_transfer_batch_t *batch)
 {
@@ -148,85 +174,4 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Allocate memory and initialize internal data structure.
- *
- * @param[in] fun DDF function to pass to callback.
- * @param[in] ep Communication target
- * @param[in] buffer Data source/destination.
- * @param[in] buffer_size Size of the buffer.
- * @param[in] setup_buffer Setup data source (if not NULL)
- * @param[in] setup_size Size of setup_buffer (should be always 8)
- * @param[in] func_in function to call on inbound transfer completion
- * @param[in] func_out function to call on outbound transfer completion
- * @param[in] arg additional parameter to func_in or func_out
- * @return Valid pointer if all structures were successfully created,
- * NULL otherwise.
- *
- * Determines the number of needed transfer descriptors (TDs).
- * Prepares a transport buffer (that is accessible by the hardware).
- * Initializes parameters needed for the transfer and callback.
- */
-usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
-    char *buffer, size_t buffer_size,
-    const char* setup_buffer, size_t setup_size,
-    usbhc_iface_transfer_in_callback_t func_in,
-    usbhc_iface_transfer_out_callback_t func_out, void *arg)
-{
-	assert(ep);
-	assert(func_in == NULL || func_out == NULL);
-	assert(func_in != NULL || func_out != NULL);
-
-#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
-	if (ptr == NULL) { \
-		usb_log_error(message); \
-		if (uhci_data) { \
-			uhci_transfer_batch_dispose(uhci_data); \
-		} \
-		return NULL; \
-	} else (void)0
-
-	uhci_transfer_batch_t *uhci_data =
-	    malloc(sizeof(uhci_transfer_batch_t));
-	CHECK_NULL_DISPOSE_RETURN(uhci_data,
-	    "Failed to allocate UHCI batch.\n");
-	bzero(uhci_data, sizeof(uhci_transfer_batch_t));
-
-	uhci_data->td_count =
-	    (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
-	if (ep->transfer_type == USB_TRANSFER_CONTROL) {
-		uhci_data->td_count += 2;
-	}
-
-	assert((sizeof(td_t) % 16) == 0);
-	const size_t total_size = (sizeof(td_t) * uhci_data->td_count)
-	    + sizeof(qh_t) + setup_size + buffer_size;
-	uhci_data->device_buffer = malloc32(total_size);
-	CHECK_NULL_DISPOSE_RETURN(uhci_data->device_buffer,
-	    "Failed to allocate UHCI buffer.\n");
-	bzero(uhci_data->device_buffer, total_size);
-
-	uhci_data->tds = uhci_data->device_buffer;
-	uhci_data->qh =
-	    (uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count));
-
-	qh_init(uhci_data->qh);
-	qh_set_element_td(uhci_data->qh, uhci_data->tds);
-
-	usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
-	CHECK_NULL_DISPOSE_RETURN(instance,
-	    "Failed to allocate batch instance.\n");
-	void *setup =
-	    uhci_data->device_buffer + (sizeof(td_t) * uhci_data->td_count)
-	    + sizeof(qh_t);
-	void *data_buffer = setup + setup_size;
-	usb_transfer_batch_init(instance, ep, buffer, data_buffer, buffer_size,
-	    setup, setup_size, func_in, func_out, arg, fun,
-	    uhci_data, uhci_transfer_batch_dispose);
-
-	memcpy(instance->setup_buffer, setup_buffer, setup_size);
-	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT
-	    " memory structures ready.\n", instance,
-	    USB_TRANSFER_BATCH_ARGS(*instance));
-	return instance;
-}
 /*----------------------------------------------------------------------------*/
 /** Check batch TDs for activity.
@@ -288,5 +233,5 @@
  * Uses generic control function with pids OUT and IN.
  */
-void batch_control_write(usb_transfer_batch_t *instance)
+static void batch_control_write(usb_transfer_batch_t *instance)
 {
 	assert(instance);
@@ -304,5 +249,5 @@
  * Uses generic control with pids IN and OUT.
  */
-void batch_control_read(usb_transfer_batch_t *instance)
+static void batch_control_read(usb_transfer_batch_t *instance)
 {
 	assert(instance);
@@ -318,5 +263,5 @@
  * Data transfer with PID_IN.
  */
-void batch_interrupt_in(usb_transfer_batch_t *instance)
+static void batch_interrupt_in(usb_transfer_batch_t *instance)
 {
 	assert(instance);
@@ -332,5 +277,5 @@
  * Data transfer with PID_OUT.
  */
-void batch_interrupt_out(usb_transfer_batch_t *instance)
+static void batch_interrupt_out(usb_transfer_batch_t *instance)
 {
 	assert(instance);
@@ -348,5 +293,5 @@
  * Data transfer with PID_IN.
  */
-void batch_bulk_in(usb_transfer_batch_t *instance)
+static void batch_bulk_in(usb_transfer_batch_t *instance)
 {
 	assert(instance);
@@ -362,5 +307,5 @@
  * Data transfer with PID_OUT.
  */
-void batch_bulk_out(usb_transfer_batch_t *instance)
+static void batch_bulk_out(usb_transfer_batch_t *instance)
 {
 	assert(instance);
@@ -380,5 +325,5 @@
  * The last transfer is marked with IOC flag.
  */
-void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
+static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
 {
 	assert(instance);
@@ -431,5 +376,5 @@
  * The last transfer is marked with IOC.
  */
-void batch_control(usb_transfer_batch_t *instance,
+static void batch_control(usb_transfer_batch_t *instance,
    usb_packet_id data_stage, usb_packet_id status_stage)
 {
Index: uspace/drv/bus/usb/uhci/batch.h
===================================================================
--- uspace/drv/bus/usb/uhci/batch.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/batch.h	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -39,26 +39,8 @@
 #include "hw_struct/queue_head.h"
 
-usb_transfer_batch_t * batch_get(
-    ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
-    const char *setup_buffer, size_t setup_size,
-    usbhc_iface_transfer_in_callback_t func_in,
-    usbhc_iface_transfer_out_callback_t func_out,
-    void *arg);
-
 void * uhci_transfer_batch_create(usb_transfer_batch_t *batch);
 void uhci_transfer_batch_dispose(void *uhci_batch);
 
-void batch_dispose(usb_transfer_batch_t *instance);
-
 bool batch_is_complete(usb_transfer_batch_t *instance);
-
-void batch_control_write(usb_transfer_batch_t *instance);
-void batch_control_read(usb_transfer_batch_t *instance);
-
-void batch_interrupt_in(usb_transfer_batch_t *instance);
-void batch_interrupt_out(usb_transfer_batch_t *instance);
-
-void batch_bulk_in(usb_transfer_batch_t *instance);
-void batch_bulk_out(usb_transfer_batch_t *instance);
 
 qh_t * batch_qh(usb_transfer_batch_t *instance);
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -48,9 +48,4 @@
     (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
 
-static int schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
-{
-	assert(hcd);
-	return hc_schedule(hcd->private_data, batch);
-}
 
 static const irq_cmd_t uhci_irq_commands[] =
@@ -64,7 +59,8 @@
 };
 
+static void hc_init_hw(const hc_t *instance);
+static int hc_init_mem_structures(hc_t *instance);
 static int hc_init_transfer_lists(hc_t *instance);
-static int hc_init_mem_structures(hc_t *instance);
-static void hc_init_hw(hc_t *instance);
+static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
 
 static int hc_interrupt_emulator(void *arg);
@@ -102,4 +98,61 @@
 	cmds[3].addr = (void*)&registers->usbsts;
 	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Take action based on the interrupt cause.
+ *
+ * @param[in] instance UHCI structure to use.
+ * @param[in] status Value of the status register at the time of interrupt.
+ *
+ * Interrupt might indicate:
+ * - transaction completed, either by triggering IOC, SPD, or an error
+ * - some kind of device error
+ * - resume from suspend state (not implemented)
+ */
+void hc_interrupt(hc_t *instance, uint16_t status)
+{
+	assert(instance);
+	/* Lower 2 bits are transaction error and transaction complete */
+	if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
+		LIST_INITIALIZE(done);
+		transfer_list_remove_finished(
+		    &instance->transfers_interrupt, &done);
+		transfer_list_remove_finished(
+		    &instance->transfers_control_slow, &done);
+		transfer_list_remove_finished(
+		    &instance->transfers_control_full, &done);
+		transfer_list_remove_finished(
+		    &instance->transfers_bulk_full, &done);
+
+		while (!list_empty(&done)) {
+			link_t *item = list_first(&done);
+			list_remove(item);
+			usb_transfer_batch_t *batch =
+			    list_get_instance(item, usb_transfer_batch_t, link);
+			usb_transfer_batch_finish(batch);
+		}
+	}
+	/* Resume interrupts are not supported */
+	if (status & UHCI_STATUS_RESUME) {
+		usb_log_error("Resume interrupt!\n");
+	}
+
+	/* Bits 4 and 5 indicate hc error */
+	if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
+		usb_log_error("UHCI hardware failure!.\n");
+		++instance->hw_failures;
+		transfer_list_abort_all(&instance->transfers_interrupt);
+		transfer_list_abort_all(&instance->transfers_control_slow);
+		transfer_list_abort_all(&instance->transfers_control_full);
+		transfer_list_abort_all(&instance->transfers_bulk_full);
+
+		if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
+			/* reinitialize hw, this triggers virtual disconnect*/
+			hc_init_hw(instance);
+		} else {
+			usb_log_fatal("Too many UHCI hardware failures!.\n");
+			hc_fini(instance);
+		}
+	}
 }
 /*----------------------------------------------------------------------------*/
@@ -138,14 +191,23 @@
 	usb_log_debug(
 	    "Device registers at %p (%zuB) accessible.\n", io, reg_size);
-	hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11);
+
+	ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11);
+	CHECK_RET_RETURN(ret, "Failed to initialize HCD generic driver: %s.\n",
+	    str_error(ret));
+
 	instance->generic.private_data = instance;
-	instance->generic.schedule = schedule;
+	instance->generic.schedule = hc_schedule;
 	instance->generic.batch_private_ctor = uhci_transfer_batch_create;
 	instance->generic.batch_private_dtor = uhci_transfer_batch_dispose;
+#undef CHECK_RET_DEST_FUN_RETURN
 
 	ret = hc_init_mem_structures(instance);
-	CHECK_RET_RETURN(ret,
-	    "Failed to initialize UHCI memory structures: %s.\n",
-	    str_error(ret));
+	if (ret != EOK) {
+		usb_log_error(
+		    "Failed to initialize UHCI memory structures: %s.\n",
+		    str_error(ret));
+		hcd_destroy(&instance->generic);
+		return ret;
+	}
 
 	hc_init_hw(instance);
@@ -158,5 +220,4 @@
 
 	return EOK;
-#undef CHECK_RET_DEST_FUN_RETURN
 }
 /*----------------------------------------------------------------------------*/
@@ -166,5 +227,5 @@
  * For magic values see UHCI Design Guide
  */
-void hc_init_hw(hc_t *instance)
+void hc_init_hw(const hc_t *instance)
 {
 	assert(instance);
@@ -210,5 +271,4 @@
  *
  * Structures:
- *  - interrupt code (I/O addressses are customized per instance)
  *  - transfer lists (queue heads need to be accessible by the hw)
  *  - frame list page (needs to be one UHCI hw accessible 4K page)
@@ -217,32 +277,21 @@
 {
 	assert(instance);
-#define CHECK_RET_RETURN(ret, message...) \
-	if (ret != EOK) { \
-		usb_log_error(message); \
-		return ret; \
-	} else (void) 0
+
+	/* Init USB frame list page */
+	instance->frame_list = get_page();
+	if (!instance->frame_list) {
+		return ENOMEM;
+	}
+	usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
 
 	/* Init transfer lists */
 	int ret = hc_init_transfer_lists(instance);
-	CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
+	if (ret != EOK) {
+		usb_log_error("Failed to initialize transfer lists.\n");
+		return_page(instance->frame_list);
+		return ENOMEM;
+	}
 	usb_log_debug("Initialized transfer lists.\n");
 
-	/* Init device keeper */
-	usb_device_keeper_init(&instance->manager);
-	usb_log_debug("Initialized device keeper.\n");
-
-	ret = usb_endpoint_manager_init(&instance->ep_manager,
-	    BANDWIDTH_AVAILABLE_USB11);
-	CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
-	    str_error(ret));
-
-	/* Init USB frame list page*/
-	instance->frame_list = get_page();
-	if (!instance->frame_list) {
-		usb_log_error("Failed to get frame list page.\n");
-		usb_endpoint_manager_destroy(&instance->ep_manager);
-		return ENOMEM;
-	}
-	usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
 
 	/* Set all frames to point to the first queue head */
@@ -255,5 +304,4 @@
 
 	return EOK;
-#undef CHECK_RET_RETURN
 }
 /*----------------------------------------------------------------------------*/
@@ -328,6 +376,8 @@
  * Checks for bandwidth availability and appends the batch to the proper queue.
  */
-int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
-{
+int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
+{
+	assert(hcd);
+	hc_t *instance = hcd->private_data;
 	assert(instance);
 	assert(batch);
@@ -339,61 +389,4 @@
 
 	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Take action based on the interrupt cause.
- *
- * @param[in] instance UHCI structure to use.
- * @param[in] status Value of the status register at the time of interrupt.
- *
- * Interrupt might indicate:
- * - transaction completed, either by triggering IOC, SPD, or an error
- * - some kind of device error
- * - resume from suspend state (not implemented)
- */
-void hc_interrupt(hc_t *instance, uint16_t status)
-{
-	assert(instance);
-	/* Lower 2 bits are transaction error and transaction complete */
-	if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
-		LIST_INITIALIZE(done);
-		transfer_list_remove_finished(
-		    &instance->transfers_interrupt, &done);
-		transfer_list_remove_finished(
-		    &instance->transfers_control_slow, &done);
-		transfer_list_remove_finished(
-		    &instance->transfers_control_full, &done);
-		transfer_list_remove_finished(
-		    &instance->transfers_bulk_full, &done);
-
-		while (!list_empty(&done)) {
-			link_t *item = list_first(&done);
-			list_remove(item);
-			usb_transfer_batch_t *batch =
-			    list_get_instance(item, usb_transfer_batch_t, link);
-			usb_transfer_batch_finish(batch);
-		}
-	}
-	/* Resume interrupts are not supported */
-	if (status & UHCI_STATUS_RESUME) {
-		usb_log_error("Resume interrupt!\n");
-	}
-
-	/* Bits 4 and 5 indicate hc error */
-	if (status & (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)) {
-		usb_log_error("UHCI hardware failure!.\n");
-		++instance->hw_failures;
-		transfer_list_abort_all(&instance->transfers_interrupt);
-		transfer_list_abort_all(&instance->transfers_control_slow);
-		transfer_list_abort_all(&instance->transfers_control_full);
-		transfer_list_abort_all(&instance->transfers_bulk_full);
-
-		if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) {
-			/* reinitialize hw, this triggers virtual disconnect*/
-			hc_init_hw(instance);
-		} else {
-			usb_log_fatal("Too many UHCI hardware failures!.\n");
-			hc_fini(instance);
-		}
-	}
 }
 /*----------------------------------------------------------------------------*/
@@ -415,8 +408,4 @@
 		if (status != 0)
 			usb_log_debug2("UHCI status: %x.\n", status);
-// Qemu fails to report stalled communication
-// see https://bugs.launchpad.net/qemu/+bug/757654
-// This is a simple workaround to force queue processing every time
-	//	status |= 1;
 		hc_interrupt(instance, status);
 		async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
@@ -424,5 +413,5 @@
 	return EOK;
 }
-/*---------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
 /** Debug function, checks consistency of memory structures.
  *
Index: uspace/drv/bus/usb/uhci/hc.h
===================================================================
--- uspace/drv/bus/usb/uhci/hc.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/hc.h	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -39,6 +39,4 @@
 #include <ddi.h>
 
-#include <usb/host/device_keeper.h>
-#include <usb/host/usb_endpoint_manager.h>
 #include <usb/host/batch.h>
 #include <usb/host/hcd.h>
@@ -95,9 +93,6 @@
 /** Main UHCI driver structure */
 typedef struct hc {
+	/** Generic HCD driver structure */
 	hcd_t generic;
-	/** USB bus driver, devices and addresses */
-	usb_device_keeper_t manager;
-	/** USB bus driver, endpoints */
-	usb_endpoint_manager_t ep_manager;
 
 	/** Addresses of I/O registers */
@@ -126,10 +121,10 @@
 	unsigned hw_failures;
 } hc_t;
+
 size_t hc_irq_cmd_count(void);
 int hc_get_irq_commands(
     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
+void hc_interrupt(hc_t *instance, uint16_t status);
 int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
-int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
-void hc_interrupt(hc_t *instance, uint16_t status);
 
 /** Safely dispose host controller internal structures
@@ -137,16 +132,5 @@
  * @param[in] instance Host controller structure to use.
  */
-static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ };
-
-/** Get and cast pointer to the driver data
- *
- * @param[in] fun DDF function pointer
- * @return cast pointer to driver_data
- */
-static inline hc_t * fun_to_hc(ddf_fun_t *fun)
-{
-	assert(fun);
-	return fun->driver_data;
-}
+static inline void hc_fini(hc_t *instance) {} /* TODO: implement*/
 #endif
 /**
Index: pace/drv/bus/usb/uhci/iface.c
===================================================================
--- uspace/drv/bus/usb/uhci/iface.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ 	(revision )
@@ -1,405 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky, 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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver hc interface implementation
- */
-#include <ddf/driver.h>
-#include <errno.h>
-
-#include <usb/debug.h>
-#include <usb/host/endpoint.h>
-
-#include "iface.h"
-#include "batch.h"
-#include "hc.h"
-
-static inline int setup_batch(
-    ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
-    void *data, size_t size, void * setup_data, size_t setup_size,
-    usbhc_iface_transfer_in_callback_t in,
-    usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
-    hc_t **hc, usb_transfer_batch_t **batch)
-{
-	assert(hc);
-	assert(batch);
-	assert(fun);
-	*hc = fun_to_hc(fun);
-	assert(*hc);
-
-	size_t res_bw;
-	endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
-	    target.address, target.endpoint, direction, &res_bw);
-	if (ep == NULL) {
-		usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
-		    target.address, target.endpoint, name);
-		return ENOENT;
-	}
-
-	usb_log_debug2("%s %d:%d %zu(%zu).\n",
-	    name, target.address, target.endpoint, size, ep->max_packet_size);
-
-	const size_t bw = bandwidth_count_usb11(
-	    ep->speed, ep->transfer_type, size, ep->max_packet_size);
-	if (res_bw < bw) {
-		usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
-		    "but only %zu is reserved.\n",
-		    target.address, target.endpoint, name, bw, res_bw);
-		return ENOSPC;
-	}
-
-	*batch = batch_get(
-	        fun, ep, data, size, setup_data, setup_size, in, out, arg);
-	if (!*batch)
-		return ENOMEM;
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Request address interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] speed Speed to associate with the new default address.
- * @param[out] address Place to write a new address.
- * @return Error code.
- */
-static int request_address(
-    ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address)
-{
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
-	assert(address);
-
-	usb_log_debug("Address request with speed %d.\n", speed);
-	*address = device_keeper_get_free_address(&hc->manager, speed);
-	usb_log_debug("Address request with result: %d.\n", *address);
-	if (*address <= 0)
-		return *address;
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Bind address interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] address Address of the device
- * @param[in] handle Devman handle of the device driver.
- * @return Error code.
- */
-static int bind_address(
-  ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
-{
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
-	usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
-	usb_device_keeper_bind(&hc->manager, address, handle);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Find device handle by address interface function.
- *
- * @param[in] fun DDF function that was called.
- * @param[in] address Address in question.
- * @param[out] handle Where to store device handle if found.
- * @return Error code.
- */
-static int find_by_address(ddf_fun_t *fun, usb_address_t address,
-    devman_handle_t *handle)
-{
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
-	const bool found =
-	    usb_device_keeper_find_by_address(&hc->manager, address, handle);
-	return found ? EOK : ENOENT;
-}
-/*----------------------------------------------------------------------------*/
-/** Release address interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] address USB address to be released.
- * @return Error code.
- */
-static int release_address(ddf_fun_t *fun, usb_address_t address)
-{
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
-	usb_log_debug("Address release %d.\n", address);
-	usb_device_keeper_release(&hc->manager, address);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int register_endpoint(
-    ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
-    usb_endpoint_t endpoint,
-    usb_transfer_type_t transfer_type, usb_direction_t direction,
-    size_t max_packet_size, unsigned int interval)
-{
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
-	const size_t size = max_packet_size;
-	usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address);
-	if (speed >= USB_SPEED_MAX) {
-		speed = ep_speed;
-	}
-	usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n",
-	    address, endpoint, usb_str_transfer_type(transfer_type),
-	    usb_str_direction(direction), usb_str_speed(speed),
-	    max_packet_size, interval);
-
-	return usb_endpoint_manager_add_ep(&hc->ep_manager, address, endpoint,
-	    direction, transfer_type, speed, max_packet_size, size);
-}
-/*----------------------------------------------------------------------------*/
-static int unregister_endpoint(
-    ddf_fun_t *fun, usb_address_t address,
-    usb_endpoint_t endpoint, usb_direction_t direction)
-{
-	assert(fun);
-	hc_t *hc = fun_to_hc(fun);
-	assert(hc);
-	usb_log_debug("Unregister endpoint %d:%d %s.\n",
-	    address, endpoint, usb_str_direction(direction));
-	return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
-	    endpoint, direction);
-}
-/*----------------------------------------------------------------------------*/
-/** Interrupt out transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
- * @return Error code.
- */
-static int interrupt_out(
-    ddf_fun_t *fun, usb_target_t target, void *data,
-    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	usb_transfer_batch_t *batch = NULL;
-	hc_t *hc = NULL;
-	int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
-	    NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
-	if (ret != EOK)
-		return ret;
-	assert(batch);
-	assert(hc);
-	batch_interrupt_out(batch);
-	ret = hc_schedule(hc, batch);
-	if (ret != EOK) {
-		usb_transfer_batch_dispose(batch);
-	}
-	return ret;
-}
-/*----------------------------------------------------------------------------*/
-/** Interrupt in transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[out] data Data destination.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
- * @return Error code.
- */
-static int interrupt_in(
-    ddf_fun_t *fun, usb_target_t target, void *data,
-    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	usb_transfer_batch_t *batch = NULL;
-	hc_t *hc = NULL;
-	int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
-	    NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
-	if (ret != EOK)
-		return ret;
-	assert(batch);
-	assert(hc);
-	batch_interrupt_in(batch);
-	ret = hc_schedule(hc, batch);
-	if (ret != EOK) {
-		usb_transfer_batch_dispose(batch);
-	}
-	return ret;
-}
-/*----------------------------------------------------------------------------*/
-/** Bulk out transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
- * @return Error code.
- */
-static int bulk_out(
-    ddf_fun_t *fun, usb_target_t target, void *data,
-    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	usb_transfer_batch_t *batch = NULL;
-	hc_t *hc = NULL;
-	int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
-	    NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
-	if (ret != EOK)
-		return ret;
-	assert(batch);
-	assert(hc);
-	batch_bulk_out(batch);
-	ret = hc_schedule(hc, batch);
-	if (ret != EOK) {
-		usb_transfer_batch_dispose(batch);
-	}
-	return ret;
-}
-/*----------------------------------------------------------------------------*/
-/** Bulk in transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[out] data Data destination.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion
- * @param[in] arg Additional for callback function.
- * @return Error code.
- */
-static int bulk_in(
-    ddf_fun_t *fun, usb_target_t target, void *data,
-    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	usb_transfer_batch_t *batch = NULL;
-	hc_t *hc = NULL;
-	int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
-	    NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
-	if (ret != EOK)
-		return ret;
-	assert(batch);
-	assert(hc);
-	batch_bulk_in(batch);
-	ret = hc_schedule(hc, batch);
-	if (ret != EOK) {
-		usb_transfer_batch_dispose(batch);
-	}
-	return ret;
-}
-/*----------------------------------------------------------------------------*/
-/** Control write transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] setup_data Data to send with SETUP transfer.
- * @param[in] setup_size Size of data to send with SETUP transfer (always 8B).
- * @param[in] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion.
- * @param[in] arg Additional for callback function.
- * @return Error code.
- */
-static int control_write(
-    ddf_fun_t *fun, usb_target_t target,
-    void *setup_data, size_t setup_size, void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	usb_transfer_batch_t *batch = NULL;
-	hc_t *hc = NULL;
-	int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
-	    setup_data, setup_size, NULL, callback, arg, "Control WRITE",
-	    &hc, &batch);
-	if (ret != EOK)
-		return ret;
-	assert(batch);
-	assert(hc);
-	usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);
-	batch_control_write(batch);
-	ret = hc_schedule(hc, batch);
-	if (ret != EOK) {
-		usb_transfer_batch_dispose(batch);
-	}
-	return ret;
-}
-/*----------------------------------------------------------------------------*/
-/** Control read transaction interface function
- *
- * @param[in] fun DDF function that was called.
- * @param[in] target USB device to write to.
- * @param[in] setup_data Data to send with SETUP packet.
- * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
- * @param[out] data Source of data.
- * @param[in] size Size of data source.
- * @param[in] callback Function to call on transaction completion.
- * @param[in] arg Additional for callback function.
- * @return Error code.
- */
-static int control_read(
-    ddf_fun_t *fun, usb_target_t target,
-    void *setup_data, size_t setup_size, void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	usb_transfer_batch_t *batch = NULL;
-	hc_t *hc = NULL;
-	int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
-	    setup_data, setup_size, callback, NULL, arg, "Control READ",
-	    &hc, &batch);
-	if (ret != EOK)
-		return ret;
-	assert(batch);
-	assert(hc);
-	batch_control_read(batch);
-	ret = hc_schedule(hc, batch);
-	if (ret != EOK) {
-		usb_transfer_batch_dispose(batch);
-	}
-	return ret;
-}
-/*----------------------------------------------------------------------------*/
-usbhc_iface_t hc_iface = {
-	.request_address = request_address,
-	.bind_address = bind_address,
-	.find_by_address = find_by_address,
-	.release_address = release_address,
-
-	.register_endpoint = register_endpoint,
-	.unregister_endpoint = unregister_endpoint,
-
-	.interrupt_out = interrupt_out,
-	.interrupt_in = interrupt_in,
-
-	.bulk_out = bulk_out,
-	.bulk_in = bulk_in,
-
-	.control_write = control_write,
-	.control_read = control_read,
-};
-/**
- * @}
- */
Index: pace/drv/bus/usb/uhci/iface.h
===================================================================
--- uspace/drv/bus/usb/uhci/iface.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ 	(revision )
@@ -1,45 +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.
- */
-
-/** @addtogroup drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver iface
- */
-#ifndef DRV_UHCI_IFACE_H
-#define DRV_UHCI_IFACE_H
-
-#include <usbhc_iface.h>
-
-extern usbhc_iface_t hc_iface;
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/bus/usb/uhci/pci.c
===================================================================
--- uspace/drv/bus/usb/uhci/pci.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/pci.c	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -142,5 +142,5 @@
 {
 	assert(device);
-	
+
 	async_sess_t *parent_sess =
 	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
@@ -148,18 +148,18 @@
 	if (!parent_sess)
 		return ENOMEM;
-	
+
 	/* See UHCI design guide for these values p.45,
 	 * write all WC bits in USB legacy register */
 	const sysarg_t address = 0xc0;
 	const sysarg_t value = 0xaf00;
-	
+
 	async_exch_t *exch = async_exchange_begin(parent_sess);
-	
+
 	const int rc = async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE),
 	    IPC_M_CONFIG_SPACE_WRITE_16, address, value);
-	
+
 	async_exchange_end(exch);
 	async_hangup(parent_sess);
-	
+
 	return rc;
 }
Index: uspace/drv/bus/usb/uhci/uhci.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci.c	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/uhci.c	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -41,5 +41,4 @@
 
 #include "uhci.h"
-#include "iface.h"
 #include "pci.h"
 
Index: uspace/drv/bus/usb/uhci/utils/malloc32.h
===================================================================
--- uspace/drv/bus/usb/uhci/utils/malloc32.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/drv/bus/usb/uhci/utils/malloc32.h	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -102,9 +102,15 @@
 	if (free_address == 0)
 		return NULL;
-	void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
+	void *address = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
 		  AS_AREA_READ | AS_AREA_WRITE);
-	if (ret != free_address)
+	if (address != free_address)
 		return NULL;
-	return ret;
+	return address;
+}
+/*----------------------------------------------------------------------------*/
+static inline void return_page(void *page)
+{
+	if (page)
+		as_area_destroy(page);
 }
 
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision 5fe0a6978c5352e80c555f1545239199e05167eb)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision 3afb7580ffb5859d718216a15a79100e3ab8aa0a)
@@ -61,4 +61,9 @@
 }
 /*----------------------------------------------------------------------------*/
+static inline void hcd_destroy(hcd_t *hcd)
+{
+	usb_endpoint_manager_destroy(&hcd->ep_manager);
+}
+/*----------------------------------------------------------------------------*/
 static inline void reset_ep_if_need(
     hcd_t *hcd, usb_target_t target, const char* setup_data)
