Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ boot/arch/amd64/Makefile.inc	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -43,8 +43,8 @@
 	isa \
 	ns8250 \
-	ehci_hcd \
+	ehci\
 	ohci \
-	uhci_hcd \
-	uhci_rhd \
+	uhci \
+	uhcirh \
 	usbflbk \
 	usbhub \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ uspace/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -101,8 +101,8 @@
 	drv/test2 \
 	drv/test3 \
-	drv/ehci_hcd \
+	drv/ehci \
 	drv/ohci \
-	drv/uhci_hcd \
-	drv/uhci_rhd \
+	drv/uhci \
+	drv/uhcirh \
 	drv/usbflbk \
 	drv/usbhid \
Index: uspace/drv/ehci/Makefile
===================================================================
--- uspace/drv/ehci/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+
+LIBS = \
+	$(LIBUSBHOST_PREFIX)/libusbhost.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBHOST_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
+BINARY = ehci
+
+SOURCES = \
+	hc_iface.c \
+	main.c \
+	pci.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/ehci/ehci.h
===================================================================
--- uspace/drv/ehci/ehci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/ehci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 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 drvusbehci
+ * @{
+ */
+/** @file
+ * Common EHCI definitions.
+ */
+#ifndef DRV_EHCI_EHCI_H
+#define DRV_EHCI_EHCI_H
+
+#include <usbhc_iface.h>
+
+#define NAME "ehci"
+
+extern usbhc_iface_t ehci_hc_iface;
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/drv/ehci/ehci.ma
===================================================================
--- uspace/drv/ehci/ehci.ma	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/ehci.ma	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,39 @@
+10 pci/ven=1002&dev=4345
+10 pci/ven=1002&dev=4386
+10 pci/ven=1002&dev=4396
+10 pci/ven=1002&dev=4373
+10 pci/ven=1022&dev=7463
+10 pci/ven=1022&dev=7808
+10 pci/ven=102f&dev=01b5
+10 pci/ven=10cf&dev=1415
+10 pci/ven=10de&dev=00e8
+10 pci/ven=10de&dev=055f
+10 pci/ven=10de&dev=056a
+10 pci/ven=10de&dev=077c
+10 pci/ven=10de&dev=077e
+10 pci/ven=10de&dev=0aa6
+10 pci/ven=10de&dev=0aa9
+10 pci/ven=10de&dev=0aaa
+10 pci/ven=10de&dev=0d9d
+10 pci/ven=1166&dev=0414
+10 pci/ven=1166&dev=0416
+10 pci/ven=1414&dev=5805
+10 pci/ven=1414&dev=5807
+10 pci/ven=15ad&dev=0770
+10 pci/ven=17a0&dev=8084
+10 pci/ven=8086&dev=24cd
+10 pci/ven=8086&dev=24dd
+10 pci/ven=8086&dev=265c
+10 pci/ven=8086&dev=268c
+10 pci/ven=8086&dev=27cc
+10 pci/ven=8086&dev=2836
+10 pci/ven=8086&dev=283a
+10 pci/ven=8086&dev=293a
+10 pci/ven=8086&dev=293c
+10 pci/ven=8086&dev=3a3a
+10 pci/ven=8086&dev=3a3c
+10 pci/ven=8086&dev=3a6a
+10 pci/ven=8086&dev=3a6c
+10 pci/ven=8086&dev=8117
+10 pci/ven=8086&dev=8807
+10 pci/ven=8086&dev=880f
Index: uspace/drv/ehci/hc_iface.c
===================================================================
--- uspace/drv/ehci/hc_iface.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/hc_iface.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2011 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 drvusbehci
+ * @{
+ */
+/** @file
+ * USB-HC interface implementation.
+ */
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <device/hw_res.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb_iface.h>
+#include <usb/ddfiface.h>
+#include <usb/debug.h>
+
+#include "ehci.h"
+
+#define UNSUPPORTED(methodname) \
+	usb_log_debug("Client called unsupported interface method " \
+	    "`%s()' in %s:%d.\n", \
+	    methodname, __FILE__, __LINE__)
+
+/** Found free USB address.
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] speed Speed of the device that will get this address.
+ * @param[out] address Non-null pointer where to store the free address.
+ * @return Error code.
+ */
+static int request_address(ddf_fun_t *fun, usb_speed_t speed,
+    usb_address_t *address)
+{
+	UNSUPPORTED("request_address");
+
+	return ENOTSUP;
+}
+
+/** Bind USB address with device devman handle.
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] address USB address of the device.
+ * @param[in] handle Devman handle of the device.
+ * @return Error code.
+ */
+static int bind_address(ddf_fun_t *fun,
+    usb_address_t address, devman_handle_t handle)
+{
+	UNSUPPORTED("bind_address");
+
+	return ENOTSUP;
+}
+
+/** Find device handle by USB address.
+ *
+ * @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)
+{
+	UNSUPPORTED("find_by_address");
+
+	return ENOTSUP;
+}
+
+/** Release previously requested address.
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] address USB address to be released.
+ * @return Error code.
+ */
+static int release_address(ddf_fun_t *fun, usb_address_t address)
+{
+	UNSUPPORTED("release_address");
+
+	return ENOTSUP;
+}
+
+/** Register endpoint for bandwidth reservation.
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] address USB address of the device.
+ * @param[in] speed Endpoint speed (invalid means to use device one).
+ * @param[in] endpoint Endpoint number.
+ * @param[in] transfer_type USB transfer type.
+ * @param[in] direction Endpoint data direction.
+ * @param[in] max_packet_size Max packet size of the endpoint.
+ * @param[in] interval Polling interval.
+ * @return Error code.
+ */
+static int register_endpoint(ddf_fun_t *fun,
+    usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
+    usb_transfer_type_t transfer_type, usb_direction_t direction,
+    size_t max_packet_size, unsigned int interval)
+{
+	UNSUPPORTED("register_endpoint");
+
+	return ENOTSUP;
+}
+
+/** Unregister endpoint (free some bandwidth reservation).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] address USB address of the device.
+ * @param[in] endpoint Endpoint number.
+ * @param[in] direction Endpoint data direction.
+ * @return Error code.
+ */
+static int unregister_endpoint(ddf_fun_t *fun, usb_address_t address,
+    usb_endpoint_t endpoint, usb_direction_t direction)
+{
+	UNSUPPORTED("unregister_endpoint");
+
+	return ENOTSUP;
+}
+
+/** Schedule interrupt out transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
+ *	by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
+ * @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)
+{
+	UNSUPPORTED("interrupt_out");
+
+	return ENOTSUP;
+}
+
+/** Schedule interrupt in transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Buffer where to store the data (in USB endianess,
+ *	allocated and deallocated by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
+ * @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)
+{
+	UNSUPPORTED("interrupt_in");
+
+	return ENOTSUP;
+}
+
+/** Schedule bulk out transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
+ *	by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
+ * @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)
+{
+	UNSUPPORTED("bulk_out");
+
+	return ENOTSUP;
+}
+
+/** Schedule bulk in transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] data Buffer where to store the data (in USB endianess,
+ *	allocated and deallocated by the caller).
+ * @param[in] size Size of the @p data buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
+ * @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)
+{
+	UNSUPPORTED("bulk_in");
+
+	return ENOTSUP;
+}
+
+/** Schedule control write transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
+ *	and deallocated by the caller).
+ * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
+ * @param[in] data_buffer Data buffer (in USB endianess, allocated and
+ *	deallocated by the caller).
+ * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
+ * @return Error code.
+ */
+static int control_write(ddf_fun_t *fun, usb_target_t target,
+    void *setup_packet, size_t setup_packet_size,
+    void *data_buffer, size_t data_buffer_size,
+    usbhc_iface_transfer_out_callback_t callback, void *arg)
+{
+	UNSUPPORTED("control_write");
+
+	return ENOTSUP;
+}
+
+/** Schedule control read transfer.
+ *
+ * The callback is supposed to be called once the transfer (on the wire) is
+ * complete regardless of the outcome.
+ * However, the callback could be called only when this function returns
+ * with success status (i.e. returns EOK).
+ *
+ * @param[in] fun Device function the action was invoked on.
+ * @param[in] target Target pipe (address and endpoint number) specification.
+ * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
+ *	and deallocated by the caller).
+ * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
+ * @param[in] data_buffer Buffer where to store the data (in USB endianess,
+ *	allocated and deallocated by the caller).
+ * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
+ * @param[in] callback Callback to be issued once the transfer is complete.
+ * @param[in] arg Pass-through argument to the callback.
+ * @return Error code.
+ */
+static int control_read(ddf_fun_t *fun, usb_target_t target,
+    void *setup_packet, size_t setup_packet_size,
+    void *data_buffer, size_t data_buffer_size,
+    usbhc_iface_transfer_in_callback_t callback, void *arg)
+{
+	UNSUPPORTED("control_read");
+
+	return ENOTSUP;
+}
+
+/** Host controller interface implementation for EHCI. */
+usbhc_iface_t ehci_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: uspace/drv/ehci/main.c
===================================================================
--- uspace/drv/ehci/main.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/main.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2011 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 drvusbehci
+ * @{
+ */
+/** @file
+ * Main routines of EHCI driver.
+ */
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <device/hw_res.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb_iface.h>
+#include <usb/ddfiface.h>
+#include <usb/debug.h>
+
+#include "pci.h"
+#include "ehci.h"
+
+static int ehci_add_device(ddf_dev_t *device);
+/*----------------------------------------------------------------------------*/
+static driver_ops_t ehci_driver_ops = {
+	.add_device = ehci_add_device,
+};
+/*----------------------------------------------------------------------------*/
+static driver_t ehci_driver = {
+	.name = NAME,
+	.driver_ops = &ehci_driver_ops
+};
+static ddf_dev_ops_t hc_ops = {
+	.interfaces[USBHC_DEV_IFACE] = &ehci_hc_iface,
+};
+
+/*----------------------------------------------------------------------------*/
+/** Initializes a new ddf driver instance of EHCI hcd.
+ *
+ * @param[in] device DDF instance of the device to initialize.
+ * @return Error code.
+ */
+static int ehci_add_device(ddf_dev_t *device)
+{
+	assert(device);
+#define CHECK_RET_RETURN(ret, message...) \
+if (ret != EOK) { \
+	usb_log_error(message); \
+	return ret; \
+}
+
+	uintptr_t reg_base = 0;
+	size_t reg_size = 0;
+	int irq = 0;
+
+	int ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	CHECK_RET_RETURN(ret,
+	    "Failed to get memory addresses for %" PRIun ": %s.\n",
+	    device->handle, str_error(ret));
+	usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
+	    reg_base, reg_size, irq);
+
+	ret = pci_disable_legacy(device, reg_base, reg_size, irq);
+	CHECK_RET_RETURN(ret,
+	    "Failed to disable legacy USB: %s.\n", str_error(ret));
+
+	ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
+	if (hc_fun == NULL) {
+		usb_log_error("Failed to create EHCI function.\n");
+		return ENOMEM;
+	}
+	hc_fun->ops = &hc_ops;
+
+	ret = ddf_fun_bind(hc_fun);
+	CHECK_RET_RETURN(ret,
+	    "Failed to bind EHCI function: %s.\n",
+	    str_error(ret));
+	ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME);
+	CHECK_RET_RETURN(ret,
+	    "Failed to add EHCI to HC class: %s.\n",
+	    str_error(ret));
+
+	usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
+	    device->name, device->handle);
+
+	return EOK;
+#undef CHECK_RET_RETURN
+}
+/*----------------------------------------------------------------------------*/
+/** Initializes global driver structures (NONE).
+ *
+ * @param[in] argc Nmber of arguments in argv vector (ignored).
+ * @param[in] argv Cmdline argument vector (ignored).
+ * @return Error code.
+ *
+ * Driver debug level is set here.
+ */
+int main(int argc, char *argv[])
+{
+	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	return ddf_driver_main(&ehci_driver);
+}
+/**
+ * @}
+ */
Index: uspace/drv/ehci/pci.c
===================================================================
--- uspace/drv/ehci/pci.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/pci.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,391 @@
+/*
+ * 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 drvusbehci
+ * @{
+ */
+/**
+ * @file
+ * PCI related functions needed by the EHCI driver.
+ */
+
+#include <errno.h>
+#include <str_error.h>
+#include <assert.h>
+#include <as.h>
+#include <devman.h>
+#include <ddi.h>
+#include <libarch/ddi.h>
+#include <device/hw_res.h>
+
+#include <usb/debug.h>
+#include <pci_dev_iface.h>
+
+#include "pci.h"
+
+#define PAGE_SIZE_MASK 0xfffff000
+
+#define HCC_PARAMS_OFFSET 0x8
+#define HCC_PARAMS_EECP_MASK 0xff
+#define HCC_PARAMS_EECP_OFFSET 8
+
+#define CMD_OFFSET 0x0
+#define STS_OFFSET 0x4
+#define INT_OFFSET 0x8
+#define CFG_OFFSET 0x40
+
+#define USBCMD_RUN 1
+#define USBSTS_HALTED (1 << 12)
+
+#define USBLEGSUP_OFFSET 0
+#define USBLEGSUP_BIOS_CONTROL (1 << 16)
+#define USBLEGSUP_OS_CONTROL (1 << 24)
+#define USBLEGCTLSTS_OFFSET 4
+
+#define DEFAULT_WAIT 1000
+#define WAIT_STEP 10
+
+#define PCI_READ(size) \
+do { \
+	async_sess_t *parent_sess = \
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
+	    IPC_FLAG_BLOCKING); \
+	if (!parent_sess) \
+		return ENOMEM; \
+	\
+	sysarg_t add = (sysarg_t) address; \
+	sysarg_t val; \
+	\
+	async_exch_t *exch = async_exchange_begin(parent_sess); \
+	\
+	const int ret = \
+	    async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
+	        IPC_M_CONFIG_SPACE_READ_##size, add, &val); \
+	\
+	async_exchange_end(exch); \
+	async_hangup(parent_sess); \
+	\
+	assert(value); \
+	\
+	*value = val; \
+	return ret; \
+} while (0)
+
+static int pci_read32(const ddf_dev_t *dev, int address, uint32_t *value)
+{
+	PCI_READ(32);
+}
+
+static int pci_read16(const ddf_dev_t *dev, int address, uint16_t *value)
+{
+	PCI_READ(16);
+}
+
+static int pci_read8(const ddf_dev_t *dev, int address, uint8_t *value)
+{
+	PCI_READ(8);
+}
+
+#define PCI_WRITE(size) \
+do { \
+	async_sess_t *parent_sess = \
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
+	    IPC_FLAG_BLOCKING); \
+	if (!parent_sess) \
+		return ENOMEM; \
+	\
+	sysarg_t add = (sysarg_t) address; \
+	sysarg_t val = value; \
+	\
+	async_exch_t *exch = async_exchange_begin(parent_sess); \
+	\
+	const int ret = \
+	    async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
+	        IPC_M_CONFIG_SPACE_WRITE_##size, add, val); \
+	\
+	async_exchange_end(exch); \
+	async_hangup(parent_sess); \
+	\
+	return ret; \
+} while(0)
+
+static int pci_write32(const ddf_dev_t *dev, int address, uint32_t value)
+{
+	PCI_WRITE(32);
+}
+
+static int pci_write16(const ddf_dev_t *dev, int address, uint16_t value)
+{
+	PCI_WRITE(16);
+}
+
+static int pci_write8(const ddf_dev_t *dev, int address, uint8_t value)
+{
+	PCI_WRITE(8);
+}
+
+/** Get address of registers and IRQ for given device.
+ *
+ * @param[in] dev Device asking for the addresses.
+ * @param[out] mem_reg_address Base address of the memory range.
+ * @param[out] mem_reg_size Size of the memory range.
+ * @param[out] irq_no IRQ assigned to the device.
+ * @return Error code.
+ */
+int pci_get_my_registers(const ddf_dev_t *dev,
+    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
+{
+	assert(dev != NULL);
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	hw_resource_list_t hw_resources;
+	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
+	if (rc != EOK) {
+		async_hangup(parent_sess);
+		return rc;
+	}
+	
+	uintptr_t mem_address = 0;
+	size_t mem_size = 0;
+	bool mem_found = false;
+	
+	int irq = 0;
+	bool irq_found = false;
+	
+	size_t i;
+	for (i = 0; i < hw_resources.count; i++) {
+		hw_resource_t *res = &hw_resources.resources[i];
+		switch (res->type) {
+		case INTERRUPT:
+			irq = res->res.interrupt.irq;
+			irq_found = true;
+			usb_log_debug2("Found interrupt: %d.\n", irq);
+			break;
+		case MEM_RANGE:
+			if (res->res.mem_range.address != 0
+			    && res->res.mem_range.size != 0 ) {
+				mem_address = res->res.mem_range.address;
+				mem_size = res->res.mem_range.size;
+				usb_log_debug2("Found mem: %" PRIxn" %zu.\n",
+				    mem_address, mem_size);
+				mem_found = true;
+			}
+		default:
+			break;
+		}
+	}
+	
+	if (mem_found && irq_found) {
+		*mem_reg_address = mem_address;
+		*mem_reg_size = mem_size;
+		*irq_no = irq;
+		rc = EOK;
+	} else {
+		rc = ENOENT;
+	}
+	
+	async_hangup(parent_sess);
+	return rc;
+}
+/*----------------------------------------------------------------------------*/
+/** Calls the PCI driver with a request to enable interrupts
+ *
+ * @param[in] device Device asking for interrupts
+ * @return Error code.
+ */
+int pci_enable_interrupts(const ddf_dev_t *device)
+{
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
+	return enabled ? EOK : EIO;
+}
+/*----------------------------------------------------------------------------*/
+/** Implements BIOS handoff routine as decribed in EHCI spec
+ *
+ * @param[in] device Device asking for interrupts
+ * @return Error code.
+ */
+int pci_disable_legacy(
+    const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size, int irq)
+{
+	assert(device);
+	(void) pci_read16;
+	(void) pci_read8;
+	(void) pci_write16;
+
+#define CHECK_RET_RETURN(ret, message...) \
+	if (ret != EOK) { \
+		usb_log_error(message); \
+		return ret; \
+	} else (void)0
+
+	/* Map EHCI registers */
+	void *regs = NULL;
+	int ret = pio_enable((void*)reg_base, reg_size, &regs);
+	CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n",
+	    (void *) reg_base, str_error(ret));
+
+	const uint32_t hcc_params =
+	    *(uint32_t*)(regs + HCC_PARAMS_OFFSET);
+	usb_log_debug("Value of hcc params register: %x.\n", hcc_params);
+
+	/* Read value of EHCI Extended Capabilities Pointer
+	 * position of EEC registers (points to PCI config space) */
+	const uint32_t eecp =
+	    (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
+	usb_log_debug("Value of EECP: %x.\n", eecp);
+
+	/* Read the first EEC. i.e. Legacy Support register */
+	uint32_t usblegsup;
+	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
+	CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));
+	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
+
+	/* Request control from firmware/BIOS, by writing 1 to highest byte.
+	 * (OS Control semaphore)*/
+	usb_log_debug("Requesting OS control.\n");
+	ret = pci_write8(device, eecp + USBLEGSUP_OFFSET + 3, 1);
+	CHECK_RET_RETURN(ret, "Failed to request OS EHCI control: %s.\n",
+	    str_error(ret));
+
+	size_t wait = 0;
+	/* Wait for BIOS to release control. */
+	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
+	while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
+		async_usleep(WAIT_STEP);
+		ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
+		wait += WAIT_STEP;
+	}
+
+
+	if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) {
+		usb_log_info("BIOS released control after %zu usec.\n", wait);
+	} else {
+		/* BIOS failed to hand over control, this should not happen. */
+		usb_log_warning( "BIOS failed to release control after "
+		    "%zu usecs, force it.\n", wait);
+		ret = pci_write32(device, eecp + USBLEGSUP_OFFSET,
+		    USBLEGSUP_OS_CONTROL);
+		CHECK_RET_RETURN(ret, "Failed to force OS control: %s.\n",
+		    str_error(ret));
+		/* Check capability type here, A value of 01h
+		 * identifies the capability as Legacy Support.
+		 * This extended capability requires one
+		 * additional 32-bit register for control/status information,
+		 * and this register is located at offset EECP+04h
+		 * */
+		if ((usblegsup & 0xff) == 1) {
+			/* Read the second EEC
+			 * Legacy Support and Control register */
+			uint32_t usblegctlsts;
+			ret = pci_read32(
+			    device, eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
+			CHECK_RET_RETURN(ret,
+			    "Failed to get USBLEGCTLSTS: %s.\n", str_error(ret));
+			usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n",
+			    usblegctlsts);
+			/* Zero SMI enables in legacy control register.
+			 * It should prevent pre-OS code from interfering. */
+			ret = pci_write32(device, eecp + USBLEGCTLSTS_OFFSET,
+			    0xe0000000); /* three upper bits are WC */
+			CHECK_RET_RETURN(ret,
+			    "Failed(%d) zero USBLEGCTLSTS.\n", ret);
+			udelay(10);
+			ret = pci_read32(
+			    device, eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
+			CHECK_RET_RETURN(ret,
+			    "Failed to get USBLEGCTLSTS 2: %s.\n",
+			    str_error(ret));
+			usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
+			    usblegctlsts);
+		}
+	}
+
+
+	/* Read again Legacy Support register */
+	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
+	CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));
+	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
+
+	/*
+	 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT
+	 */
+
+	/* Get size of capability registers in memory space. */
+	const unsigned operation_offset = *(uint8_t*)regs;
+	usb_log_debug("USBCMD offset: %d.\n", operation_offset);
+
+	/* Zero USBCMD register. */
+	volatile uint32_t *usbcmd =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + CMD_OFFSET);
+	volatile uint32_t *usbsts =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + STS_OFFSET);
+	volatile uint32_t *usbconf =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + CFG_OFFSET);
+	volatile uint32_t *usbint =
+	    (uint32_t*)((uint8_t*)regs + operation_offset + INT_OFFSET);
+	usb_log_debug("USBCMD value: %x.\n", *usbcmd);
+	if (*usbcmd & USBCMD_RUN) {
+		*usbsts = 0x3f; /* ack all interrupts */
+		*usbint = 0; /* disable all interrutps */
+		*usbconf = 0; /* relase control of RH ports */
+
+		*usbcmd = 0;
+		/* Wait until hc is halted */
+		while ((*usbsts & USBSTS_HALTED) == 0);
+		usb_log_info("EHCI turned off.\n");
+	} else {
+		usb_log_info("EHCI was not running.\n");
+	}
+	usb_log_debug("Registers: \n"
+	    "\t USBCMD: %x(0x00080000 = at least 1ms between interrupts)\n"
+	    "\t USBSTS: %x(0x00001000 = HC halted)\n"
+	    "\t USBINT: %x(0x0 = no interrupts).\n"
+	    "\t CONFIG: %x(0x0 = ports controlled by companion hc).\n",
+	    *usbcmd, *usbsts, *usbint, *usbconf);
+
+	return ret;
+#undef CHECK_RET_RETURN
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/ehci/pci.h
===================================================================
--- uspace/drv/ehci/pci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/ehci/pci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 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 drvusbehci
+ * @{
+ */
+/** @file
+ * PCI related functions needed by EHCI driver.
+ */
+#ifndef DRV_EHCI_PCI_H
+#define DRV_EHCI_PCI_H
+
+#include <ddf/driver.h>
+
+int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
+int pci_enable_interrupts(const ddf_dev_t *);
+int pci_disable_legacy(const ddf_dev_t *, uintptr_t, size_t, int);
+
+#endif
+/**
+ * @}
+ */
+
Index: pace/drv/ehci_hcd/Makefile
===================================================================
--- uspace/drv/ehci_hcd/Makefile	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,47 +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.
-#
-
-USPACE_PREFIX = ../..
-
-LIBS = \
-	$(LIBUSBHOST_PREFIX)/libusbhost.a \
-	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS += \
-	-I$(LIBUSB_PREFIX)/include \
-	-I$(LIBUSBHOST_PREFIX)/include \
-	-I$(LIBDRV_PREFIX)/include
-
-BINARY = ehci_hcd
-
-SOURCES = \
-	hc_iface.c \
-	main.c \
-	pci.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/drv/ehci_hcd/ehci.h
===================================================================
--- uspace/drv/ehci_hcd/ehci.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2011 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 drvusbehci
- * @{
- */
-/** @file
- * Common EHCI definitions.
- */
-#ifndef DRV_EHCI_EHCI_H
-#define DRV_EHCI_EHCI_H
-
-#include <usbhc_iface.h>
-
-#define NAME "ehci_hcd"
-
-extern usbhc_iface_t ehci_hc_iface;
-
-#endif
-/**
- * @}
- */
-
Index: pace/drv/ehci_hcd/ehci_hcd.ma
===================================================================
--- uspace/drv/ehci_hcd/ehci_hcd.ma	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,39 +1,0 @@
-10 pci/ven=1002&dev=4345
-10 pci/ven=1002&dev=4386
-10 pci/ven=1002&dev=4396
-10 pci/ven=1002&dev=4373
-10 pci/ven=1022&dev=7463
-10 pci/ven=1022&dev=7808
-10 pci/ven=102f&dev=01b5
-10 pci/ven=10cf&dev=1415
-10 pci/ven=10de&dev=00e8
-10 pci/ven=10de&dev=055f
-10 pci/ven=10de&dev=056a
-10 pci/ven=10de&dev=077c
-10 pci/ven=10de&dev=077e
-10 pci/ven=10de&dev=0aa6
-10 pci/ven=10de&dev=0aa9
-10 pci/ven=10de&dev=0aaa
-10 pci/ven=10de&dev=0d9d
-10 pci/ven=1166&dev=0414
-10 pci/ven=1166&dev=0416
-10 pci/ven=1414&dev=5805
-10 pci/ven=1414&dev=5807
-10 pci/ven=15ad&dev=0770
-10 pci/ven=17a0&dev=8084
-10 pci/ven=8086&dev=24cd
-10 pci/ven=8086&dev=24dd
-10 pci/ven=8086&dev=265c
-10 pci/ven=8086&dev=268c
-10 pci/ven=8086&dev=27cc
-10 pci/ven=8086&dev=2836
-10 pci/ven=8086&dev=283a
-10 pci/ven=8086&dev=293a
-10 pci/ven=8086&dev=293c
-10 pci/ven=8086&dev=3a3a
-10 pci/ven=8086&dev=3a3c
-10 pci/ven=8086&dev=3a6a
-10 pci/ven=8086&dev=3a6c
-10 pci/ven=8086&dev=8117
-10 pci/ven=8086&dev=8807
-10 pci/ven=8086&dev=880f
Index: pace/drv/ehci_hcd/hc_iface.c
===================================================================
--- uspace/drv/ehci_hcd/hc_iface.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,327 +1,0 @@
-/*
- * Copyright (c) 2011 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 drvusbehci
- * @{
- */
-/** @file
- * USB-HC interface implementation.
- */
-#include <ddf/driver.h>
-#include <ddf/interrupt.h>
-#include <device/hw_res.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb_iface.h>
-#include <usb/ddfiface.h>
-#include <usb/debug.h>
-
-#include "ehci.h"
-
-#define UNSUPPORTED(methodname) \
-	usb_log_debug("Client called unsupported interface method " \
-	    "`%s()' in %s:%d.\n", \
-	    methodname, __FILE__, __LINE__)
-
-/** Found free USB address.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] speed Speed of the device that will get this address.
- * @param[out] address Non-null pointer where to store the free address.
- * @return Error code.
- */
-static int request_address(ddf_fun_t *fun, usb_speed_t speed,
-    usb_address_t *address)
-{
-	UNSUPPORTED("request_address");
-
-	return ENOTSUP;
-}
-
-/** Bind USB address with device devman handle.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address of the device.
- * @param[in] handle Devman handle of the device.
- * @return Error code.
- */
-static int bind_address(ddf_fun_t *fun,
-    usb_address_t address, devman_handle_t handle)
-{
-	UNSUPPORTED("bind_address");
-
-	return ENOTSUP;
-}
-
-/** Find device handle by USB address.
- *
- * @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)
-{
-	UNSUPPORTED("find_by_address");
-
-	return ENOTSUP;
-}
-
-/** Release previously requested address.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address to be released.
- * @return Error code.
- */
-static int release_address(ddf_fun_t *fun, usb_address_t address)
-{
-	UNSUPPORTED("release_address");
-
-	return ENOTSUP;
-}
-
-/** Register endpoint for bandwidth reservation.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address of the device.
- * @param[in] speed Endpoint speed (invalid means to use device one).
- * @param[in] endpoint Endpoint number.
- * @param[in] transfer_type USB transfer type.
- * @param[in] direction Endpoint data direction.
- * @param[in] max_packet_size Max packet size of the endpoint.
- * @param[in] interval Polling interval.
- * @return Error code.
- */
-static int register_endpoint(ddf_fun_t *fun,
-    usb_address_t address, usb_speed_t speed, usb_endpoint_t endpoint,
-    usb_transfer_type_t transfer_type, usb_direction_t direction,
-    size_t max_packet_size, unsigned int interval)
-{
-	UNSUPPORTED("register_endpoint");
-
-	return ENOTSUP;
-}
-
-/** Unregister endpoint (free some bandwidth reservation).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address of the device.
- * @param[in] endpoint Endpoint number.
- * @param[in] direction Endpoint data direction.
- * @return Error code.
- */
-static int unregister_endpoint(ddf_fun_t *fun, usb_address_t address,
-    usb_endpoint_t endpoint, usb_direction_t direction)
-{
-	UNSUPPORTED("unregister_endpoint");
-
-	return ENOTSUP;
-}
-
-/** Schedule interrupt out transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
- *	by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @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)
-{
-	UNSUPPORTED("interrupt_out");
-
-	return ENOTSUP;
-}
-
-/** Schedule interrupt in transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Buffer where to store the data (in USB endianess,
- *	allocated and deallocated by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @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)
-{
-	UNSUPPORTED("interrupt_in");
-
-	return ENOTSUP;
-}
-
-/** Schedule bulk out transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
- *	by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @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)
-{
-	UNSUPPORTED("bulk_out");
-
-	return ENOTSUP;
-}
-
-/** Schedule bulk in transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Buffer where to store the data (in USB endianess,
- *	allocated and deallocated by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @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)
-{
-	UNSUPPORTED("bulk_in");
-
-	return ENOTSUP;
-}
-
-/** Schedule control write transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
- *	and deallocated by the caller).
- * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
- * @param[in] data_buffer Data buffer (in USB endianess, allocated and
- *	deallocated by the caller).
- * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int control_write(ddf_fun_t *fun, usb_target_t target,
-    void *setup_packet, size_t setup_packet_size,
-    void *data_buffer, size_t data_buffer_size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	UNSUPPORTED("control_write");
-
-	return ENOTSUP;
-}
-
-/** Schedule control read transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
- *	and deallocated by the caller).
- * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
- * @param[in] data_buffer Buffer where to store the data (in USB endianess,
- *	allocated and deallocated by the caller).
- * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int control_read(ddf_fun_t *fun, usb_target_t target,
-    void *setup_packet, size_t setup_packet_size,
-    void *data_buffer, size_t data_buffer_size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	UNSUPPORTED("control_read");
-
-	return ENOTSUP;
-}
-
-/** Host controller interface implementation for EHCI. */
-usbhc_iface_t ehci_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/ehci_hcd/main.c
===================================================================
--- uspace/drv/ehci_hcd/main.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,130 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * Copyright (c) 2011 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 drvusbehci
- * @{
- */
-/** @file
- * Main routines of EHCI driver.
- */
-#include <ddf/driver.h>
-#include <ddf/interrupt.h>
-#include <device/hw_res.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb_iface.h>
-#include <usb/ddfiface.h>
-#include <usb/debug.h>
-
-#include "pci.h"
-#include "ehci.h"
-
-static int ehci_add_device(ddf_dev_t *device);
-/*----------------------------------------------------------------------------*/
-static driver_ops_t ehci_driver_ops = {
-	.add_device = ehci_add_device,
-};
-/*----------------------------------------------------------------------------*/
-static driver_t ehci_driver = {
-	.name = NAME,
-	.driver_ops = &ehci_driver_ops
-};
-static ddf_dev_ops_t hc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &ehci_hc_iface,
-};
-
-/*----------------------------------------------------------------------------*/
-/** Initializes a new ddf driver instance of EHCI hcd.
- *
- * @param[in] device DDF instance of the device to initialize.
- * @return Error code.
- */
-static int ehci_add_device(ddf_dev_t *device)
-{
-	assert(device);
-#define CHECK_RET_RETURN(ret, message...) \
-if (ret != EOK) { \
-	usb_log_error(message); \
-	return ret; \
-}
-
-	uintptr_t reg_base = 0;
-	size_t reg_size = 0;
-	int irq = 0;
-
-	int ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
-	CHECK_RET_RETURN(ret,
-	    "Failed to get memory addresses for %" PRIun ": %s.\n",
-	    device->handle, str_error(ret));
-	usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
-	    reg_base, reg_size, irq);
-
-	ret = pci_disable_legacy(device, reg_base, reg_size, irq);
-	CHECK_RET_RETURN(ret,
-	    "Failed to disable legacy USB: %s.\n", str_error(ret));
-
-	ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
-	if (hc_fun == NULL) {
-		usb_log_error("Failed to create EHCI function.\n");
-		return ENOMEM;
-	}
-	hc_fun->ops = &hc_ops;
-
-	ret = ddf_fun_bind(hc_fun);
-	CHECK_RET_RETURN(ret,
-	    "Failed to bind EHCI function: %s.\n",
-	    str_error(ret));
-	ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME);
-	CHECK_RET_RETURN(ret,
-	    "Failed to add EHCI to HC class: %s.\n",
-	    str_error(ret));
-
-	usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
-	    device->name, device->handle);
-
-	return EOK;
-#undef CHECK_RET_RETURN
-}
-/*----------------------------------------------------------------------------*/
-/** Initializes global driver structures (NONE).
- *
- * @param[in] argc Nmber of arguments in argv vector (ignored).
- * @param[in] argv Cmdline argument vector (ignored).
- * @return Error code.
- *
- * Driver debug level is set here.
- */
-int main(int argc, char *argv[])
-{
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
-	return ddf_driver_main(&ehci_driver);
-}
-/**
- * @}
- */
Index: pace/drv/ehci_hcd/pci.c
===================================================================
--- uspace/drv/ehci_hcd/pci.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,391 +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 drvusbehci
- * @{
- */
-/**
- * @file
- * PCI related functions needed by the EHCI driver.
- */
-
-#include <errno.h>
-#include <str_error.h>
-#include <assert.h>
-#include <as.h>
-#include <devman.h>
-#include <ddi.h>
-#include <libarch/ddi.h>
-#include <device/hw_res.h>
-
-#include <usb/debug.h>
-#include <pci_dev_iface.h>
-
-#include "pci.h"
-
-#define PAGE_SIZE_MASK 0xfffff000
-
-#define HCC_PARAMS_OFFSET 0x8
-#define HCC_PARAMS_EECP_MASK 0xff
-#define HCC_PARAMS_EECP_OFFSET 8
-
-#define CMD_OFFSET 0x0
-#define STS_OFFSET 0x4
-#define INT_OFFSET 0x8
-#define CFG_OFFSET 0x40
-
-#define USBCMD_RUN 1
-#define USBSTS_HALTED (1 << 12)
-
-#define USBLEGSUP_OFFSET 0
-#define USBLEGSUP_BIOS_CONTROL (1 << 16)
-#define USBLEGSUP_OS_CONTROL (1 << 24)
-#define USBLEGCTLSTS_OFFSET 4
-
-#define DEFAULT_WAIT 1000
-#define WAIT_STEP 10
-
-#define PCI_READ(size) \
-do { \
-	async_sess_t *parent_sess = \
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
-	    IPC_FLAG_BLOCKING); \
-	if (!parent_sess) \
-		return ENOMEM; \
-	\
-	sysarg_t add = (sysarg_t) address; \
-	sysarg_t val; \
-	\
-	async_exch_t *exch = async_exchange_begin(parent_sess); \
-	\
-	const int ret = \
-	    async_req_2_1(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
-	        IPC_M_CONFIG_SPACE_READ_##size, add, &val); \
-	\
-	async_exchange_end(exch); \
-	async_hangup(parent_sess); \
-	\
-	assert(value); \
-	\
-	*value = val; \
-	return ret; \
-} while (0)
-
-static int pci_read32(const ddf_dev_t *dev, int address, uint32_t *value)
-{
-	PCI_READ(32);
-}
-
-static int pci_read16(const ddf_dev_t *dev, int address, uint16_t *value)
-{
-	PCI_READ(16);
-}
-
-static int pci_read8(const ddf_dev_t *dev, int address, uint8_t *value)
-{
-	PCI_READ(8);
-}
-
-#define PCI_WRITE(size) \
-do { \
-	async_sess_t *parent_sess = \
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle, \
-	    IPC_FLAG_BLOCKING); \
-	if (!parent_sess) \
-		return ENOMEM; \
-	\
-	sysarg_t add = (sysarg_t) address; \
-	sysarg_t val = value; \
-	\
-	async_exch_t *exch = async_exchange_begin(parent_sess); \
-	\
-	const int ret = \
-	    async_req_3_0(exch, DEV_IFACE_ID(PCI_DEV_IFACE), \
-	        IPC_M_CONFIG_SPACE_WRITE_##size, add, val); \
-	\
-	async_exchange_end(exch); \
-	async_hangup(parent_sess); \
-	\
-	return ret; \
-} while(0)
-
-static int pci_write32(const ddf_dev_t *dev, int address, uint32_t value)
-{
-	PCI_WRITE(32);
-}
-
-static int pci_write16(const ddf_dev_t *dev, int address, uint16_t value)
-{
-	PCI_WRITE(16);
-}
-
-static int pci_write8(const ddf_dev_t *dev, int address, uint8_t value)
-{
-	PCI_WRITE(8);
-}
-
-/** Get address of registers and IRQ for given device.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] mem_reg_address Base address of the memory range.
- * @param[out] mem_reg_size Size of the memory range.
- * @param[out] irq_no IRQ assigned to the device.
- * @return Error code.
- */
-int pci_get_my_registers(const ddf_dev_t *dev,
-    uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
-{
-	assert(dev != NULL);
-	
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	hw_resource_list_t hw_resources;
-	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
-	if (rc != EOK) {
-		async_hangup(parent_sess);
-		return rc;
-	}
-	
-	uintptr_t mem_address = 0;
-	size_t mem_size = 0;
-	bool mem_found = false;
-	
-	int irq = 0;
-	bool irq_found = false;
-	
-	size_t i;
-	for (i = 0; i < hw_resources.count; i++) {
-		hw_resource_t *res = &hw_resources.resources[i];
-		switch (res->type) {
-		case INTERRUPT:
-			irq = res->res.interrupt.irq;
-			irq_found = true;
-			usb_log_debug2("Found interrupt: %d.\n", irq);
-			break;
-		case MEM_RANGE:
-			if (res->res.mem_range.address != 0
-			    && res->res.mem_range.size != 0 ) {
-				mem_address = res->res.mem_range.address;
-				mem_size = res->res.mem_range.size;
-				usb_log_debug2("Found mem: %" PRIxn" %zu.\n",
-				    mem_address, mem_size);
-				mem_found = true;
-			}
-		default:
-			break;
-		}
-	}
-	
-	if (mem_found && irq_found) {
-		*mem_reg_address = mem_address;
-		*mem_reg_size = mem_size;
-		*irq_no = irq;
-		rc = EOK;
-	} else {
-		rc = ENOENT;
-	}
-	
-	async_hangup(parent_sess);
-	return rc;
-}
-/*----------------------------------------------------------------------------*/
-/** Calls the PCI driver with a request to enable interrupts
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_enable_interrupts(const ddf_dev_t *device)
-{
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-	
-	return enabled ? EOK : EIO;
-}
-/*----------------------------------------------------------------------------*/
-/** Implements BIOS handoff routine as decribed in EHCI spec
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_disable_legacy(
-    const ddf_dev_t *device, uintptr_t reg_base, size_t reg_size, int irq)
-{
-	assert(device);
-	(void) pci_read16;
-	(void) pci_read8;
-	(void) pci_write16;
-
-#define CHECK_RET_RETURN(ret, message...) \
-	if (ret != EOK) { \
-		usb_log_error(message); \
-		return ret; \
-	} else (void)0
-
-	/* Map EHCI registers */
-	void *regs = NULL;
-	int ret = pio_enable((void*)reg_base, reg_size, &regs);
-	CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n",
-	    (void *) reg_base, str_error(ret));
-
-	const uint32_t hcc_params =
-	    *(uint32_t*)(regs + HCC_PARAMS_OFFSET);
-	usb_log_debug("Value of hcc params register: %x.\n", hcc_params);
-
-	/* Read value of EHCI Extended Capabilities Pointer
-	 * position of EEC registers (points to PCI config space) */
-	const uint32_t eecp =
-	    (hcc_params >> HCC_PARAMS_EECP_OFFSET) & HCC_PARAMS_EECP_MASK;
-	usb_log_debug("Value of EECP: %x.\n", eecp);
-
-	/* Read the first EEC. i.e. Legacy Support register */
-	uint32_t usblegsup;
-	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));
-	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
-
-	/* Request control from firmware/BIOS, by writing 1 to highest byte.
-	 * (OS Control semaphore)*/
-	usb_log_debug("Requesting OS control.\n");
-	ret = pci_write8(device, eecp + USBLEGSUP_OFFSET + 3, 1);
-	CHECK_RET_RETURN(ret, "Failed to request OS EHCI control: %s.\n",
-	    str_error(ret));
-
-	size_t wait = 0;
-	/* Wait for BIOS to release control. */
-	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
-		async_usleep(WAIT_STEP);
-		ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-		wait += WAIT_STEP;
-	}
-
-
-	if ((usblegsup & USBLEGSUP_BIOS_CONTROL) == 0) {
-		usb_log_info("BIOS released control after %zu usec.\n", wait);
-	} else {
-		/* BIOS failed to hand over control, this should not happen. */
-		usb_log_warning( "BIOS failed to release control after "
-		    "%zu usecs, force it.\n", wait);
-		ret = pci_write32(device, eecp + USBLEGSUP_OFFSET,
-		    USBLEGSUP_OS_CONTROL);
-		CHECK_RET_RETURN(ret, "Failed to force OS control: %s.\n",
-		    str_error(ret));
-		/* Check capability type here, A value of 01h
-		 * identifies the capability as Legacy Support.
-		 * This extended capability requires one
-		 * additional 32-bit register for control/status information,
-		 * and this register is located at offset EECP+04h
-		 * */
-		if ((usblegsup & 0xff) == 1) {
-			/* Read the second EEC
-			 * Legacy Support and Control register */
-			uint32_t usblegctlsts;
-			ret = pci_read32(
-			    device, eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
-			CHECK_RET_RETURN(ret,
-			    "Failed to get USBLEGCTLSTS: %s.\n", str_error(ret));
-			usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n",
-			    usblegctlsts);
-			/* Zero SMI enables in legacy control register.
-			 * It should prevent pre-OS code from interfering. */
-			ret = pci_write32(device, eecp + USBLEGCTLSTS_OFFSET,
-			    0xe0000000); /* three upper bits are WC */
-			CHECK_RET_RETURN(ret,
-			    "Failed(%d) zero USBLEGCTLSTS.\n", ret);
-			udelay(10);
-			ret = pci_read32(
-			    device, eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
-			CHECK_RET_RETURN(ret,
-			    "Failed to get USBLEGCTLSTS 2: %s.\n",
-			    str_error(ret));
-			usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
-			    usblegctlsts);
-		}
-	}
-
-
-	/* Read again Legacy Support register */
-	ret = pci_read32(device, eecp + USBLEGSUP_OFFSET, &usblegsup);
-	CHECK_RET_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", str_error(ret));
-	usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
-
-	/*
-	 * TURN OFF EHCI FOR NOW, DRIVER WILL REINITIALIZE IT
-	 */
-
-	/* Get size of capability registers in memory space. */
-	const unsigned operation_offset = *(uint8_t*)regs;
-	usb_log_debug("USBCMD offset: %d.\n", operation_offset);
-
-	/* Zero USBCMD register. */
-	volatile uint32_t *usbcmd =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + CMD_OFFSET);
-	volatile uint32_t *usbsts =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + STS_OFFSET);
-	volatile uint32_t *usbconf =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + CFG_OFFSET);
-	volatile uint32_t *usbint =
-	    (uint32_t*)((uint8_t*)regs + operation_offset + INT_OFFSET);
-	usb_log_debug("USBCMD value: %x.\n", *usbcmd);
-	if (*usbcmd & USBCMD_RUN) {
-		*usbsts = 0x3f; /* ack all interrupts */
-		*usbint = 0; /* disable all interrutps */
-		*usbconf = 0; /* relase control of RH ports */
-
-		*usbcmd = 0;
-		/* Wait until hc is halted */
-		while ((*usbsts & USBSTS_HALTED) == 0);
-		usb_log_info("EHCI turned off.\n");
-	} else {
-		usb_log_info("EHCI was not running.\n");
-	}
-	usb_log_debug("Registers: \n"
-	    "\t USBCMD: %x(0x00080000 = at least 1ms between interrupts)\n"
-	    "\t USBSTS: %x(0x00001000 = HC halted)\n"
-	    "\t USBINT: %x(0x0 = no interrupts).\n"
-	    "\t CONFIG: %x(0x0 = ports controlled by companion hc).\n",
-	    *usbcmd, *usbsts, *usbint, *usbconf);
-
-	return ret;
-#undef CHECK_RET_RETURN
-}
-
-/**
- * @}
- */
Index: pace/drv/ehci_hcd/pci.h
===================================================================
--- uspace/drv/ehci_hcd/pci.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2011 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 drvusbehci
- * @{
- */
-/** @file
- * PCI related functions needed by EHCI driver.
- */
-#ifndef DRV_EHCI_PCI_H
-#define DRV_EHCI_PCI_H
-
-#include <ddf/driver.h>
-
-int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int pci_enable_interrupts(const ddf_dev_t *);
-int pci_disable_legacy(const ddf_dev_t *, uintptr_t, size_t, int);
-
-#endif
-/**
- * @}
- */
-
Index: uspace/drv/uhci/Makefile
===================================================================
--- uspace/drv/uhci/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,53 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../..
+
+LIBS = \
+	$(LIBUSBHOST_PREFIX)/libusbhost.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBHOST_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
+BINARY = uhci
+
+SOURCES = \
+	iface.c \
+	main.c \
+	transfer_list.c \
+	uhci.c \
+	hc.c \
+	root_hub.c \
+	hw_struct/transfer_descriptor.c \
+	pci.c \
+	batch.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/uhci/batch.c
===================================================================
--- uspace/drv/uhci/batch.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/batch.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,428 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver USB transfer structure
+ */
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb/usb.h>
+#include <usb/debug.h>
+
+#include "batch.h"
+#include "transfer_list.h"
+#include "hw_struct/transfer_descriptor.h"
+#include "utils/malloc32.h"
+
+#define DEFAULT_ERROR_COUNT 3
+
+/** UHCI specific data required for USB transfer */
+typedef struct uhci_transfer_batch {
+	/** Queue head
+	 * This QH is used to maintain UHCI schedule structure and the element
+	 * pointer points to the first TD of this batch.
+	 */
+	qh_t *qh;
+	/** List of TDs needed for the transfer */
+	td_t *tds;
+	/** Number of TDs used by the transfer */
+	size_t td_count;
+	/** Data buffer, must be accessible by the UHCI hw */
+	void *device_buffer;
+} uhci_transfer_batch_t;
+/*----------------------------------------------------------------------------*/
+static void batch_control(usb_transfer_batch_t *instance,
+    usb_packet_id data_stage, usb_packet_id status_stage);
+static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid);
+/*----------------------------------------------------------------------------*/
+/** Safely destructs uhci_transfer_batch_t structure
+ *
+ * @param[in] uhci_batch Instance to destroy.
+ */
+static void uhci_transfer_batch_dispose(void *uhci_batch)
+{
+	uhci_transfer_batch_t *instance = uhci_batch;
+	assert(instance);
+	free32(instance->device_buffer);
+	free(instance);
+}
+/*----------------------------------------------------------------------------*/
+/** 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.
+ *
+ * @param[in] instance Batch structure to use.
+ * @return False, if there is an active TD, true otherwise.
+ *
+ * Walk all TDs. Stop with false if there is an active one (it is to be
+ * processed). Stop with true if an error is found. Return true if the last TD
+ * is reached.
+ */
+bool batch_is_complete(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	uhci_transfer_batch_t *data = instance->private_data;
+	assert(data);
+
+	usb_log_debug2("Batch(%p) checking %zu transfer(s) for completion.\n",
+	    instance, data->td_count);
+	instance->transfered_size = 0;
+	size_t i = 0;
+	for (;i < data->td_count; ++i) {
+		if (td_is_active(&data->tds[i])) {
+			return false;
+		}
+
+		instance->error = td_status(&data->tds[i]);
+		if (instance->error != EOK) {
+			usb_log_debug("Batch(%p) found error TD(%zu):%"
+			    PRIx32 ".\n", instance, i, data->tds[i].status);
+			td_print_status(&data->tds[i]);
+
+			assert(instance->ep != NULL);
+			endpoint_toggle_set(instance->ep,
+			    td_toggle(&data->tds[i]));
+			if (i > 0)
+				goto substract_ret;
+			return true;
+		}
+
+		instance->transfered_size += td_act_size(&data->tds[i]);
+		if (td_is_short(&data->tds[i]))
+			goto substract_ret;
+	}
+substract_ret:
+	instance->transfered_size -= instance->setup_size;
+	return true;
+}
+
+#define LOG_BATCH_INITIALIZED(batch, name) \
+	usb_log_debug2("Batch %p %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
+	    (batch), (name), USB_TRANSFER_BATCH_ARGS(*(batch)))
+
+/*----------------------------------------------------------------------------*/
+/** Prepares control write transfer.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ * Uses generic control function with pids OUT and IN.
+ */
+void batch_control_write(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	/* We are data out, we are supposed to provide data */
+	memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
+	batch_control(instance, USB_PID_OUT, USB_PID_IN);
+	instance->next_step = usb_transfer_batch_call_out_and_dispose;
+	LOG_BATCH_INITIALIZED(instance, "control write");
+}
+/*----------------------------------------------------------------------------*/
+/** Prepares control read transfer.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ * Uses generic control with pids IN and OUT.
+ */
+void batch_control_read(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	batch_control(instance, USB_PID_IN, USB_PID_OUT);
+	instance->next_step = usb_transfer_batch_call_in_and_dispose;
+	LOG_BATCH_INITIALIZED(instance, "control read");
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare interrupt in transfer.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ * Data transfer with PID_IN.
+ */
+void batch_interrupt_in(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	batch_data(instance, USB_PID_IN);
+	instance->next_step = usb_transfer_batch_call_in_and_dispose;
+	LOG_BATCH_INITIALIZED(instance, "interrupt in");
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare interrupt out transfer.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ * Data transfer with PID_OUT.
+ */
+void batch_interrupt_out(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	/* We are data out, we are supposed to provide data */
+	memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
+	batch_data(instance, USB_PID_OUT);
+	instance->next_step = usb_transfer_batch_call_out_and_dispose;
+	LOG_BATCH_INITIALIZED(instance, "interrupt out");
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare bulk in transfer.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ * Data transfer with PID_IN.
+ */
+void batch_bulk_in(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	batch_data(instance, USB_PID_IN);
+	instance->next_step = usb_transfer_batch_call_in_and_dispose;
+	LOG_BATCH_INITIALIZED(instance, "bulk in");
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare bulk out transfer.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ * Data transfer with PID_OUT.
+ */
+void batch_bulk_out(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	/* We are data out, we are supposed to provide data */
+	memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
+	batch_data(instance, USB_PID_OUT);
+	instance->next_step = usb_transfer_batch_call_out_and_dispose;
+	LOG_BATCH_INITIALIZED(instance, "bulk out");
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare generic data transfer
+ *
+ * @param[in] instance Batch structure to use.
+ * @param[in] pid Pid to use for data transactions.
+ *
+ * Transactions with alternating toggle bit and supplied pid value.
+ * The last transfer is marked with IOC flag.
+ */
+void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
+{
+	assert(instance);
+	uhci_transfer_batch_t *data = instance->private_data;
+	assert(data);
+
+	const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
+	int toggle = endpoint_toggle_get(instance->ep);
+	assert(toggle == 0 || toggle == 1);
+
+	size_t td = 0;
+	size_t remain_size = instance->buffer_size;
+	char *buffer = instance->data_buffer;
+	while (remain_size > 0) {
+		const size_t packet_size =
+		    (instance->ep->max_packet_size > remain_size) ?
+		    remain_size : instance->ep->max_packet_size;
+
+		td_t *next_td = (td + 1 < data->td_count)
+		    ? &data->tds[td + 1] : NULL;
+
+
+		usb_target_t target =
+		    { instance->ep->address, instance->ep->endpoint };
+
+		assert(td < data->td_count);
+		td_init(
+		    &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
+		    toggle, false, low_speed, target, pid, buffer, next_td);
+
+		++td;
+		toggle = 1 - toggle;
+		buffer += packet_size;
+		assert(packet_size <= remain_size);
+		remain_size -= packet_size;
+	}
+	td_set_ioc(&data->tds[td - 1]);
+	endpoint_toggle_set(instance->ep, toggle);
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare generic control transfer
+ *
+ * @param[in] instance Batch structure to use.
+ * @param[in] data_stage Pid to use for data tds.
+ * @param[in] status_stage Pid to use for data tds.
+ *
+ * Setup stage with toggle 0 and USB_PID_SETUP.
+ * Data stage with alternating toggle and pid supplied by parameter.
+ * Status stage with toggle 1 and pid supplied by parameter.
+ * The last transfer is marked with IOC.
+ */
+void batch_control(usb_transfer_batch_t *instance,
+   usb_packet_id data_stage, usb_packet_id status_stage)
+{
+	assert(instance);
+	uhci_transfer_batch_t *data = instance->private_data;
+	assert(data);
+	assert(data->td_count >= 2);
+
+	const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
+	const usb_target_t target =
+	    { instance->ep->address, instance->ep->endpoint };
+
+	/* setup stage */
+	td_init(
+	    data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false,
+	    low_speed, target, USB_PID_SETUP, instance->setup_buffer,
+	    &data->tds[1]);
+
+	/* data stage */
+	size_t td = 1;
+	unsigned toggle = 1;
+	size_t remain_size = instance->buffer_size;
+	char *buffer = instance->data_buffer;
+	while (remain_size > 0) {
+		const size_t packet_size =
+		    (instance->ep->max_packet_size > remain_size) ?
+		    remain_size : instance->ep->max_packet_size;
+
+		td_init(
+		    &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
+		    toggle, false, low_speed, target, data_stage,
+		    buffer, &data->tds[td + 1]);
+
+		++td;
+		toggle = 1 - toggle;
+		buffer += packet_size;
+		assert(td < data->td_count);
+		assert(packet_size <= remain_size);
+		remain_size -= packet_size;
+	}
+
+	/* status stage */
+	assert(td == data->td_count - 1);
+
+	td_init(
+	    &data->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
+	    target, status_stage, NULL, NULL);
+	td_set_ioc(&data->tds[td]);
+
+	usb_log_debug2("Control last TD status: %x.\n",
+	    data->tds[td].status);
+}
+/*----------------------------------------------------------------------------*/
+/** Provides access to QH data structure.
+ *
+ * @param[in] instance Batch pointer to use.
+ * @return Pointer to the QH used by the batch.
+ */
+qh_t * batch_qh(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	uhci_transfer_batch_t *data = instance->private_data;
+	assert(data);
+	return data->qh;
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/batch.h
===================================================================
--- uspace/drv/uhci/batch.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/batch.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,65 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver USB tranfer helper functions
+ */
+#ifndef DRV_UHCI_BATCH_H
+#define DRV_UHCI_BATCH_H
+
+#include <usb/host/batch.h>
+
+#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 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);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/hc.c
===================================================================
--- uspace/drv/uhci/hc.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/hc.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,474 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI Host controller driver routines
+ */
+#include <errno.h>
+#include <str_error.h>
+#include <adt/list.h>
+#include <libarch/ddi.h>
+
+#include <usb/debug.h>
+#include <usb/usb.h>
+
+#include "hc.h"
+
+#define UHCI_INTR_ALLOW_INTERRUPTS \
+    (UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET)
+#define UHCI_STATUS_USED_INTERRUPTS \
+    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
+
+
+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_interrupt_emulator(void *arg);
+static int hc_debug_checker(void *arg);
+/*----------------------------------------------------------------------------*/
+/** Initialize UHCI hc driver structure
+ *
+ * @param[in] instance Memory place to initialize.
+ * @param[in] regs Address of I/O control registers.
+ * @param[in] reg_size Size of I/O control registers.
+ * @param[in] interrupts True if hw interrupts should be used.
+ * @return Error code.
+ * @note Should be called only once on any structure.
+ *
+ * Initializes memory structures, starts up hw, and launches debugger and
+ * interrupt fibrils.
+ */
+int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts)
+{
+	assert(reg_size >= sizeof(regs_t));
+	int ret;
+
+#define CHECK_RET_RETURN(ret, message...) \
+	if (ret != EOK) { \
+		usb_log_error(message); \
+		return ret; \
+	} else (void) 0
+
+	instance->hw_interrupts = interrupts;
+	instance->hw_failures = 0;
+
+	/* allow access to hc control registers */
+	regs_t *io;
+	ret = pio_enable(regs, reg_size, (void **)&io);
+	CHECK_RET_RETURN(ret,
+	    "Failed(%d) to gain access to registers at %p: %s.\n",
+	    ret, io, str_error(ret));
+	instance->registers = io;
+	usb_log_debug("Device registers at %p (%zuB) accessible.\n",
+	    io, reg_size);
+
+	ret = hc_init_mem_structures(instance);
+	CHECK_RET_RETURN(ret,
+	    "Failed(%d) to initialize UHCI memory structures: %s.\n",
+	    ret, str_error(ret));
+
+	hc_init_hw(instance);
+	if (!interrupts) {
+		instance->interrupt_emulator =
+		    fibril_create(hc_interrupt_emulator, instance);
+		fibril_add_ready(instance->interrupt_emulator);
+	}
+	(void)hc_debug_checker;
+
+	return EOK;
+#undef CHECK_RET_DEST_FUN_RETURN
+}
+/*----------------------------------------------------------------------------*/
+/** Initialize UHCI hc hw resources.
+ *
+ * @param[in] instance UHCI structure to use.
+ * For magic values see UHCI Design Guide
+ */
+void hc_init_hw(hc_t *instance)
+{
+	assert(instance);
+	regs_t *registers = instance->registers;
+
+	/* Reset everything, who knows what touched it before us */
+	pio_write_16(&registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
+	async_usleep(10000); /* 10ms according to USB spec */
+	pio_write_16(&registers->usbcmd, 0);
+
+	/* Reset hc, all states and counters */
+	pio_write_16(&registers->usbcmd, UHCI_CMD_HCRESET);
+	do { async_usleep(10); }
+	while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
+
+	/* Set frame to exactly 1ms */
+	pio_write_8(&registers->sofmod, 64);
+
+	/* Set frame list pointer */
+	const uint32_t pa = addr_to_phys(instance->frame_list);
+	pio_write_32(&registers->flbaseadd, pa);
+
+	if (instance->hw_interrupts) {
+		/* Enable all interrupts, but resume interrupt */
+		pio_write_16(&instance->registers->usbintr,
+		    UHCI_INTR_ALLOW_INTERRUPTS);
+	}
+
+	const uint16_t status = pio_read_16(&registers->usbcmd);
+	if (status != 0)
+		usb_log_warning("Previous command value: %x.\n", status);
+
+	/* Start the hc with large(64B) packet FSBR */
+	pio_write_16(&registers->usbcmd,
+	    UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
+}
+/*----------------------------------------------------------------------------*/
+/** Initialize UHCI hc memory structures.
+ *
+ * @param[in] instance UHCI structure to use.
+ * @return Error code
+ * @note Should be called only once on any structure.
+ *
+ * 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)
+ */
+int hc_init_mem_structures(hc_t *instance)
+{
+	assert(instance);
+#define CHECK_RET_RETURN(ret, message...) \
+	if (ret != EOK) { \
+		usb_log_error(message); \
+		return ret; \
+	} else (void) 0
+
+	/* Init interrupt code */
+	instance->interrupt_code.cmds = instance->interrupt_commands;
+	{
+		/* Read status register */
+		instance->interrupt_commands[0].cmd = CMD_PIO_READ_16;
+		instance->interrupt_commands[0].dstarg = 1;
+		instance->interrupt_commands[0].addr =
+		    &instance->registers->usbsts;
+
+		/* Test whether we are the interrupt cause */
+		instance->interrupt_commands[1].cmd = CMD_BTEST;
+		instance->interrupt_commands[1].value =
+		    UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS;
+		instance->interrupt_commands[1].srcarg = 1;
+		instance->interrupt_commands[1].dstarg = 2;
+
+		/* Predicate cleaning and accepting */
+		instance->interrupt_commands[2].cmd = CMD_PREDICATE;
+		instance->interrupt_commands[2].value = 2;
+		instance->interrupt_commands[2].srcarg = 2;
+
+		/* Write clean status register */
+		instance->interrupt_commands[3].cmd = CMD_PIO_WRITE_A_16;
+		instance->interrupt_commands[3].srcarg = 1;
+		instance->interrupt_commands[3].addr =
+		    &instance->registers->usbsts;
+
+		/* Accept interrupt */
+		instance->interrupt_commands[4].cmd = CMD_ACCEPT;
+
+		instance->interrupt_code.cmdcount = UHCI_NEEDED_IRQ_COMMANDS;
+	}
+
+	/* Init transfer lists */
+	int ret = hc_init_transfer_lists(instance);
+	CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n");
+	usb_log_debug("Initialized transfer lists.\n");
+
+	/* Init USB frame list page*/
+	instance->frame_list = get_page();
+	ret = instance->frame_list ? EOK : ENOMEM;
+	CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
+	usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
+
+	/* Set all frames to point to the first queue head */
+	const uint32_t queue = LINK_POINTER_QH(
+	        addr_to_phys(instance->transfers_interrupt.queue_head));
+
+	unsigned i = 0;
+	for(; i < UHCI_FRAME_LIST_COUNT; ++i) {
+		instance->frame_list[i] = queue;
+	}
+
+	/* Init device keeper */
+	usb_device_keeper_init(&instance->manager);
+	usb_log_debug("Initialized device manager.\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));
+
+	return EOK;
+#undef CHECK_RET_RETURN
+}
+/*----------------------------------------------------------------------------*/
+/** Initialize UHCI hc transfer lists.
+ *
+ * @param[in] instance UHCI structure to use.
+ * @return Error code
+ * @note Should be called only once on any structure.
+ *
+ * Initializes transfer lists and sets them in one chain to support proper
+ * USB scheduling. Sets pointer table for quick access.
+ */
+int hc_init_transfer_lists(hc_t *instance)
+{
+	assert(instance);
+#define SETUP_TRANSFER_LIST(type, name) \
+do { \
+	int ret = transfer_list_init(&instance->transfers_##type, name); \
+	if (ret != EOK) { \
+		usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \
+		    ret, name, str_error(ret)); \
+		transfer_list_fini(&instance->transfers_bulk_full); \
+		transfer_list_fini(&instance->transfers_control_full); \
+		transfer_list_fini(&instance->transfers_control_slow); \
+		transfer_list_fini(&instance->transfers_interrupt); \
+		return ret; \
+	} \
+} while (0)
+
+	SETUP_TRANSFER_LIST(bulk_full, "BULK FULL");
+	SETUP_TRANSFER_LIST(control_full, "CONTROL FULL");
+	SETUP_TRANSFER_LIST(control_slow, "CONTROL LOW");
+	SETUP_TRANSFER_LIST(interrupt, "INTERRUPT");
+#undef SETUP_TRANSFER_LIST
+	/* Connect lists into one schedule */
+	transfer_list_set_next(&instance->transfers_control_full,
+		&instance->transfers_bulk_full);
+	transfer_list_set_next(&instance->transfers_control_slow,
+		&instance->transfers_control_full);
+	transfer_list_set_next(&instance->transfers_interrupt,
+		&instance->transfers_control_slow);
+
+	/*FSBR, This feature is not needed (adds no benefit) and is supposedly
+	 * buggy on certain hw, enable at your own risk. */
+#ifdef FSBR
+	transfer_list_set_next(&instance->transfers_bulk_full,
+	    &instance->transfers_control_full);
+#endif
+
+	/* Assign pointers to be used during scheduling */
+	instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] =
+	  &instance->transfers_interrupt;
+	instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] =
+	  &instance->transfers_interrupt;
+	instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] =
+	  &instance->transfers_control_full;
+	instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] =
+	  &instance->transfers_control_slow;
+	instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] =
+	  &instance->transfers_bulk_full;
+
+	return EOK;
+#undef CHECK_RET_CLEAR_RETURN
+}
+/*----------------------------------------------------------------------------*/
+/** Schedule batch for execution.
+ *
+ * @param[in] instance UHCI structure to use.
+ * @param[in] batch Transfer batch to schedule.
+ * @return Error code
+ *
+ * Checks for bandwidth availability and appends the batch to the proper queue.
+ */
+int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
+{
+	assert(instance);
+	assert(batch);
+
+	transfer_list_t *list =
+	    instance->transfers[batch->ep->speed][batch->ep->transfer_type];
+	assert(list);
+	transfer_list_add_batch(list, batch);
+
+	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 = done.next;
+			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);
+		}
+	}
+}
+/*----------------------------------------------------------------------------*/
+/** Polling function, emulates interrupts.
+ *
+ * @param[in] arg UHCI hc structure to use.
+ * @return EOK (should never return)
+ */
+int hc_interrupt_emulator(void* arg)
+{
+	usb_log_debug("Started interrupt emulator.\n");
+	hc_t *instance = arg;
+	assert(instance);
+
+	while (1) {
+		/* Read and clear status register */
+		uint16_t status = pio_read_16(&instance->registers->usbsts);
+		pio_write_16(&instance->registers->usbsts, status);
+		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);
+	}
+	return EOK;
+}
+/*---------------------------------------------------------------------------*/
+/** Debug function, checks consistency of memory structures.
+ *
+ * @param[in] arg UHCI structure to use.
+ * @return EOK (should never return)
+ */
+int hc_debug_checker(void *arg)
+{
+	hc_t *instance = arg;
+	assert(instance);
+
+#define QH(queue) \
+	instance->transfers_##queue.queue_head
+
+	while (1) {
+		const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
+		const uint16_t sts = pio_read_16(&instance->registers->usbsts);
+		const uint16_t intr =
+		    pio_read_16(&instance->registers->usbintr);
+
+		if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) {
+			usb_log_debug2("Command: %X Status: %X Intr: %x\n",
+			    cmd, sts, intr);
+		}
+
+		const uintptr_t frame_list =
+		    pio_read_32(&instance->registers->flbaseadd) & ~0xfff;
+		if (frame_list != addr_to_phys(instance->frame_list)) {
+			usb_log_debug("Framelist address: %p vs. %p.\n",
+			    (void *) frame_list,
+			    (void *) addr_to_phys(instance->frame_list));
+		}
+
+		int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff;
+
+		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) {
+			usb_log_debug("Interrupt QH: %p (frame %d) vs. %p.\n",
+			    (void *) expected_pa, frnum, (void *) real_pa);
+		}
+
+		expected_pa = QH(interrupt)->next & LINK_POINTER_ADDRESS_MASK;
+		real_pa = addr_to_phys(QH(control_slow));
+		if (expected_pa != real_pa) {
+			usb_log_debug("Control Slow QH: %p vs. %p.\n",
+			    (void *) expected_pa, (void *) real_pa);
+		}
+
+		expected_pa = QH(control_slow)->next & LINK_POINTER_ADDRESS_MASK;
+		real_pa = addr_to_phys(QH(control_full));
+		if (expected_pa != real_pa) {
+			usb_log_debug("Control Full QH: %p vs. %p.\n",
+			    (void *) expected_pa, (void *) real_pa);
+		}
+
+		expected_pa = QH(control_full)->next & LINK_POINTER_ADDRESS_MASK;
+		real_pa = addr_to_phys(QH(bulk_full));
+		if (expected_pa != real_pa ) {
+			usb_log_debug("Bulk QH: %p vs. %p.\n",
+			    (void *) expected_pa, (void *) real_pa);
+		}
+		async_usleep(UHCI_DEBUGER_TIMEOUT);
+	}
+	return EOK;
+#undef QH
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/hc.h
===================================================================
--- uspace/drv/uhci/hc.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/hc.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,160 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI host controller driver structure
+ */
+#ifndef DRV_UHCI_HC_H
+#define DRV_UHCI_HC_H
+
+#include <fibril.h>
+#include <ddi.h>
+
+#include <usb/host/device_keeper.h>
+#include <usb/host/usb_endpoint_manager.h>
+#include <usb/host/batch.h>
+
+#include "transfer_list.h"
+
+/** UHCI I/O registers layout */
+typedef struct uhci_regs {
+	/** Command register, controls HC behaviour */
+	uint16_t usbcmd;
+#define UHCI_CMD_MAX_PACKET (1 << 7)
+#define UHCI_CMD_CONFIGURE  (1 << 6)
+#define UHCI_CMD_DEBUG  (1 << 5)
+#define UHCI_CMD_FORCE_GLOBAL_RESUME  (1 << 4)
+#define UHCI_CMD_FORCE_GLOBAL_SUSPEND  (1 << 3)
+#define UHCI_CMD_GLOBAL_RESET  (1 << 2)
+#define UHCI_CMD_HCRESET  (1 << 1)
+#define UHCI_CMD_RUN_STOP  (1 << 0)
+
+	/** Status register, 1 means interrupt is asserted (if enabled) */
+	uint16_t usbsts;
+#define UHCI_STATUS_HALTED (1 << 5)
+#define UHCI_STATUS_PROCESS_ERROR (1 << 4)
+#define UHCI_STATUS_SYSTEM_ERROR (1 << 3)
+#define UHCI_STATUS_RESUME (1 << 2)
+#define UHCI_STATUS_ERROR_INTERRUPT (1 << 1)
+#define UHCI_STATUS_INTERRUPT (1 << 0)
+#define UHCI_STATUS_NM_INTERRUPTS \
+    (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)
+
+	/** Interrupt enabled registers */
+	uint16_t usbintr;
+#define UHCI_INTR_SHORT_PACKET (1 << 3)
+#define UHCI_INTR_COMPLETE (1 << 2)
+#define UHCI_INTR_RESUME (1 << 1)
+#define UHCI_INTR_CRC (1 << 0)
+
+	/** Register stores frame number used in SOF packet */
+	uint16_t frnum;
+
+	/** Pointer(physical) to the Frame List */
+	uint32_t flbaseadd;
+
+	/** SOF modification to match external timers */
+	uint8_t sofmod;
+} regs_t;
+
+#define UHCI_FRAME_LIST_COUNT 1024
+#define UHCI_INT_EMULATOR_TIMEOUT 10000
+#define UHCI_DEBUGER_TIMEOUT 5000000
+#define UHCI_ALLOWED_HW_FAIL 5
+#define UHCI_NEEDED_IRQ_COMMANDS 5
+
+/** Main UHCI driver structure */
+typedef struct hc {
+	/** 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 */
+	regs_t *registers;
+
+	/** Frame List contains 1024 link pointers */
+	link_pointer_t *frame_list;
+
+	/** List and queue of interrupt transfers */
+	transfer_list_t transfers_interrupt;
+	/** List and queue of low speed control transfers */
+	transfer_list_t transfers_control_slow;
+	/** List and queue of full speed bulk transfers */
+	transfer_list_t transfers_bulk_full;
+	/** List and queue of full speed control transfers */
+	transfer_list_t transfers_control_full;
+
+	/** Pointer table to the above lists, helps during scheduling */
+	transfer_list_t *transfers[2][4];
+
+	/** Code to be executed in kernel interrupt handler */
+	irq_code_t interrupt_code;
+
+	/** Commands that form interrupt code */
+	irq_cmd_t interrupt_commands[UHCI_NEEDED_IRQ_COMMANDS];
+
+	/** Fibril periodically checking status register*/
+	fid_t interrupt_emulator;
+
+	/** Indicator of hw interrupts availability */
+	bool hw_interrupts;
+
+	/** Number of hw failures detected. */
+	unsigned hw_failures;
+} hc_t;
+
+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
+ *
+ * @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;
+}
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/hw_struct/link_pointer.h
===================================================================
--- uspace/drv/uhci/hw_struct/link_pointer.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/hw_struct/link_pointer.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010 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
+ */
+#ifndef DRV_UHCI_HW_STRUCT_LINK_POINTER_H
+#define DRV_UHCI_HW_STRUCT_LINK_POINTER_H
+
+/* UHCI link pointer, used by many data structures */
+typedef uint32_t link_pointer_t;
+
+#define LINK_POINTER_TERMINATE_FLAG (1 << 0)
+#define LINK_POINTER_QUEUE_HEAD_FLAG (1 << 1)
+#define LINK_POINTER_ZERO_BIT_FLAG (1 << 2)
+#define LINK_POINTER_VERTICAL_FLAG (1 << 2)
+#define LINK_POINTER_RESERVED_FLAG (1 << 3)
+
+#define LINK_POINTER_ADDRESS_MASK 0xfffffff0 /* upper 28 bits */
+
+#define LINK_POINTER_QH(address) \
+	((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/hw_struct/queue_head.h
===================================================================
--- uspace/drv/uhci/hw_struct/queue_head.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/hw_struct/queue_head.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010 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
+ */
+#ifndef DRV_UHCI_HW_STRUCT_QH_H
+#define DRV_UHCI_HW_STRUCT_QH_H
+#include <assert.h>
+
+#include "link_pointer.h"
+#include "transfer_descriptor.h"
+#include "../utils/malloc32.h"
+
+/** This structure is defined in UHCI design guide p. 31 */
+typedef struct queue_head {
+	/** Pointer to the next entity (another QH or TD */
+	volatile link_pointer_t next;
+	/** Pointer to the contained entities (execution controlled by vertical flag*/
+	volatile link_pointer_t element;
+} __attribute__((packed)) qh_t;
+/*----------------------------------------------------------------------------*/
+/** Initialize queue head structure
+ *
+ * @param[in] instance qh_t structure to initialize.
+ *
+ * Sets both pointer to terminal NULL.
+ */
+static inline void qh_init(qh_t *instance)
+{
+	assert(instance);
+
+	instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
+	instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
+}
+/*----------------------------------------------------------------------------*/
+/** Set queue head next pointer
+ *
+ * @param[in] instance qh_t structure to use.
+ * @param[in] next Address of the next queue.
+ *
+ * Adds proper flag. If the pointer is NULL, sets next to terminal NULL.
+ */
+static inline void qh_set_next_qh(qh_t *instance, qh_t *next)
+{
+	uint32_t pa = addr_to_phys(next);
+	if (pa) {
+		instance->next = LINK_POINTER_QH(pa);
+	} else {
+		instance->next = LINK_POINTER_TERM;
+	}
+}
+/*----------------------------------------------------------------------------*/
+/** Set queue head element pointer
+ *
+ * @param[in] instance qh_t structure to use.
+ * @param[in] td Transfer descriptor to set as the first element.
+ *
+ * Adds proper flag. If the pointer is NULL, sets element to terminal NULL.
+ */
+static inline void qh_set_element_td(qh_t *instance, td_t *td)
+{
+	uint32_t pa = addr_to_phys(td);
+	if (pa) {
+		instance->element = LINK_POINTER_TD(pa);
+	} else {
+		instance->element = LINK_POINTER_TERM;
+	}
+}
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/hw_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci/hw_struct/transfer_descriptor.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/hw_struct/transfer_descriptor.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,176 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#include <errno.h>
+#include <usb/debug.h>
+
+#include "transfer_descriptor.h"
+#include "../utils/malloc32.h"
+
+/** Initialize Transfer Descriptor
+ *
+ * @param[in] instance Memory place to initialize.
+ * @param[in] err_count Number of retries hc should attempt.
+ * @param[in] size Size of data source.
+ * @param[in] toggle Value of toggle bit.
+ * @param[in] iso True if TD represents Isochronous transfer.
+ * @param[in] low_speed Target device's speed.
+ * @param[in] target Address and endpoint receiving the transfer.
+ * @param[in] pid Packet identification (SETUP, IN or OUT).
+ * @param[in] buffer Source of data.
+ * @param[in] next Net TD in transaction.
+ * @return Error code.
+ *
+ * Uses a mix of supplied and default values.
+ * Implicit values:
+ *  - all TDs have vertical flag set (makes transfers to endpoints atomic)
+ *  - in the error field only active it is set
+ *  - if the packet uses PID_IN and is not isochronous SPD is set
+ *
+ * Dumps 8 bytes of buffer if PID_SETUP is used.
+ */
+void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
+    bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
+    td_t *next)
+{
+	assert(instance);
+	assert(size < 1024);
+	assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN)
+	    || (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_pa ? next_pa : LINK_POINTER_TERMINATE_FLAG);
+
+	instance->status = 0
+	    | ((err_count & TD_STATUS_ERROR_COUNT_MASK)
+	        << TD_STATUS_ERROR_COUNT_POS)
+	    | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
+	    | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0)
+	    | TD_STATUS_ERROR_ACTIVE;
+
+	if (pid == USB_PID_IN && !iso) {
+		instance->status |= TD_STATUS_SPD_FLAG;
+	}
+
+	instance->device = 0
+	    | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
+	    | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
+	    | ((target.address & TD_DEVICE_ADDRESS_MASK)
+	        << TD_DEVICE_ADDRESS_POS)
+	    | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK)
+	        << TD_DEVICE_ENDPOINT_POS)
+	    | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
+
+	instance->buffer_ptr = addr_to_phys(buffer);
+
+	usb_log_debug2("Created TD(%p): %X:%X:%X:%X(%p).\n",
+	    instance, instance->next, instance->status, instance->device,
+	    instance->buffer_ptr, buffer);
+	td_print_status(instance);
+	if (pid == USB_PID_SETUP) {
+		usb_log_debug2("SETUP BUFFER: %s\n",
+		    usb_debug_str_buffer(buffer, 8, 8));
+	}
+}
+/*----------------------------------------------------------------------------*/
+/** Convert TD status into standard error code
+ *
+ * @param[in] instance TD structure to use.
+ * @return Error code.
+ */
+int td_status(td_t *instance)
+{
+	assert(instance);
+
+	/* 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;
+
+	/* HC does not end transactions 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;
+
+	/* Stall might represent err count reaching zero or stall response from
+	 * the device. If err count reached zero, one of the above is reported*/
+	if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
+		return ESTALL;
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Print values in status field (dw1) in a human readable way.
+ *
+ * @param[in] instance TD structure to use.
+ */
+void td_print_status(td_t *instance)
+{
+	assert(instance);
+	const uint32_t s = instance->status;
+	usb_log_debug2("TD(%p) status(%#" PRIx32 "):%s %d,%s%s%s%s%s%s%s%s%s%s%s %zu.\n",
+	    instance, instance->status,
+	    (s & TD_STATUS_SPD_FLAG) ? " SPD," : "",
+	    (s >> TD_STATUS_ERROR_COUNT_POS) & TD_STATUS_ERROR_COUNT_MASK,
+	    (s & TD_STATUS_LOW_SPEED_FLAG) ? " LOW SPEED," : "",
+	    (s & TD_STATUS_ISOCHRONOUS_FLAG) ? " ISOCHRONOUS," : "",
+	    (s & TD_STATUS_IOC_FLAG) ? " IOC," : "",
+	    (s & TD_STATUS_ERROR_ACTIVE) ? " ACTIVE," : "",
+	    (s & TD_STATUS_ERROR_STALLED) ? " STALLED," : "",
+	    (s & TD_STATUS_ERROR_BUFFER) ? " BUFFER," : "",
+	    (s & TD_STATUS_ERROR_BABBLE) ? " BABBLE," : "",
+	    (s & TD_STATUS_ERROR_NAK) ? " NAK," : "",
+	    (s & TD_STATUS_ERROR_CRC) ? " CRC/TIMEOUT," : "",
+	    (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "",
+	    (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "",
+	    td_act_size(instance)
+	);
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/hw_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/uhci/hw_struct/transfer_descriptor.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/hw_struct/transfer_descriptor.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,166 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
+#define DRV_UHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
+
+#include <mem.h>
+#include <usb/usb.h>
+
+#include "link_pointer.h"
+
+/** Transfer Descriptor, defined in UHCI design guide p. 26 */
+typedef struct transfer_descriptor {
+	/** Pointer to the next entity (TD or QH) */
+	link_pointer_t next;
+
+	/** Status doubleword */
+	volatile uint32_t status;
+#define TD_STATUS_RESERVED_MASK 0xc000f800
+#define TD_STATUS_SPD_FLAG         (1 << 29)
+#define TD_STATUS_ERROR_COUNT_POS 27
+#define TD_STATUS_ERROR_COUNT_MASK 0x3
+#define TD_STATUS_LOW_SPEED_FLAG   (1 << 26)
+#define TD_STATUS_ISOCHRONOUS_FLAG (1 << 25)
+#define TD_STATUS_IOC_FLAG         (1 << 24)
+
+#define TD_STATUS_ERROR_ACTIVE    (1 << 23)
+#define TD_STATUS_ERROR_STALLED   (1 << 22)
+#define TD_STATUS_ERROR_BUFFER    (1 << 21)
+#define TD_STATUS_ERROR_BABBLE    (1 << 20)
+#define TD_STATUS_ERROR_NAK       (1 << 19)
+#define TD_STATUS_ERROR_CRC       (1 << 18)
+#define TD_STATUS_ERROR_BIT_STUFF (1 << 17)
+#define TD_STATUS_ERROR_RESERVED  (1 << 16)
+#define TD_STATUS_ERROR_POS 16
+#define TD_STATUS_ERROR_MASK 0xff
+
+#define TD_STATUS_ACTLEN_POS 0
+#define TD_STATUS_ACTLEN_MASK 0x7ff
+
+	/* double word with USB device specific info */
+	volatile uint32_t device;
+#define TD_DEVICE_MAXLEN_POS 21
+#define TD_DEVICE_MAXLEN_MASK 0x7ff
+#define TD_DEVICE_RESERVED_FLAG        (1 << 20)
+#define TD_DEVICE_DATA_TOGGLE_ONE_FLAG (1 << 19)
+#define TD_DEVICE_ENDPOINT_POS 15
+#define TD_DEVICE_ENDPOINT_MASK 0xf
+#define TD_DEVICE_ADDRESS_POS 8
+#define TD_DEVICE_ADDRESS_MASK 0x7f
+#define TD_DEVICE_PID_POS 0
+#define TD_DEVICE_PID_MASK 0xff
+
+	/** Pointer(physical) to the beginning of the transaction's buffer */
+	volatile uint32_t buffer_ptr;
+
+	/* According to UHCI design guide, there is 16 bytes of
+	 * data available here.
+	 * According to linux kernel the hardware does not care,
+	 * it just needs to be aligned. We don't use it anyway.
+	 */
+} __attribute__((packed)) td_t;
+
+
+void td_init(td_t *instance, int error_count, size_t size, bool toggle,
+    bool iso, bool low_speed, usb_target_t target, usb_packet_id pid,
+    void *buffer, td_t *next);
+
+int td_status(td_t *instance);
+
+void td_print_status(td_t *instance);
+/*----------------------------------------------------------------------------*/
+/** Helper function for parsing actual size out of TD.
+ *
+ * @param[in] instance TD structure to use.
+ * @return Parsed actual size.
+ */
+static inline size_t td_act_size(td_t *instance)
+{
+	assert(instance);
+	const uint32_t s = instance->status;
+	return ((s >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK;
+}
+/*----------------------------------------------------------------------------*/
+/** Check whether less than max data were received on SPD marked transfer.
+ *
+ * @param[in] instance TD structure to use.
+ * @return True if data packet is short (less than max bytes and SPD set),
+ * false otherwise.
+ */
+static inline bool td_is_short(td_t *instance)
+{
+	const size_t act_size = td_act_size(instance);
+	const size_t max_size =
+	    ((instance->device >> TD_DEVICE_MAXLEN_POS) + 1)
+	    & TD_DEVICE_MAXLEN_MASK;
+	return
+	    (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size;
+}
+/*----------------------------------------------------------------------------*/
+/** Helper function for parsing value of toggle bit.
+ *
+ * @param[in] instance TD structure to use.
+ * @return Toggle bit value.
+ */
+static inline int td_toggle(td_t *instance)
+{
+	assert(instance);
+	return (instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) ? 1 : 0;
+}
+/*----------------------------------------------------------------------------*/
+/** Helper function for parsing value of active bit
+ *
+ * @param[in] instance TD structure to use.
+ * @return Active bit value.
+ */
+static inline bool td_is_active(td_t *instance)
+{
+	assert(instance);
+	return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0;
+}
+/*----------------------------------------------------------------------------*/
+/** Helper function for setting IOC bit.
+ *
+ * @param[in] instance TD structure to use.
+ */
+static inline void td_set_ioc(td_t *instance)
+{
+	assert(instance);
+	instance->status |= TD_STATUS_IOC_FLAG;
+}
+/*----------------------------------------------------------------------------*/
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/iface.c
===================================================================
--- uspace/drv/uhci/iface.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/iface.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,405 @@
+/*
+ * 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: uspace/drv/uhci/iface.h
===================================================================
--- uspace/drv/uhci/iface.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/iface.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,45 @@
+/*
+ * 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/uhci/main.c
===================================================================
--- uspace/drv/uhci/main.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/main.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,94 @@
+/*
+ * 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 initialization
+ */
+#include <ddf/driver.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb/ddfiface.h>
+#include <usb/debug.h>
+
+#include "uhci.h"
+
+#define NAME "uhci"
+
+static int uhci_add_device(ddf_dev_t *device);
+/*----------------------------------------------------------------------------*/
+static driver_ops_t uhci_driver_ops = {
+	.add_device = uhci_add_device,
+};
+/*----------------------------------------------------------------------------*/
+static driver_t uhci_driver = {
+	.name = NAME,
+	.driver_ops = &uhci_driver_ops
+};
+/*----------------------------------------------------------------------------*/
+/** Initialize a new ddf driver instance for uhci hc and hub.
+ *
+ * @param[in] device DDF instance of the device to initialize.
+ * @return Error code.
+ */
+int uhci_add_device(ddf_dev_t *device)
+{
+	usb_log_debug2("uhci_add_device() called\n");
+	assert(device);
+
+	int ret = device_setup_uhci(device);
+	if (ret != EOK) {
+		usb_log_error("Failed to initialize UHCI driver: %s.\n",
+		    str_error(ret));
+		return ret;
+	}
+	usb_log_info("Controlling new UHCI device '%s'.\n", device->name);
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Initialize global driver structures (NONE).
+ *
+ * @param[in] argc Number of arguments in argv vector (ignored).
+ * @param[in] argv Cmdline argument vector (ignored).
+ * @return Error code.
+ *
+ * Driver debug level is set here.
+ */
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS UHCI driver.\n");
+	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+
+	return ddf_driver_main(&uhci_driver);
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/pci.c
===================================================================
--- uspace/drv/uhci/pci.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/pci.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011 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
+ * PCI related functions needed by the UHCI driver.
+ */
+
+#include <errno.h>
+#include <assert.h>
+#include <devman.h>
+#include <device/hw_res.h>
+
+#include <usb/debug.h>
+#include <pci_dev_iface.h>
+
+#include "pci.h"
+
+/** Get I/O address of registers and IRQ for given device.
+ *
+ * @param[in] dev Device asking for the addresses.
+ * @param[out] io_reg_address Base address of the I/O range.
+ * @param[out] io_reg_size Size of the I/O range.
+ * @param[out] irq_no IRQ assigned to the device.
+ * @return Error code.
+ */
+int pci_get_my_registers(const ddf_dev_t *dev,
+    uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
+{
+	assert(dev);
+	assert(io_reg_address);
+	assert(io_reg_size);
+	assert(irq_no);
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	hw_resource_list_t hw_resources;
+	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
+	if (rc != EOK) {
+		async_hangup(parent_sess);
+		return rc;
+	}
+	
+	uintptr_t io_address = 0;
+	size_t io_size = 0;
+	bool io_found = false;
+	
+	int irq = 0;
+	bool irq_found = false;
+	
+	size_t i;
+	for (i = 0; i < hw_resources.count; i++) {
+		const hw_resource_t *res = &hw_resources.resources[i];
+		switch (res->type) {
+		case INTERRUPT:
+			irq = res->res.interrupt.irq;
+			irq_found = true;
+			usb_log_debug2("Found interrupt: %d.\n", irq);
+			break;
+		case IO_RANGE:
+			io_address = res->res.io_range.address;
+			io_size = res->res.io_range.size;
+			usb_log_debug2("Found io: %" PRIx64" %zu.\n",
+			    res->res.io_range.address, res->res.io_range.size);
+			io_found = true;
+			break;
+		default:
+			break;
+		}
+	}
+	
+	async_hangup(parent_sess);
+	
+	if (!io_found || !irq_found)
+		return ENOENT;
+	
+	*io_reg_address = io_address;
+	*io_reg_size = io_size;
+	*irq_no = irq;
+	
+	return EOK;
+}
+
+/** Call the PCI driver with a request to enable interrupts
+ *
+ * @param[in] device Device asking for interrupts
+ * @return Error code.
+ */
+int pci_enable_interrupts(const ddf_dev_t *device)
+{
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	const bool enabled = hw_res_enable_interrupt(parent_sess);
+	async_hangup(parent_sess);
+	
+	return enabled ? EOK : EIO;
+}
+
+/** Call the PCI driver with a request to clear legacy support register
+ *
+ * @param[in] device Device asking to disable interrupts
+ * @return Error code.
+ */
+int pci_disable_legacy(const ddf_dev_t *device)
+{
+	assert(device);
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
+	    IPC_FLAG_BLOCKING);
+	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/uhci/pci.h
===================================================================
--- uspace/drv/uhci/pci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/pci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,48 @@
+/*
+ * 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 PCI helper functions
+ */
+#ifndef DRV_UHCI_PCI_H
+#define DRV_UHCI_PCI_H
+
+#include <ddf/driver.h>
+
+int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
+int pci_enable_interrupts(const ddf_dev_t *);
+int pci_disable_legacy(const ddf_dev_t *);
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/drv/uhci/root_hub.c
===================================================================
--- uspace/drv/uhci/root_hub.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/root_hub.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,85 @@
+/*
+ * 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 drvusbuhci
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#include <assert.h>
+#include <errno.h>
+#include <str_error.h>
+#include <stdio.h>
+
+#include <usb/debug.h>
+
+#include "root_hub.h"
+
+/** Root hub initialization
+ * @param[in] instance RH structure to initialize
+ * @param[in] fun DDF function representing UHCI root hub
+ * @param[in] reg_addr Address of root hub status and control registers.
+ * @param[in] reg_size Size of accessible address space.
+ * @return Error code.
+ */
+int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
+{
+	assert(fun);
+
+	char *match_str = NULL;
+	int ret = asprintf(&match_str, "usb&uhci&root-hub");
+	if (ret < 0) {
+		usb_log_error(
+		    "Failed(%d) to create root hub match string: %s.\n",
+		    ret, str_error(ret));
+		return ret;
+	}
+	assert(match_str);
+
+	ret = ddf_fun_add_match_id(fun, match_str, 100);
+	if (ret != EOK) {
+		free(match_str);
+		usb_log_error("Failed(%d) to add root hub match id: %s\n",
+		    ret, str_error(ret));
+		return ret;
+	}
+
+	/* Initialize resource structure */
+	instance->resource_list.count = 1;
+	instance->resource_list.resources = &instance->io_regs;
+
+	instance->io_regs.type = IO_RANGE;
+	instance->io_regs.res.io_range.address = reg_addr;
+	instance->io_regs.res.io_range.size = reg_size;
+	instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN;
+
+	return EOK;
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/root_hub.h
===================================================================
--- uspace/drv/uhci/root_hub.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/root_hub.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,55 @@
+/*
+ * 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 drvusbuhci
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_RH_H
+#define DRV_UHCI_RH_H
+
+#include <ddf/driver.h>
+#include <ops/hw_res.h>
+
+/** DDF support structure for uhci_rhd driver, provides I/O resources */
+typedef struct rh {
+	/** List of resources available to the root hub. */
+	hw_resource_list_t resource_list;
+	/** The only resource in the RH resource list */
+	hw_resource_t io_regs;
+} rh_t;
+
+int rh_init(
+    rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/transfer_list.c
===================================================================
--- uspace/drv/uhci/transfer_list.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/transfer_list.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,241 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver transfer list implementation
+ */
+#include <errno.h>
+#include <usb/debug.h>
+#include <arch/barrier.h>
+
+
+#include "transfer_list.h"
+#include "batch.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->queue_head = malloc32(sizeof(qh_t));
+	if (!instance->queue_head) {
+		usb_log_error("Failed to allocate queue head.\n");
+		return ENOMEM;
+	}
+	const uint32_t queue_head_pa = addr_to_phys(instance->queue_head);
+	usb_log_debug2("Transfer list %s setup with QH: %p (%#" PRIx32" ).\n",
+	    name, instance->queue_head, queue_head_pa);
+
+	qh_init(instance->queue_head);
+	list_initialize(&instance->batch_list);
+	fibril_mutex_initialize(&instance->guard);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Dispose transfer list structures.
+ *
+ * @param[in] instance Memory place to use.
+ *
+ * Frees memory of the internal qh_t structure.
+ */
+void transfer_list_fini(transfer_list_t *instance)
+{
+	assert(instance);
+	free32(instance->queue_head);
+}
+/** 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(instance->queue_head);
+	assert(next);
+	/* Set queue_head.next to point to the follower */
+	qh_set_next_qh(instance->queue_head, next->queue_head);
+}
+/*----------------------------------------------------------------------------*/
+/** Add transfer batch to the list and queue.
+ *
+ * @param[in] instance List to use.
+ * @param[in] batch Transfer batch to submit.
+ *
+ * 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);
+
+	qh_t *last_qh = NULL;
+	/* Add to the hardware queue. */
+	if (list_empty(&instance->batch_list)) {
+		/* There is nothing scheduled */
+		last_qh = instance->queue_head;
+	} else {
+		/* There is something scheduled */
+		usb_transfer_batch_t *last =
+		    usb_transfer_batch_from_link(instance->batch_list.prev);
+		last_qh = batch_qh(last);
+	}
+	const uint32_t pa = addr_to_phys(batch_qh(batch));
+	assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
+
+	/* Make sure all data in the batch are written */
+	write_barrier();
+
+	/* keep link */
+	batch_qh(batch)->next = last_qh->next;
+	qh_set_next_qh(last_qh, batch_qh(batch));
+
+	/* Make sure the pointer is updated */
+	write_barrier();
+
+	/* Add to the driver's list */
+	list_append(&batch->link, &instance->batch_list);
+
+	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
+	    batch, USB_TRANSFER_BATCH_ARGS(*batch), instance->name);
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+/** Add completed bantches to the provided list.
+ *
+ * @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);
+	link_t *current = instance->batch_list.next;
+	while (current != &instance->batch_list) {
+		link_t * const next = current->next;
+		usb_transfer_batch_t *batch =
+		    usb_transfer_batch_from_link(current);
+
+		if (batch_is_complete(batch)) {
+			/* Save for processing */
+			transfer_list_remove_batch(instance, batch);
+			list_append(current, done);
+		}
+		current = next;
+	}
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+/** Walk the list and finish all batches with EINTR.
+ *
+ * @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 * const current = instance->batch_list.next;
+		usb_transfer_batch_t *batch =
+		    usb_transfer_batch_from_link(current);
+		transfer_list_remove_batch(instance, batch);
+		usb_transfer_batch_finish_error(batch, EINTR);
+	}
+	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.
+ *
+ * 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->queue_head);
+	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 *qpos = NULL;
+	qh_t *prev_qh = NULL;
+	/* Remove from the hardware queue */
+	if (instance->batch_list.next == &batch->link) {
+		/* I'm the first one here */
+		prev_qh = instance->queue_head;
+		qpos = "FIRST";
+	} else {
+		/* The thing before me is a batch too */
+		usb_transfer_batch_t *prev =
+		    usb_transfer_batch_from_link(batch->link.prev);
+		prev_qh = batch_qh(prev);
+		qpos = "NOT FIRST";
+	}
+	assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK)
+	    == addr_to_phys(batch_qh(batch)));
+	prev_qh->next = batch_qh(batch)->next;
+
+	/* Make sure the pointer is updated */
+	write_barrier();
+
+	/* Remove from the batch list */
+	list_remove(&batch->link);
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " removed (%s) "
+	    "from %s, next: %x.\n",
+	    batch, USB_TRANSFER_BATCH_ARGS(*batch),
+	    qpos, instance->name, batch_qh(batch)->next);
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/transfer_list.h
===================================================================
--- uspace/drv/uhci/transfer_list.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/transfer_list.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,66 @@
+/*
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI driver transfer list structure
+ */
+#ifndef DRV_UHCI_TRANSFER_LIST_H
+#define DRV_UHCI_TRANSFER_LIST_H
+
+#include <fibril_synch.h>
+#include <usb/host/batch.h>
+
+#include "hw_struct/queue_head.h"
+
+/** Structure maintaining both hw queue and software list
+ * of currently executed transfers
+ */
+typedef struct transfer_list {
+	/** Guard against multiple add/remove races */
+	fibril_mutex_t guard;
+	/** UHCI hw structure represeting this queue */
+	qh_t *queue_head;
+	/** Assigned name, for nicer debug output */
+	const char *name;
+	/** List of all batches in this list */
+	link_t batch_list;
+} transfer_list_t;
+
+void transfer_list_fini(transfer_list_t *instance);
+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
+/**
+ * @}
+ */
Index: uspace/drv/uhci/uhci.c
===================================================================
--- uspace/drv/uhci/uhci.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/uhci.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,286 @@
+/*
+ * 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 drvusbuhci
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#include <errno.h>
+#include <str_error.h>
+#include <ddf/interrupt.h>
+#include <usb_iface.h>
+#include <usb/ddfiface.h>
+#include <usb/debug.h>
+
+#include "uhci.h"
+#include "iface.h"
+#include "pci.h"
+
+#include "hc.h"
+#include "root_hub.h"
+
+/** Structure representing both functions of UHCI hc, USB host controller
+ * and USB root hub */
+typedef struct uhci {
+	/** Pointer to DDF represenation of UHCI host controller */
+	ddf_fun_t *hc_fun;
+	/** Pointer to DDF represenation of UHCI root hub */
+	ddf_fun_t *rh_fun;
+
+	/** Internal driver's represenation of UHCI host controller */
+	hc_t hc;
+	/** Internal driver's represenation of UHCI root hub */
+	rh_t rh;
+} uhci_t;
+
+static inline uhci_t * dev_to_uhci(const ddf_dev_t *dev)
+{
+	assert(dev);
+	assert(dev->driver_data);
+	return dev->driver_data;
+}
+/*----------------------------------------------------------------------------*/
+/** IRQ handling callback, forward status from call to diver structure.
+ *
+ * @param[in] dev DDF instance of the device to use.
+ * @param[in] iid (Unused).
+ * @param[in] call Pointer to the call from kernel.
+ */
+static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
+{
+	assert(dev);
+	uhci_t *uhci = dev_to_uhci(dev);
+	hc_t *hc = &uhci->hc;
+	const uint16_t status = IPC_GET_ARG1(*call);
+	assert(hc);
+	hc_interrupt(hc, status);
+}
+/*----------------------------------------------------------------------------*/
+/** Operations supported by the HC driver */
+static ddf_dev_ops_t hc_ops = {
+	.interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
+};
+/*----------------------------------------------------------------------------*/
+/** Get address of the device identified by handle.
+ *
+ * @param[in] fun DDF instance of the function to use.
+ * @param[in] handle DDF handle of the driver seeking its USB address.
+ * @param[out] address Found address.
+ */
+static int usb_iface_get_address(
+    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
+{
+	assert(fun);
+	usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
+	usb_address_t addr = usb_device_keeper_find(manager, handle);
+
+	if (addr < 0) {
+		return addr;
+	}
+
+	if (address != NULL) {
+		*address = addr;
+	}
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Gets handle of the respective hc.
+ *
+ * @param[in] fun DDF function of uhci device.
+ * @param[out] handle Host cotnroller handle.
+ * @return Error code.
+ */
+static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
+{
+	assert(fun);
+	ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
+	assert(hc_fun);
+
+	if (handle != NULL)
+		*handle = hc_fun->handle;
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** USB interface implementation used by RH */
+static usb_iface_t usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle,
+	.get_address = usb_iface_get_address
+};
+/*----------------------------------------------------------------------------*/
+/** Get root hub hw resources (I/O registers).
+ *
+ * @param[in] fun Root hub function.
+ * @return Pointer to the resource list used by the root hub.
+ */
+static hw_resource_list_t *get_resource_list(ddf_fun_t *fun)
+{
+	assert(fun);
+	rh_t *rh = fun->driver_data;
+	assert(rh);
+	return &rh->resource_list;
+}
+/*----------------------------------------------------------------------------*/
+/** Interface to provide the root hub driver with hw info */
+static hw_res_ops_t hw_res_iface = {
+	.get_resource_list = get_resource_list,
+	.enable_interrupt = NULL,
+};
+/*----------------------------------------------------------------------------*/
+/** RH function support for uhci_rhd */
+static ddf_dev_ops_t rh_ops = {
+	.interfaces[USB_DEV_IFACE] = &usb_iface,
+	.interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
+};
+/*----------------------------------------------------------------------------*/
+/** Initialize hc and rh DDF structures and their respective drivers.
+ *
+ * @param[in] device DDF instance of the device to use.
+ *
+ * This function does all the preparatory work for hc and rh drivers:
+ *  - gets device's hw resources
+ *  - disables UHCI legacy support (PCI config space)
+ *  - attempts to enable interrupts
+ *  - registers interrupt handler
+ */
+int device_setup_uhci(ddf_dev_t *device)
+{
+	assert(device);
+	uhci_t *instance = malloc(sizeof(uhci_t));
+	if (instance == NULL) {
+		usb_log_error("Failed to allocate OHCI driver.\n");
+		return ENOMEM;
+	}
+
+#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
+if (ret != EOK) { \
+	if (instance->hc_fun) \
+		instance->hc_fun->ops = NULL; \
+		instance->hc_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->hc_fun); \
+	if (instance->rh_fun) {\
+		instance->rh_fun->ops = NULL; \
+		instance->rh_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->rh_fun); \
+	} \
+	free(instance); \
+	usb_log_error(message); \
+	return ret; \
+} else (void)0
+
+	instance->rh_fun = NULL;
+	instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc");
+	int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
+	instance->hc_fun->ops = &hc_ops;
+	instance->hc_fun->driver_data = &instance->hc;
+
+	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
+	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
+	instance->rh_fun->ops = &rh_ops;
+	instance->rh_fun->driver_data = &instance->rh;
+
+	uintptr_t reg_base = 0;
+	size_t reg_size = 0;
+	int irq = 0;
+
+	ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	CHECK_RET_DEST_FREE_RETURN(ret,
+	    "Failed to get I/O addresses for %" PRIun ": %s.\n",
+	    device->handle, str_error(ret));
+	usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
+	    (void *) reg_base, reg_size, irq);
+
+	ret = pci_disable_legacy(device);
+	CHECK_RET_DEST_FREE_RETURN(ret,
+	    "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
+
+	bool interrupts = false;
+#ifdef CONFIG_USBHC_NO_INTERRUPTS
+	usb_log_warning("Interrupts disabled in OS config, " \
+	    "falling back to polling.\n");
+#else
+	ret = pci_enable_interrupts(device);
+	if (ret != EOK) {
+		usb_log_warning("Failed to enable interrupts: %s.\n",
+		    str_error(ret));
+		usb_log_info("HW interrupts not available, " \
+		    "falling back to polling.\n");
+	} else {
+		usb_log_debug("Hw interrupts enabled.\n");
+		interrupts = true;
+	}
+#endif
+
+
+	ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
+	CHECK_RET_DEST_FREE_RETURN(ret,
+	    "Failed(%d) to init uhci_hcd: %s.\n", ret, str_error(ret));
+
+#define CHECK_RET_FINI_RETURN(ret, message...) \
+if (ret != EOK) { \
+	hc_fini(&instance->hc); \
+	CHECK_RET_DEST_FREE_RETURN(ret, message); \
+	return ret; \
+} else (void)0
+
+	/* It does no harm if we register this on polling */
+	ret = register_interrupt_handler(device, irq, irq_handler,
+	    &instance->hc.interrupt_code);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed(%d) to register interrupt handler: %s.\n",
+	    ret, str_error(ret));
+
+	ret = ddf_fun_bind(instance->hc_fun);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed(%d) to bind UHCI device function: %s.\n",
+	    ret, str_error(ret));
+
+	ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed to add UHCI to HC class: %s.\n", str_error(ret));
+
+	ret = rh_init(&instance->rh, instance->rh_fun,
+	    (uintptr_t)instance->hc.registers + 0x10, 4);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
+
+	ret = ddf_fun_bind(instance->rh_fun);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
+
+	device->driver_data = instance;
+	return EOK;
+#undef CHECK_RET_FINI_RETURN
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhci/uhci.h
===================================================================
--- uspace/drv/uhci/uhci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/uhci.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,43 @@
+/*
+ * 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 drvusbuhci
+ * @{
+ */
+/** @file
+ * @brief UHCI driver main structure for both host controller and root-hub.
+ */
+#ifndef DRV_UHCI_UHCI_H
+#define DRV_UHCI_UHCI_H
+#include <ddf/driver.h>
+
+int device_setup_uhci(ddf_dev_t *device);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/uhci.ma
===================================================================
--- uspace/drv/uhci/uhci.ma	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/uhci.ma	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,29 @@
+10 pci/ven=8086&dev=7020
+10 pci/ven=8086&dev=7112
+
+10 pci/ven=8086&dev=27c8
+10 pci/ven=8086&dev=27c9
+10 pci/ven=8086&dev=27ca
+10 pci/ven=8086&dev=27cb
+
+10 pci/ven=8086&dev=2830
+10 pci/ven=8086&dev=2831
+10 pci/ven=8086&dev=2832
+10 pci/ven=8086&dev=2834
+10 pci/ven=8086&dev=2835
+
+10 pci/ven=8086&dev=2934
+10 pci/ven=8086&dev=2935
+10 pci/ven=8086&dev=2936
+10 pci/ven=8086&dev=2937
+10 pci/ven=8086&dev=2938
+10 pci/ven=8086&dev=2939
+
+10 pci/ven=8086&dev=24c2
+10 pci/ven=8086&dev=24c4
+10 pci/ven=8086&dev=24c7
+
+10 pci/ven=8086&dev=2688
+10 pci/ven=8086&dev=2689
+10 pci/ven=8086&dev=268a
+10 pci/ven=8086&dev=268b
Index: uspace/drv/uhci/utils/malloc32.h
===================================================================
--- uspace/drv/uhci/utils/malloc32.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhci/utils/malloc32.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2010 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 drvusbuhci
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_UTILS_MALLOC32_H
+#define DRV_UHCI_UTILS_MALLOC32_H
+
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <as.h>
+
+#define UHCI_STRCUTURES_ALIGNMENT 16
+#define UHCI_REQUIRED_PAGE_SIZE 4096
+
+
+/** Get physical address translation
+ *
+ * @param[in] addr Virtual address to translate
+ * @return Physical address if exists, NULL otherwise.
+ */
+static inline uintptr_t addr_to_phys(void *addr)
+{
+	if (addr == NULL)
+		return 0;
+
+	uintptr_t result;
+	const int ret = as_get_physical_mapping(addr, &result);
+	if (ret != EOK)
+		return 0;
+	return (result | ((uintptr_t)addr & 0xfff));
+}
+/*----------------------------------------------------------------------------*/
+/** Physical mallocator simulator
+ *
+ * @param[in] size Size of the required memory space
+ * @return Address of the alligned and big enough memory place, NULL on failure.
+ */
+static inline void * malloc32(size_t size) {
+	/* This works only when the host has less than 4GB of memory as
+	 * physical address needs to fit into 32 bits */
+
+	/* If we need more than one page there is no guarantee that the
+	 * memory will be continuous */
+	if (size > PAGE_SIZE)
+		return NULL;
+	/* Calculate alignment to make sure the block won't cross page
+	 * boundary */
+	size_t alignment = UHCI_STRCUTURES_ALIGNMENT;
+	while (alignment < size)
+		alignment *= 2;
+	return memalign(alignment, size);
+}
+/*----------------------------------------------------------------------------*/
+/** Physical mallocator simulator
+ *
+ * @param[in] addr Address of the place allocated by malloc32
+ */
+static inline void free32(void *addr) {
+	if (!addr)
+		return;
+	free(addr);
+}
+/*----------------------------------------------------------------------------*/
+/** Create 4KB page mapping
+ *
+ * @return Address of the mapped page, NULL on failure.
+ */
+static inline void * get_page(void)
+{
+	void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
+	if (free_address == 0)
+		return NULL;
+	void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
+		  AS_AREA_READ | AS_AREA_WRITE);
+	if (ret != free_address)
+		return NULL;
+	return ret;
+}
+
+#endif
+/**
+ * @}
+ */
Index: pace/drv/uhci_hcd/Makefile
===================================================================
--- uspace/drv/uhci_hcd/Makefile	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,53 +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.
-#
-
-USPACE_PREFIX = ../..
-
-LIBS = \
-	$(LIBUSBHOST_PREFIX)/libusbhost.a \
-	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS += \
-	-I$(LIBUSB_PREFIX)/include \
-	-I$(LIBUSBHOST_PREFIX)/include \
-	-I$(LIBDRV_PREFIX)/include
-
-BINARY = uhci_hcd
-
-SOURCES = \
-	iface.c \
-	main.c \
-	transfer_list.c \
-	uhci.c \
-	hc.c \
-	root_hub.c \
-	hw_struct/transfer_descriptor.c \
-	pci.c \
-	batch.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/drv/uhci_hcd/batch.c
===================================================================
--- uspace/drv/uhci_hcd/batch.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,428 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver USB transfer structure
- */
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb/usb.h>
-#include <usb/debug.h>
-
-#include "batch.h"
-#include "transfer_list.h"
-#include "hw_struct/transfer_descriptor.h"
-#include "utils/malloc32.h"
-
-#define DEFAULT_ERROR_COUNT 3
-
-/** UHCI specific data required for USB transfer */
-typedef struct uhci_transfer_batch {
-	/** Queue head
-	 * This QH is used to maintain UHCI schedule structure and the element
-	 * pointer points to the first TD of this batch.
-	 */
-	qh_t *qh;
-	/** List of TDs needed for the transfer */
-	td_t *tds;
-	/** Number of TDs used by the transfer */
-	size_t td_count;
-	/** Data buffer, must be accessible by the UHCI hw */
-	void *device_buffer;
-} uhci_transfer_batch_t;
-/*----------------------------------------------------------------------------*/
-static void batch_control(usb_transfer_batch_t *instance,
-    usb_packet_id data_stage, usb_packet_id status_stage);
-static void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid);
-/*----------------------------------------------------------------------------*/
-/** Safely destructs uhci_transfer_batch_t structure
- *
- * @param[in] uhci_batch Instance to destroy.
- */
-static void uhci_transfer_batch_dispose(void *uhci_batch)
-{
-	uhci_transfer_batch_t *instance = uhci_batch;
-	assert(instance);
-	free32(instance->device_buffer);
-	free(instance);
-}
-/*----------------------------------------------------------------------------*/
-/** 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.
- *
- * @param[in] instance Batch structure to use.
- * @return False, if there is an active TD, true otherwise.
- *
- * Walk all TDs. Stop with false if there is an active one (it is to be
- * processed). Stop with true if an error is found. Return true if the last TD
- * is reached.
- */
-bool batch_is_complete(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	uhci_transfer_batch_t *data = instance->private_data;
-	assert(data);
-
-	usb_log_debug2("Batch(%p) checking %zu transfer(s) for completion.\n",
-	    instance, data->td_count);
-	instance->transfered_size = 0;
-	size_t i = 0;
-	for (;i < data->td_count; ++i) {
-		if (td_is_active(&data->tds[i])) {
-			return false;
-		}
-
-		instance->error = td_status(&data->tds[i]);
-		if (instance->error != EOK) {
-			usb_log_debug("Batch(%p) found error TD(%zu):%"
-			    PRIx32 ".\n", instance, i, data->tds[i].status);
-			td_print_status(&data->tds[i]);
-
-			assert(instance->ep != NULL);
-			endpoint_toggle_set(instance->ep,
-			    td_toggle(&data->tds[i]));
-			if (i > 0)
-				goto substract_ret;
-			return true;
-		}
-
-		instance->transfered_size += td_act_size(&data->tds[i]);
-		if (td_is_short(&data->tds[i]))
-			goto substract_ret;
-	}
-substract_ret:
-	instance->transfered_size -= instance->setup_size;
-	return true;
-}
-
-#define LOG_BATCH_INITIALIZED(batch, name) \
-	usb_log_debug2("Batch %p %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
-	    (batch), (name), USB_TRANSFER_BATCH_ARGS(*(batch)))
-
-/*----------------------------------------------------------------------------*/
-/** Prepares control write transfer.
- *
- * @param[in] instance Batch structure to use.
- *
- * Uses generic control function with pids OUT and IN.
- */
-void batch_control_write(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	/* We are data out, we are supposed to provide data */
-	memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
-	batch_control(instance, USB_PID_OUT, USB_PID_IN);
-	instance->next_step = usb_transfer_batch_call_out_and_dispose;
-	LOG_BATCH_INITIALIZED(instance, "control write");
-}
-/*----------------------------------------------------------------------------*/
-/** Prepares control read transfer.
- *
- * @param[in] instance Batch structure to use.
- *
- * Uses generic control with pids IN and OUT.
- */
-void batch_control_read(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	batch_control(instance, USB_PID_IN, USB_PID_OUT);
-	instance->next_step = usb_transfer_batch_call_in_and_dispose;
-	LOG_BATCH_INITIALIZED(instance, "control read");
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare interrupt in transfer.
- *
- * @param[in] instance Batch structure to use.
- *
- * Data transfer with PID_IN.
- */
-void batch_interrupt_in(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	batch_data(instance, USB_PID_IN);
-	instance->next_step = usb_transfer_batch_call_in_and_dispose;
-	LOG_BATCH_INITIALIZED(instance, "interrupt in");
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare interrupt out transfer.
- *
- * @param[in] instance Batch structure to use.
- *
- * Data transfer with PID_OUT.
- */
-void batch_interrupt_out(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	/* We are data out, we are supposed to provide data */
-	memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
-	batch_data(instance, USB_PID_OUT);
-	instance->next_step = usb_transfer_batch_call_out_and_dispose;
-	LOG_BATCH_INITIALIZED(instance, "interrupt out");
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare bulk in transfer.
- *
- * @param[in] instance Batch structure to use.
- *
- * Data transfer with PID_IN.
- */
-void batch_bulk_in(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	batch_data(instance, USB_PID_IN);
-	instance->next_step = usb_transfer_batch_call_in_and_dispose;
-	LOG_BATCH_INITIALIZED(instance, "bulk in");
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare bulk out transfer.
- *
- * @param[in] instance Batch structure to use.
- *
- * Data transfer with PID_OUT.
- */
-void batch_bulk_out(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	/* We are data out, we are supposed to provide data */
-	memcpy(instance->data_buffer, instance->buffer, instance->buffer_size);
-	batch_data(instance, USB_PID_OUT);
-	instance->next_step = usb_transfer_batch_call_out_and_dispose;
-	LOG_BATCH_INITIALIZED(instance, "bulk out");
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare generic data transfer
- *
- * @param[in] instance Batch structure to use.
- * @param[in] pid Pid to use for data transactions.
- *
- * Transactions with alternating toggle bit and supplied pid value.
- * The last transfer is marked with IOC flag.
- */
-void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid)
-{
-	assert(instance);
-	uhci_transfer_batch_t *data = instance->private_data;
-	assert(data);
-
-	const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
-	int toggle = endpoint_toggle_get(instance->ep);
-	assert(toggle == 0 || toggle == 1);
-
-	size_t td = 0;
-	size_t remain_size = instance->buffer_size;
-	char *buffer = instance->data_buffer;
-	while (remain_size > 0) {
-		const size_t packet_size =
-		    (instance->ep->max_packet_size > remain_size) ?
-		    remain_size : instance->ep->max_packet_size;
-
-		td_t *next_td = (td + 1 < data->td_count)
-		    ? &data->tds[td + 1] : NULL;
-
-
-		usb_target_t target =
-		    { instance->ep->address, instance->ep->endpoint };
-
-		assert(td < data->td_count);
-		td_init(
-		    &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
-		    toggle, false, low_speed, target, pid, buffer, next_td);
-
-		++td;
-		toggle = 1 - toggle;
-		buffer += packet_size;
-		assert(packet_size <= remain_size);
-		remain_size -= packet_size;
-	}
-	td_set_ioc(&data->tds[td - 1]);
-	endpoint_toggle_set(instance->ep, toggle);
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare generic control transfer
- *
- * @param[in] instance Batch structure to use.
- * @param[in] data_stage Pid to use for data tds.
- * @param[in] status_stage Pid to use for data tds.
- *
- * Setup stage with toggle 0 and USB_PID_SETUP.
- * Data stage with alternating toggle and pid supplied by parameter.
- * Status stage with toggle 1 and pid supplied by parameter.
- * The last transfer is marked with IOC.
- */
-void batch_control(usb_transfer_batch_t *instance,
-   usb_packet_id data_stage, usb_packet_id status_stage)
-{
-	assert(instance);
-	uhci_transfer_batch_t *data = instance->private_data;
-	assert(data);
-	assert(data->td_count >= 2);
-
-	const bool low_speed = instance->ep->speed == USB_SPEED_LOW;
-	const usb_target_t target =
-	    { instance->ep->address, instance->ep->endpoint };
-
-	/* setup stage */
-	td_init(
-	    data->tds, DEFAULT_ERROR_COUNT, instance->setup_size, 0, false,
-	    low_speed, target, USB_PID_SETUP, instance->setup_buffer,
-	    &data->tds[1]);
-
-	/* data stage */
-	size_t td = 1;
-	unsigned toggle = 1;
-	size_t remain_size = instance->buffer_size;
-	char *buffer = instance->data_buffer;
-	while (remain_size > 0) {
-		const size_t packet_size =
-		    (instance->ep->max_packet_size > remain_size) ?
-		    remain_size : instance->ep->max_packet_size;
-
-		td_init(
-		    &data->tds[td], DEFAULT_ERROR_COUNT, packet_size,
-		    toggle, false, low_speed, target, data_stage,
-		    buffer, &data->tds[td + 1]);
-
-		++td;
-		toggle = 1 - toggle;
-		buffer += packet_size;
-		assert(td < data->td_count);
-		assert(packet_size <= remain_size);
-		remain_size -= packet_size;
-	}
-
-	/* status stage */
-	assert(td == data->td_count - 1);
-
-	td_init(
-	    &data->tds[td], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,
-	    target, status_stage, NULL, NULL);
-	td_set_ioc(&data->tds[td]);
-
-	usb_log_debug2("Control last TD status: %x.\n",
-	    data->tds[td].status);
-}
-/*----------------------------------------------------------------------------*/
-/** Provides access to QH data structure.
- *
- * @param[in] instance Batch pointer to use.
- * @return Pointer to the QH used by the batch.
- */
-qh_t * batch_qh(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	uhci_transfer_batch_t *data = instance->private_data;
-	assert(data);
-	return data->qh;
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/batch.h
===================================================================
--- uspace/drv/uhci_hcd/batch.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,65 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver USB tranfer helper functions
- */
-#ifndef DRV_UHCI_BATCH_H
-#define DRV_UHCI_BATCH_H
-
-#include <usb/host/batch.h>
-
-#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 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);
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/hc.c
===================================================================
--- uspace/drv/uhci_hcd/hc.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,474 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI Host controller driver routines
- */
-#include <errno.h>
-#include <str_error.h>
-#include <adt/list.h>
-#include <libarch/ddi.h>
-
-#include <usb/debug.h>
-#include <usb/usb.h>
-
-#include "hc.h"
-
-#define UHCI_INTR_ALLOW_INTERRUPTS \
-    (UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET)
-#define UHCI_STATUS_USED_INTERRUPTS \
-    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
-
-
-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_interrupt_emulator(void *arg);
-static int hc_debug_checker(void *arg);
-/*----------------------------------------------------------------------------*/
-/** Initialize UHCI hc driver structure
- *
- * @param[in] instance Memory place to initialize.
- * @param[in] regs Address of I/O control registers.
- * @param[in] reg_size Size of I/O control registers.
- * @param[in] interrupts True if hw interrupts should be used.
- * @return Error code.
- * @note Should be called only once on any structure.
- *
- * Initializes memory structures, starts up hw, and launches debugger and
- * interrupt fibrils.
- */
-int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts)
-{
-	assert(reg_size >= sizeof(regs_t));
-	int ret;
-
-#define CHECK_RET_RETURN(ret, message...) \
-	if (ret != EOK) { \
-		usb_log_error(message); \
-		return ret; \
-	} else (void) 0
-
-	instance->hw_interrupts = interrupts;
-	instance->hw_failures = 0;
-
-	/* allow access to hc control registers */
-	regs_t *io;
-	ret = pio_enable(regs, reg_size, (void **)&io);
-	CHECK_RET_RETURN(ret,
-	    "Failed(%d) to gain access to registers at %p: %s.\n",
-	    ret, io, str_error(ret));
-	instance->registers = io;
-	usb_log_debug("Device registers at %p (%zuB) accessible.\n",
-	    io, reg_size);
-
-	ret = hc_init_mem_structures(instance);
-	CHECK_RET_RETURN(ret,
-	    "Failed(%d) to initialize UHCI memory structures: %s.\n",
-	    ret, str_error(ret));
-
-	hc_init_hw(instance);
-	if (!interrupts) {
-		instance->interrupt_emulator =
-		    fibril_create(hc_interrupt_emulator, instance);
-		fibril_add_ready(instance->interrupt_emulator);
-	}
-	(void)hc_debug_checker;
-
-	return EOK;
-#undef CHECK_RET_DEST_FUN_RETURN
-}
-/*----------------------------------------------------------------------------*/
-/** Initialize UHCI hc hw resources.
- *
- * @param[in] instance UHCI structure to use.
- * For magic values see UHCI Design Guide
- */
-void hc_init_hw(hc_t *instance)
-{
-	assert(instance);
-	regs_t *registers = instance->registers;
-
-	/* Reset everything, who knows what touched it before us */
-	pio_write_16(&registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
-	async_usleep(10000); /* 10ms according to USB spec */
-	pio_write_16(&registers->usbcmd, 0);
-
-	/* Reset hc, all states and counters */
-	pio_write_16(&registers->usbcmd, UHCI_CMD_HCRESET);
-	do { async_usleep(10); }
-	while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
-
-	/* Set frame to exactly 1ms */
-	pio_write_8(&registers->sofmod, 64);
-
-	/* Set frame list pointer */
-	const uint32_t pa = addr_to_phys(instance->frame_list);
-	pio_write_32(&registers->flbaseadd, pa);
-
-	if (instance->hw_interrupts) {
-		/* Enable all interrupts, but resume interrupt */
-		pio_write_16(&instance->registers->usbintr,
-		    UHCI_INTR_ALLOW_INTERRUPTS);
-	}
-
-	const uint16_t status = pio_read_16(&registers->usbcmd);
-	if (status != 0)
-		usb_log_warning("Previous command value: %x.\n", status);
-
-	/* Start the hc with large(64B) packet FSBR */
-	pio_write_16(&registers->usbcmd,
-	    UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
-}
-/*----------------------------------------------------------------------------*/
-/** Initialize UHCI hc memory structures.
- *
- * @param[in] instance UHCI structure to use.
- * @return Error code
- * @note Should be called only once on any structure.
- *
- * 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)
- */
-int hc_init_mem_structures(hc_t *instance)
-{
-	assert(instance);
-#define CHECK_RET_RETURN(ret, message...) \
-	if (ret != EOK) { \
-		usb_log_error(message); \
-		return ret; \
-	} else (void) 0
-
-	/* Init interrupt code */
-	instance->interrupt_code.cmds = instance->interrupt_commands;
-	{
-		/* Read status register */
-		instance->interrupt_commands[0].cmd = CMD_PIO_READ_16;
-		instance->interrupt_commands[0].dstarg = 1;
-		instance->interrupt_commands[0].addr =
-		    &instance->registers->usbsts;
-
-		/* Test whether we are the interrupt cause */
-		instance->interrupt_commands[1].cmd = CMD_BTEST;
-		instance->interrupt_commands[1].value =
-		    UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS;
-		instance->interrupt_commands[1].srcarg = 1;
-		instance->interrupt_commands[1].dstarg = 2;
-
-		/* Predicate cleaning and accepting */
-		instance->interrupt_commands[2].cmd = CMD_PREDICATE;
-		instance->interrupt_commands[2].value = 2;
-		instance->interrupt_commands[2].srcarg = 2;
-
-		/* Write clean status register */
-		instance->interrupt_commands[3].cmd = CMD_PIO_WRITE_A_16;
-		instance->interrupt_commands[3].srcarg = 1;
-		instance->interrupt_commands[3].addr =
-		    &instance->registers->usbsts;
-
-		/* Accept interrupt */
-		instance->interrupt_commands[4].cmd = CMD_ACCEPT;
-
-		instance->interrupt_code.cmdcount = UHCI_NEEDED_IRQ_COMMANDS;
-	}
-
-	/* Init transfer lists */
-	int ret = hc_init_transfer_lists(instance);
-	CHECK_RET_RETURN(ret, "Failed to init transfer lists.\n");
-	usb_log_debug("Initialized transfer lists.\n");
-
-	/* Init USB frame list page*/
-	instance->frame_list = get_page();
-	ret = instance->frame_list ? EOK : ENOMEM;
-	CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
-	usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
-
-	/* Set all frames to point to the first queue head */
-	const uint32_t queue = LINK_POINTER_QH(
-	        addr_to_phys(instance->transfers_interrupt.queue_head));
-
-	unsigned i = 0;
-	for(; i < UHCI_FRAME_LIST_COUNT; ++i) {
-		instance->frame_list[i] = queue;
-	}
-
-	/* Init device keeper */
-	usb_device_keeper_init(&instance->manager);
-	usb_log_debug("Initialized device manager.\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));
-
-	return EOK;
-#undef CHECK_RET_RETURN
-}
-/*----------------------------------------------------------------------------*/
-/** Initialize UHCI hc transfer lists.
- *
- * @param[in] instance UHCI structure to use.
- * @return Error code
- * @note Should be called only once on any structure.
- *
- * Initializes transfer lists and sets them in one chain to support proper
- * USB scheduling. Sets pointer table for quick access.
- */
-int hc_init_transfer_lists(hc_t *instance)
-{
-	assert(instance);
-#define SETUP_TRANSFER_LIST(type, name) \
-do { \
-	int ret = transfer_list_init(&instance->transfers_##type, name); \
-	if (ret != EOK) { \
-		usb_log_error("Failed(%d) to setup %s transfer list: %s.\n", \
-		    ret, name, str_error(ret)); \
-		transfer_list_fini(&instance->transfers_bulk_full); \
-		transfer_list_fini(&instance->transfers_control_full); \
-		transfer_list_fini(&instance->transfers_control_slow); \
-		transfer_list_fini(&instance->transfers_interrupt); \
-		return ret; \
-	} \
-} while (0)
-
-	SETUP_TRANSFER_LIST(bulk_full, "BULK FULL");
-	SETUP_TRANSFER_LIST(control_full, "CONTROL FULL");
-	SETUP_TRANSFER_LIST(control_slow, "CONTROL LOW");
-	SETUP_TRANSFER_LIST(interrupt, "INTERRUPT");
-#undef SETUP_TRANSFER_LIST
-	/* Connect lists into one schedule */
-	transfer_list_set_next(&instance->transfers_control_full,
-		&instance->transfers_bulk_full);
-	transfer_list_set_next(&instance->transfers_control_slow,
-		&instance->transfers_control_full);
-	transfer_list_set_next(&instance->transfers_interrupt,
-		&instance->transfers_control_slow);
-
-	/*FSBR, This feature is not needed (adds no benefit) and is supposedly
-	 * buggy on certain hw, enable at your own risk. */
-#ifdef FSBR
-	transfer_list_set_next(&instance->transfers_bulk_full,
-	    &instance->transfers_control_full);
-#endif
-
-	/* Assign pointers to be used during scheduling */
-	instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] =
-	  &instance->transfers_interrupt;
-	instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] =
-	  &instance->transfers_interrupt;
-	instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] =
-	  &instance->transfers_control_full;
-	instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] =
-	  &instance->transfers_control_slow;
-	instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] =
-	  &instance->transfers_bulk_full;
-
-	return EOK;
-#undef CHECK_RET_CLEAR_RETURN
-}
-/*----------------------------------------------------------------------------*/
-/** Schedule batch for execution.
- *
- * @param[in] instance UHCI structure to use.
- * @param[in] batch Transfer batch to schedule.
- * @return Error code
- *
- * Checks for bandwidth availability and appends the batch to the proper queue.
- */
-int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch)
-{
-	assert(instance);
-	assert(batch);
-
-	transfer_list_t *list =
-	    instance->transfers[batch->ep->speed][batch->ep->transfer_type];
-	assert(list);
-	transfer_list_add_batch(list, batch);
-
-	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 = done.next;
-			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);
-		}
-	}
-}
-/*----------------------------------------------------------------------------*/
-/** Polling function, emulates interrupts.
- *
- * @param[in] arg UHCI hc structure to use.
- * @return EOK (should never return)
- */
-int hc_interrupt_emulator(void* arg)
-{
-	usb_log_debug("Started interrupt emulator.\n");
-	hc_t *instance = arg;
-	assert(instance);
-
-	while (1) {
-		/* Read and clear status register */
-		uint16_t status = pio_read_16(&instance->registers->usbsts);
-		pio_write_16(&instance->registers->usbsts, status);
-		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);
-	}
-	return EOK;
-}
-/*---------------------------------------------------------------------------*/
-/** Debug function, checks consistency of memory structures.
- *
- * @param[in] arg UHCI structure to use.
- * @return EOK (should never return)
- */
-int hc_debug_checker(void *arg)
-{
-	hc_t *instance = arg;
-	assert(instance);
-
-#define QH(queue) \
-	instance->transfers_##queue.queue_head
-
-	while (1) {
-		const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
-		const uint16_t sts = pio_read_16(&instance->registers->usbsts);
-		const uint16_t intr =
-		    pio_read_16(&instance->registers->usbintr);
-
-		if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) {
-			usb_log_debug2("Command: %X Status: %X Intr: %x\n",
-			    cmd, sts, intr);
-		}
-
-		const uintptr_t frame_list =
-		    pio_read_32(&instance->registers->flbaseadd) & ~0xfff;
-		if (frame_list != addr_to_phys(instance->frame_list)) {
-			usb_log_debug("Framelist address: %p vs. %p.\n",
-			    (void *) frame_list,
-			    (void *) addr_to_phys(instance->frame_list));
-		}
-
-		int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff;
-
-		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) {
-			usb_log_debug("Interrupt QH: %p (frame %d) vs. %p.\n",
-			    (void *) expected_pa, frnum, (void *) real_pa);
-		}
-
-		expected_pa = QH(interrupt)->next & LINK_POINTER_ADDRESS_MASK;
-		real_pa = addr_to_phys(QH(control_slow));
-		if (expected_pa != real_pa) {
-			usb_log_debug("Control Slow QH: %p vs. %p.\n",
-			    (void *) expected_pa, (void *) real_pa);
-		}
-
-		expected_pa = QH(control_slow)->next & LINK_POINTER_ADDRESS_MASK;
-		real_pa = addr_to_phys(QH(control_full));
-		if (expected_pa != real_pa) {
-			usb_log_debug("Control Full QH: %p vs. %p.\n",
-			    (void *) expected_pa, (void *) real_pa);
-		}
-
-		expected_pa = QH(control_full)->next & LINK_POINTER_ADDRESS_MASK;
-		real_pa = addr_to_phys(QH(bulk_full));
-		if (expected_pa != real_pa ) {
-			usb_log_debug("Bulk QH: %p vs. %p.\n",
-			    (void *) expected_pa, (void *) real_pa);
-		}
-		async_usleep(UHCI_DEBUGER_TIMEOUT);
-	}
-	return EOK;
-#undef QH
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/hc.h
===================================================================
--- uspace/drv/uhci_hcd/hc.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,160 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI host controller driver structure
- */
-#ifndef DRV_UHCI_HC_H
-#define DRV_UHCI_HC_H
-
-#include <fibril.h>
-#include <ddi.h>
-
-#include <usb/host/device_keeper.h>
-#include <usb/host/usb_endpoint_manager.h>
-#include <usb/host/batch.h>
-
-#include "transfer_list.h"
-
-/** UHCI I/O registers layout */
-typedef struct uhci_regs {
-	/** Command register, controls HC behaviour */
-	uint16_t usbcmd;
-#define UHCI_CMD_MAX_PACKET (1 << 7)
-#define UHCI_CMD_CONFIGURE  (1 << 6)
-#define UHCI_CMD_DEBUG  (1 << 5)
-#define UHCI_CMD_FORCE_GLOBAL_RESUME  (1 << 4)
-#define UHCI_CMD_FORCE_GLOBAL_SUSPEND  (1 << 3)
-#define UHCI_CMD_GLOBAL_RESET  (1 << 2)
-#define UHCI_CMD_HCRESET  (1 << 1)
-#define UHCI_CMD_RUN_STOP  (1 << 0)
-
-	/** Status register, 1 means interrupt is asserted (if enabled) */
-	uint16_t usbsts;
-#define UHCI_STATUS_HALTED (1 << 5)
-#define UHCI_STATUS_PROCESS_ERROR (1 << 4)
-#define UHCI_STATUS_SYSTEM_ERROR (1 << 3)
-#define UHCI_STATUS_RESUME (1 << 2)
-#define UHCI_STATUS_ERROR_INTERRUPT (1 << 1)
-#define UHCI_STATUS_INTERRUPT (1 << 0)
-#define UHCI_STATUS_NM_INTERRUPTS \
-    (UHCI_STATUS_PROCESS_ERROR | UHCI_STATUS_SYSTEM_ERROR)
-
-	/** Interrupt enabled registers */
-	uint16_t usbintr;
-#define UHCI_INTR_SHORT_PACKET (1 << 3)
-#define UHCI_INTR_COMPLETE (1 << 2)
-#define UHCI_INTR_RESUME (1 << 1)
-#define UHCI_INTR_CRC (1 << 0)
-
-	/** Register stores frame number used in SOF packet */
-	uint16_t frnum;
-
-	/** Pointer(physical) to the Frame List */
-	uint32_t flbaseadd;
-
-	/** SOF modification to match external timers */
-	uint8_t sofmod;
-} regs_t;
-
-#define UHCI_FRAME_LIST_COUNT 1024
-#define UHCI_INT_EMULATOR_TIMEOUT 10000
-#define UHCI_DEBUGER_TIMEOUT 5000000
-#define UHCI_ALLOWED_HW_FAIL 5
-#define UHCI_NEEDED_IRQ_COMMANDS 5
-
-/** Main UHCI driver structure */
-typedef struct hc {
-	/** 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 */
-	regs_t *registers;
-
-	/** Frame List contains 1024 link pointers */
-	link_pointer_t *frame_list;
-
-	/** List and queue of interrupt transfers */
-	transfer_list_t transfers_interrupt;
-	/** List and queue of low speed control transfers */
-	transfer_list_t transfers_control_slow;
-	/** List and queue of full speed bulk transfers */
-	transfer_list_t transfers_bulk_full;
-	/** List and queue of full speed control transfers */
-	transfer_list_t transfers_control_full;
-
-	/** Pointer table to the above lists, helps during scheduling */
-	transfer_list_t *transfers[2][4];
-
-	/** Code to be executed in kernel interrupt handler */
-	irq_code_t interrupt_code;
-
-	/** Commands that form interrupt code */
-	irq_cmd_t interrupt_commands[UHCI_NEEDED_IRQ_COMMANDS];
-
-	/** Fibril periodically checking status register*/
-	fid_t interrupt_emulator;
-
-	/** Indicator of hw interrupts availability */
-	bool hw_interrupts;
-
-	/** Number of hw failures detected. */
-	unsigned hw_failures;
-} hc_t;
-
-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
- *
- * @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;
-}
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/hw_struct/link_pointer.h
===================================================================
--- uspace/drv/uhci_hcd/hw_struct/link_pointer.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2010 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
- */
-#ifndef DRV_UHCI_HW_STRUCT_LINK_POINTER_H
-#define DRV_UHCI_HW_STRUCT_LINK_POINTER_H
-
-/* UHCI link pointer, used by many data structures */
-typedef uint32_t link_pointer_t;
-
-#define LINK_POINTER_TERMINATE_FLAG (1 << 0)
-#define LINK_POINTER_QUEUE_HEAD_FLAG (1 << 1)
-#define LINK_POINTER_ZERO_BIT_FLAG (1 << 2)
-#define LINK_POINTER_VERTICAL_FLAG (1 << 2)
-#define LINK_POINTER_RESERVED_FLAG (1 << 3)
-
-#define LINK_POINTER_ADDRESS_MASK 0xfffffff0 /* upper 28 bits */
-
-#define LINK_POINTER_QH(address) \
-	((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: pace/drv/uhci_hcd/hw_struct/queue_head.h
===================================================================
--- uspace/drv/uhci_hcd/hw_struct/queue_head.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,100 +1,0 @@
-/*
- * Copyright (c) 2010 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
- */
-#ifndef DRV_UHCI_HW_STRUCT_QH_H
-#define DRV_UHCI_HW_STRUCT_QH_H
-#include <assert.h>
-
-#include "link_pointer.h"
-#include "transfer_descriptor.h"
-#include "../utils/malloc32.h"
-
-/** This structure is defined in UHCI design guide p. 31 */
-typedef struct queue_head {
-	/** Pointer to the next entity (another QH or TD */
-	volatile link_pointer_t next;
-	/** Pointer to the contained entities (execution controlled by vertical flag*/
-	volatile link_pointer_t element;
-} __attribute__((packed)) qh_t;
-/*----------------------------------------------------------------------------*/
-/** Initialize queue head structure
- *
- * @param[in] instance qh_t structure to initialize.
- *
- * Sets both pointer to terminal NULL.
- */
-static inline void qh_init(qh_t *instance)
-{
-	assert(instance);
-
-	instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;
-	instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
-}
-/*----------------------------------------------------------------------------*/
-/** Set queue head next pointer
- *
- * @param[in] instance qh_t structure to use.
- * @param[in] next Address of the next queue.
- *
- * Adds proper flag. If the pointer is NULL, sets next to terminal NULL.
- */
-static inline void qh_set_next_qh(qh_t *instance, qh_t *next)
-{
-	uint32_t pa = addr_to_phys(next);
-	if (pa) {
-		instance->next = LINK_POINTER_QH(pa);
-	} else {
-		instance->next = LINK_POINTER_TERM;
-	}
-}
-/*----------------------------------------------------------------------------*/
-/** Set queue head element pointer
- *
- * @param[in] instance qh_t structure to use.
- * @param[in] td Transfer descriptor to set as the first element.
- *
- * Adds proper flag. If the pointer is NULL, sets element to terminal NULL.
- */
-static inline void qh_set_element_td(qh_t *instance, td_t *td)
-{
-	uint32_t pa = addr_to_phys(td);
-	if (pa) {
-		instance->element = LINK_POINTER_TD(pa);
-	} else {
-		instance->element = LINK_POINTER_TERM;
-	}
-}
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/hw_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci_hcd/hw_struct/transfer_descriptor.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,176 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#include <errno.h>
-#include <usb/debug.h>
-
-#include "transfer_descriptor.h"
-#include "../utils/malloc32.h"
-
-/** Initialize Transfer Descriptor
- *
- * @param[in] instance Memory place to initialize.
- * @param[in] err_count Number of retries hc should attempt.
- * @param[in] size Size of data source.
- * @param[in] toggle Value of toggle bit.
- * @param[in] iso True if TD represents Isochronous transfer.
- * @param[in] low_speed Target device's speed.
- * @param[in] target Address and endpoint receiving the transfer.
- * @param[in] pid Packet identification (SETUP, IN or OUT).
- * @param[in] buffer Source of data.
- * @param[in] next Net TD in transaction.
- * @return Error code.
- *
- * Uses a mix of supplied and default values.
- * Implicit values:
- *  - all TDs have vertical flag set (makes transfers to endpoints atomic)
- *  - in the error field only active it is set
- *  - if the packet uses PID_IN and is not isochronous SPD is set
- *
- * Dumps 8 bytes of buffer if PID_SETUP is used.
- */
-void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
-    bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
-    td_t *next)
-{
-	assert(instance);
-	assert(size < 1024);
-	assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN)
-	    || (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_pa ? next_pa : LINK_POINTER_TERMINATE_FLAG);
-
-	instance->status = 0
-	    | ((err_count & TD_STATUS_ERROR_COUNT_MASK)
-	        << TD_STATUS_ERROR_COUNT_POS)
-	    | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
-	    | (iso ? TD_STATUS_ISOCHRONOUS_FLAG : 0)
-	    | TD_STATUS_ERROR_ACTIVE;
-
-	if (pid == USB_PID_IN && !iso) {
-		instance->status |= TD_STATUS_SPD_FLAG;
-	}
-
-	instance->device = 0
-	    | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
-	    | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
-	    | ((target.address & TD_DEVICE_ADDRESS_MASK)
-	        << TD_DEVICE_ADDRESS_POS)
-	    | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK)
-	        << TD_DEVICE_ENDPOINT_POS)
-	    | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS);
-
-	instance->buffer_ptr = addr_to_phys(buffer);
-
-	usb_log_debug2("Created TD(%p): %X:%X:%X:%X(%p).\n",
-	    instance, instance->next, instance->status, instance->device,
-	    instance->buffer_ptr, buffer);
-	td_print_status(instance);
-	if (pid == USB_PID_SETUP) {
-		usb_log_debug2("SETUP BUFFER: %s\n",
-		    usb_debug_str_buffer(buffer, 8, 8));
-	}
-}
-/*----------------------------------------------------------------------------*/
-/** Convert TD status into standard error code
- *
- * @param[in] instance TD structure to use.
- * @return Error code.
- */
-int td_status(td_t *instance)
-{
-	assert(instance);
-
-	/* 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;
-
-	/* HC does not end transactions 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;
-
-	/* Stall might represent err count reaching zero or stall response from
-	 * the device. If err count reached zero, one of the above is reported*/
-	if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
-		return ESTALL;
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Print values in status field (dw1) in a human readable way.
- *
- * @param[in] instance TD structure to use.
- */
-void td_print_status(td_t *instance)
-{
-	assert(instance);
-	const uint32_t s = instance->status;
-	usb_log_debug2("TD(%p) status(%#" PRIx32 "):%s %d,%s%s%s%s%s%s%s%s%s%s%s %zu.\n",
-	    instance, instance->status,
-	    (s & TD_STATUS_SPD_FLAG) ? " SPD," : "",
-	    (s >> TD_STATUS_ERROR_COUNT_POS) & TD_STATUS_ERROR_COUNT_MASK,
-	    (s & TD_STATUS_LOW_SPEED_FLAG) ? " LOW SPEED," : "",
-	    (s & TD_STATUS_ISOCHRONOUS_FLAG) ? " ISOCHRONOUS," : "",
-	    (s & TD_STATUS_IOC_FLAG) ? " IOC," : "",
-	    (s & TD_STATUS_ERROR_ACTIVE) ? " ACTIVE," : "",
-	    (s & TD_STATUS_ERROR_STALLED) ? " STALLED," : "",
-	    (s & TD_STATUS_ERROR_BUFFER) ? " BUFFER," : "",
-	    (s & TD_STATUS_ERROR_BABBLE) ? " BABBLE," : "",
-	    (s & TD_STATUS_ERROR_NAK) ? " NAK," : "",
-	    (s & TD_STATUS_ERROR_CRC) ? " CRC/TIMEOUT," : "",
-	    (s & TD_STATUS_ERROR_BIT_STUFF) ? " BIT_STUFF," : "",
-	    (s & TD_STATUS_ERROR_RESERVED) ? " RESERVED," : "",
-	    td_act_size(instance)
-	);
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/hw_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/uhci_hcd/hw_struct/transfer_descriptor.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,166 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
-#define DRV_UHCI_HW_STRUCT_TRANSFER_DESCRIPTOR_H
-
-#include <mem.h>
-#include <usb/usb.h>
-
-#include "link_pointer.h"
-
-/** Transfer Descriptor, defined in UHCI design guide p. 26 */
-typedef struct transfer_descriptor {
-	/** Pointer to the next entity (TD or QH) */
-	link_pointer_t next;
-
-	/** Status doubleword */
-	volatile uint32_t status;
-#define TD_STATUS_RESERVED_MASK 0xc000f800
-#define TD_STATUS_SPD_FLAG         (1 << 29)
-#define TD_STATUS_ERROR_COUNT_POS 27
-#define TD_STATUS_ERROR_COUNT_MASK 0x3
-#define TD_STATUS_LOW_SPEED_FLAG   (1 << 26)
-#define TD_STATUS_ISOCHRONOUS_FLAG (1 << 25)
-#define TD_STATUS_IOC_FLAG         (1 << 24)
-
-#define TD_STATUS_ERROR_ACTIVE    (1 << 23)
-#define TD_STATUS_ERROR_STALLED   (1 << 22)
-#define TD_STATUS_ERROR_BUFFER    (1 << 21)
-#define TD_STATUS_ERROR_BABBLE    (1 << 20)
-#define TD_STATUS_ERROR_NAK       (1 << 19)
-#define TD_STATUS_ERROR_CRC       (1 << 18)
-#define TD_STATUS_ERROR_BIT_STUFF (1 << 17)
-#define TD_STATUS_ERROR_RESERVED  (1 << 16)
-#define TD_STATUS_ERROR_POS 16
-#define TD_STATUS_ERROR_MASK 0xff
-
-#define TD_STATUS_ACTLEN_POS 0
-#define TD_STATUS_ACTLEN_MASK 0x7ff
-
-	/* double word with USB device specific info */
-	volatile uint32_t device;
-#define TD_DEVICE_MAXLEN_POS 21
-#define TD_DEVICE_MAXLEN_MASK 0x7ff
-#define TD_DEVICE_RESERVED_FLAG        (1 << 20)
-#define TD_DEVICE_DATA_TOGGLE_ONE_FLAG (1 << 19)
-#define TD_DEVICE_ENDPOINT_POS 15
-#define TD_DEVICE_ENDPOINT_MASK 0xf
-#define TD_DEVICE_ADDRESS_POS 8
-#define TD_DEVICE_ADDRESS_MASK 0x7f
-#define TD_DEVICE_PID_POS 0
-#define TD_DEVICE_PID_MASK 0xff
-
-	/** Pointer(physical) to the beginning of the transaction's buffer */
-	volatile uint32_t buffer_ptr;
-
-	/* According to UHCI design guide, there is 16 bytes of
-	 * data available here.
-	 * According to linux kernel the hardware does not care,
-	 * it just needs to be aligned. We don't use it anyway.
-	 */
-} __attribute__((packed)) td_t;
-
-
-void td_init(td_t *instance, int error_count, size_t size, bool toggle,
-    bool iso, bool low_speed, usb_target_t target, usb_packet_id pid,
-    void *buffer, td_t *next);
-
-int td_status(td_t *instance);
-
-void td_print_status(td_t *instance);
-/*----------------------------------------------------------------------------*/
-/** Helper function for parsing actual size out of TD.
- *
- * @param[in] instance TD structure to use.
- * @return Parsed actual size.
- */
-static inline size_t td_act_size(td_t *instance)
-{
-	assert(instance);
-	const uint32_t s = instance->status;
-	return ((s >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK;
-}
-/*----------------------------------------------------------------------------*/
-/** Check whether less than max data were received on SPD marked transfer.
- *
- * @param[in] instance TD structure to use.
- * @return True if data packet is short (less than max bytes and SPD set),
- * false otherwise.
- */
-static inline bool td_is_short(td_t *instance)
-{
-	const size_t act_size = td_act_size(instance);
-	const size_t max_size =
-	    ((instance->device >> TD_DEVICE_MAXLEN_POS) + 1)
-	    & TD_DEVICE_MAXLEN_MASK;
-	return
-	    (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size;
-}
-/*----------------------------------------------------------------------------*/
-/** Helper function for parsing value of toggle bit.
- *
- * @param[in] instance TD structure to use.
- * @return Toggle bit value.
- */
-static inline int td_toggle(td_t *instance)
-{
-	assert(instance);
-	return (instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) ? 1 : 0;
-}
-/*----------------------------------------------------------------------------*/
-/** Helper function for parsing value of active bit
- *
- * @param[in] instance TD structure to use.
- * @return Active bit value.
- */
-static inline bool td_is_active(td_t *instance)
-{
-	assert(instance);
-	return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0;
-}
-/*----------------------------------------------------------------------------*/
-/** Helper function for setting IOC bit.
- *
- * @param[in] instance TD structure to use.
- */
-static inline void td_set_ioc(td_t *instance)
-{
-	assert(instance);
-	instance->status |= TD_STATUS_IOC_FLAG;
-}
-/*----------------------------------------------------------------------------*/
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/iface.c
===================================================================
--- uspace/drv/uhci_hcd/iface.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(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/uhci_hcd/iface.h
===================================================================
--- uspace/drv/uhci_hcd/iface.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(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: pace/drv/uhci_hcd/main.c
===================================================================
--- uspace/drv/uhci_hcd/main.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,94 +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 initialization
- */
-#include <ddf/driver.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb/ddfiface.h>
-#include <usb/debug.h>
-
-#include "uhci.h"
-
-#define NAME "uhci_hcd"
-
-static int uhci_add_device(ddf_dev_t *device);
-/*----------------------------------------------------------------------------*/
-static driver_ops_t uhci_driver_ops = {
-	.add_device = uhci_add_device,
-};
-/*----------------------------------------------------------------------------*/
-static driver_t uhci_driver = {
-	.name = NAME,
-	.driver_ops = &uhci_driver_ops
-};
-/*----------------------------------------------------------------------------*/
-/** Initialize a new ddf driver instance for uhci hc and hub.
- *
- * @param[in] device DDF instance of the device to initialize.
- * @return Error code.
- */
-int uhci_add_device(ddf_dev_t *device)
-{
-	usb_log_debug2("uhci_add_device() called\n");
-	assert(device);
-
-	int ret = device_setup_uhci(device);
-	if (ret != EOK) {
-		usb_log_error("Failed to initialize UHCI driver: %s.\n",
-		    str_error(ret));
-		return ret;
-	}
-	usb_log_info("Controlling new UHCI device '%s'.\n", device->name);
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Initialize global driver structures (NONE).
- *
- * @param[in] argc Number of arguments in argv vector (ignored).
- * @param[in] argv Cmdline argument vector (ignored).
- * @return Error code.
- *
- * Driver debug level is set here.
- */
-int main(int argc, char *argv[])
-{
-	printf(NAME ": HelenOS UHCI driver.\n");
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
-
-	return ddf_driver_main(&uhci_driver);
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/pci.c
===================================================================
--- uspace/drv/uhci_hcd/pci.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,169 +1,0 @@
-/*
- * Copyright (c) 2011 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
- * PCI related functions needed by the UHCI driver.
- */
-
-#include <errno.h>
-#include <assert.h>
-#include <devman.h>
-#include <device/hw_res.h>
-
-#include <usb/debug.h>
-#include <pci_dev_iface.h>
-
-#include "pci.h"
-
-/** Get I/O address of registers and IRQ for given device.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] io_reg_address Base address of the I/O range.
- * @param[out] io_reg_size Size of the I/O range.
- * @param[out] irq_no IRQ assigned to the device.
- * @return Error code.
- */
-int pci_get_my_registers(const ddf_dev_t *dev,
-    uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no)
-{
-	assert(dev);
-	assert(io_reg_address);
-	assert(io_reg_size);
-	assert(irq_no);
-	
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	hw_resource_list_t hw_resources;
-	int rc = hw_res_get_resource_list(parent_sess, &hw_resources);
-	if (rc != EOK) {
-		async_hangup(parent_sess);
-		return rc;
-	}
-	
-	uintptr_t io_address = 0;
-	size_t io_size = 0;
-	bool io_found = false;
-	
-	int irq = 0;
-	bool irq_found = false;
-	
-	size_t i;
-	for (i = 0; i < hw_resources.count; i++) {
-		const hw_resource_t *res = &hw_resources.resources[i];
-		switch (res->type) {
-		case INTERRUPT:
-			irq = res->res.interrupt.irq;
-			irq_found = true;
-			usb_log_debug2("Found interrupt: %d.\n", irq);
-			break;
-		case IO_RANGE:
-			io_address = res->res.io_range.address;
-			io_size = res->res.io_range.size;
-			usb_log_debug2("Found io: %" PRIx64" %zu.\n",
-			    res->res.io_range.address, res->res.io_range.size);
-			io_found = true;
-			break;
-		default:
-			break;
-		}
-	}
-	
-	async_hangup(parent_sess);
-	
-	if (!io_found || !irq_found)
-		return ENOENT;
-	
-	*io_reg_address = io_address;
-	*io_reg_size = io_size;
-	*irq_no = irq;
-	
-	return EOK;
-}
-
-/** Call the PCI driver with a request to enable interrupts
- *
- * @param[in] device Device asking for interrupts
- * @return Error code.
- */
-int pci_enable_interrupts(const ddf_dev_t *device)
-{
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	const bool enabled = hw_res_enable_interrupt(parent_sess);
-	async_hangup(parent_sess);
-	
-	return enabled ? EOK : EIO;
-}
-
-/** Call the PCI driver with a request to clear legacy support register
- *
- * @param[in] device Device asking to disable interrupts
- * @return Error code.
- */
-int pci_disable_legacy(const ddf_dev_t *device)
-{
-	assert(device);
-	
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,
-	    IPC_FLAG_BLOCKING);
-	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: pace/drv/uhci_hcd/pci.h
===================================================================
--- uspace/drv/uhci_hcd/pci.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,48 +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 PCI helper functions
- */
-#ifndef DRV_UHCI_PCI_H
-#define DRV_UHCI_PCI_H
-
-#include <ddf/driver.h>
-
-int pci_get_my_registers(const ddf_dev_t *, uintptr_t *, size_t *, int *);
-int pci_enable_interrupts(const ddf_dev_t *);
-int pci_disable_legacy(const ddf_dev_t *);
-
-#endif
-/**
- * @}
- */
-
Index: pace/drv/uhci_hcd/root_hub.c
===================================================================
--- uspace/drv/uhci_hcd/root_hub.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,85 +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 drvusbuhci
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#include <assert.h>
-#include <errno.h>
-#include <str_error.h>
-#include <stdio.h>
-
-#include <usb/debug.h>
-
-#include "root_hub.h"
-
-/** Root hub initialization
- * @param[in] instance RH structure to initialize
- * @param[in] fun DDF function representing UHCI root hub
- * @param[in] reg_addr Address of root hub status and control registers.
- * @param[in] reg_size Size of accessible address space.
- * @return Error code.
- */
-int rh_init(rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)
-{
-	assert(fun);
-
-	char *match_str = NULL;
-	int ret = asprintf(&match_str, "usb&uhci&root-hub");
-	if (ret < 0) {
-		usb_log_error(
-		    "Failed(%d) to create root hub match string: %s.\n",
-		    ret, str_error(ret));
-		return ret;
-	}
-	assert(match_str);
-
-	ret = ddf_fun_add_match_id(fun, match_str, 100);
-	if (ret != EOK) {
-		free(match_str);
-		usb_log_error("Failed(%d) to add root hub match id: %s\n",
-		    ret, str_error(ret));
-		return ret;
-	}
-
-	/* Initialize resource structure */
-	instance->resource_list.count = 1;
-	instance->resource_list.resources = &instance->io_regs;
-
-	instance->io_regs.type = IO_RANGE;
-	instance->io_regs.res.io_range.address = reg_addr;
-	instance->io_regs.res.io_range.size = reg_size;
-	instance->io_regs.res.io_range.endianness = LITTLE_ENDIAN;
-
-	return EOK;
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/root_hub.h
===================================================================
--- uspace/drv/uhci_hcd/root_hub.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,55 +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 drvusbuhci
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_RH_H
-#define DRV_UHCI_RH_H
-
-#include <ddf/driver.h>
-#include <ops/hw_res.h>
-
-/** DDF support structure for uhci_rhd driver, provides I/O resources */
-typedef struct rh {
-	/** List of resources available to the root hub. */
-	hw_resource_list_t resource_list;
-	/** The only resource in the RH resource list */
-	hw_resource_t io_regs;
-} rh_t;
-
-int rh_init(
-    rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size);
-
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci_hcd/transfer_list.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,241 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver transfer list implementation
- */
-#include <errno.h>
-#include <usb/debug.h>
-#include <arch/barrier.h>
-
-
-#include "transfer_list.h"
-#include "batch.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->queue_head = malloc32(sizeof(qh_t));
-	if (!instance->queue_head) {
-		usb_log_error("Failed to allocate queue head.\n");
-		return ENOMEM;
-	}
-	const uint32_t queue_head_pa = addr_to_phys(instance->queue_head);
-	usb_log_debug2("Transfer list %s setup with QH: %p (%#" PRIx32" ).\n",
-	    name, instance->queue_head, queue_head_pa);
-
-	qh_init(instance->queue_head);
-	list_initialize(&instance->batch_list);
-	fibril_mutex_initialize(&instance->guard);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Dispose transfer list structures.
- *
- * @param[in] instance Memory place to use.
- *
- * Frees memory of the internal qh_t structure.
- */
-void transfer_list_fini(transfer_list_t *instance)
-{
-	assert(instance);
-	free32(instance->queue_head);
-}
-/** 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(instance->queue_head);
-	assert(next);
-	/* Set queue_head.next to point to the follower */
-	qh_set_next_qh(instance->queue_head, next->queue_head);
-}
-/*----------------------------------------------------------------------------*/
-/** Add transfer batch to the list and queue.
- *
- * @param[in] instance List to use.
- * @param[in] batch Transfer batch to submit.
- *
- * 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);
-
-	qh_t *last_qh = NULL;
-	/* Add to the hardware queue. */
-	if (list_empty(&instance->batch_list)) {
-		/* There is nothing scheduled */
-		last_qh = instance->queue_head;
-	} else {
-		/* There is something scheduled */
-		usb_transfer_batch_t *last =
-		    usb_transfer_batch_from_link(instance->batch_list.prev);
-		last_qh = batch_qh(last);
-	}
-	const uint32_t pa = addr_to_phys(batch_qh(batch));
-	assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
-
-	/* Make sure all data in the batch are written */
-	write_barrier();
-
-	/* keep link */
-	batch_qh(batch)->next = last_qh->next;
-	qh_set_next_qh(last_qh, batch_qh(batch));
-
-	/* Make sure the pointer is updated */
-	write_barrier();
-
-	/* Add to the driver's list */
-	list_append(&batch->link, &instance->batch_list);
-
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
-	    batch, USB_TRANSFER_BATCH_ARGS(*batch), instance->name);
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Add completed bantches to the provided list.
- *
- * @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);
-	link_t *current = instance->batch_list.next;
-	while (current != &instance->batch_list) {
-		link_t * const next = current->next;
-		usb_transfer_batch_t *batch =
-		    usb_transfer_batch_from_link(current);
-
-		if (batch_is_complete(batch)) {
-			/* Save for processing */
-			transfer_list_remove_batch(instance, batch);
-			list_append(current, done);
-		}
-		current = next;
-	}
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Walk the list and finish all batches with EINTR.
- *
- * @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 * const current = instance->batch_list.next;
-		usb_transfer_batch_t *batch =
-		    usb_transfer_batch_from_link(current);
-		transfer_list_remove_batch(instance, batch);
-		usb_transfer_batch_finish_error(batch, EINTR);
-	}
-	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.
- *
- * 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->queue_head);
-	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 *qpos = NULL;
-	qh_t *prev_qh = NULL;
-	/* Remove from the hardware queue */
-	if (instance->batch_list.next == &batch->link) {
-		/* I'm the first one here */
-		prev_qh = instance->queue_head;
-		qpos = "FIRST";
-	} else {
-		/* The thing before me is a batch too */
-		usb_transfer_batch_t *prev =
-		    usb_transfer_batch_from_link(batch->link.prev);
-		prev_qh = batch_qh(prev);
-		qpos = "NOT FIRST";
-	}
-	assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK)
-	    == addr_to_phys(batch_qh(batch)));
-	prev_qh->next = batch_qh(batch)->next;
-
-	/* Make sure the pointer is updated */
-	write_barrier();
-
-	/* Remove from the batch list */
-	list_remove(&batch->link);
-	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " removed (%s) "
-	    "from %s, next: %x.\n",
-	    batch, USB_TRANSFER_BATCH_ARGS(*batch),
-	    qpos, instance->name, batch_qh(batch)->next);
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/transfer_list.h
===================================================================
--- uspace/drv/uhci_hcd/transfer_list.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,66 +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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI driver transfer list structure
- */
-#ifndef DRV_UHCI_TRANSFER_LIST_H
-#define DRV_UHCI_TRANSFER_LIST_H
-
-#include <fibril_synch.h>
-#include <usb/host/batch.h>
-
-#include "hw_struct/queue_head.h"
-
-/** Structure maintaining both hw queue and software list
- * of currently executed transfers
- */
-typedef struct transfer_list {
-	/** Guard against multiple add/remove races */
-	fibril_mutex_t guard;
-	/** UHCI hw structure represeting this queue */
-	qh_t *queue_head;
-	/** Assigned name, for nicer debug output */
-	const char *name;
-	/** List of all batches in this list */
-	link_t batch_list;
-} transfer_list_t;
-
-void transfer_list_fini(transfer_list_t *instance);
-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
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/uhci.c
===================================================================
--- uspace/drv/uhci_hcd/uhci.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,286 +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 drvusbuhci
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#include <errno.h>
-#include <str_error.h>
-#include <ddf/interrupt.h>
-#include <usb_iface.h>
-#include <usb/ddfiface.h>
-#include <usb/debug.h>
-
-#include "uhci.h"
-#include "iface.h"
-#include "pci.h"
-
-#include "hc.h"
-#include "root_hub.h"
-
-/** Structure representing both functions of UHCI hc, USB host controller
- * and USB root hub */
-typedef struct uhci {
-	/** Pointer to DDF represenation of UHCI host controller */
-	ddf_fun_t *hc_fun;
-	/** Pointer to DDF represenation of UHCI root hub */
-	ddf_fun_t *rh_fun;
-
-	/** Internal driver's represenation of UHCI host controller */
-	hc_t hc;
-	/** Internal driver's represenation of UHCI root hub */
-	rh_t rh;
-} uhci_t;
-
-static inline uhci_t * dev_to_uhci(const ddf_dev_t *dev)
-{
-	assert(dev);
-	assert(dev->driver_data);
-	return dev->driver_data;
-}
-/*----------------------------------------------------------------------------*/
-/** IRQ handling callback, forward status from call to diver structure.
- *
- * @param[in] dev DDF instance of the device to use.
- * @param[in] iid (Unused).
- * @param[in] call Pointer to the call from kernel.
- */
-static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
-{
-	assert(dev);
-	uhci_t *uhci = dev_to_uhci(dev);
-	hc_t *hc = &uhci->hc;
-	const uint16_t status = IPC_GET_ARG1(*call);
-	assert(hc);
-	hc_interrupt(hc, status);
-}
-/*----------------------------------------------------------------------------*/
-/** Operations supported by the HC driver */
-static ddf_dev_ops_t hc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
-};
-/*----------------------------------------------------------------------------*/
-/** Get address of the device identified by handle.
- *
- * @param[in] fun DDF instance of the function to use.
- * @param[in] handle DDF handle of the driver seeking its USB address.
- * @param[out] address Found address.
- */
-static int usb_iface_get_address(
-    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
-{
-	assert(fun);
-	usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
-	usb_address_t addr = usb_device_keeper_find(manager, handle);
-
-	if (addr < 0) {
-		return addr;
-	}
-
-	if (address != NULL) {
-		*address = addr;
-	}
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Gets handle of the respective hc.
- *
- * @param[in] fun DDF function of uhci device.
- * @param[out] handle Host cotnroller handle.
- * @return Error code.
- */
-static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
-{
-	assert(fun);
-	ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
-	assert(hc_fun);
-
-	if (handle != NULL)
-		*handle = hc_fun->handle;
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** USB interface implementation used by RH */
-static usb_iface_t usb_iface = {
-	.get_hc_handle = usb_iface_get_hc_handle,
-	.get_address = usb_iface_get_address
-};
-/*----------------------------------------------------------------------------*/
-/** Get root hub hw resources (I/O registers).
- *
- * @param[in] fun Root hub function.
- * @return Pointer to the resource list used by the root hub.
- */
-static hw_resource_list_t *get_resource_list(ddf_fun_t *fun)
-{
-	assert(fun);
-	rh_t *rh = fun->driver_data;
-	assert(rh);
-	return &rh->resource_list;
-}
-/*----------------------------------------------------------------------------*/
-/** Interface to provide the root hub driver with hw info */
-static hw_res_ops_t hw_res_iface = {
-	.get_resource_list = get_resource_list,
-	.enable_interrupt = NULL,
-};
-/*----------------------------------------------------------------------------*/
-/** RH function support for uhci_rhd */
-static ddf_dev_ops_t rh_ops = {
-	.interfaces[USB_DEV_IFACE] = &usb_iface,
-	.interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
-};
-/*----------------------------------------------------------------------------*/
-/** Initialize hc and rh DDF structures and their respective drivers.
- *
- * @param[in] device DDF instance of the device to use.
- *
- * This function does all the preparatory work for hc and rh drivers:
- *  - gets device's hw resources
- *  - disables UHCI legacy support (PCI config space)
- *  - attempts to enable interrupts
- *  - registers interrupt handler
- */
-int device_setup_uhci(ddf_dev_t *device)
-{
-	assert(device);
-	uhci_t *instance = malloc(sizeof(uhci_t));
-	if (instance == NULL) {
-		usb_log_error("Failed to allocate OHCI driver.\n");
-		return ENOMEM;
-	}
-
-#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
-if (ret != EOK) { \
-	if (instance->hc_fun) \
-		instance->hc_fun->ops = NULL; \
-		instance->hc_fun->driver_data = NULL; \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) {\
-		instance->rh_fun->ops = NULL; \
-		instance->rh_fun->driver_data = NULL; \
-		ddf_fun_destroy(instance->rh_fun); \
-	} \
-	free(instance); \
-	usb_log_error(message); \
-	return ret; \
-} else (void)0
-
-	instance->rh_fun = NULL;
-	instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc");
-	int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
-	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc;
-
-	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
-	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
-	instance->rh_fun->ops = &rh_ops;
-	instance->rh_fun->driver_data = &instance->rh;
-
-	uintptr_t reg_base = 0;
-	size_t reg_size = 0;
-	int irq = 0;
-
-	ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed to get I/O addresses for %" PRIun ": %s.\n",
-	    device->handle, str_error(ret));
-	usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
-	    (void *) reg_base, reg_size, irq);
-
-	ret = pci_disable_legacy(device);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
-
-	bool interrupts = false;
-#ifdef CONFIG_USBHC_NO_INTERRUPTS
-	usb_log_warning("Interrupts disabled in OS config, " \
-	    "falling back to polling.\n");
-#else
-	ret = pci_enable_interrupts(device);
-	if (ret != EOK) {
-		usb_log_warning("Failed to enable interrupts: %s.\n",
-		    str_error(ret));
-		usb_log_info("HW interrupts not available, " \
-		    "falling back to polling.\n");
-	} else {
-		usb_log_debug("Hw interrupts enabled.\n");
-		interrupts = true;
-	}
-#endif
-
-
-	ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
-	CHECK_RET_DEST_FREE_RETURN(ret,
-	    "Failed(%d) to init uhci_hcd: %s.\n", ret, str_error(ret));
-
-#define CHECK_RET_FINI_RETURN(ret, message...) \
-if (ret != EOK) { \
-	hc_fini(&instance->hc); \
-	CHECK_RET_DEST_FREE_RETURN(ret, message); \
-	return ret; \
-} else (void)0
-
-	/* It does no harm if we register this on polling */
-	ret = register_interrupt_handler(device, irq, irq_handler,
-	    &instance->hc.interrupt_code);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to register interrupt handler: %s.\n",
-	    ret, str_error(ret));
-
-	ret = ddf_fun_bind(instance->hc_fun);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to bind UHCI device function: %s.\n",
-	    ret, str_error(ret));
-
-	ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed to add UHCI to HC class: %s.\n", str_error(ret));
-
-	ret = rh_init(&instance->rh, instance->rh_fun,
-	    (uintptr_t)instance->hc.registers + 0x10, 4);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
-
-	ret = ddf_fun_bind(instance->rh_fun);
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
-
-	device->driver_data = instance;
-	return EOK;
-#undef CHECK_RET_FINI_RETURN
-}
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/uhci.h
===================================================================
--- uspace/drv/uhci_hcd/uhci.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,43 +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 drvusbuhci
- * @{
- */
-/** @file
- * @brief UHCI driver main structure for both host controller and root-hub.
- */
-#ifndef DRV_UHCI_UHCI_H
-#define DRV_UHCI_UHCI_H
-#include <ddf/driver.h>
-
-int device_setup_uhci(ddf_dev_t *device);
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_hcd/uhci_hcd.ma
===================================================================
--- uspace/drv/uhci_hcd/uhci_hcd.ma	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,29 +1,0 @@
-10 pci/ven=8086&dev=7020
-10 pci/ven=8086&dev=7112
-
-10 pci/ven=8086&dev=27c8
-10 pci/ven=8086&dev=27c9
-10 pci/ven=8086&dev=27ca
-10 pci/ven=8086&dev=27cb
-
-10 pci/ven=8086&dev=2830
-10 pci/ven=8086&dev=2831
-10 pci/ven=8086&dev=2832
-10 pci/ven=8086&dev=2834
-10 pci/ven=8086&dev=2835
-
-10 pci/ven=8086&dev=2934
-10 pci/ven=8086&dev=2935
-10 pci/ven=8086&dev=2936
-10 pci/ven=8086&dev=2937
-10 pci/ven=8086&dev=2938
-10 pci/ven=8086&dev=2939
-
-10 pci/ven=8086&dev=24c2
-10 pci/ven=8086&dev=24c4
-10 pci/ven=8086&dev=24c7
-
-10 pci/ven=8086&dev=2688
-10 pci/ven=8086&dev=2689
-10 pci/ven=8086&dev=268a
-10 pci/ven=8086&dev=268b
Index: pace/drv/uhci_hcd/utils/malloc32.h
===================================================================
--- uspace/drv/uhci_hcd/utils/malloc32.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,114 +1,0 @@
-/*
- * Copyright (c) 2010 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 drvusbuhci
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_UTILS_MALLOC32_H
-#define DRV_UHCI_UTILS_MALLOC32_H
-
-#include <assert.h>
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-#include <as.h>
-
-#define UHCI_STRCUTURES_ALIGNMENT 16
-#define UHCI_REQUIRED_PAGE_SIZE 4096
-
-
-/** Get physical address translation
- *
- * @param[in] addr Virtual address to translate
- * @return Physical address if exists, NULL otherwise.
- */
-static inline uintptr_t addr_to_phys(void *addr)
-{
-	if (addr == NULL)
-		return 0;
-
-	uintptr_t result;
-	const int ret = as_get_physical_mapping(addr, &result);
-	if (ret != EOK)
-		return 0;
-	return (result | ((uintptr_t)addr & 0xfff));
-}
-/*----------------------------------------------------------------------------*/
-/** Physical mallocator simulator
- *
- * @param[in] size Size of the required memory space
- * @return Address of the alligned and big enough memory place, NULL on failure.
- */
-static inline void * malloc32(size_t size) {
-	/* This works only when the host has less than 4GB of memory as
-	 * physical address needs to fit into 32 bits */
-
-	/* If we need more than one page there is no guarantee that the
-	 * memory will be continuous */
-	if (size > PAGE_SIZE)
-		return NULL;
-	/* Calculate alignment to make sure the block won't cross page
-	 * boundary */
-	size_t alignment = UHCI_STRCUTURES_ALIGNMENT;
-	while (alignment < size)
-		alignment *= 2;
-	return memalign(alignment, size);
-}
-/*----------------------------------------------------------------------------*/
-/** Physical mallocator simulator
- *
- * @param[in] addr Address of the place allocated by malloc32
- */
-static inline void free32(void *addr) {
-	if (!addr)
-		return;
-	free(addr);
-}
-/*----------------------------------------------------------------------------*/
-/** Create 4KB page mapping
- *
- * @return Address of the mapped page, NULL on failure.
- */
-static inline void * get_page(void)
-{
-	void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
-	if (free_address == 0)
-		return NULL;
-	void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
-		  AS_AREA_READ | AS_AREA_WRITE);
-	if (ret != free_address)
-		return NULL;
-	return ret;
-}
-
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_rhd/Makefile
===================================================================
--- uspace/drv/uhci_rhd/Makefile	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,47 +1,0 @@
-#
-# Copyright (c) 2010 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.
-#
-
-USPACE_PREFIX = ../..
-
-LIBS = \
-	$(LIBUSBDEV_PREFIX)/libusbdev.a \
-	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS += \
-	-I$(LIBUSB_PREFIX)/include \
-	-I$(LIBUSBDEV_PREFIX)/include \
-	-I$(LIBDRV_PREFIX)/include
-
-BINARY = uhci_rhd
-
-SOURCES = \
-	main.c \
-	port.c \
-	root_hub.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/drv/uhci_rhd/main.c
===================================================================
--- uspace/drv/uhci_rhd/main.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,182 +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 drvusbuhcirh
- * @{
- */
-/** @file
- * @brief UHCI root hub initialization routines
- */
-
-#include <ddf/driver.h>
-#include <devman.h>
-#include <device/hw_res.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb_iface.h>
-#include <usb/ddfiface.h>
-#include <usb/debug.h>
-
-#include "root_hub.h"
-
-#define NAME "uhci_rhd"
-
-static int hc_get_my_registers(const ddf_dev_t *dev,
-    uintptr_t *io_reg_address, size_t *io_reg_size);
-
-static int uhci_rh_add_device(ddf_dev_t *device);
-
-static driver_ops_t uhci_rh_driver_ops = {
-	.add_device = uhci_rh_add_device,
-};
-
-static driver_t uhci_rh_driver = {
-	.name = NAME,
-	.driver_ops = &uhci_rh_driver_ops
-};
-
-/** Initialize global driver structures (NONE).
- *
- * @param[in] argc Nmber of arguments in argv vector (ignored).
- * @param[in] argv Cmdline argument vector (ignored).
- * @return Error code.
- *
- * Driver debug level is set here.
- */
-int main(int argc, char *argv[])
-{
-	printf(NAME ": HelenOS UHCI root hub driver.\n");
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
-	return ddf_driver_main(&uhci_rh_driver);
-}
-
-/** Initialize a new ddf driver instance of UHCI root hub.
- *
- * @param[in] device DDF instance of the device to initialize.
- * @return Error code.
- */
-static int uhci_rh_add_device(ddf_dev_t *device)
-{
-	if (!device)
-		return EINVAL;
-
-	usb_log_debug2("uhci_rh_add_device(handle=%" PRIun ")\n",
-	    device->handle);
-
-	uintptr_t io_regs = 0;
-	size_t io_size = 0;
-	uhci_root_hub_t *rh = NULL;
-	int ret = EOK;
-
-#define CHECK_RET_FREE_RH_RETURN(ret, message...) \
-if (ret != EOK) { \
-	usb_log_error(message); \
-	if (rh) \
-		free(rh); \
-	return ret; \
-} else (void)0
-
-	ret = hc_get_my_registers(device, &io_regs, &io_size);
-	CHECK_RET_FREE_RH_RETURN(ret,
-	    "Failed to get registers from HC: %s.\n", str_error(ret));
-	usb_log_debug("I/O regs at %p (size %zuB).\n",
-	    (void *) io_regs, io_size);
-
-	rh = malloc(sizeof(uhci_root_hub_t));
-	ret = (rh == NULL) ? ENOMEM : EOK;
-	CHECK_RET_FREE_RH_RETURN(ret,
-	    "Failed to allocate rh driver instance.\n");
-
-	ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
-	CHECK_RET_FREE_RH_RETURN(ret,
-	    "Failed(%d) to initialize rh driver instance: %s.\n",
-	    ret, str_error(ret));
-
-	device->driver_data = rh;
-	usb_log_info("Controlling root hub '%s' (%" PRIun ").\n",
-	    device->name, device->handle);
-	return EOK;
-}
-
-/** Get address of I/O registers.
- *
- * @param[in] dev Device asking for the addresses.
- * @param[out] io_reg_address Base address of the memory range.
- * @param[out] io_reg_size Size of the memory range.
- * @return Error code.
- */
-int hc_get_my_registers(
-    const ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
-{
-	assert(dev);
-	
-	async_sess_t *parent_sess =
-	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (!parent_sess)
-		return ENOMEM;
-	
-	hw_resource_list_t hw_resources;
-	const int ret = hw_res_get_resource_list(parent_sess, &hw_resources);
-	if (ret != EOK) {
-		async_hangup(parent_sess);
-		return ret;
-	}
-	
-	uintptr_t io_address = 0;
-	size_t io_size = 0;
-	bool io_found = false;
-	
-	size_t i = 0;
-	for (; i < hw_resources.count; i++) {
-		hw_resource_t *res = &hw_resources.resources[i];
-		if (res->type == IO_RANGE) {
-			io_address = res->res.io_range.address;
-			io_size = res->res.io_range.size;
-			io_found = true;
-		}
-	
-	}
-	async_hangup(parent_sess);
-	
-	if (!io_found)
-		return ENOENT;
-	
-	if (io_reg_address != NULL)
-		*io_reg_address = io_address;
-	
-	if (io_reg_size != NULL)
-		*io_reg_size = io_size;
-	
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/drv/uhci_rhd/port.c
===================================================================
--- uspace/drv/uhci_rhd/port.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,355 +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 drvusbuhcirh
- * @{
- */
-/** @file
- * @brief UHCI root hub port routines
- */
-#include <libarch/ddi.h>  /* pio_read and pio_write */
-#include <fibril_synch.h> /* async_usleep */
-#include <errno.h>
-#include <str_error.h>
-#include <async.h>
-
-#include <usb/usb.h>    /* usb_address_t */
-#include <usb/dev/hub.h>    /* usb_hc_new_device_wrapper */
-#include <usb/debug.h>
-
-#include "port.h"
-
-static int uhci_port_check(void *port);
-static int uhci_port_reset_enable(int portno, void *arg);
-static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
-static int uhci_port_remove_device(uhci_port_t *port);
-static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
-static void uhci_port_print_status(
-    uhci_port_t *port, const port_status_t value);
-
-/** Register reading helper function.
- *
- * @param[in] port Structure to use.
- * @return Error code. (Always EOK)
- */
-static inline port_status_t uhci_port_read_status(uhci_port_t *port)
-{
-	assert(port);
-	return pio_read_16(port->address);
-}
-/*----------------------------------------------------------------------------*/
-/** Register writing helper function.
- *
- * @param[in] port Structure to use.
- * @param[in] val New register value.
- * @return Error code. (Always EOK)
- */
-static inline void uhci_port_write_status(uhci_port_t *port, port_status_t val)
-{
-	assert(port);
-	pio_write_16(port->address, val);
-}
-/*----------------------------------------------------------------------------*/
-/** Initialize UHCI root hub port instance.
- *
- * @param[in] port Memory structure to use.
- * @param[in] address Address of I/O register.
- * @param[in] number Port number.
- * @param[in] usec Polling interval.
- * @param[in] rh Pointer to ddf instance of the root hub driver.
- * @return Error code.
- *
- * Creates and starts the polling fibril.
- */
-int uhci_port_init(uhci_port_t *port,
-    port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
-{
-	assert(port);
-	char *id_string;
-	asprintf(&id_string, "Port (%p - %u)", port, number);
-	if (id_string == NULL) {
-		return ENOMEM;
-	}
-
-	port->id_string = id_string;
-	port->address = address;
-	port->number = number;
-	port->wait_period_usec = usec;
-	port->attached_device = 0;
-	port->rh = rh;
-
-	int ret =
-	    usb_hc_connection_initialize_from_device(&port->hc_connection, rh);
-	if (ret != EOK) {
-		usb_log_error("%s: failed to initialize connection to HC.",
-		    port->id_string);
-		free(id_string);
-		return ret;
-	}
-
-	port->checker = fibril_create(uhci_port_check, port);
-	if (port->checker == 0) {
-		usb_log_error("%s: failed to create polling fibril.",
-		    port->id_string);
-		free(id_string);
-		return ENOMEM;
-	}
-
-	fibril_add_ready(port->checker);
-	usb_log_debug("%s: Started polling fibril (%" PRIun ").\n",
-	    port->id_string, port->checker);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Cleanup UHCI root hub port instance.
- *
- * @param[in] port Memory structure to use.
- *
- * Stops the polling fibril.
- */
-void uhci_port_fini(uhci_port_t *port)
-{
-	assert(port);
-	free(port->id_string);
-	// TODO: Kill fibril here
-	return;
-}
-/*----------------------------------------------------------------------------*/
-/** Periodically checks port status and reports new devices.
- *
- * @param[in] port Port structure to use.
- * @return Error code.
- */
-int uhci_port_check(void *port)
-{
-	uhci_port_t *instance = port;
-	assert(instance);
-
-	while (1) {
-		async_usleep(instance->wait_period_usec);
-
-		/* Read register value */
-		const port_status_t port_status =
-		    uhci_port_read_status(instance);
-
-		/* Print the value if it's interesting */
-		if (port_status & ~STATUS_ALWAYS_ONE)
-			uhci_port_print_status(instance, port_status);
-
-		if ((port_status & STATUS_CONNECTED_CHANGED) == 0)
-			continue;
-
-		usb_log_debug("%s: Connected change detected: %x.\n",
-		    instance->id_string, port_status);
-
-		/* Remove any old device */
-		if (instance->attached_device) {
-			usb_log_debug2("%s: Removing device.\n",
-			    instance->id_string);
-			uhci_port_remove_device(instance);
-		}
-
-		int ret =
-		    usb_hc_connection_open(&instance->hc_connection);
-		if (ret != EOK) {
-			usb_log_error("%s: Failed to connect to HC.",
-			    instance->id_string);
-			continue;
-		}
-
-		if ((port_status & STATUS_CONNECTED) != 0) {
-			/* New device */
-			const usb_speed_t speed =
-			    ((port_status & STATUS_LOW_SPEED) != 0) ?
-			    USB_SPEED_LOW : USB_SPEED_FULL;
-			uhci_port_new_device(instance, speed);
-		} else {
-			/* Write one to WC bits, to ack changes */
-			uhci_port_write_status(instance, port_status);
-			usb_log_debug("%s: status change ACK.\n",
-			    instance->id_string);
-		}
-
-		ret = usb_hc_connection_close(&instance->hc_connection);
-		if (ret != EOK) {
-			usb_log_error("%s: Failed to disconnect.",
-			    instance->id_string);
-		}
-	}
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Callback for enabling port during adding a new device.
- *
- * @param portno Port number (unused).
- * @param arg Pointer to uhci_port_t of port with the new device.
- * @return Error code.
- *
- * Resets and enables the ub port.
- */
-int uhci_port_reset_enable(int portno, void *arg)
-{
-	uhci_port_t *port = arg;
-	assert(port);
-
-	usb_log_debug2("%s: new_device_enable_port.\n", port->id_string);
-
-	/*
-	 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3)
-	 */
-	{
-		usb_log_debug("%s: Reset Signal start.\n", port->id_string);
-		port_status_t port_status = uhci_port_read_status(port);
-		port_status |= STATUS_IN_RESET;
-		uhci_port_write_status(port, port_status);
-		async_usleep(50000);
-		port_status = uhci_port_read_status(port);
-		port_status &= ~STATUS_IN_RESET;
-		uhci_port_write_status(port, port_status);
-		while (uhci_port_read_status(port) & STATUS_IN_RESET);
-	}
-	/* PIO delay, should not be longer than 3ms as the device might
-	 * enter suspend state. */
-	udelay(10);
-	/* Enable the port. */
-	uhci_port_set_enabled(port, true);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Initialize and report connected device.
- *
- * @param[in] port Port structure to use.
- * @param[in] speed Detected speed.
- * @return Error code.
- *
- * Uses libUSB function to do the actual work.
- */
-int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
-{
-	assert(port);
-	assert(usb_hc_connection_is_opened(&port->hc_connection));
-
-	usb_log_debug("%s: Detected new device.\n", port->id_string);
-
-	int ret, count = 0;
-	usb_address_t dev_addr;
-	do {
-		ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
-		    speed, uhci_port_reset_enable, port->number, port,
-		    &dev_addr, &port->attached_device, NULL, NULL, NULL);
-	} while (ret != EOK && ++count < 4);
-
-	if (ret != EOK) {
-		usb_log_error("%s: Failed(%d) to add device: %s.\n",
-		    port->id_string, ret, str_error(ret));
-		uhci_port_set_enabled(port, false);
-		return ret;
-	}
-
-	usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n",
-	    port->number, dev_addr, port->attached_device);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Remove device.
- *
- * @param[in] port Memory structure to use.
- * @return Error code.
- *
- * Does not work, DDF does not support device removal.
- * Does not even free used USB address (it would be dangerous if tis driver
- * is still running).
- */
-int uhci_port_remove_device(uhci_port_t *port)
-{
-	usb_log_error("%s: Don't know how to remove device %" PRIun ".\n",
-	    port->id_string, port->attached_device);
-	port->attached_device = 0;
-	return ENOTSUP;
-}
-/*----------------------------------------------------------------------------*/
-/** Enable or disable root hub port.
- *
- * @param[in] port Port structure to use.
- * @param[in] enabled Port status to set.
- * @return Error code. (Always EOK)
- */
-int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
-{
-	assert(port);
-
-	/* Read register value */
-	port_status_t port_status = uhci_port_read_status(port);
-
-	/* Set enabled bit */
-	if (enabled) {
-		port_status |= STATUS_ENABLED;
-	} else {
-		port_status &= ~STATUS_ENABLED;
-	}
-
-	/* Write new value. */
-	uhci_port_write_status(port, port_status);
-
-	/* Wait for port to become enabled */
-	do {
-		port_status = uhci_port_read_status(port);
-	} while ((port_status & STATUS_CONNECTED) &&
-	    !(port_status & STATUS_ENABLED));
-
-	usb_log_debug("%s: %sabled port.\n",
-		port->id_string, enabled ? "En" : "Dis");
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Print the port status value in a human friendly way
- *
- * @param[in] port Port structure to use.
- * @param[in] value Port register value to print.
- * @return Error code. (Always EOK)
- */
-void uhci_port_print_status(uhci_port_t *port, const port_status_t value)
-{
-	assert(port);
-	usb_log_debug2("%s Port status(%#x):%s%s%s%s%s%s%s%s%s%s%s.\n",
-	    port->id_string, value,
-	    (value & STATUS_SUSPEND) ? " SUSPENDED," : "",
-	    (value & STATUS_RESUME) ? " IN RESUME," : "",
-	    (value & STATUS_IN_RESET) ? " IN RESET," : "",
-	    (value & STATUS_LINE_D_MINUS) ? " VD-," : "",
-	    (value & STATUS_LINE_D_PLUS) ? " VD+," : "",
-	    (value & STATUS_LOW_SPEED) ? " LOWSPEED," : "",
-	    (value & STATUS_ENABLED_CHANGED) ? " ENABLED-CHANGE," : "",
-	    (value & STATUS_ENABLED) ? " ENABLED," : "",
-	    (value & STATUS_CONNECTED_CHANGED) ? " CONNECTED-CHANGE," : "",
-	    (value & STATUS_CONNECTED) ? " CONNECTED," : "",
-	    (value & STATUS_ALWAYS_ONE) ? " ALWAYS ONE" : " ERR: NO ALWAYS ONE"
-	);
-}
-/**
- * @}
- */
Index: pace/drv/uhci_rhd/port.h
===================================================================
--- uspace/drv/uhci_rhd/port.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,77 +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 drvusbuhcirh
- * @{
- */
-/** @file
- * @brief UHCI root hub port routines
- */
-#ifndef DRV_UHCI_PORT_H
-#define DRV_UHCI_PORT_H
-
-#include <stdint.h>
-#include <fibril.h>
-#include <ddf/driver.h>
-#include <usb/hc.h> /* usb_hc_connection_t */
-
-typedef uint16_t port_status_t;
-#define STATUS_CONNECTED         (1 << 0)
-#define STATUS_CONNECTED_CHANGED (1 << 1)
-#define STATUS_ENABLED           (1 << 2)
-#define STATUS_ENABLED_CHANGED   (1 << 3)
-#define STATUS_LINE_D_PLUS       (1 << 4)
-#define STATUS_LINE_D_MINUS      (1 << 5)
-#define STATUS_RESUME            (1 << 6)
-#define STATUS_ALWAYS_ONE        (1 << 7)
-
-#define STATUS_LOW_SPEED (1 <<  8)
-#define STATUS_IN_RESET  (1 <<  9)
-#define STATUS_SUSPEND   (1 << 12)
-
-/** UHCI port structure */
-typedef struct uhci_port {
-	const char *id_string;
-	port_status_t *address;
-	unsigned number;
-	unsigned wait_period_usec;
-	usb_hc_connection_t hc_connection;
-	ddf_dev_t *rh;
-	devman_handle_t attached_device;
-	fid_t checker;
-} uhci_port_t;
-
-int uhci_port_init(
-    uhci_port_t *port, port_status_t *address, unsigned number,
-    unsigned usec, ddf_dev_t *rh);
-
-void uhci_port_fini(uhci_port_t *port);
-
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_rhd/root_hub.c
===================================================================
--- uspace/drv/uhci_rhd/root_hub.c	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,97 +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 drvusbuhcirh
- * @{
- */
-/** @file
- * @brief UHCI root hub driver
- */
-#include <errno.h>
-#include <str_error.h>
-#include <ddi.h>
-#include <usb/debug.h>
-
-#include "root_hub.h"
-
-/** Initialize UHCI root hub instance.
- *
- * @param[in] instance Driver memory structure to use.
- * @param[in] addr Address of I/O registers.
- * @param[in] size Size of available I/O space.
- * @param[in] rh Pointer to DDF instance of the root hub driver.
- * @return Error code.
- */
-int uhci_root_hub_init(
-  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
-{
-	assert(instance);
-	assert(rh);
-
-	/* Allow access to root hub port registers */
-	assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size);
-	port_status_t *regs;
-	int ret = pio_enable(addr, size, (void**)&regs);
-	if (ret < 0) {
-		usb_log_error(
-		    "Failed(%d) to gain access to port registers at %p: %s.\n",
-		    ret, regs, str_error(ret));
-		return ret;
-	}
-
-	/* Initialize root hub ports */
-	unsigned i = 0;
-	for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
-		ret = uhci_port_init(
-		    &instance->ports[i], &regs[i], i, ROOT_HUB_WAIT_USEC, rh);
-		if (ret != EOK) {
-			unsigned j = 0;
-			for (;j < i; ++j)
-				uhci_port_fini(&instance->ports[j]);
-			return ret;
-		}
-	}
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-/** Cleanup UHCI root hub instance.
- *
- * @param[in] instance Root hub structure to use.
- */
-void uhci_root_hub_fini(uhci_root_hub_t* instance)
-{
-	assert(instance);
-	unsigned i = 0;
-	for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
-		uhci_port_fini(&instance->ports[i]);
-	}
-}
-/*----------------------------------------------------------------------------*/
-/**
- * @}
- */
Index: pace/drv/uhci_rhd/root_hub.h
===================================================================
--- uspace/drv/uhci_rhd/root_hub.h	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,57 +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 drvusbuhcirh
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_ROOT_HUB_H
-#define DRV_UHCI_ROOT_HUB_H
-
-#include <ddf/driver.h>
-
-#include "port.h"
-
-#define UHCI_ROOT_HUB_PORT_COUNT 2
-#define ROOT_HUB_WAIT_USEC 250000 /* 250 miliseconds */
-
-/** UHCI root hub drvier structure */
-typedef struct root_hub {
-	/** Ports provided by the hub */
-	uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT];
-} uhci_root_hub_t;
-
-int uhci_root_hub_init(
-    uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh);
-
-void uhci_root_hub_fini(uhci_root_hub_t *instance);
-#endif
-/**
- * @}
- */
Index: pace/drv/uhci_rhd/uhci_rhd.ma
===================================================================
--- uspace/drv/uhci_rhd/uhci_rhd.ma	(revision c4fb5ecd0a4e0a7c884639ad36c66c4344f7b200)
+++ 	(revision )
@@ -1,1 +1,0 @@
-10 usb&uhci&root-hub
Index: uspace/drv/uhcirh/Makefile
===================================================================
--- uspace/drv/uhcirh/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/Makefile	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2010 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.
+#
+
+USPACE_PREFIX = ../..
+
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
+BINARY = uhcirh
+
+SOURCES = \
+	main.c \
+	port.c \
+	root_hub.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/uhcirh/main.c
===================================================================
--- uspace/drv/uhcirh/main.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/main.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,182 @@
+/*
+ * 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 drvusbuhcirh
+ * @{
+ */
+/** @file
+ * @brief UHCI root hub initialization routines
+ */
+
+#include <ddf/driver.h>
+#include <devman.h>
+#include <device/hw_res.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb_iface.h>
+#include <usb/ddfiface.h>
+#include <usb/debug.h>
+
+#include "root_hub.h"
+
+#define NAME "uhcirh"
+
+static int hc_get_my_registers(const ddf_dev_t *dev,
+    uintptr_t *io_reg_address, size_t *io_reg_size);
+
+static int uhci_rh_add_device(ddf_dev_t *device);
+
+static driver_ops_t uhci_rh_driver_ops = {
+	.add_device = uhci_rh_add_device,
+};
+
+static driver_t uhci_rh_driver = {
+	.name = NAME,
+	.driver_ops = &uhci_rh_driver_ops
+};
+
+/** Initialize global driver structures (NONE).
+ *
+ * @param[in] argc Nmber of arguments in argv vector (ignored).
+ * @param[in] argv Cmdline argument vector (ignored).
+ * @return Error code.
+ *
+ * Driver debug level is set here.
+ */
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS UHCI root hub driver.\n");
+	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	return ddf_driver_main(&uhci_rh_driver);
+}
+
+/** Initialize a new ddf driver instance of UHCI root hub.
+ *
+ * @param[in] device DDF instance of the device to initialize.
+ * @return Error code.
+ */
+static int uhci_rh_add_device(ddf_dev_t *device)
+{
+	if (!device)
+		return EINVAL;
+
+	usb_log_debug2("uhci_rh_add_device(handle=%" PRIun ")\n",
+	    device->handle);
+
+	uintptr_t io_regs = 0;
+	size_t io_size = 0;
+	uhci_root_hub_t *rh = NULL;
+	int ret = EOK;
+
+#define CHECK_RET_FREE_RH_RETURN(ret, message...) \
+if (ret != EOK) { \
+	usb_log_error(message); \
+	if (rh) \
+		free(rh); \
+	return ret; \
+} else (void)0
+
+	ret = hc_get_my_registers(device, &io_regs, &io_size);
+	CHECK_RET_FREE_RH_RETURN(ret,
+	    "Failed to get registers from HC: %s.\n", str_error(ret));
+	usb_log_debug("I/O regs at %p (size %zuB).\n",
+	    (void *) io_regs, io_size);
+
+	rh = malloc(sizeof(uhci_root_hub_t));
+	ret = (rh == NULL) ? ENOMEM : EOK;
+	CHECK_RET_FREE_RH_RETURN(ret,
+	    "Failed to allocate rh driver instance.\n");
+
+	ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
+	CHECK_RET_FREE_RH_RETURN(ret,
+	    "Failed(%d) to initialize rh driver instance: %s.\n",
+	    ret, str_error(ret));
+
+	device->driver_data = rh;
+	usb_log_info("Controlling root hub '%s' (%" PRIun ").\n",
+	    device->name, device->handle);
+	return EOK;
+}
+
+/** Get address of I/O registers.
+ *
+ * @param[in] dev Device asking for the addresses.
+ * @param[out] io_reg_address Base address of the memory range.
+ * @param[out] io_reg_size Size of the memory range.
+ * @return Error code.
+ */
+int hc_get_my_registers(
+    const ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
+{
+	assert(dev);
+	
+	async_sess_t *parent_sess =
+	    devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (!parent_sess)
+		return ENOMEM;
+	
+	hw_resource_list_t hw_resources;
+	const int ret = hw_res_get_resource_list(parent_sess, &hw_resources);
+	if (ret != EOK) {
+		async_hangup(parent_sess);
+		return ret;
+	}
+	
+	uintptr_t io_address = 0;
+	size_t io_size = 0;
+	bool io_found = false;
+	
+	size_t i = 0;
+	for (; i < hw_resources.count; i++) {
+		hw_resource_t *res = &hw_resources.resources[i];
+		if (res->type == IO_RANGE) {
+			io_address = res->res.io_range.address;
+			io_size = res->res.io_range.size;
+			io_found = true;
+		}
+	
+	}
+	async_hangup(parent_sess);
+	
+	if (!io_found)
+		return ENOENT;
+	
+	if (io_reg_address != NULL)
+		*io_reg_address = io_address;
+	
+	if (io_reg_size != NULL)
+		*io_reg_size = io_size;
+	
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/uhcirh/port.c
===================================================================
--- uspace/drv/uhcirh/port.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/port.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,355 @@
+/*
+ * 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 drvusbuhcirh
+ * @{
+ */
+/** @file
+ * @brief UHCI root hub port routines
+ */
+#include <libarch/ddi.h>  /* pio_read and pio_write */
+#include <fibril_synch.h> /* async_usleep */
+#include <errno.h>
+#include <str_error.h>
+#include <async.h>
+
+#include <usb/usb.h>    /* usb_address_t */
+#include <usb/dev/hub.h>    /* usb_hc_new_device_wrapper */
+#include <usb/debug.h>
+
+#include "port.h"
+
+static int uhci_port_check(void *port);
+static int uhci_port_reset_enable(int portno, void *arg);
+static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
+static int uhci_port_remove_device(uhci_port_t *port);
+static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
+static void uhci_port_print_status(
+    uhci_port_t *port, const port_status_t value);
+
+/** Register reading helper function.
+ *
+ * @param[in] port Structure to use.
+ * @return Error code. (Always EOK)
+ */
+static inline port_status_t uhci_port_read_status(uhci_port_t *port)
+{
+	assert(port);
+	return pio_read_16(port->address);
+}
+/*----------------------------------------------------------------------------*/
+/** Register writing helper function.
+ *
+ * @param[in] port Structure to use.
+ * @param[in] val New register value.
+ * @return Error code. (Always EOK)
+ */
+static inline void uhci_port_write_status(uhci_port_t *port, port_status_t val)
+{
+	assert(port);
+	pio_write_16(port->address, val);
+}
+/*----------------------------------------------------------------------------*/
+/** Initialize UHCI root hub port instance.
+ *
+ * @param[in] port Memory structure to use.
+ * @param[in] address Address of I/O register.
+ * @param[in] number Port number.
+ * @param[in] usec Polling interval.
+ * @param[in] rh Pointer to ddf instance of the root hub driver.
+ * @return Error code.
+ *
+ * Creates and starts the polling fibril.
+ */
+int uhci_port_init(uhci_port_t *port,
+    port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
+{
+	assert(port);
+	char *id_string;
+	asprintf(&id_string, "Port (%p - %u)", port, number);
+	if (id_string == NULL) {
+		return ENOMEM;
+	}
+
+	port->id_string = id_string;
+	port->address = address;
+	port->number = number;
+	port->wait_period_usec = usec;
+	port->attached_device = 0;
+	port->rh = rh;
+
+	int ret =
+	    usb_hc_connection_initialize_from_device(&port->hc_connection, rh);
+	if (ret != EOK) {
+		usb_log_error("%s: failed to initialize connection to HC.",
+		    port->id_string);
+		free(id_string);
+		return ret;
+	}
+
+	port->checker = fibril_create(uhci_port_check, port);
+	if (port->checker == 0) {
+		usb_log_error("%s: failed to create polling fibril.",
+		    port->id_string);
+		free(id_string);
+		return ENOMEM;
+	}
+
+	fibril_add_ready(port->checker);
+	usb_log_debug("%s: Started polling fibril (%" PRIun ").\n",
+	    port->id_string, port->checker);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Cleanup UHCI root hub port instance.
+ *
+ * @param[in] port Memory structure to use.
+ *
+ * Stops the polling fibril.
+ */
+void uhci_port_fini(uhci_port_t *port)
+{
+	assert(port);
+	free(port->id_string);
+	// TODO: Kill fibril here
+	return;
+}
+/*----------------------------------------------------------------------------*/
+/** Periodically checks port status and reports new devices.
+ *
+ * @param[in] port Port structure to use.
+ * @return Error code.
+ */
+int uhci_port_check(void *port)
+{
+	uhci_port_t *instance = port;
+	assert(instance);
+
+	while (1) {
+		async_usleep(instance->wait_period_usec);
+
+		/* Read register value */
+		const port_status_t port_status =
+		    uhci_port_read_status(instance);
+
+		/* Print the value if it's interesting */
+		if (port_status & ~STATUS_ALWAYS_ONE)
+			uhci_port_print_status(instance, port_status);
+
+		if ((port_status & STATUS_CONNECTED_CHANGED) == 0)
+			continue;
+
+		usb_log_debug("%s: Connected change detected: %x.\n",
+		    instance->id_string, port_status);
+
+		/* Remove any old device */
+		if (instance->attached_device) {
+			usb_log_debug2("%s: Removing device.\n",
+			    instance->id_string);
+			uhci_port_remove_device(instance);
+		}
+
+		int ret =
+		    usb_hc_connection_open(&instance->hc_connection);
+		if (ret != EOK) {
+			usb_log_error("%s: Failed to connect to HC.",
+			    instance->id_string);
+			continue;
+		}
+
+		if ((port_status & STATUS_CONNECTED) != 0) {
+			/* New device */
+			const usb_speed_t speed =
+			    ((port_status & STATUS_LOW_SPEED) != 0) ?
+			    USB_SPEED_LOW : USB_SPEED_FULL;
+			uhci_port_new_device(instance, speed);
+		} else {
+			/* Write one to WC bits, to ack changes */
+			uhci_port_write_status(instance, port_status);
+			usb_log_debug("%s: status change ACK.\n",
+			    instance->id_string);
+		}
+
+		ret = usb_hc_connection_close(&instance->hc_connection);
+		if (ret != EOK) {
+			usb_log_error("%s: Failed to disconnect.",
+			    instance->id_string);
+		}
+	}
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Callback for enabling port during adding a new device.
+ *
+ * @param portno Port number (unused).
+ * @param arg Pointer to uhci_port_t of port with the new device.
+ * @return Error code.
+ *
+ * Resets and enables the ub port.
+ */
+int uhci_port_reset_enable(int portno, void *arg)
+{
+	uhci_port_t *port = arg;
+	assert(port);
+
+	usb_log_debug2("%s: new_device_enable_port.\n", port->id_string);
+
+	/*
+	 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3)
+	 */
+	{
+		usb_log_debug("%s: Reset Signal start.\n", port->id_string);
+		port_status_t port_status = uhci_port_read_status(port);
+		port_status |= STATUS_IN_RESET;
+		uhci_port_write_status(port, port_status);
+		async_usleep(50000);
+		port_status = uhci_port_read_status(port);
+		port_status &= ~STATUS_IN_RESET;
+		uhci_port_write_status(port, port_status);
+		while (uhci_port_read_status(port) & STATUS_IN_RESET);
+	}
+	/* PIO delay, should not be longer than 3ms as the device might
+	 * enter suspend state. */
+	udelay(10);
+	/* Enable the port. */
+	uhci_port_set_enabled(port, true);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Initialize and report connected device.
+ *
+ * @param[in] port Port structure to use.
+ * @param[in] speed Detected speed.
+ * @return Error code.
+ *
+ * Uses libUSB function to do the actual work.
+ */
+int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
+{
+	assert(port);
+	assert(usb_hc_connection_is_opened(&port->hc_connection));
+
+	usb_log_debug("%s: Detected new device.\n", port->id_string);
+
+	int ret, count = 0;
+	usb_address_t dev_addr;
+	do {
+		ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
+		    speed, uhci_port_reset_enable, port->number, port,
+		    &dev_addr, &port->attached_device, NULL, NULL, NULL);
+	} while (ret != EOK && ++count < 4);
+
+	if (ret != EOK) {
+		usb_log_error("%s: Failed(%d) to add device: %s.\n",
+		    port->id_string, ret, str_error(ret));
+		uhci_port_set_enabled(port, false);
+		return ret;
+	}
+
+	usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n",
+	    port->number, dev_addr, port->attached_device);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Remove device.
+ *
+ * @param[in] port Memory structure to use.
+ * @return Error code.
+ *
+ * Does not work, DDF does not support device removal.
+ * Does not even free used USB address (it would be dangerous if tis driver
+ * is still running).
+ */
+int uhci_port_remove_device(uhci_port_t *port)
+{
+	usb_log_error("%s: Don't know how to remove device %" PRIun ".\n",
+	    port->id_string, port->attached_device);
+	port->attached_device = 0;
+	return ENOTSUP;
+}
+/*----------------------------------------------------------------------------*/
+/** Enable or disable root hub port.
+ *
+ * @param[in] port Port structure to use.
+ * @param[in] enabled Port status to set.
+ * @return Error code. (Always EOK)
+ */
+int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
+{
+	assert(port);
+
+	/* Read register value */
+	port_status_t port_status = uhci_port_read_status(port);
+
+	/* Set enabled bit */
+	if (enabled) {
+		port_status |= STATUS_ENABLED;
+	} else {
+		port_status &= ~STATUS_ENABLED;
+	}
+
+	/* Write new value. */
+	uhci_port_write_status(port, port_status);
+
+	/* Wait for port to become enabled */
+	do {
+		port_status = uhci_port_read_status(port);
+	} while ((port_status & STATUS_CONNECTED) &&
+	    !(port_status & STATUS_ENABLED));
+
+	usb_log_debug("%s: %sabled port.\n",
+		port->id_string, enabled ? "En" : "Dis");
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Print the port status value in a human friendly way
+ *
+ * @param[in] port Port structure to use.
+ * @param[in] value Port register value to print.
+ * @return Error code. (Always EOK)
+ */
+void uhci_port_print_status(uhci_port_t *port, const port_status_t value)
+{
+	assert(port);
+	usb_log_debug2("%s Port status(%#x):%s%s%s%s%s%s%s%s%s%s%s.\n",
+	    port->id_string, value,
+	    (value & STATUS_SUSPEND) ? " SUSPENDED," : "",
+	    (value & STATUS_RESUME) ? " IN RESUME," : "",
+	    (value & STATUS_IN_RESET) ? " IN RESET," : "",
+	    (value & STATUS_LINE_D_MINUS) ? " VD-," : "",
+	    (value & STATUS_LINE_D_PLUS) ? " VD+," : "",
+	    (value & STATUS_LOW_SPEED) ? " LOWSPEED," : "",
+	    (value & STATUS_ENABLED_CHANGED) ? " ENABLED-CHANGE," : "",
+	    (value & STATUS_ENABLED) ? " ENABLED," : "",
+	    (value & STATUS_CONNECTED_CHANGED) ? " CONNECTED-CHANGE," : "",
+	    (value & STATUS_CONNECTED) ? " CONNECTED," : "",
+	    (value & STATUS_ALWAYS_ONE) ? " ALWAYS ONE" : " ERR: NO ALWAYS ONE"
+	);
+}
+/**
+ * @}
+ */
Index: uspace/drv/uhcirh/port.h
===================================================================
--- uspace/drv/uhcirh/port.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/port.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,77 @@
+/*
+ * 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 drvusbuhcirh
+ * @{
+ */
+/** @file
+ * @brief UHCI root hub port routines
+ */
+#ifndef DRV_UHCI_PORT_H
+#define DRV_UHCI_PORT_H
+
+#include <stdint.h>
+#include <fibril.h>
+#include <ddf/driver.h>
+#include <usb/hc.h> /* usb_hc_connection_t */
+
+typedef uint16_t port_status_t;
+#define STATUS_CONNECTED         (1 << 0)
+#define STATUS_CONNECTED_CHANGED (1 << 1)
+#define STATUS_ENABLED           (1 << 2)
+#define STATUS_ENABLED_CHANGED   (1 << 3)
+#define STATUS_LINE_D_PLUS       (1 << 4)
+#define STATUS_LINE_D_MINUS      (1 << 5)
+#define STATUS_RESUME            (1 << 6)
+#define STATUS_ALWAYS_ONE        (1 << 7)
+
+#define STATUS_LOW_SPEED (1 <<  8)
+#define STATUS_IN_RESET  (1 <<  9)
+#define STATUS_SUSPEND   (1 << 12)
+
+/** UHCI port structure */
+typedef struct uhci_port {
+	const char *id_string;
+	port_status_t *address;
+	unsigned number;
+	unsigned wait_period_usec;
+	usb_hc_connection_t hc_connection;
+	ddf_dev_t *rh;
+	devman_handle_t attached_device;
+	fid_t checker;
+} uhci_port_t;
+
+int uhci_port_init(
+    uhci_port_t *port, port_status_t *address, unsigned number,
+    unsigned usec, ddf_dev_t *rh);
+
+void uhci_port_fini(uhci_port_t *port);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhcirh/root_hub.c
===================================================================
--- uspace/drv/uhcirh/root_hub.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/root_hub.c	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,97 @@
+/*
+ * 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 drvusbuhcirh
+ * @{
+ */
+/** @file
+ * @brief UHCI root hub driver
+ */
+#include <errno.h>
+#include <str_error.h>
+#include <ddi.h>
+#include <usb/debug.h>
+
+#include "root_hub.h"
+
+/** Initialize UHCI root hub instance.
+ *
+ * @param[in] instance Driver memory structure to use.
+ * @param[in] addr Address of I/O registers.
+ * @param[in] size Size of available I/O space.
+ * @param[in] rh Pointer to DDF instance of the root hub driver.
+ * @return Error code.
+ */
+int uhci_root_hub_init(
+  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
+{
+	assert(instance);
+	assert(rh);
+
+	/* Allow access to root hub port registers */
+	assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size);
+	port_status_t *regs;
+	int ret = pio_enable(addr, size, (void**)&regs);
+	if (ret < 0) {
+		usb_log_error(
+		    "Failed(%d) to gain access to port registers at %p: %s.\n",
+		    ret, regs, str_error(ret));
+		return ret;
+	}
+
+	/* Initialize root hub ports */
+	unsigned i = 0;
+	for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
+		ret = uhci_port_init(
+		    &instance->ports[i], &regs[i], i, ROOT_HUB_WAIT_USEC, rh);
+		if (ret != EOK) {
+			unsigned j = 0;
+			for (;j < i; ++j)
+				uhci_port_fini(&instance->ports[j]);
+			return ret;
+		}
+	}
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/** Cleanup UHCI root hub instance.
+ *
+ * @param[in] instance Root hub structure to use.
+ */
+void uhci_root_hub_fini(uhci_root_hub_t* instance)
+{
+	assert(instance);
+	unsigned i = 0;
+	for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
+		uhci_port_fini(&instance->ports[i]);
+	}
+}
+/*----------------------------------------------------------------------------*/
+/**
+ * @}
+ */
Index: uspace/drv/uhcirh/root_hub.h
===================================================================
--- uspace/drv/uhcirh/root_hub.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/root_hub.h	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,57 @@
+/*
+ * 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 drvusbuhcirh
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_ROOT_HUB_H
+#define DRV_UHCI_ROOT_HUB_H
+
+#include <ddf/driver.h>
+
+#include "port.h"
+
+#define UHCI_ROOT_HUB_PORT_COUNT 2
+#define ROOT_HUB_WAIT_USEC 250000 /* 250 miliseconds */
+
+/** UHCI root hub drvier structure */
+typedef struct root_hub {
+	/** Ports provided by the hub */
+	uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT];
+} uhci_root_hub_t;
+
+int uhci_root_hub_init(
+    uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh);
+
+void uhci_root_hub_fini(uhci_root_hub_t *instance);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhcirh/uhcirh.ma
===================================================================
--- uspace/drv/uhcirh/uhcirh.ma	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
+++ uspace/drv/uhcirh/uhcirh.ma	(revision 497b6f3135cb82d98d8ae1b63a4d9d9182e3f18d)
@@ -0,0 +1,1 @@
+10 usb&uhci&root-hub
