Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/Makefile	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -118,4 +118,5 @@
 		srv/hw/irc/i8259 \
 		drv/uhci-hcd \
+		drv/uhci-rhd \
 		drv/usbhid \
 		drv/usbhub \
@@ -132,4 +133,5 @@
 		srv/hw/irc/i8259 \
 		drv/uhci-hcd \
+		drv/uhci-rhd \
 		drv/usbhid \
 		drv/usbhub \
Index: uspace/drv/uhci-hcd/Makefile
===================================================================
--- uspace/drv/uhci-hcd/Makefile	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/drv/uhci-hcd/Makefile	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -36,7 +36,5 @@
 	iface.c \
 	main.c \
-	root_hub/port.c \
-	root_hub/port_status.c \
-	root_hub/root_hub.c \
+	root_hub.c \
 	transfer_list.c \
 	uhci.c \
Index: uspace/drv/uhci-hcd/main.c
===================================================================
--- uspace/drv/uhci-hcd/main.c	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/drv/uhci-hcd/main.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -34,4 +34,6 @@
 #include "iface.h"
 #include "name.h"
+#include "pci.h"
+#include "root_hub.h"
 #include "uhci.h"
 
@@ -75,5 +77,27 @@
 	    io_reg_base, io_reg_size, irq);
 
-	return uhci_init(device, (void*)io_reg_base, io_reg_size);
+	int ret = uhci_init(device, (void*)io_reg_base, io_reg_size);
+
+	if (ret != EOK) {
+		uhci_print_error("Failed to init uhci-hcd.\n");
+		return ret;
+	}
+	device_t *rh;
+	ret = setup_root_hub(&rh, device);
+
+	if (ret != EOK) {
+		uhci_print_error("Failed to setup uhci root hub.\n");
+		/* TODO: destroy uhci here */
+		return ret;
+	}
+
+	ret = child_device_register(rh, device);
+	if (ret != EOK) {
+		uhci_print_error("Failed to register root hub.\n");
+		/* TODO: destroy uhci here */
+		return ret;
+	}
+
+	return EOK;
 }
 
Index: uspace/drv/uhci-hcd/name.h
===================================================================
--- uspace/drv/uhci-hcd/name.h	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/drv/uhci-hcd/name.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -32,6 +32,6 @@
  * @brief UHCI driver
  */
-#ifndef DRV_UHCI_TD_NAME_H
-#define DRV_UHCI_TD_NAME_H
+#ifndef DRV_UHCI_NAME_H
+#define DRV_UHCI_NAME_H
 
 #define NAME "uhci-hcd"
Index: uspace/drv/uhci-hcd/pci.c
===================================================================
--- uspace/drv/uhci-hcd/pci.c	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/drv/uhci-hcd/pci.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -34,5 +34,5 @@
  * PCI related functions needed by the UHCI driver.
  */
-#include "uhci.h"
+#include "pci.h"
 #include <errno.h>
 #include <assert.h>
