Index: uspace/drv/uhci/root_hub/port_status.c
===================================================================
--- uspace/drv/uhci/root_hub/port_status.c	(revision 35155333e1633196384ead6b221f756629e1e10d)
+++ uspace/drv/uhci/root_hub/port_status.c	(revision 18e35a74cbf1c0e26ce4c307fe9ba7e2bd556879)
@@ -4,17 +4,17 @@
 #include "port_status.h"
 
-void print_port_status( port_status_t *status )
+void print_port_status( const port_status_t *status )
 {
 	assert( status );
-	printf( "\tsuspended: %s\n", status->suspended ? "YES" : "NO" );
-	printf( "\tin reset: %s\n", status->reset ? "YES" : "NO" );
-	printf( "\tlow speed: %s\n", status->low_speed ? "YES" : "NO" );
-	printf( "\tresume detected: %s\n", status->resume ? "YES" : "NO" );
+	printf( "\tsuspended: %s\n", status->status.suspended ? "YES" : "NO" );
+	printf( "\tin reset: %s\n", status->status.reset ? "YES" : "NO" );
+	printf( "\tlow speed: %s\n", status->status.low_speed ? "YES" : "NO" );
+	printf( "\tresume detected: %s\n", status->status.resume ? "YES" : "NO" );
 	printf( "\talways \"1\" reserved bit: %s\n",
-	  status->always_one ? "YES" : "NO" );
+	  status->status.always_one ? "YES" : "NO" );
 	/* line status skipped */
-	printf( "\tenable/disable change: %s\n", status->enabled_change ? "YES" : "NO" );
-	printf( "\tport enabled: %s\n", status->enabled ? "YES" : "NO" );
-	printf( "\tconnect change: %s\n", status->connect_change ? "YES" : "NO" );
-	printf( "\tconnected: %s\n", status->connected ? "YES" : "NO" );
+	printf( "\tenable/disable change: %s\n", status->status.enabled_change ? "YES" : "NO" );
+	printf( "\tport enabled: %s\n", status->status.enabled ? "YES" : "NO" );
+	printf( "\tconnect change: %s\n", status->status.connect_change ? "YES" : "NO" );
+	printf( "\tconnected: %s\n", status->status.connected ? "YES" : "NO" );
 }
Index: uspace/drv/uhci/root_hub/port_status.h
===================================================================
--- uspace/drv/uhci/root_hub/port_status.h	(revision 35155333e1633196384ead6b221f756629e1e10d)
+++ uspace/drv/uhci/root_hub/port_status.h	(revision 18e35a74cbf1c0e26ce4c307fe9ba7e2bd556879)
@@ -37,5 +37,5 @@
 #include <stdint.h>
 
-typedef struct port_status {
+struct port_register {
 	uint8_t connected:1;
 	uint8_t connect_change:1;
@@ -66,7 +66,12 @@
 //	uint8_t connect_change:1;
 //	uint8_t connected:1;
-} __attribute__((packed)) port_status_t;
+} __attribute__((packed));
 
-void print_port_status( port_status_t *status );
+typedef union port_status {
+	struct port_register status;
+	uint16_t raw_value;
+} port_status_t;
+
+void print_port_status( const port_status_t *status );
 #endif
 /**
Index: uspace/drv/uhci/root_hub/root_hub.c
===================================================================
--- uspace/drv/uhci/root_hub/root_hub.c	(revision 35155333e1633196384ead6b221f756629e1e10d)
+++ uspace/drv/uhci/root_hub/root_hub.c	(revision 18e35a74cbf1c0e26ce4c307fe9ba7e2bd556879)
@@ -4,4 +4,5 @@
 #include <stdint.h>
 #include <stdio.h>
+
 #include <usb/debug.h>
 
@@ -11,22 +12,33 @@
 #include "root_hub.h"
 
-static int uhci_root_hub_check_ports( void * device );
+#define ROOT_HUB_WAIT_USEC 10000000 /* 10 second */
+
+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 );
+
 /*----------------------------------------------------------------------------*/
