Index: uspace/drv/uhci/Makefile
===================================================================
--- uspace/drv/uhci/Makefile	(revision 602eac5121765fe0259312734c435c5e033ba368)
+++ uspace/drv/uhci/Makefile	(revision 0bd28790f565afdb5cc601dd323bf4d6ee95d31f)
@@ -41,5 +41,5 @@
 	utils/fibril_semaphore.c \
 	utils/hc_synchronizer.c \
-	utils/identify.c
+	utils/usb_device.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/uhci/root_hub/port.c
===================================================================
--- uspace/drv/uhci/root_hub/port.c	(revision 602eac5121765fe0259312734c435c5e033ba368)
+++ uspace/drv/uhci/root_hub/port.c	(revision 0bd28790f565afdb5cc601dd323bf4d6ee95d31f)
@@ -9,16 +9,10 @@
 #include "port_status.h"
 #include "utils/hc_synchronizer.h"
-#include "utils/identify.h"
-
-struct usb_match {
-	int id_score;
-	const char *id_string;
-};
+#include "utils/usb_device.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 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);
+static usb_address_t assign_address_to_zero_device(device_t *hc);
 
 /*----------------------------------------------------------------------------*/
@@ -43,13 +37,7 @@
 		if (port_status & STATUS_CONNECTED_CHANGED) {
 			if (port_status & STATUS_CONNECTED) {
-				/* assign address and report new device */
 				uhci_port_new_device(port_instance);
 			} else {
-				/* TODO */
-				/* remove device here */
-				uhci_print_error(
-				  "Don't know how to remove device %#x.\n",
-				  port_instance->attached_device);
-				uhci_port_set_enabled(port_instance, false);
+				uhci_port_remove_device(port_instance);
 			}
 		}
@@ -77,22 +65,53 @@
 	usb_address_t address = assign_address_to_zero_device(port->hc);
 
+
+	if (address <= 0) { /* address assigning went wrong */
+		uhci_print_error("Failed to assign address to the device.\n");
+		uhci_port_set_enabled(port, false);
+		usb_address_keeping_release_default(&uhci_instance->address_manager);
+		return ENOMEM;
+	}
+
 	/* 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.\n");
-		return ENOMEM;
-	}
+	/* communicate and possibly report to devman */
+	assert(port->attached_device == 0);
 
-	/* communicate and possibly report to devman */
-	assert( port->attached_device == 0 );
-	report_new_device(port->hc, address, port->number,
-		&port->attached_device);
+#define CHECK_RET_DELETE_CHILD_RETURN(ret, child, message, args...)\
+	if (ret < 0) { \
+		uhci_print_error("Failed(%d) to "message, ret, ##args); \
+		if (child) { \
+			delete_device(child); \
+		} \
+		uhci_port_set_enabled(port, false); \
+		usb_address_keeping_release(&uhci_instance->address_manager, address); \
+		return ret; \
+	} else (void)0
 
-	/* bind address */
+	device_t *child = create_device();
+
+	int ret = child ? EOK : ENOMEM;
+	CHECK_RET_DELETE_CHILD_RETURN(ret, child, "create device.\n" );
+
+	ret = usb_device_init(child, port->hc, address, port->number );
+	CHECK_RET_DELETE_CHILD_RETURN(ret, child, "init usb device.\n" );
+
+	ret = child_device_register(child, port->hc);
+	CHECK_RET_DELETE_CHILD_RETURN(ret, child, "register usb device.\n" );
+
+	/* store device and bind address, can not fail */
+	port->attached_device = child->handle;
 	usb_address_keeping_devman_bind(&uhci_instance->address_manager,
 	  address, port->attached_device);
 
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+static int uhci_port_remove_device(uhci_port_t *port)
+{
+	uhci_print_error(	"Don't know how to remove device %#x.\n",
+		port->attached_device);
+	uhci_port_set_enabled(port, false);
 	return EOK;
 }
@@ -114,52 +133,6 @@
 	port_status_write( port->address, port_status );
 
-/*
-	port_status.status.enabled = enabled;
-	pio_write_16( port->address, port_status.raw_value );
-*/
-
 	uhci_print_info( "%s port %d.\n",
 	  enabled ? "Enabled" : "Disabled", port->number );
-	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; }
-
-	int ret = 0;
-#define CHECK_RET_DELETE_CHILD_RETURN(ret, child, message, args...)\
-	if (ret < 0) { \
-		uhci_print_error("Failed(%d) to "message, ret, ##args); \
-		delete_device(child); \
-		return ret; \
-	} else (void)0
-
-	char *name;
-
-	/* create name */
-	ret = asprintf(&name, "usbdevice on hc%p/%d(%#x)", hc, hub_port, address);
-	CHECK_RET_DELETE_CHILD_RETURN(ret, child, "create device name.\n");
-
-	child->name = name;
-
-	/* use descriptors to identify the device */
-	ret = identify_device(hc, child, address);
-	CHECK_RET_DELETE_CHILD_RETURN(ret, child, "identify device.\n");
-
-	/* all went well, tell devman */
-	ret = child_device_register( child, hc );
-	CHECK_RET_DELETE_CHILD_RETURN(ret, child, "register device.\n");
-
-	if (handle != NULL)
-		{ *handle = child->handle; }
-
 	return EOK;
 }
