Index: uspace/drv/uhci/root_hub/port.c
===================================================================
--- uspace/drv/uhci/root_hub/port.c	(revision 28f660d2d933fbece3b8e41bc9300c5ed4977324)
+++ uspace/drv/uhci/root_hub/port.c	(revision 28f660d2d933fbece3b8e41bc9300c5ed4977324)
@@ -0,0 +1,207 @@
+
+#include <usb/devreq.h>
+#include <usb/usb.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "uhci.h"
+#include "port.h"
+#include "port_status.h"
+
+struct usb_match {
+	int id_score;
+	const char *id_string;
+};
+
+static int uhci_port_new_device(uhci_port_t *port);
+static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
+static usb_address_t assign_address_to_zero_device( device_t *hc );
+static int report_new_device(
+  device_t *hc, usb_address_t address, int hub_port, devman_handle_t *handle);
+
+/*----------------------------------------------------------------------------*/
+int uhci_port_check(void *port)
+{
+	uhci_port_t *port_instance = port;
+	assert(port_instance);
+
+	while (1) {
+		uhci_print_info("Port(%d) status address %p:\n",
+		  port_instance->number, port_instance->address);
+
+		/* read register value */
+		port_status_t port_status;
+		port_status.raw_value = pio_read_16(port_instance->address);
+
+		/* debug print */
+		uhci_print_info("Port(%d) status %#x:\n",
+		  port_instance->number, port_status.raw_value);
+		print_port_status( &port_status );
+
+		if (port_status.status.connect_change) {
+			if (port_status.status.connected) {
+				/* assign address and report new device */
+				uhci_port_new_device(port_instance);
+			} else {
+				/* TODO */
+				/* remove device here */
+			}
+		}
+		async_usleep(port_instance->wait_period_usec);
+	}
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static int uhci_port_new_device(uhci_port_t *port)
+{
+	assert(port);
+	assert(port->hc);
+
+	uhci_print_info("Adding new device on port %d.\n", port->number);
+
+	uhci_t *uhci_instance = (uhci_t*)(port->hc->driver_data);
+
+	/* get default address */
+	usb_address_keeping_reserve_default(&uhci_instance->address_manager);
+
+	/* enable port */
+	uhci_port_set_enabled( port, true );
+
+	/* assign address to device */
+	usb_address_t address = assign_address_to_zero_device(port->hc);
+
+	/* release default address */
+	usb_address_keeping_release_default(&uhci_instance->address_manager);
+
+	if (address <= 0) { /* address assigning went wrong */
+		uhci_port_set_enabled(port, false);
+		uhci_print_error("Failed to assign address to the device");
+		return ENOMEM;
+	}
+
+	/* report to devman */
+	devman_handle_t child = 0;
+	report_new_device(port->hc, address, port->number, &child);
+
+	/* bind address */
+	usb_address_keeping_devman_bind(&uhci_instance->address_manager,
+	  address, child);
+
+	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.raw_value = pio_read_16( port->address );
+
+	/* enable port: register write */
+	port_status.status.enabled_change = 0;
+	port_status.status.enabled = (bool)enabled;
+	pio_write_16( port->address, port_status.raw_value );
+
+	uhci_print_info( "Enabled port %d.\n", port );
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static int report_new_device(
+  device_t *hc, usb_address_t address, int hub_port, devman_handle_t *handle)
+{
+	assert( hc );
+	assert( address > 0 );
+	assert( address <= USB11_ADDRESS_MAX );
+
+	device_t *child = create_device();
+	if (child == NULL)
+		{ return ENOMEM; }
+
+	char *name;
+	int ret;
+
+	ret = asprintf( &name, "usbdevice on hc%p/%d/%#x", hc, hub_port, address );
+	if (ret < 0) {
+		uhci_print_error( "Failed to create device name.\n" );
+		delete_device( child );
+		return ret;
+	}
+	child->name = name;
+
+	/* TODO get and parse device descriptor */
+	const int vendor = 1;
+	const int product = 1;
+	const char* release = "unknown";
+	const char* class = "unknown";
+
+	/* create match ids TODO fix class printf*/
+	static const struct usb_match usb_matches[] = {
+	  { 100, "usb&vendor=%d&product=%d&release=%s" },
+	  {  90, "usb&vendor=%d&product=%d" },
+	  {  50, "usb&class=%d" },
+	  {   1, "usb&fallback" }
+	};
+
+	unsigned i = 0;
+	for (;i < sizeof( usb_matches )/ sizeof( struct usb_match ); ++i ) {
+		char *match_str;
+		const int ret = asprintf(
+		  &match_str, usb_matches[i].id_string, vendor, product, release, class );
+		if (ret < 0 ) {
+			uhci_print_error( "Failed to create matchid string.\n" );
+			delete_device( child );
+			return ret;
+		}
+		uhci_print_verbose( "Adding match id rule:%s\n", match_str );
+
+		match_id_t *id = create_match_id();
+		if (id == NULL) {
+			uhci_print_error( "Failed to create matchid.\n" );
+			delete_device( child );
+			free( match_str );
+			return ENOMEM;
+		}
+		id->id = match_str;
+		id->score = usb_matches[i].id_score;
+		add_match_id( &child->match_ids, id );
+
+		uhci_print_info( "Added match id, score: %d, string %s\n",
+		  id->score, id->id );
+	}
+
+	ret = child_device_register( child, hc );
+	if (ret < 0) {
+		uhci_print_error( "Failed to create device name.\n" );
+		delete_device( child );
+		return ret;
+	}
+
+	if (handle != NULL)
+		{ *handle = child->handle; }
+
+	return EOK;
+}
+static usb_address_t assign_address_to_zero_device( device_t *hc )
+{
+	assert( hc );
+	assert( hc->driver_data );
+
+	uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
+	/* get new address */
+	const usb_address_t usb_address =
+	  usb_address_keeping_request( &uhci_instance->address_manager );
+
+	/* assign new address */
+	usb_target_t new_device = { USB_ADDRESS_DEFAULT, 0 };
+	usb_device_request_setup_packet_t data;
+
+	uhci_setup(
+	  hc, new_device, USB_TRANSFER_CONTROL, &data, sizeof(data), NULL, NULL );
+	uhci_print_verbose( "address assignment sent, waiting to complete.\n" );
+
+
+	uhci_print_info( "Assigned address %#x.\n", usb_address );
+
+	return usb_address;
+}
Index: uspace/drv/uhci/root_hub/port.h
===================================================================
--- uspace/drv/uhci/root_hub/port.h	(revision 28f660d2d933fbece3b8e41bc9300c5ed4977324)
+++ uspace/drv/uhci/root_hub/port.h	(revision 28f660d2d933fbece3b8e41bc9300c5ed4977324)
@@ -0,0 +1,66 @@
+/*
+ * 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>
+#include <stdint.h>
+
+typedef uint16_t uhci_port_reg_t;
+
+typedef struct uhci_port
+{
+	uhci_port_reg_t *address;
+	device_t *hc;
+	unsigned number;
+	unsigned wait_period_usec;
+} uhci_port_t;
+
+static inline void uhci_port_init(
+  uhci_port_t *port, uhci_port_reg_t *address, device_t *hc, unsigned number,
+  unsigned usec)
+{
+	assert( port );
+	port->address = address;
+	port->hc = hc;
+	port->number = number;
+	port->wait_period_usec = usec;
+}
+
+int uhci_port_check(void *port);
+#endif
+/**
+ * @}
+ */
Index: uspace/drv/uhci/root_hub/root_hub.c
===================================================================
--- uspace/drv/uhci/root_hub/root_hub.c	(revision 2972e219df3e7ee8a8f2f574b0405467ead119d4)
+++ uspace/drv/uhci/root_hub/root_hub.c	(revision 28f660d2d933fbece3b8e41bc9300c5ed4977324)
@@ -1,32 +1,13 @@
-#include <bool.h>
+#include <async.h>
 #include <ddi.h>
-#include <devman.h>
-#include <async.h>
 #include <errno.h>
 #include <stdint.h>
 #include <stdio.h>
 
-#include "../name.h"
-#include "../uhci.h"
-#include "../debug.h"
-#include "port_status.h"
+#include "debug.h"
 #include "root_hub.h"
 
 #define ROOT_HUB_WAIT_USEC 10000000 /* 10 second */
 
-struct usb_match {
-	int id_score;
-	const char *id_string;
-};
-
-static int uhci_root_hub_check_ports( void *hc );
-static int uhci_root_hub_new_device( device_t *hc, unsigned port );
-static usb_address_t uhci_root_hub_assign_address( device_t *hc );
-static int uhci_root_hub_report_new_device(
-  device_t *hc, usb_address_t address, int port, devman_handle_t *handle );
-static int uhci_root_hub_port_set_enabled(
-  uhci_root_hub_t *instance, unsigned port, bool enabled );
-
-/*----------------------------------------------------------------------------*/
 int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *hc, void *addr )
 {
@@ -34,20 +15,27 @@
 
 	/* allow access to root hub registers */
-	port_regs_t *regs;
-	const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)&regs);
+	uhci_port_reg_t *regs;
+	const int ret = pio_enable(
+	  addr, sizeof(uhci_port_reg_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 );
+		uhci_print_error(": Failed to gain access to port registers at %p\n", regs);
 		return ret;
 	}