-int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *device, void *addr )
+int uhci_root_hub_init( uhci_root_hub_t *hub, device_t *hc, void *addr )
 {
 	assert( hub );
-	hub->checker = fibril_create( uhci_root_hub_check_ports, device );
+
+	/* allow access to root hub registers */
+	port_regs_t *regs;
+	const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)&regs);
+	if (ret < 0) {
+		printf( NAME": 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) {
-		printf( NAME": Failed to launch root hub fibril." );
+		printf( NAME": failed to launch root hub fibril." );
 		return ENOMEM;
 	}
 	fibril_add_ready( hub->checker );
-	port_regs_t *regs;
-	const int ret = pio_enable( addr, sizeof(port_regs_t), (void**)&regs);
-	if (ret < 0) {
-		printf(NAME": Failed to gain access to port registers at %p\n", regs);
-		return ret;
-	}
-	hub->registers = regs;
 
 	return EOK;
@@ -36,5 +48,7 @@
 {
 	assert( instance );
+	// TODO:
 	//destroy fibril here
+	//disable access to registers
 	return EOK;
 }
@@ -44,4 +58,5 @@
 	assert( device );
 	uhci_t *uhci_instance = ((device_t*)device)->driver_data;
+
 	while (1) {
 		int i = 0;
@@ -51,10 +66,130 @@
 
 			usb_dprintf( NAME, 1, "Port(%d) status address %p:\n", i, address );
-			uint16_t value = pio_read_16( address );
-			usb_dprintf( NAME, 1, "Port(%d) status 0x%x:\n", i, value );
-			print_port_status( (port_status_t*)&value );
+
+			/* read register value */
+			port_status_t port_status;
+			port_status.raw_value = pio_read_16( address );
+
+			/* debug print */
+			usb_dprintf( NAME, 1, "Port(%d) status 0x%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( 1000000 );
+		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 );
+
+	usb_dprintf( NAME, 2, "Adding new device on port %d.\n", port );
+
+	uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
+
+	/* enable port */
+	{
+		volatile uint16_t * address =
+			&(uhci_instance->root_hub.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 = 1;
+		pio_write_16( address, port_status.raw_value );
+
+		usb_dprintf( NAME, 2, "Enabled port %d.\n", port );
+	}
+
+	/* assign address to device */
+	usb_address_t address =
+	 uhci_root_hub_assign_address( hc );
+	if (address <= 0) {
+		printf( NAME": 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 );
+
+	/* get default address */
+	usb_address_keeping_reserve_default( &uhci_instance->address_manager );
+
+	/* assign new address */
+	/* TODO send new address*/
+	usb_dprintf( NAME, 3, "Assigned address 0x%x.\n", usb_address );
+
+	/* release default address */
+	usb_address_keeping_release_default( &uhci_instance->address_manager );
+
+	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 );
+
+	int ret;
+	device_t *child = create_device();
+	if (child == NULL)
+		{ return ENOMEM; }
+	char *name;
+
+	ret = asprintf( &name, "usbdevice on hc%p/%d/0x%x", hc, hub_port, address );
+	if (ret < 0) {
+		usb_dprintf( NAME, 4, "Failed to create device name.\n" );
+		delete_device( child );
+		return ret;
+	}
+	child->name = name;
+
+	/* TODO create match ids */
+
+	ret = child_device_register( child, hc );
+	if (ret < 0) {
+		usb_dprintf( NAME, 4, "Failed to create device name.\n" );
+		delete_device( child );
+		return ret;
+	}
+
+	if (handle != NULL)
+		{ *handle = child->handle; }
+
+	return EOK;
+}
Index: uspace/drv/uhci/uhci.c
===================================================================
--- uspace/drv/uhci/uhci.c	(revision 35155333e1633196384ead6b221f756629e1e10d)
+++ uspace/drv/uhci/uhci.c	(revision 18e35a74cbf1c0e26ce4c307fe9ba7e2bd556879)
@@ -1,4 +1,5 @@
 #include <errno.h>
 #include <usb/debug.h>
+#include <usb/usb.h>
 
 #include "name.h"
@@ -16,4 +17,7 @@
 		{ return ENOMEM; }
 	memset( instance, 0, sizeof(uhci_t) );
+
+	/* init address keeper(libusb) */
+	usb_address_keeping_init( &instance->address_manager, USB11_ADDRESS_MAX );
 
 	/* allow access to hc control registers */