Index: uspace/drv/uhci-hcd/pci.h
===================================================================
--- uspace/drv/uhci-hcd/pci.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-hcd/pci.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,46 @@
+/*
+ * 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 drvusbuhci
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_PCI_H
+#define DRV_UHCI_PCI_H
+
+#include <driver.h>
+
+int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *);
+
+#endif
+/**
+ * @}
+ */
+
Index: uspace/drv/uhci-hcd/root_hub.c
===================================================================
--- uspace/drv/uhci-hcd/root_hub.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-hcd/root_hub.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,80 @@
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <usb_iface.h>
+
+#include "debug.h"
+#include "root_hub.h"
+/*----------------------------------------------------------------------------*/
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
+{
+  assert(dev);
+  assert(dev->parent != NULL);
+
+  device_t *parent = dev->parent;
+
+  if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
+    usb_iface_t *usb_iface
+        = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
+    assert(usb_iface != NULL);
+    if (usb_iface->get_hc_handle) {
+      int rc = usb_iface->get_hc_handle(parent, handle);
+      return rc;
+    }
+  }
+
+  return ENOTSUP;
+}
+/*----------------------------------------------------------------------------*/
+
+static usb_iface_t usb_iface = {
+  .get_hc_handle = usb_iface_get_hc_handle
+};
+
+static device_ops_t rh_ops = {
+	.interfaces[USB_DEV_IFACE] = &usb_iface
+};
+
+int setup_root_hub(device_t **device, device_t *hc)
+{
+	assert(device);
+	device_t *hub = create_device();
+	if (!hub) {
+		uhci_print_error("Failed to create root hub device structure.\n");
+		return ENOMEM;
+	}
+	char *name;
+	int ret = asprintf(&name, "UHCI Root Hub");
+	if (ret < 0) {
+		uhci_print_error("Failed to create root hub name.\n");
+		free(hub);
+		return ENOMEM;
+	}
+
+	char *match_str;
+	ret = asprintf(&match_str, "usb&uhci&root-hub");
+	if (ret < 0) {
+		uhci_print_error("Failed to create root hub match string.\n");
+		free(hub);
+		free(name);
+		return ENOMEM;
+	}
+
+	match_id_t *match_id = create_match_id();
+	if (!match_id) {
+		uhci_print_error("Failed to create root hub match id.\n");
+		free(hub);
+		free(match_str);
+		return ENOMEM;
+	}
+	match_id->id = match_str;
+	match_id->score = 90;
+
+	add_match_id(&hub->match_ids, match_id);
+	hub->name = name;
+	hub->parent = hc;
+	hub->ops = &rh_ops;
+
+	*device = hub;
+	return EOK;
+}
Index: uspace/drv/uhci-hcd/root_hub.h
===================================================================
--- uspace/drv/uhci-hcd/root_hub.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-hcd/root_hub.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,45 @@
+/*
+ * 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_ROOT_HUB_H
+#define DRV_UHCI_ROOT_HUB_H
+
+#include <driver.h>
+
+int setup_root_hub(device_t **device, device_t *hc);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci-hcd/root_hub/debug.h
===================================================================
--- uspace/drv/uhci-hcd/root_hub/debug.h	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,72 +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 usb
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_ROOT_HUB_DEBUG_H
-#define DRV_UHCI_ROOT_HUB_DEBUG_H
-
-#include <stdio.h>
-#include <usb/debug.h>
-
-#define NAME "uhci_root_hubd"
-
-enum debug_levels {
-	DEBUG_LEVEL_FATAL_ERROR = 1,
-	DEBUG_LEVEL_ERROR = 2,
-	DEBUG_LEVEL_WARNING = 3,
-	DEBUG_LEVEL_INFO = 4,
-	DEBUG_LEVEL_VERBOSE = 5,
-	DEBUG_LEVEL_MAX = DEBUG_LEVEL_VERBOSE
-};
-
-#define uhci_printf( level, fmt, args...) \
-	usb_dprintf(NAME, level, fmt, ##args)
-
-#define uhci_print_fatal( fmt, args... ) \
-	fprintf(stderr, "[" NAME ":FATAL ERROR]: " fmt, ##args)
-
-#define uhci_print_error( fmt, args... ) \
-	fprintf(stderr, "[" NAME ":ERROR]: " fmt, ##args)
-
-#define uhci_print_warning( fmt, args... ) \
-	usb_dprintf( NAME, DEBUG_LEVEL_WARNING, fmt, ##args )
-
-#define uhci_print_info( fmt, args... ) \
-	usb_dprintf( NAME, DEBUG_LEVEL_INFO, fmt, ##args )
-
-#define uhci_print_verbose( fmt, args... ) \
-	usb_dprintf( NAME, DEBUG_LEVEL_VERBOSE, fmt, ##args )
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/uhci-hcd/root_hub/port.c
===================================================================
--- uspace/drv/uhci-hcd/root_hub/port.c	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,165 +1,0 @@
-
-#include <errno.h>
-#include <usb/usb.h>    /* usb_address_t */
-#include <usb/usbdrv.h> /* usb_drv_*     */
-
-#include "debug.h"
-#include "port.h"
-#include "port_status.h"
-
-static int uhci_port_new_device(uhci_port_t *port);
-static int uhci_port_remove_device(uhci_port_t *port);
-static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
-
-/*----------------------------------------------------------------------------*/
-int uhci_port_check(void *port)
-{
-	async_usleep( 1000000 );
-	uhci_port_t *port_instance = port;
-	assert(port_instance);
-	port_instance->hc_phone = devman_device_connect(port_instance->hc->handle, 0);
-	if (port_instance->hc_phone < 0) {
-		uhci_print_fatal("Failed(%d) to connect to the hc(handle=%x.\n",
-			port_instance->hc_phone, (unsigned)port_instance->hc->handle);
-		return port_instance->hc_phone;
-	}
-
-	while (1) {
-		uhci_print_verbose("Port(%d) status address %p:\n",
-		  port_instance->number, port_instance->address);
-
-		/* read register value */
-		port_status_t port_status =
-			port_status_read(port_instance->address);
-
-		/* debug print */
-		uhci_print_info("Port(%d) status %#.4x\n",
-		  port_instance->number, port_status);
-		print_port_status(port_status);
-
-		if (port_status & STATUS_CONNECTED_CHANGED) {
-			if (port_status & STATUS_CONNECTED) {
-				/* new device */
-				uhci_port_new_device(port_instance);
-			} else {
-				uhci_port_remove_device(port_instance);
-			}
-		}
-		async_usleep(port_instance->wait_period_usec);
-	}
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int uhci_port_new_device(uhci_port_t *port)
-{
-	assert(port);
-	assert(port->hc_phone);
-
-	uhci_print_info("Adding new device on port %d.\n", port->number);
-
-
-	/* get default address */
-	int ret = usb_drv_reserve_default_address(port->hc_phone);
-	if (ret != EOK) {
-		uhci_print_error("Failed to reserve default address.\n");
-		return ret;
-	}
-
-	const usb_address_t usb_address = usb_drv_request_address(port->hc_phone);
-
-	if (usb_address <= 0) {
-		uhci_print_error("Recieved invalid address(%d).\n", usb_address);
-		return usb_address;
-	}
-	/*
-	 * the host then waits for at least 100 ms to allow completion of
-	 * an insertion process and for power at the device to become stable.
-	 */
-	async_usleep(100000);
-
-	/* enable port */
-	uhci_port_set_enabled(port, true);
-
-	/* The hub maintains the reset signal to that port for 10 ms
-	 * (See Section 11.5.1.5)
-	 */
-	port_status_t port_status =
-		port_status_read(port->address);
-	port_status |= STATUS_IN_RESET;
-	port_status_write(port->address, port_status);
-	async_usleep(10000);
-	port_status =
-		port_status_read(port->address);
-	port_status &= ~STATUS_IN_RESET;
-	port_status_write(port->address, port_status);
-
-	/* assign address to device */
-	ret = usb_drv_req_set_address(port->hc_phone, 0, usb_address);
-
-
-	if (ret != EOK) { /* address assigning went wrong */
-		uhci_print_error("Failed(%d) to assign address to the device.\n", ret);
-		uhci_port_set_enabled(port, false);
-		int release = usb_drv_release_default_address(port->hc_phone);
-		if (release != EOK) {
-			uhci_print_fatal("Failed to release default address.\n");
-			return release;
-		}
-		return ret;
-	}
-
-	/* release default address */
-	ret = usb_drv_release_default_address(port->hc_phone);
-	if (ret != EOK) {
-		uhci_print_fatal("Failed to release default address.\n");
-		return ret;
-	}
-
-	/* communicate and possibly report to devman */
-	assert(port->attached_device == 0);
-
-	ret = usb_drv_register_child_in_devman(port->hc_phone, port->hc, usb_address,
-		&port->attached_device);
-
-	if (ret != EOK) { /* something went wrong */
-		uhci_print_error("Failed(%d) in usb_drv_register_child.\n", ret);
-		uhci_port_set_enabled(port, false);
-		return ENOMEM;
-	}
-	uhci_print_info("Sucessfully added device on port(%d) address(%d).\n",
-		port->number, usb_address);
-
-	/* TODO: bind the address here */
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int uhci_port_remove_device(uhci_port_t *port)
-{
-	uhci_print_error("Don't know how to remove device %#x.\n",
-		(unsigned int)port->attached_device);
-	uhci_port_set_enabled(port, false);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
-{
-	assert(port);
-
-	/* read register value */
-	port_status_t port_status
-		= port_status_read(port->address);
-
-	/* enable port: register write */
-	if (enabled) {
-		port_status |= STATUS_ENABLED;
-	} else {
-		port_status &= ~STATUS_ENABLED;
-	}
-	port_status_write(port->address, port_status);
-
-	uhci_print_info("%s port %d.\n",
-	  enabled ? "Enabled" : "Disabled", port->number);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci-hcd/root_hub/port.h
===================================================================
--- uspace/drv/uhci-hcd/root_hub/port.h	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,70 +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 usb
- * @{
- */
-/** @file
- * @brief UHCI port driver
- */
-#ifndef DRV_UHCI_PORT_H
-#define DRV_UHCI_PORT_H
-
-#include <assert.h>
-#include <driver.h> /* device_t */
-#include <stdint.h>
-
-#include "port_status.h"
-
-typedef struct uhci_port
-{
-	port_status_t *address;
-	device_t *hc;
-	unsigned number;
-	unsigned wait_period_usec;
-	int hc_phone;
-	devman_handle_t attached_device;
-} uhci_port_t;
-
-static inline void uhci_port_init(
-  uhci_port_t *port, port_status_t *address, device_t *hc, unsigned number,
-  unsigned usec)
-{
-	assert(port);
-	port->address = address;
-	port->hc = hc;
-	port->number = number;
-	port->hc_phone = -1;
-	port->wait_period_usec = usec;
-	port->attached_device = 0;
-}
-
-int uhci_port_check(void *port);
-#endif
-/**
- * @}
- */
Index: uspace/drv/uhci-hcd/root_hub/port_status.c
===================================================================
--- uspace/drv/uhci-hcd/root_hub/port_status.c	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#include <assert.h>
-#include <stdio.h>
-
-#include "debug.h"
-#include "port_status.h"
-
-struct flag_name
-{
-	unsigned flag;
-	const char *name;
-};
-
-static const struct flag_name flags[] =
-{
-	{ STATUS_SUSPEND, "suspended" },
-	{ STATUS_IN_RESET, "in reset" },
-	{ STATUS_LOW_SPEED, "low speed device" },
-	{ STATUS_ALWAYS_ONE, "always 1 bit" },
-	{ STATUS_RESUME, "resume" },
-	{ STATUS_LINE_D_MINUS, "line D- value" },
-	{ STATUS_LINE_D_PLUS, "line D+ value" },
-	{ STATUS_ENABLED_CHANGED, "enabled changed" },
-	{ STATUS_ENABLED, "enabled" },
-	{ STATUS_CONNECTED_CHANGED, "connected changed" },
-	{ STATUS_CONNECTED, "connected" }
-};
-
-void print_port_status(port_status_t value)
-{
-	unsigned i = 0;
-	for (;i < sizeof(flags)/sizeof(struct flag_name); ++i) {
-		uhci_print_verbose("\t%s status: %s.\n", flags[i].name,
-		  value & flags[i].flag ? "YES" : "NO");
-	}
-}
Index: uspace/drv/uhci-hcd/root_hub/port_status.h
===================================================================
--- uspace/drv/uhci-hcd/root_hub/port_status.h	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,68 +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 usb
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_TD_PORT_STATUS_H
-#define DRV_UHCI_TD_PORT_STATUS_H
-
-#include <libarch/ddi.h>
-#include <stdint.h>
-
-typedef uint16_t port_status_t;
-
-enum {
-	STATUS_CONNECTED         = 1 << 0,
-	STATUS_CONNECTED_CHANGED = 1 << 1,
-	STATUS_ENABLED           = 1 << 2,
-	STATUS_ENABLED_CHANGED   = 1 << 3,
-	STATUS_LINE_D_PLUS       = 1 << 4,
-	STATUS_LINE_D_MINUS      = 1 << 5,
-	STATUS_RESUME            = 1 << 6,
-	STATUS_ALWAYS_ONE        = 1 << 7,
-
-	STATUS_LOW_SPEED = 1 <<  8,
-	STATUS_IN_RESET  = 1 <<  9,
-	STATUS_SUSPEND   = 1 << 12,
-};
-
-static inline port_status_t port_status_read(port_status_t * address)
-	{ return pio_read_16(address); }
-
-static inline void port_status_write(
-  port_status_t * address, port_status_t value)
-	{ pio_write_16(address, value); }
-
-void print_port_status(const port_status_t status);
-#endif
-/**
- * @}
- */
Index: uspace/drv/uhci-hcd/root_hub/root_hub.c
===================================================================
--- uspace/drv/uhci-hcd/root_hub/root_hub.c	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#include <async.h>
-#include <ddi.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include "debug.h"
-#include "root_hub.h"
-
-
-int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *hc, void *addr )
-{
-	assert(hub);
-	usb_dprintf_enable(NAME, DEBUG_LEVEL_INFO);
-
-	/* allow access to root hub registers */
-	port_status_t *regs;
-	const int ret = pio_enable(
-	  addr, sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT, (void**)&regs);
-
-	if (ret < 0) {
-		uhci_print_error(": Failed to gain access to port registers at %p\n", regs);
-		return ret;
-	}
-
-	/* add fibrils for periodic port checks */
-	unsigned i = 0;
-	for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
-		/* mind pointer arithmetics */
-		uhci_port_init(
-		  &hub->ports[i], regs + i, hc, i, ROOT_HUB_WAIT_USEC);
-
-		hub->checker[i] = fibril_create(uhci_port_check, &hub->ports[i]);
-		if (hub->checker[i] == 0) {
-			uhci_print_error(": failed to launch root hub fibril.");
-			return ENOMEM;
-		}
-		fibril_add_ready(hub->checker[i]);
-		uhci_print_verbose(" added fibril for port %d: %p.\n", i, hub->checker[i]);
-	}
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-int uhci_root_hub_fini( uhci_root_hub_t* instance )
-{
-	assert( instance );
-	// TODO:
-	//destroy fibril here
-	//disable access to registers
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci-hcd/root_hub/root_hub.h
===================================================================
--- uspace/drv/uhci-hcd/root_hub/root_hub.h	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ 	(revision )
@@ -1,58 +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 usb
- * @{
- */
-/** @file
- * @brief UHCI driver
- */
-#ifndef DRV_UHCI_ROOT_HUB_H
-#define DRV_UHCI_ROOT_HUB_H
-
-#include <fibril.h>
-#include <driver.h> /* for device_t */
-
-#include "port.h"
-
-#define UHCI_ROOT_HUB_PORT_COUNT 2
-#define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10
-#define ROOT_HUB_WAIT_USEC 10000000 /* 10 seconds */
-
-typedef struct root_hub {
-	uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT];
-	fid_t checker[UHCI_ROOT_HUB_PORT_COUNT];
-} uhci_root_hub_t;
-
-int uhci_root_hub_init(
-  uhci_root_hub_t *instance, device_t *device, void *addr);
-
-int uhci_root_hub_fini(uhci_root_hub_t* instance);
-#endif
-/**
- * @}
- */
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -51,18 +51,9 @@
 	uhci_print_verbose("Transfer lists initialized.\n");
 
-	/* init root hub */
-	ret = uhci_root_hub_init(&instance->root_hub, device,
-	  (char*)regs + UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET);
-	CHECK_RET_FREE_INSTANCE("Failed to initialize root hub driver.\n");
 
 	uhci_print_verbose("Initializing frame list.\n");
 	instance->frame_list = get_page();
-//	  memalign32(sizeof(link_pointer_t) * UHCI_FRAME_LIST_COUNT, 4096);
-	if (instance->frame_list == NULL) {
-		uhci_print_error("Failed to allocate frame list pointer.\n");
-		uhci_root_hub_fini(&instance->root_hub);
-		free(instance);
-		return ENOMEM;
-	}
+	ret = instance ? EOK : ENOMEM;
+	CHECK_RET_FREE_INSTANCE("Failed to get frame list page.\n");
 
 	/* initialize all frames to point to the first queue head */
Index: uspace/drv/uhci-hcd/uhci.h
===================================================================
--- uspace/drv/uhci-hcd/uhci.h	(revision 37ac7bb09e864d980b717c10059697d50baf89df)
+++ uspace/drv/uhci-hcd/uhci.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -41,5 +41,4 @@
 #include <usbhc_iface.h>
 
-#include "root_hub/root_hub.h"
 #include "transfer_list.h"
 
@@ -76,5 +75,4 @@
 typedef struct uhci {
 	usb_address_keeping_t address_manager;
-	uhci_root_hub_t root_hub;
 	volatile regs_t *registers;
 
@@ -87,7 +85,7 @@
 
 /* init uhci specifics in device.driver_data */
-int uhci_init( device_t *device, void *regs, size_t reg_size );
+int uhci_init(device_t *device, void *regs, size_t reg_size);
 
-int uhci_destroy( device_t *device );
+int uhci_destroy(device_t *device);
 
 int uhci_transfer(
@@ -102,6 +100,4 @@
   void *arg );
 
-int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *);
-
 #endif
 /**
Index: uspace/drv/uhci-rhd/Makefile
===================================================================
--- uspace/drv/uhci-rhd/Makefile	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/Makefile	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,40 @@
+#
+# 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 = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+BINARY = uhci-rhd
+
+SOURCES = \
+	main.c \
+	port.c \
+	port_status.c \
+	root_hub.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/uhci-rhd/debug.h
===================================================================
--- uspace/drv/uhci-rhd/debug.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/debug.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,73 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_ROOT_HUB_DEBUG_H
+#define DRV_UHCI_ROOT_HUB_DEBUG_H
+
+#include <stdio.h>
+#include <usb/debug.h>
+
+#include "name.h"
+
+
+enum debug_levels {
+	DEBUG_LEVEL_FATAL_ERROR = 1,
+	DEBUG_LEVEL_ERROR = 2,
+	DEBUG_LEVEL_WARNING = 3,
+	DEBUG_LEVEL_INFO = 4,
+	DEBUG_LEVEL_VERBOSE = 5,
+	DEBUG_LEVEL_MAX = DEBUG_LEVEL_VERBOSE
+};
+
+#define uhci_printf( level, fmt, args...) \
+	usb_dprintf(NAME, level, fmt, ##args)
+
+#define uhci_print_fatal( fmt, args... ) \
+	fprintf(stderr, "[" NAME ":FATAL ERROR]: " fmt, ##args)
+
+#define uhci_print_error( fmt, args... ) \
+	fprintf(stderr, "[" NAME ":ERROR]: " fmt, ##args)
+
+#define uhci_print_warning( fmt, args... ) \
+	usb_dprintf( NAME, DEBUG_LEVEL_WARNING, fmt, ##args )
+
+#define uhci_print_info( fmt, args... ) \
+	usb_dprintf( NAME, DEBUG_LEVEL_INFO, fmt, ##args )
+
+#define uhci_print_verbose( fmt, args... ) \
+	usb_dprintf( NAME, DEBUG_LEVEL_VERBOSE, fmt, ##args )
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci-rhd/main.c
===================================================================
--- uspace/drv/uhci-rhd/main.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/main.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010 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.
+ */
+#include <driver.h>
+#include <errno.h>
+#include <str_error.h>
+#include <usb_iface.h>
+
+#include "debug.h"
+//#include "iface.h"
+#include "root_hub.h"
+
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
+{
+	/* This shall be called only for the UHCI itself. */
+	assert(dev);
+	assert(dev->driver_data);
+	*handle = ((uhci_root_hub_t*)dev->driver_data)->hc_handle;
+
+	return EOK;
+}
+
+static usb_iface_t uhci_rh_usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle
+};
+
+static device_ops_t uhci_rh_ops = {
+	.interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface,
+};
+
+static int uhci_rh_add_device(device_t *device)
+{
+	if (!device)
+		return ENOTSUP;
+
+	uhci_print_info("%s called device %d\n", __FUNCTION__, device->handle);
+	device->ops = &uhci_rh_ops;
+
+	uhci_root_hub_t *rh = malloc(sizeof(uhci_root_hub_t));
+	if (!rh) {
+		return ENOMEM;
+	}
+	int ret = uhci_root_hub_init(rh, (void*)0xc030, 4, device);
+	if (ret != EOK) {
+		free(rh);
+		return ret;
+	}
+	device->driver_data = rh;
+	return EOK;
+}
+
+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
+};
+
+int main(int argc, char *argv[])
+{
+	/*
+	 * Do some global initializations.
+	 */
+	usb_dprintf_enable(NAME, DEBUG_LEVEL_INFO);
+
+	return driver_main(&uhci_rh_driver);
+}
Index: uspace/drv/uhci-rhd/name.h
===================================================================
--- uspace/drv/uhci-rhd/name.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/name.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,42 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_RHD_NAME_H
+#define DRV_UHCI_RHD_NAME_H
+
+#define NAME "uhci-rhd"
+
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci-rhd/port.c
===================================================================
--- uspace/drv/uhci-rhd/port.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/port.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,188 @@
+
+#include <errno.h>
+#include <usb/usb.h>    /* usb_address_t */
+#include <usb/usbdrv.h> /* usb_drv_*     */
+
+#include "debug.h"
+#include "port.h"
+#include "port_status.h"
+
+static int uhci_port_new_device(uhci_port_t *port);
+static int uhci_port_remove_device(uhci_port_t *port);
+static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
+static int uhci_port_check(void *port);
+
+int uhci_port_init(
+  uhci_port_t *port, port_status_t *address, unsigned number,
+  unsigned usec, device_t *rh)
+{
+	assert(port);
+	port->address = address;
+	port->number = number;
+	port->wait_period_usec = usec;
+	port->attached_device = 0;
+	port->rh = rh;
+	port->hc_phone = rh->parent_phone;
+
+	port->checker = fibril_create(uhci_port_check, port);
+	if (port->checker == 0) {
+		uhci_print_error(": failed to launch root hub fibril.");
+		return ENOMEM;
+	}
+	fibril_add_ready(port->checker);
+	uhci_print_verbose(
+	  "Added fibril for port %d: %p.\n", number, port->checker);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+void uhci_port_fini(uhci_port_t *port)
+{
+//	fibril_teardown(port->checker);
+	return;
+}
+/*----------------------------------------------------------------------------*/
+int uhci_port_check(void *port)
+{
+	async_usleep( 1000000 );
+	uhci_port_t *port_instance = port;
+	assert(port_instance);
+
+	while (1) {
+		uhci_print_verbose("Port(%d) status address %p:\n",
+		  port_instance->number, port_instance->address);
+
+		/* read register value */
+		port_status_t port_status =
+			port_status_read(port_instance->address);
+
+		/* debug print */
+		uhci_print_info("Port(%d) status %#.4x\n",
+		  port_instance->number, port_status);
+		print_port_status(port_status);
+
+		if (port_status & STATUS_CONNECTED_CHANGED) {
+			if (port_status & STATUS_CONNECTED) {
+				/* new device */
+				uhci_port_new_device(port_instance);
+			} else {
+				uhci_port_remove_device(port_instance);
+			}
+		}
+		async_usleep(port_instance->wait_period_usec);
+	}
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static int uhci_port_new_device(uhci_port_t *port)
+{
+	assert(port);
+	assert(port->hc_phone);
+
+	uhci_print_info("Adding new device on port %d.\n", port->number);
+
+
+	/* get default address */
+	int ret = usb_drv_reserve_default_address(port->hc_phone);
+	if (ret != EOK) {
+		uhci_print_error("Failed to reserve default address.\n");
+		return ret;
+	}
+
+	const usb_address_t usb_address = usb_drv_request_address(port->hc_phone);
+
+	if (usb_address <= 0) {
+		uhci_print_error("Recieved invalid address(%d).\n", usb_address);
+		return usb_address;
+	}
+	/*
+	 * the host then waits for at least 100 ms to allow completion of
+	 * an insertion process and for power at the device to become stable.
+	 */
+	async_usleep(100000);
+
+	/* enable port */
+	uhci_port_set_enabled(port, true);
+
+	/* The hub maintains the reset signal to that port for 10 ms
+	 * (See Section 11.5.1.5)
+	 */
+	port_status_t port_status =
+		port_status_read(port->address);
+	port_status |= STATUS_IN_RESET;
+	port_status_write(port->address, port_status);
+	async_usleep(10000);
+	port_status =
+		port_status_read(port->address);
+	port_status &= ~STATUS_IN_RESET;
+	port_status_write(port->address, port_status);
+
+	/* assign address to device */
+	ret = usb_drv_req_set_address(port->hc_phone, 0, usb_address);
+
+
+	if (ret != EOK) { /* address assigning went wrong */
+		uhci_print_error("Failed(%d) to assign address to the device.\n", ret);
+		uhci_port_set_enabled(port, false);
+		int release = usb_drv_release_default_address(port->hc_phone);
+		if (release != EOK) {
+			uhci_print_fatal("Failed to release default address.\n");
+			return release;
+		}
+		return ret;
+	}
+
+	/* release default address */
+	ret = usb_drv_release_default_address(port->hc_phone);
+	if (ret != EOK) {
+		uhci_print_fatal("Failed to release default address.\n");
+		return ret;
+	}
+
+	/* communicate and possibly report to devman */
+	assert(port->attached_device == 0);
+
+	ret = usb_drv_register_child_in_devman(port->hc_phone, port->rh,
+	  usb_address, &port->attached_device);
+
+	if (ret != EOK) { /* something went wrong */
+		uhci_print_error("Failed(%d) in usb_drv_register_child.\n", ret);
+		uhci_port_set_enabled(port, false);
+		return ENOMEM;
+	}
+	uhci_print_info("Sucessfully added device on port(%d) address(%d).\n",
+		port->number, usb_address);
+
+	/* TODO: bind the address here */
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static int uhci_port_remove_device(uhci_port_t *port)
+{
+	uhci_print_error("Don't know how to remove device %#x.\n",
+		(unsigned int)port->attached_device);
+	uhci_port_set_enabled(port, false);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
+{
+	assert(port);
+
+	/* read register value */
+	port_status_t port_status
+		= port_status_read(port->address);
+
+	/* enable port: register write */
+	if (enabled) {
+		port_status |= STATUS_ENABLED;
+	} else {
+		port_status &= ~STATUS_ENABLED;
+	}
+	port_status_write(port->address, port_status);
+
+	uhci_print_info("%s port %d.\n",
+	  enabled ? "Enabled" : "Disabled", port->number);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci-rhd/port.h
===================================================================
--- uspace/drv/uhci-rhd/port.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/port.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,62 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief UHCI port driver
+ */
+#ifndef DRV_UHCI_PORT_H
+#define DRV_UHCI_PORT_H
+
+#include <assert.h>
+#include <driver.h> /* device_t */
+#include <stdint.h>
+
+#include "port_status.h"
+
+typedef struct uhci_port
+{
+	port_status_t *address;
+	unsigned number;
+	unsigned wait_period_usec;
+	int hc_phone;
+	device_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, device_t *rh);
+
+void uhci_port_fini(uhci_port_t *port);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci-rhd/port_status.c
===================================================================
--- uspace/drv/uhci-rhd/port_status.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/port_status.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,35 @@
+#include <assert.h>
+#include <stdio.h>
+
+#include "debug.h"
+#include "port_status.h"
+
+struct flag_name
+{
+	unsigned flag;
+	const char *name;
+};
+
+static const struct flag_name flags[] =
+{
+	{ STATUS_SUSPEND, "suspended" },
+	{ STATUS_IN_RESET, "in reset" },
+	{ STATUS_LOW_SPEED, "low speed device" },
+	{ STATUS_ALWAYS_ONE, "always 1 bit" },
+	{ STATUS_RESUME, "resume" },
+	{ STATUS_LINE_D_MINUS, "line D- value" },
+	{ STATUS_LINE_D_PLUS, "line D+ value" },
+	{ STATUS_ENABLED_CHANGED, "enabled changed" },
+	{ STATUS_ENABLED, "enabled" },
+	{ STATUS_CONNECTED_CHANGED, "connected changed" },
+	{ STATUS_CONNECTED, "connected" }
+};
+
+void print_port_status(port_status_t value)
+{
+	unsigned i = 0;
+	for (;i < sizeof(flags)/sizeof(struct flag_name); ++i) {
+		uhci_print_verbose("\t%s status: %s.\n", flags[i].name,
+		  value & flags[i].flag ? "YES" : "NO");
+	}
+}
Index: uspace/drv/uhci-rhd/port_status.h
===================================================================
--- uspace/drv/uhci-rhd/port_status.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/port_status.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,68 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_TD_PORT_STATUS_H
+#define DRV_UHCI_TD_PORT_STATUS_H
+
+#include <libarch/ddi.h>
+#include <stdint.h>
+
+typedef uint16_t port_status_t;
+
+enum {
+	STATUS_CONNECTED         = 1 << 0,
+	STATUS_CONNECTED_CHANGED = 1 << 1,
+	STATUS_ENABLED           = 1 << 2,
+	STATUS_ENABLED_CHANGED   = 1 << 3,
+	STATUS_LINE_D_PLUS       = 1 << 4,
+	STATUS_LINE_D_MINUS      = 1 << 5,
+	STATUS_RESUME            = 1 << 6,
+	STATUS_ALWAYS_ONE        = 1 << 7,
+
+	STATUS_LOW_SPEED = 1 <<  8,
+	STATUS_IN_RESET  = 1 <<  9,
+	STATUS_SUSPEND   = 1 << 12,
+};
+
+static inline port_status_t port_status_read(port_status_t * address)
+	{ return pio_read_16(address); }
+
+static inline void port_status_write(
+  port_status_t * address, port_status_t value)
+	{ pio_write_16(address, value); }
+
+void print_port_status(const port_status_t status);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci-rhd/root_hub.c
===================================================================
--- uspace/drv/uhci-rhd/root_hub.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/root_hub.c	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,69 @@
+#include <async.h>
+#include <ddi.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <usb/usbdrv.h>
+
+#include "debug.h"
+#include "root_hub.h"
+
+
+int uhci_root_hub_init(
+  uhci_root_hub_t *instance, void *addr, size_t size, device_t *rh)
+{
+	assert(instance);
+	assert(rh);
+	int ret;
+	ret = usb_drv_find_hc(rh, &instance->hc_handle);
+	uhci_print_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle);
+	if (ret != EOK) {
+		return ret;
+	}
+
+	/* connect to the parent device (HC) */
+	rh->parent_phone = devman_device_connect(8, 0);
+	//usb_drv_hc_connect(rh, instance->hc_handle, 0);
+	if (rh->parent_phone < 0) {
+		uhci_print_error("Failed to connect to the HC device.\n");
+		return rh->parent_phone;
+	}
+
+	/* allow access to root hub registers */
+	assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size);
+	port_status_t *regs;
+	ret = pio_enable(
+	  addr, sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT, (void**)&regs);
+
+	if (ret < 0) {
+		uhci_print_error(": Failed to gain access to port registers at %p\n", regs);
+		return ret;
+	}
+
+	/* add fibrils for periodic port checks */
+	unsigned i = 0;
+	for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
+		/* mind pointer arithmetics */
+		int 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;
+}
+/*----------------------------------------------------------------------------*/
+int uhci_root_hub_fini( uhci_root_hub_t* instance )
+{
+	assert( instance );
+	// TODO:
+	//destroy fibril here
+	//disable access to registers
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci-rhd/root_hub.h
===================================================================
--- uspace/drv/uhci-rhd/root_hub.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/root_hub.h	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,58 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief UHCI driver
+ */
+#ifndef DRV_UHCI_ROOT_HUB_H
+#define DRV_UHCI_ROOT_HUB_H
+
+#include <fibril.h>
+#include <driver.h> /* for device_t */
+
+#include "port.h"
+
+#define UHCI_ROOT_HUB_PORT_COUNT 2
+#define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10
+#define ROOT_HUB_WAIT_USEC 10000000 /* 10 seconds */
+
+typedef struct root_hub {
+	uhci_port_t ports[UHCI_ROOT_HUB_PORT_COUNT];
+	devman_handle_t hc_handle;
+} uhci_root_hub_t;
+
+int uhci_root_hub_init(
+  uhci_root_hub_t *instance, void *addr, size_t size, device_t *rh);
+
+int uhci_root_hub_fini(uhci_root_hub_t* instance);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci-rhd/uhci-rhd.ma
===================================================================
--- uspace/drv/uhci-rhd/uhci-rhd.ma	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
+++ uspace/drv/uhci-rhd/uhci-rhd.ma	(revision 1256a0a8bd51a5f673fce31e8397498509b6127d)
@@ -0,0 +1,1 @@
+10 usb&uhci&root-hub