-	hub->registers = regs;
 
-	/* add fibril for periodic checks */
-	hub->checker = fibril_create( uhci_root_hub_check_ports, hc );
-	if (hub->checker == 0) {
-		uhci_print_error( ": failed to launch root hub fibril." );
-		return ENOMEM;
+	/* 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]);
 	}
-	fibril_add_ready( hub->checker );
 
 	return EOK;
@@ -63,193 +51,2 @@
 }
 /*----------------------------------------------------------------------------*/
-static int uhci_root_hub_port_set_enabled( uhci_root_hub_t *instance,
-  unsigned port, bool enabled )
-{
-	assert( instance );
-	assert( instance->registers );
-	assert( port < UHCI_ROOT_HUB_PORT_COUNT );
-
-	volatile uint16_t * address =
-		&(instance->registers->portsc[port]);
-
-	/* read register value */
-	port_status_t port_status;
-	port_status.raw_value = pio_read_16( address );
-
-	/* enable port: register write */
-	port_status.status.enabled_change = 0;
-	port_status.status.enabled = (bool)enabled;
-	pio_write_16( address, port_status.raw_value );
-
-	uhci_print_info( "Enabled port %d.\n", port );
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int uhci_root_hub_check_ports( void * device )
-{
-	assert( device );
-	uhci_t *uhci_instance = ((device_t*)device)->driver_data;
-
-	while (1) {
-		int i = 0;
-		for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
-			volatile uint16_t * address =
-				&(uhci_instance->root_hub.registers->portsc[i]);
-
-			uhci_print_info( "Port(%d) status address %p:\n", i, address );
-
-			/* read register value */
-			port_status_t port_status;
-			port_status.raw_value = pio_read_16( address );
-
-			/* debug print */
-			uhci_print_info( "Port(%d) status %#x:\n", i, port_status.raw_value );
-			print_port_status( &port_status );
-
-			if (port_status.status.connect_change) {
-				if (port_status.status.connected) {
-					/* assign address and report new device */
-					uhci_root_hub_new_device( (device_t*)device, i );
-				} else {
-					/* TODO */
-					/* remove device here */
-				}
-			}
-		}
-		async_usleep( ROOT_HUB_WAIT_USEC );
-	}
-	return ENOTSUP;
-}
-/*----------------------------------------------------------------------------*/
-int uhci_root_hub_new_device( device_t *hc, unsigned port )
-{
-	assert( hc );
-	assert( hc->driver_data );
-	assert( port < UHCI_ROOT_HUB_PORT_COUNT );
-
-	uhci_print_info( "Adding new device on port %d.\n", port );
-
-	uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
-
-	/* get default address */
-	usb_address_keeping_reserve_default( &uhci_instance->address_manager );
-
-	/* enable port */
-	uhci_root_hub_port_set_enabled( &uhci_instance->root_hub, port, true );
-
-	/* assign address to device */
-	usb_address_t address = uhci_root_hub_assign_address( hc );
-
-	/* release default address */
-	usb_address_keeping_release_default( &uhci_instance->address_manager );
-
-	if (address <= 0) { /* address assigning went wrong */
-		uhci_root_hub_port_set_enabled( &uhci_instance->root_hub, port, false );
-		uhci_print_error( "Failed to assign address to the device" );
-		return ENOMEM;
-	}
-
-	/* report to devman */
-	devman_handle_t child = 0;
-	uhci_root_hub_report_new_device( hc, address, port, &child );
-
-	/* bind address */
-	usb_address_keeping_devman_bind( &uhci_instance->address_manager,
-	  address, child );
-
-
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static usb_address_t uhci_root_hub_assign_address( device_t *hc )
-{
-	assert( hc );
-	assert( hc->driver_data );
-
-	uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
-	/* get new address */
-	const usb_address_t usb_address =
-	  usb_address_keeping_request( &uhci_instance->address_manager );
-
-	/* assign new address */
-	/* TODO send new address to the device*/
-	uhci_print_error( "Assigned address %#x.\n", usb_address );
-
-	return usb_address;
-}
-/*----------------------------------------------------------------------------*/
-static int uhci_root_hub_report_new_device(
-  device_t *hc, usb_address_t address, int hub_port, devman_handle_t *handle )
-{
-	assert( hc );
-	assert( address > 0 );
-	assert( address <= USB11_ADDRESS_MAX );
-
-	device_t *child = create_device();
-	if (child == NULL)
-		{ return ENOMEM; }
-
-	char *name;
-	int ret;
-
-	ret = asprintf( &name, "usbdevice on hc%p/%d/%#x", hc, hub_port, address );
-	if (ret < 0) {
-		uhci_print_error( "Failed to create device name.\n" );
-		delete_device( child );
-		return ret;
-	}
-	child->name = name;
-
-	/* TODO get and parse device descriptor */
-	const int vendor = 1;
-	const int product = 1;
-	const char* release = "unknown";
-	const char* class = "unknown";
-
-	/* create match ids TODO fix class printf*/
-	static const struct usb_match usb_matches[] = {
-	  { 100, "usb&vendor=%d&product=%d&release=%s" },
-	  {  90, "usb&vendor=%d&product=%d" },
-	  {  50, "usb&class=%d" },
-	  {   1, "usb&fallback" }
-	};
-
-	unsigned i = 0;
-	for (;i < sizeof( usb_matches )/ sizeof( struct usb_match ); ++i ) {
-		char *match_str;
-		const int ret = asprintf(
-		  &match_str, usb_matches[i].id_string, vendor, product, release, class );
-		if (ret < 0 ) {
-			uhci_print_error( "Failed to create matchid string.\n" );
-			delete_device( child );
-			return ret;
-		}
-		uhci_print_info( "Adding match id rule:%s\n", match_str );
-
-		match_id_t *id = create_match_id();
-		if (id == NULL) {
-			uhci_print_error( "Failed to create matchid.\n" );
-			delete_device( child );
-			free( match_str );
-			return ENOMEM;
-		}
-		id->id = match_str;
-		id->score = usb_matches[i].id_score;
-		add_match_id( &child->match_ids, id );
-
-		uhci_print_info( "Added match id, score: %d, string %s\n",
-		  id->score, id->id );
-	}
-
-	ret = child_device_register( child, hc );
-	if (ret < 0) {
-		uhci_print_error( "Failed to create device name.\n" );
-		delete_device( child );
-		return ret;
-	}
-
-	if (handle != NULL)
-		{ *handle = child->handle; }
-
-	return EOK;
-}
Index: uspace/drv/uhci/root_hub/root_hub.h
===================================================================
--- uspace/drv/uhci/root_hub/root_hub.h	(revision 2972e219df3e7ee8a8f2f574b0405467ead119d4)
+++ uspace/drv/uhci/root_hub/root_hub.h	(revision 28f660d2d933fbece3b8e41bc9300c5ed4977324)
@@ -32,29 +32,24 @@
  * @brief UHCI driver
  */
-#ifndef DRV_UHCI_TD_ROOT_HUB_H
-#define DRV_UHCI_TD_ROOT_HUB_H
+#ifndef DRV_UHCI_ROOT_HUB_H
+#define DRV_UHCI_ROOT_HUB_H
 
 #include <fibril.h>
 #include <driver.h>
 
+#include "port.h"
+
 #define UHCI_ROOT_HUB_PORT_COUNT 2
 #define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10
 
-typedef struct port_regs {
-	uint16_t portsc[UHCI_ROOT_HUB_PORT_COUNT];
-} port_regs_t;
-
 typedef struct root_hub {
-	port_regs_t *registers;
-	fid_t checker;
+	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 );
+  uhci_root_hub_t *instance, device_t *device, void *addr);
 
-int uhci_root_hub_fini( uhci_root_hub_t* instance );
-
-//int uhci_root_hub_check_ports( void * device );
-
+int uhci_root_hub_fini(uhci_root_hub_t* instance);
 #endif
 /**