@@ -171,4 +144,5 @@
 
 	uhci_t *uhci_instance = (uhci_t*)hc->driver_data;
+
 	/* get new address */
 	const usb_address_t usb_address =
Index: uspace/drv/uhci/utils/identify.c
===================================================================
--- uspace/drv/uhci/utils/identify.c	(revision 602eac5121765fe0259312734c435c5e033ba368)
+++ 	(revision )
@@ -1,78 +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.
- */
-
-#include <errno.h>
-#include <usb/classes/classes.h>
-#include <usb/descriptor.h>
-#include <usb/usbdrv.h>
-
-#include "identify.h"
-
-struct device_descriptor_packet
-{
-	usb_device_request_setup_packet_t request;
-	usb_standard_device_descriptor_t descriptor;
-};
-#define DEVICE_DESCRIPTOR_PACKET_INITIALIZER \
-	{ \
-		.request = { \
-			.request_type = 0, \
-			.request = USB_DEVREQ_GET_DESCRIPTOR, \
-			{ .value = USB_DESCTYPE_DEVICE }, \
-			.index = 0, \
-			.length = sizeof(usb_standard_device_descriptor_t) \
-		} \
-	}
-/*----------------------------------------------------------------------------*/
-struct configuration_descriptor_packet
-{
-	usb_device_request_setup_packet_t request;
-	usb_standard_configuration_descriptor_t descriptor;
-};
-#define CONFIGURATION_DESCRIPTOR_PACKET_INITIALIZER \
-	{ \
-		.request = { \
-			.request_type = 0, \
-			.request = USB_DEVREQ_GET_DESCRIPTOR, \
-			{ .value = USB_DESCTYPE_CONFIGURATION }, \
-			.index = 0, \
-			.length = sizeof(usb_standard_device_descriptor_t); \
-		}; \
-	}
-/*----------------------------------------------------------------------------*/
-int identify_device(device_t *hc, device_t *child, usb_address_t address)
-{
-	struct device_descriptor_packet packet =
-	  DEVICE_DESCRIPTOR_PACKET_INITIALIZER;
-
-  packet.descriptor.device_class = USB_CLASS_HUB;
-  usb_drv_create_match_ids_from_device_descriptor(
-	  &child->match_ids, &packet.descriptor );
-
-	return 0;
-}
Index: uspace/drv/uhci/utils/identify.h
===================================================================
--- uspace/drv/uhci/utils/identify.h	(revision 602eac5121765fe0259312734c435c5e033ba368)
+++ 	(revision )
@@ -1,45 +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_UTILS_IDENTIFY_H
-#define DRV_UHCI_UTILS_IDENTIFY_H
-
-#include <driver.h>
-#include <usb/usb.h>
-
-int identify_device(device_t *hc, device_t *child, usb_address_t address);
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/uhci/utils/usb_device.c
===================================================================
--- uspace/drv/uhci/utils/usb_device.c	(revision 0bd28790f565afdb5cc601dd323bf4d6ee95d31f)
+++ uspace/drv/uhci/utils/usb_device.c	(revision 0bd28790f565afdb5cc601dd323bf4d6ee95d31f)
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <usb/classes/classes.h>
+#include <usb/descriptor.h>
+#include <usb/usbdrv.h>
+
+#include "debug.h"
+#include "usb_device.h"
+
+/*----------------------------------------------------------------------------*/
+#define CHECK_RET_RETURN(ret, child, message, args...)\
+  if (ret < 0) { \
+    uhci_print_error("Failed(%d) to "message, ret, ##args); \
+    return ret; \
+  } else (void)0
+
+int usb_device_init(device_t *device, device_t *hc, usb_address_t address,
+  int hub_port)
+{
+	assert(device);
+	assert(hc);
+
+	int ret = 0;
+  char *name;
+
+  /* create name */
+  ret = asprintf(&name, "usbdevice on hc%p/root_hub[%d]/%#x",
+	  hc, hub_port, address);
+  CHECK_RET_RETURN(ret, child, "create device name.\n");
+
+  device->name = name;
+
+	/* use descriptors to identify the device */
+  ret = usb_device_identify(device, hc, address);
+  CHECK_RET_RETURN(ret, child, "identify device.\n");
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+struct device_descriptor_packet
+{
+	usb_device_request_setup_packet_t request;
+	usb_standard_device_descriptor_t descriptor;
+};
+#define DEVICE_DESCRIPTOR_PACKET_INITIALIZER \
+	{ \
+		.request = { \
+			.request_type = 0, \
+			.request = USB_DEVREQ_GET_DESCRIPTOR, \
+			{ .value = USB_DESCTYPE_DEVICE }, \
+			.index = 0, \
+			.length = sizeof(usb_standard_device_descriptor_t) \
+		} \
+	}
+/*----------------------------------------------------------------------------*/
+struct configuration_descriptor_packet
+{
+	usb_device_request_setup_packet_t request;
+	usb_standard_configuration_descriptor_t descriptor;
+};
+#define CONFIGURATION_DESCRIPTOR_PACKET_INITIALIZER \
+	{ \
+		.request = { \
+			.request_type = 0, \
+			.request = USB_DEVREQ_GET_DESCRIPTOR, \
+			{ .value = USB_DESCTYPE_CONFIGURATION }, \
+			.index = 0, \
+			.length = sizeof(usb_standard_device_descriptor_t); \
+		}; \
+	}
+/*----------------------------------------------------------------------------*/
+int usb_device_identify(device_t *device, device_t *hc, usb_address_t address)
+{
+	assert(device);
+	assert(hc);
+
+	struct device_descriptor_packet packet =
+	  DEVICE_DESCRIPTOR_PACKET_INITIALIZER;
+
+  packet.descriptor.device_class = USB_CLASS_HUB;
+  usb_drv_create_match_ids_from_device_descriptor(
+	  &device->match_ids, &packet.descriptor );
+
+	return 0;
+}
+/*----------------------------------------------------------------------------*/
Index: uspace/drv/uhci/utils/usb_device.h
===================================================================
--- uspace/drv/uhci/utils/usb_device.h	(revision 0bd28790f565afdb5cc601dd323bf4d6ee95d31f)
+++ uspace/drv/uhci/utils/usb_device.h	(revision 0bd28790f565afdb5cc601dd323bf4d6ee95d31f)
@@ -0,0 +1,48 @@
+/*
+ * 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_UTILS_IDENTIFY_H
+#define DRV_UHCI_UTILS_IDENTIFY_H
+
+#include <driver.h>
+#include <usb/usb.h>
+
+int usb_device_identify(device_t *device, device_t *hc, usb_address_t address);
+
+int usb_device_init(device_t *device, device_t *hc, usb_address_t address,
+  int port);
+
+#endif
+/**
+ * @}
+ */
