Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -571,6 +571,5 @@
 	usb_log_debug2("OHCI HCCA initialized at %p.\n", instance->hcca);
 
-	unsigned i = 0;
-	for (; i < 32; ++i) {
+	for (unsigned i = 0; i < 32; ++i) {
 		instance->hcca->int_ep[i] =
 		    instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa;
Index: uspace/drv/bus/usb/ohci/ohci_batch.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_batch.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/ohci/ohci_batch.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -52,7 +52,6 @@
 	if (!ohci_batch)
 		return;
-	unsigned i = 0;
 	if (ohci_batch->tds) {
-		for (; i< ohci_batch->td_count; ++i) {
+		for (unsigned i = 0; i < ohci_batch->td_count; ++i) {
 			if (i != ohci_batch->leave_td)
 				free32(ohci_batch->tds[i]);
@@ -107,6 +106,6 @@
 	ohci_batch->tds[0] = ohci_endpoint_get(usb_batch->ep)->td;
 	ohci_batch->leave_td = 0;
-	unsigned i = 1;
-	for (; i <= ohci_batch->td_count; ++i) {
+
+	for (unsigned i = 1; i <= ohci_batch->td_count; ++i) {
 		ohci_batch->tds[i] = malloc32(sizeof(td_t));
 		CHECK_NULL_DISPOSE_RET(ohci_batch->tds[i],
@@ -160,5 +159,5 @@
 	usb_log_debug("Batch %p checking %zu td(s) for completion.\n",
 	    ohci_batch->usb_batch, ohci_batch->td_count);
-	usb_log_debug2("ED: %x:%x:%x:%x.\n",
+	usb_log_debug2("ED: %08x:%08x:%08x:%08x.\n",
 	    ohci_batch->ed->status, ohci_batch->ed->td_head,
 	    ohci_batch->ed->td_tail, ohci_batch->ed->next);
@@ -167,5 +166,5 @@
 	for (; i < ohci_batch->td_count; ++i) {
 		assert(ohci_batch->tds[i] != NULL);
-		usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i,
+		usb_log_debug("TD %zu: %08x:%08x:%08x:%08x.\n", i,
 		    ohci_batch->tds[i]->status, ohci_batch->tds[i]->cbp,
 		    ohci_batch->tds[i]->next, ohci_batch->tds[i]->be);
@@ -175,5 +174,5 @@
 		ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]);
 		if (ohci_batch->usb_batch->error != EOK) {
-			usb_log_debug("Batch %p found error TD(%zu):%x.\n",
+			usb_log_debug("Batch %p found error TD(%zu):%08x.\n",
 			    ohci_batch->usb_batch, i,
 			    ohci_batch->tds[i]->status);
@@ -196,7 +195,8 @@
 	ohci_batch->usb_batch->transfered_size =
 	    ohci_batch->usb_batch->buffer_size;
-	for (--i;i < ohci_batch->td_count; ++i)
+	for (--i;i < ohci_batch->td_count; ++i) {
 		ohci_batch->usb_batch->transfered_size
 		    -= td_remain_size(ohci_batch->tds[i]);
+	}
 
 	/* Clear possible ED HALT */
@@ -234,5 +234,5 @@
 	assert(ohci_batch->usb_batch);
 	assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
-	usb_log_debug("Using ED(%p): %x:%x:%x:%x.\n", ohci_batch->ed,
+	usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed,
 	    ohci_batch->ed->status, ohci_batch->ed->td_tail,
 	    ohci_batch->ed->td_head, ohci_batch->ed->next);
@@ -251,5 +251,5 @@
 		ohci_batch->usb_batch->setup_size, toggle);
 	td_set_next(ohci_batch->tds[0], ohci_batch->tds[1]);
-	usb_log_debug("Created CONTROL SETUP TD: %x:%x:%x:%x.\n",
+	usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n",
 	    ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp,
 	    ohci_batch->tds[0]->next, ohci_batch->tds[0]->be);
@@ -269,5 +269,5 @@
 		td_set_next(ohci_batch->tds[td_current],
 		    ohci_batch->tds[td_current + 1]);
-		usb_log_debug("Created CONTROL DATA TD: %x:%x:%x:%x.\n",
+		usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x:%08x.\n",
 		    ohci_batch->tds[td_current]->status,
 		    ohci_batch->tds[td_current]->cbp,
@@ -286,5 +286,5 @@
 	td_set_next(ohci_batch->tds[td_current],
 	    ohci_batch->tds[td_current + 1]);
-	usb_log_debug("Created CONTROL STATUS TD: %x:%x:%x:%x.\n",
+	usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x:%08x.\n",
 	    ohci_batch->tds[td_current]->status,
 	    ohci_batch->tds[td_current]->cbp,
@@ -312,5 +312,5 @@
 	assert(ohci_batch->usb_batch);
 	assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT);
-	usb_log_debug("Using ED(%p): %x:%x:%x:%x.\n", ohci_batch->ed,
+	usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed,
 	    ohci_batch->ed->status, ohci_batch->ed->td_tail,
 	    ohci_batch->ed->td_head, ohci_batch->ed->next);
@@ -328,5 +328,5 @@
 		    ohci_batch->tds[td_current + 1]);
 
-		usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",
+		usb_log_debug("Created DATA TD: %08x:%08x:%08x:%08x.\n",
 		    ohci_batch->tds[td_current]->status,
 		    ohci_batch->tds[td_current]->cbp,
Index: uspace/drv/bus/usb/ohci/pci.c
===================================================================
--- uspace/drv/bus/usb/ohci/pci.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/ohci/pci.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -85,6 +85,5 @@
 	bool irq_found = false;
 
-	size_t i;
-	for (i = 0; i < hw_resources.count; i++) {
+	for (size_t i = 0; i < hw_resources.count; i++) {
 		hw_resource_t *res = &hw_resources.resources[i];
 		switch (res->type) {
Index: uspace/drv/bus/usb/ohci/root_hub.c
===================================================================
--- uspace/drv/bus/usb/ohci/root_hub.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/ohci/root_hub.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -351,6 +351,5 @@
 		mask |= 1;
 	}
-	size_t port = 1;
-	for (; port <= instance->port_count; ++port) {
+	for (size_t port = 1; port <= instance->port_count; ++port) {
 		/* Write-clean bits are those that indicate change */
 		if (RHPS_CHANGE_WC_MASK
Index: uspace/drv/bus/usb/ohci/utils/malloc32.h
===================================================================
--- uspace/drv/bus/usb/ohci/utils/malloc32.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/ohci/utils/malloc32.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -69,5 +69,5 @@
  */
 static inline void free32(void *addr)
-	{ if (addr) free(addr); }
+	{ free(addr); }
 #endif
 /**
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -299,6 +299,6 @@
 	const uint32_t queue = LINK_POINTER_QH(
 	        addr_to_phys(instance->transfers_interrupt.queue_head));
-	unsigned i = 0;
-	for(; i < UHCI_FRAME_LIST_COUNT; ++i) {
+
+	for (unsigned i = 0; i < UHCI_FRAME_LIST_COUNT; ++i) {
 		instance->frame_list[i] = queue;
 	}
Index: uspace/drv/bus/usb/uhci/pci.c
===================================================================
--- uspace/drv/bus/usb/uhci/pci.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/uhci/pci.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -82,6 +82,5 @@
 	bool irq_found = false;
 
-	size_t i;
-	for (i = 0; i < hw_resources.count; i++) {
+	for (size_t i = 0; i < hw_resources.count; i++) {
 		const hw_resource_t *res = &hw_resources.resources[i];
 		switch (res->type) {
Index: uspace/drv/bus/usb/uhci/uhci_batch.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci_batch.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/uhci/uhci_batch.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -167,6 +167,6 @@
 	    uhci_batch->td_count);
 	uhci_batch->usb_batch->transfered_size = 0;
-	size_t i = 0;
-	for (;i < uhci_batch->td_count; ++i) {
+
+	for (size_t i = 0;i < uhci_batch->td_count; ++i) {
 		if (td_is_active(&uhci_batch->tds[i])) {
 			return false;
Index: uspace/drv/bus/usb/uhci/utils/malloc32.h
===================================================================
--- uspace/drv/bus/usb/uhci/utils/malloc32.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/uhci/utils/malloc32.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -62,10 +62,11 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Physical mallocator simulator
+/** DMA malloc simulator
  *
  * @param[in] size Size of the required memory space
- * @return Address of the alligned and big enough memory place, NULL on failure.
+ * @return Address of the aligned and big enough memory place, NULL on failure.
  */
-static inline void * malloc32(size_t size) {
+static inline void * malloc32(size_t size)
+{
 	/* This works only when the host has less than 4GB of memory as
 	 * physical address needs to fit into 32 bits */
@@ -83,13 +84,10 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Physical mallocator simulator
+/** DMA malloc simulator
  *
  * @param[in] addr Address of the place allocated by malloc32
  */
-static inline void free32(void *addr) {
-	if (!addr)
-		return;
-	free(addr);
-}
+static inline void free32(void *addr)
+	{ free(addr); }
 /*----------------------------------------------------------------------------*/
 /** Create 4KB page mapping
Index: uspace/drv/bus/usb/uhcirh/port.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/uhcirh/port.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -37,13 +37,15 @@
 #include <str_error.h>
 #include <async.h>
+#include <devman.h>
 
 #include <usb/usb.h>    /* usb_address_t */
-#include <usb/dev/hub.h>    /* usb_hc_new_device_wrapper */
 #include <usb/debug.h>
 
 #include "port.h"
 
+#define MAX_ERROR_COUNT 5
+
 static int uhci_port_check(void *port);
-static int uhci_port_reset_enable(int portno, void *arg);
+static int uhci_port_reset_enable(void *arg);
 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
 static int uhci_port_remove_device(uhci_port_t *port);
@@ -100,5 +102,6 @@
 	port->number = number;
 	port->wait_period_usec = usec;
-	port->attached_device = 0;
+	port->attached_device.fun = NULL;
+	port->attached_device.address = -1;
 	port->rh = rh;
 
@@ -150,4 +153,17 @@
 	assert(instance);
 
+	unsigned allowed_failures = MAX_ERROR_COUNT;
+#define CHECK_RET_FAIL(ret, msg...) \
+	if (ret != EOK) { \
+		usb_log_error(msg); \
+		if (!(allowed_failures-- > 0)) { \
+			usb_log_fatal( \
+			   "Maximum number of failures reached, " \
+			   "bailing out.\n"); \
+			return ret; \
+		} \
+		continue; \
+	} else (void)0
+
 	while (1) {
 		async_usleep(instance->wait_period_usec);
@@ -167,21 +183,15 @@
 		    instance->id_string, port_status);
 
+		int ret = usb_hc_connection_open(&instance->hc_connection);
+		CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n",
+		    instance->id_string, str_error(ret));
+
 		/* Remove any old device */
-		if (instance->attached_device) {
-			usb_log_debug2("%s: Removing device.\n",
-			    instance->id_string);
+		if (instance->attached_device.fun) {
 			uhci_port_remove_device(instance);
 		}
 
-		int ret =
-		    usb_hc_connection_open(&instance->hc_connection);
-		if (ret != EOK) {
-			usb_log_error("%s: Failed to connect to HC.",
-			    instance->id_string);
-			continue;
-		}
-
 		if ((port_status & STATUS_CONNECTED) != 0) {
-			/* New device */
+			/* New device, this will take care of WC bits */
 			const usb_speed_t speed =
 			    ((port_status & STATUS_LOW_SPEED) != 0) ?
@@ -196,8 +206,6 @@
 
 		ret = usb_hc_connection_close(&instance->hc_connection);
-		if (ret != EOK) {
-			usb_log_error("%s: Failed to disconnect.",
-			    instance->id_string);
-		}
+		CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n",
+		    instance->id_string, str_error(ret));
 	}
 	return EOK;
@@ -212,5 +220,5 @@
  * Resets and enables the ub port.
  */
-int uhci_port_reset_enable(int portno, void *arg)
+int uhci_port_reset_enable(void *arg)
 {
 	uhci_port_t *port = arg;
@@ -256,11 +264,11 @@
 	usb_log_debug("%s: Detected new device.\n", port->id_string);
 
-	int ret, count = 0;
-	usb_address_t dev_addr;
+	int ret, count = MAX_ERROR_COUNT;
 	do {
 		ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
-		    speed, uhci_port_reset_enable, port->number, port,
-		    &dev_addr, &port->attached_device, NULL, NULL, NULL);
-	} while (ret != EOK && ++count < 4);
+		    speed, uhci_port_reset_enable, port,
+		    &port->attached_device.address, NULL, NULL,
+		    &port->attached_device.fun);
+	} while (ret != EOK && count-- > 0);
 
 	if (ret != EOK) {
@@ -271,6 +279,7 @@
 	}
 
-	usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n",
-	    port->number, dev_addr, port->attached_device);
+	usb_log_info("%s: New device, address %d (handle %" PRIun ").\n",
+	    port->id_string, port->attached_device.address,
+	    port->attached_device.fun->handle);
 	return EOK;
 }
@@ -278,17 +287,42 @@
 /** Remove device.
  *
- * @param[in] port Memory structure to use.
- * @return Error code.
- *
- * Does not work, DDF does not support device removal.
- * Does not even free used USB address (it would be dangerous if tis driver
- * is still running).
+ * @param[in] port Port instance to use.
+ * @return Error code.
  */
 int uhci_port_remove_device(uhci_port_t *port)
 {
-	usb_log_error("%s: Don't know how to remove device %" PRIun ".\n",
-	    port->id_string, port->attached_device);
-	port->attached_device = 0;
-	return ENOTSUP;
+	assert(port);
+	/* There is nothing to remove. */
+	if (port->attached_device.fun == NULL) {
+		usb_log_warning("%s: Removed a ghost device.\n",
+		    port->id_string);
+		assert(port->attached_device.address == -1);
+		return EOK;
+	}
+
+	usb_log_debug("%s: Removing device.\n", port->id_string);
+
+	/* Stop driver first */
+	int ret = ddf_fun_unbind(port->attached_device.fun);
+	if (ret != EOK) {
+		usb_log_error("%s: Failed to remove child function: %s.\n",
+		   port->id_string, str_error(ret));
+		return ret;
+	}
+	ddf_fun_destroy(port->attached_device.fun);
+	port->attached_device.fun = NULL;
+
+	/* Driver stopped, free used address */
+	ret = usb_hc_unregister_device(&port->hc_connection,
+	    port->attached_device.address);
+	if (ret != EOK) {
+		usb_log_error("%s: Failed to unregister address of removed "
+		    "device: %s.\n", port->id_string, str_error(ret));
+		return ret;
+	}
+	port->attached_device.address = -1;
+
+	usb_log_info("%s: Removed attached device.\n", port->id_string);
+	return EOK;
 }
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/bus/usb/uhcirh/port.h
===================================================================
--- uspace/drv/bus/usb/uhcirh/port.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/uhcirh/port.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -39,4 +39,5 @@
 #include <ddf/driver.h>
 #include <usb/hc.h> /* usb_hc_connection_t */
+#include <usb/dev/hub.h>
 
 typedef uint16_t port_status_t;
@@ -62,5 +63,5 @@
 	usb_hc_connection_t hc_connection;
 	ddf_dev_t *rh;
-	devman_handle_t attached_device;
+	usb_hub_attached_device_t attached_device;
 	fid_t checker;
 } uhci_port_t;
Index: uspace/drv/bus/usb/usbflbk/main.c
===================================================================
--- uspace/drv/bus/usb/usbflbk/main.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbflbk/main.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -46,5 +46,5 @@
  * @return Error code.
  */
-static int usbfallback_add_device(usb_device_t *dev)
+static int usbfallback_device_add(usb_device_t *dev)
 {
 	int rc;
@@ -74,5 +74,5 @@
 /** USB fallback driver ops. */
 static usb_driver_ops_t usbfallback_driver_ops = {
-	.add_device = usbfallback_add_device,
+	.device_add = usbfallback_device_add,
 };
 
Index: uspace/drv/bus/usb/usbhid/main.c
===================================================================
--- uspace/drv/bus/usb/usbhid/main.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbhid/main.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -150,7 +150,7 @@
  * @retval EREFUSED if the device is not supported.
  */
-static int usb_hid_add_device(usb_device_t *dev)
+static int usb_hid_device_add(usb_device_t *dev)
 {
-	usb_log_debug("usb_hid_add_device()\n");
+	usb_log_debug("usb_hid_device_add()\n");
 	
 	if (dev == NULL) {
@@ -185,5 +185,5 @@
  * supports unplug, more callbacks will be added. */
 static usb_driver_ops_t usb_hid_driver_ops = {
-        .add_device = usb_hid_add_device,
+        .device_add = usb_hid_device_add,
 };
 
Index: uspace/drv/bus/usb/usbhub/main.c
===================================================================
--- uspace/drv/bus/usb/usbhub/main.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbhub/main.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -59,8 +59,9 @@
  * USB hub driver operations
  *
- * The most important one is add_device, which is set to usb_hub_add_device.
+ * The most important one is device_add, which is set to usb_hub_device_add.
  */
 static usb_driver_ops_t usb_hub_driver_ops = {
-	.add_device = usb_hub_add_device
+	.device_add = usb_hub_device_add,
+	.device_gone = usb_hub_device_gone,
 };
 
Index: uspace/drv/bus/usb/usbhub/port.c
===================================================================
--- uspace/drv/bus/usb/usbhub/port.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbhub/port.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -50,26 +50,31 @@
 /** Information for fibril for device discovery. */
 struct add_device_phase1 {
-	usb_hub_info_t *hub;
+	usb_hub_dev_t *hub;
 	usb_hub_port_t *port;
 	usb_speed_t speed;
 };
 
-static void usb_hub_port_removed_device(usb_hub_port_t *port,
-    usb_hub_info_t *hub);
+static int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub);
 static void usb_hub_port_reset_completed(usb_hub_port_t *port,
     usb_port_status_t status);
 static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status);
-static int enable_port_callback(int port_no, void *arg);
+static int enable_port_callback(void *arg);
 static int add_device_phase1_worker_fibril(void *arg);
-static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_info_t *hub,
+static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_dev_t *hub,
     usb_speed_t speed);
 
+int usb_hub_port_fini(usb_hub_port_t *port, usb_hub_dev_t *hub)
+{
+	assert(port);
+	if (port->attached_device.fun)
+		return usb_hub_port_device_gone(port, hub);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
 /**
  * Clear feature on hub port.
  *
- * @param hc Host controller telephone
- * @param address Hub address
- * @param port_index Port
- * @param feature Feature selector
+ * @param port Port structure.
+ * @param feature Feature selector.
  * @return Operation result
  */
@@ -78,5 +83,5 @@
 {
 	assert(port);
-	usb_device_request_setup_packet_t clear_request = {
+	const usb_device_request_setup_packet_t clear_request = {
 		.request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
 		.request = USB_DEVREQ_CLEAR_FEATURE,
@@ -90,10 +95,8 @@
 /*----------------------------------------------------------------------------*/
 /**
- * Clear feature on hub port.
- *
- * @param hc Host controller telephone
- * @param address Hub address
- * @param port_index Port
- * @param feature Feature selector
+ * Set feature on hub port.
+ *
+ * @param port Port structure.
+ * @param feature Feature selector.
  * @return Operation result
  */
@@ -102,5 +105,5 @@
 {
 	assert(port);
-	usb_device_request_setup_packet_t clear_request = {
+	const usb_device_request_setup_packet_t clear_request = {
 		.request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE,
 		.request = USB_DEVREQ_SET_FEATURE,
@@ -113,4 +116,9 @@
 }
 /*----------------------------------------------------------------------------*/
+/**
+ * Mark reset process as failed due to external reasons
+ *
+ * @param port Port structure
+ */
 void usb_hub_port_reset_fail(usb_hub_port_t *port)
 {
@@ -124,11 +132,11 @@
 /*----------------------------------------------------------------------------*/
 /**
- * Process interrupts on given hub port
+ * Process interrupts on given port
  *
  * Accepts connection, over current and port reset change.
+ * @param port port structure
  * @param hub hub representation
- * @param port port number, starting from 1
- */
-void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub)
+ */
+void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub)
 {
 	assert(port);
@@ -171,5 +179,5 @@
 			 * to that handler, it shall ACK the change too. */
 			if (!(status & USB_HUB_PORT_C_STATUS_ENABLED)) {
-				usb_hub_port_removed_device(port, hub);
+				usb_hub_port_device_gone(port, hub);
 			}
 		}
@@ -180,5 +188,5 @@
 		usb_log_info("Port %zu, disabled because of errors.\n",
 		   port->port_number);
-		usb_hub_port_removed_device(port, hub);
+		usb_hub_port_device_gone(port, hub);
 		const int rc = usb_hub_port_clear_feature(port,
 		        USB_HUB_FEATURE_C_PORT_ENABLE);
@@ -238,5 +246,5 @@
 	    port->port_number, status);
 }
-
+/*----------------------------------------------------------------------------*/
 /**
  * routine called when a device on port has been removed
@@ -245,20 +253,12 @@
  * Otherwise does not do anything, because DDF does not allow to remove device
  * from it`s device tree.
+ * @param port port structure
  * @param hub hub representation
- * @param port port number, starting from 1
- */
-static void usb_hub_port_removed_device(usb_hub_port_t *port,
-    usb_hub_info_t *hub)
+ */
+int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub)
 {
 	assert(port);
 	assert(hub);
-	if (port->attached_device.address >= 0) {
-		fibril_mutex_lock(&port->mutex);
-		port->attached_device.address = -1;
-		port->attached_device.handle = 0;
-		fibril_mutex_unlock(&port->mutex);
-		usb_log_info("Removed device on port %zu.\n",
-		    port->port_number);
-	} else {
+	if (port->attached_device.address < 0) {
 		usb_log_warning(
 		    "Device on port %zu removed before being registered.\n",
@@ -271,7 +271,33 @@
 		 */
 		usb_hub_port_reset_fail(port);
-	}
-}
-
+		return EOK;
+	}
+
+	fibril_mutex_lock(&port->mutex);
+	assert(port->attached_device.fun);
+	usb_log_debug("Removing device on port %zu.\n", port->port_number);
+	int ret = ddf_fun_unbind(port->attached_device.fun);
+	if (ret != EOK) {
+		usb_log_error("Failed to unbind child function on port"
+		    " %zu: %s.\n", port->port_number, str_error(ret));
+		fibril_mutex_unlock(&port->mutex);
+		return ret;
+	}
+
+	ddf_fun_destroy(port->attached_device.fun);
+	port->attached_device.fun = NULL;
+
+	ret = usb_hc_unregister_device(&hub->connection,
+	    port->attached_device.address);
+	if (ret != EOK) {
+		usb_log_warning("Failed to unregister address of the removed "
+		    "device: %s.\n", str_error(ret));
+	}
+	port->attached_device.address = -1;
+	fibril_mutex_unlock(&port->mutex);
+	usb_log_info("Removed device on port %zu.\n", port->port_number);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
 /**
  * Process port reset change
@@ -279,9 +305,8 @@
  * After this change port should be enabled, unless some problem occurred.
  * This functions triggers second phase of enabling new device.
- * @param hub
- * @param port
- * @param status
- */
-static void usb_hub_port_reset_completed(usb_hub_port_t *port,
+ * @param port Port structure
+ * @param status Port status mask
+ */
+void usb_hub_port_reset_completed(usb_hub_port_t *port,
     usb_port_status_t status)
 {
@@ -313,6 +338,5 @@
 /** Retrieve port status.
  *
- * @param[in] ctrl_pipe Control pipe to use.
- * @param[in] port Port number (starting at 1).
+ * @param[in] port Port structure
  * @param[out] status Where to store the port status.
  * @return Error code.
@@ -358,8 +382,8 @@
  *
  * @param port_no Port number (starting at 1).
- * @param arg Custom argument, points to @c usb_hub_info_t.
+ * @param arg Custom argument, points to @c usb_hub_dev_t.
  * @return Error code.
  */
-static int enable_port_callback(int port_no, void *arg)
+static int enable_port_callback(void *arg)
 {
 	usb_hub_port_t *port = arg;
@@ -380,11 +404,7 @@
 	fibril_mutex_unlock(&port->mutex);
 
-	if (port->reset_okay) {
-		return EOK;
-	} else {
-		return ESTALL;
-	}
-}
-
+	return port->reset_okay ? EOK : ESTALL;
+}
+/*----------------------------------------------------------------------------*/
 /** Fibril for adding a new device.
  *
@@ -395,5 +415,5 @@
  * @return 0 Always.
  */
-static int add_device_phase1_worker_fibril(void *arg)
+int add_device_phase1_worker_fibril(void *arg)
 {
 	struct add_device_phase1 *data = arg;
@@ -401,11 +421,9 @@
 
 	usb_address_t new_address;
-	devman_handle_t child_handle;
+	ddf_fun_t *child_fun;
 
 	const int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,
-	    &data->hub->connection, data->speed,
-	    enable_port_callback, (int) data->port->port_number,
-	    data->port, &new_address, &child_handle,
-	    NULL, NULL, NULL);
+	    &data->hub->connection, data->speed, enable_port_callback,
+	    data->port, &new_address, NULL, NULL, &child_fun);
 
 	if (rc != EOK) {
@@ -416,5 +434,5 @@
 
 	fibril_mutex_lock(&data->port->mutex);
-	data->port->attached_device.handle = child_handle;
+	data->port->attached_device.fun = child_fun;
 	data->port->attached_device.address = new_address;
 	fibril_mutex_unlock(&data->port->mutex);
@@ -423,5 +441,5 @@
 	    "address %d (handle %" PRIun ").\n",
 	    data->hub->usb_device->ddf_dev->name, data->port->port_number,
-	    new_address, child_handle);
+	    new_address, child_fun->handle);
 
 leave:
@@ -434,7 +452,7 @@
 	free(arg);
 
-	return EOK;
-}
-
+	return rc;
+}
+/*----------------------------------------------------------------------------*/
 /** Start device adding when connection change is detected.
  *
@@ -446,5 +464,5 @@
  * @return Error code.
  */
-static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_info_t *hub,
+static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_dev_t *hub,
     usb_speed_t speed)
 {
@@ -452,5 +470,5 @@
 	assert(port);
 	struct add_device_phase1 *data
-	    = malloc(sizeof (struct add_device_phase1));
+	    = malloc(sizeof(struct add_device_phase1));
 	if (data == NULL) {
 		return ENOMEM;
Index: uspace/drv/bus/usb/usbhub/port.h
===================================================================
--- uspace/drv/bus/usb/usbhub/port.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbhub/port.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -40,5 +40,5 @@
 #include <usb/classes/hub.h>
 
-typedef struct usb_hub_info_t usb_hub_info_t;
+typedef struct usb_hub_dev usb_hub_dev_t;
 
 /** Information about single port on a hub. */
@@ -58,5 +58,5 @@
 
 	/** Information about attached device. */
-	usb_hc_attached_device_t attached_device;
+	usb_hub_attached_device_t attached_device;
 } usb_hub_port_t;
 
@@ -70,5 +70,5 @@
 	assert(port);
 	port->attached_device.address = -1;
-	port->attached_device.handle = 0;
+	port->attached_device.fun = NULL;
 	port->port_number = port_number;
 	port->control_pipe = control_pipe;
@@ -76,11 +76,11 @@
 	fibril_condvar_initialize(&port->reset_cv);
 }
-
-void usb_hub_port_reset_fail(usb_hub_port_t *port);
-void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub);
+int usb_hub_port_fini(usb_hub_port_t *port, usb_hub_dev_t *hub);
 int usb_hub_port_clear_feature(
     usb_hub_port_t *port, usb_hub_class_feature_t feature);
 int usb_hub_port_set_feature(
     usb_hub_port_t *port, usb_hub_class_feature_t feature);
+void usb_hub_port_reset_fail(usb_hub_port_t *port);
+void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub);
 
 #endif
Index: uspace/drv/bus/usb/usbhub/usbhub.c
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbhub/usbhub.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -68,12 +68,11 @@
 
 static int usb_set_first_configuration(usb_device_t *usb_device);
-static usb_hub_info_t * usb_hub_info_create(usb_device_t *usb_dev);
-static int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info);
-static void usb_hub_over_current(const usb_hub_info_t *hub_info,
+static usb_hub_dev_t * usb_hub_dev_create(usb_device_t *usb_dev);
+static int usb_hub_process_hub_specific_info(usb_hub_dev_t *hub_dev);
+static void usb_hub_over_current(const usb_hub_dev_t *hub_dev,
     usb_hub_status_t status);
-static void usb_hub_global_interrupt(const usb_hub_info_t *hub_info);
+static void usb_hub_global_interrupt(const usb_hub_dev_t *hub_dev);
 static void usb_hub_polling_terminated_callback(usb_device_t *device,
     bool was_error, void *data);
-
 /**
  * Initialize hub device driver fibril
@@ -84,10 +83,58 @@
  * @return error code
  */
-int usb_hub_add_device(usb_device_t *usb_dev)
+int usb_hub_device_gone(usb_device_t *usb_dev)
+{
+	assert(usb_dev);
+	usb_hub_dev_t *hub = usb_dev->driver_data;
+	assert(hub);
+	unsigned tries = 10;
+	while (hub->running) {
+		async_usleep(100000);
+		if (!tries--) {
+			usb_log_error("Can't remove hub, still running.\n");
+			return EINPROGRESS;
+		}
+	}
+
+	assert(!hub->running);
+
+	for (size_t port = 0; port < hub->port_count; ++port) {
+		if (hub->ports[port].attached_device.fun) {
+			const int ret =
+			    usb_hub_port_fini(&hub->ports[port], hub);
+			if (ret != EOK)
+				return ret;
+		}
+	}
+	free(hub->ports);
+
+	const int ret = ddf_fun_unbind(hub->hub_fun);
+	if (ret != EOK) {
+		usb_log_error("Failed to unbind '%s' function: %s.\n",
+		   HUB_FNC_NAME, str_error(ret));
+		return ret;
+	}
+	ddf_fun_destroy(hub->hub_fun);
+
+	free(hub);
+	usb_dev->driver_data = NULL;
+	usb_log_info("USB hub driver, stopped and cleaned.\n");
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+/**
+ * Initialize hub device driver fibril
+ *
+ * Creates hub representation and fibril that periodically checks hub's status.
+ * Hub representation is passed to the fibril.
+ * @param usb_dev generic usb device information
+ * @return error code
+ */
+int usb_hub_device_add(usb_device_t *usb_dev)
 {
 	assert(usb_dev);
 	/* Create driver soft-state structure */
-	usb_hub_info_t *hub_info = usb_hub_info_create(usb_dev);
-	if (hub_info == NULL) {
+	usb_hub_dev_t *hub_dev = usb_hub_dev_create(usb_dev);
+	if (hub_dev == NULL) {
 		usb_log_error("Failed to create hun driver structure.\n");
 		return ENOMEM;
@@ -97,9 +144,9 @@
 	usb_log_debug("Initializing USB wire abstraction.\n");
 	int opResult = usb_hc_connection_initialize_from_device(
-	    &hub_info->connection, hub_info->usb_device->ddf_dev);
+	    &hub_dev->connection, hub_dev->usb_device->ddf_dev);
 	if (opResult != EOK) {
 		usb_log_error("Could not initialize connection to device: %s\n",
 		    str_error(opResult));
-		free(hub_info);
+		free(hub_dev);
 		return opResult;
 	}
@@ -110,47 +157,50 @@
 		usb_log_error("Could not set hub configuration: %s\n",
 		    str_error(opResult));
-		free(hub_info);
+		free(hub_dev);
 		return opResult;
 	}
 
-	//get port count and create attached_devs
-	opResult = usb_hub_process_hub_specific_info(hub_info);
+	/* Get port count and create attached_devices. */
+	opResult = usb_hub_process_hub_specific_info(hub_dev);
 	if (opResult != EOK) {
 		usb_log_error("Could process hub specific info, %s\n",
 		    str_error(opResult));
-		free(hub_info);
+		free(hub_dev);
 		return opResult;
 	}
 
 	usb_log_debug("Creating DDF function '" HUB_FNC_NAME "'.\n");
-	ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
+	hub_dev->hub_fun = ddf_fun_create(hub_dev->usb_device->ddf_dev,
 	    fun_exposed, HUB_FNC_NAME);
-	if (hub_fun == NULL) {
+	if (hub_dev->hub_fun == NULL) {
 		usb_log_error("Failed to create hub function.\n");
-		free(hub_info);
+		free(hub_dev);
 		return ENOMEM;
 	}
 
-	opResult = ddf_fun_bind(hub_fun);
+	opResult = ddf_fun_bind(hub_dev->hub_fun);
 	if (opResult != EOK) {
 		usb_log_error("Failed to bind hub function: %s.\n",
 		   str_error(opResult));
-		free(hub_info);
-		ddf_fun_destroy(hub_fun);
+		free(hub_dev);
+		ddf_fun_destroy(hub_dev->hub_fun);
 		return opResult;
 	}
 
-	opResult = usb_device_auto_poll(hub_info->usb_device, 0,
-	    hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1,
-	    usb_hub_polling_terminated_callback, hub_info);
-	if (opResult != EOK) {
-		ddf_fun_destroy(hub_fun);
-		free(hub_info);
+	opResult = usb_device_auto_poll(hub_dev->usb_device, 0,
+	    hub_port_changes_callback, ((hub_dev->port_count + 1 + 8) / 8),
+	    usb_hub_polling_terminated_callback, hub_dev);
+	if (opResult != EOK) {
+		/* Function is already bound */
+		ddf_fun_unbind(hub_dev->hub_fun);
+		ddf_fun_destroy(hub_dev->hub_fun);
+		free(hub_dev);
 		usb_log_error("Failed to create polling fibril: %s.\n",
 		    str_error(opResult));
 		return opResult;
 	}
+	hub_dev->running = true;
 	usb_log_info("Controlling hub '%s' (%zu ports).\n",
-	    hub_info->usb_device->ddf_dev->name, hub_info->port_count);
+	    hub_dev->usb_device->ddf_dev->name, hub_dev->port_count);
 
 	return EOK;
@@ -162,5 +212,5 @@
  * @param change_bitmap Bitmap of changed ports.
  * @param change_bitmap_size Size of the bitmap in bytes.
- * @param arg Custom argument, points to @c usb_hub_info_t.
+ * @param arg Custom argument, points to @c usb_hub_dev_t.
  * @return Whether to continue polling.
  */
@@ -169,5 +219,5 @@
 {
 	usb_log_debug("hub_port_changes_callback\n");
-	usb_hub_info_t *hub = arg;
+	usb_hub_dev_t *hub = arg;
 	assert(hub);
 
@@ -184,7 +234,7 @@
 
 	/* N + 1 bit indicates change on port N */
-	size_t port = 1;
-	for (; port < hub->port_count + 1; port++) {
-		const bool change = (change_bitmap[port / 8] >> (port % 8)) & 1;
+	for (size_t port = 0; port < hub->port_count + 1; port++) {
+		const size_t bit = port + 1;
+		const bool change = (change_bitmap[bit / 8] >> (bit % 8)) & 1;
 		if (change) {
 			usb_hub_port_process_interrupt(&hub->ports[port], hub);
@@ -195,30 +245,32 @@
 /*----------------------------------------------------------------------------*/
 /**
- * create usb_hub_info_t structure
+ * create usb_hub_dev_t structure
  *
  * Does only basic copying of known information into new structure.
  * @param usb_dev usb device structure
- * @return basic usb_hub_info_t structure
- */
-static usb_hub_info_t * usb_hub_info_create(usb_device_t *usb_dev)
+ * @return basic usb_hub_dev_t structure
+ */
+static usb_hub_dev_t * usb_hub_dev_create(usb_device_t *usb_dev)
 {
 	assert(usb_dev);
-	usb_hub_info_t *info = malloc(sizeof(usb_hub_info_t));
-	if (!info)
+	usb_hub_dev_t *hub_dev = malloc(sizeof(usb_hub_dev_t));
+	if (!hub_dev)
 	    return NULL;
 
-	info->usb_device = usb_dev;
-
-	info->ports = NULL;
-	info->port_count = -1;
-	fibril_mutex_initialize(&info->pending_ops_mutex);
-	fibril_condvar_initialize(&info->pending_ops_cv);
-	info->pending_ops_count = 0;
-
-	return info;
-}
-/*----------------------------------------------------------------------------*/
-/**
- * Load hub-specific information into hub_info structure and process if needed
+	hub_dev->usb_device = usb_dev;
+
+	hub_dev->ports = NULL;
+	hub_dev->port_count = 0;
+	hub_dev->pending_ops_count = 0;
+	hub_dev->running = false;
+	fibril_mutex_initialize(&hub_dev->pending_ops_mutex);
+	fibril_condvar_initialize(&hub_dev->pending_ops_cv);
+	usb_dev->driver_data = hub_dev;
+
+	return hub_dev;
+}
+/*----------------------------------------------------------------------------*/
+/**
+ * Load hub-specific information into hub_dev structure and process if needed
  *
  * Read port count and initialize structures holding per port information.
@@ -226,14 +278,14 @@
  * This function is hub-specific and should be run only after the hub is
  * configured using usb_set_first_configuration function.
- * @param hub_info hub representation
+ * @param hub_dev hub representation
  * @return error code
  */
-static int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info)
-{
-	assert(hub_info);
+static int usb_hub_process_hub_specific_info(usb_hub_dev_t *hub_dev)
+{
+	assert(hub_dev);
 
 	/* Get hub descriptor. */
 	usb_log_debug("Retrieving descriptor\n");
-	usb_pipe_t *control_pipe = &hub_info->usb_device->ctrl_pipe;
+	usb_pipe_t *control_pipe = &hub_dev->usb_device->ctrl_pipe;
 
 	usb_hub_descriptor_header_t descriptor;
@@ -250,16 +302,14 @@
 
 	usb_log_debug("Setting port count to %d.\n", descriptor.port_count);
-	hub_info->port_count = descriptor.port_count;
-
-	// TODO: +1 hack is no longer necessary
-	hub_info->ports =
-	    malloc(sizeof(usb_hub_port_t) * (hub_info->port_count + 1));
-	if (!hub_info->ports) {
+	hub_dev->port_count = descriptor.port_count;
+
+	hub_dev->ports = calloc(hub_dev->port_count, sizeof(usb_hub_port_t));
+	if (!hub_dev->ports) {
 		return ENOMEM;
 	}
 
-	size_t port;
-	for (port = 0; port < hub_info->port_count + 1; ++port) {
-		usb_hub_port_init(&hub_info->ports[port], port, control_pipe);
+	for (size_t port = 0; port < hub_dev->port_count; ++port) {
+		usb_hub_port_init(
+		    &hub_dev->ports[port], port + 1, control_pipe);
 	}
 
@@ -271,8 +321,8 @@
 		    & HUB_CHAR_POWER_PER_PORT_FLAG;
 
-		for (port = 1; port <= hub_info->port_count; ++port) {
+		for (size_t port = 0; port < hub_dev->port_count; ++port) {
 			usb_log_debug("Powering port %zu.\n", port);
 			opResult = usb_hub_port_set_feature(
-			    &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER);
+			    &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER);
 			if (opResult != EOK) {
 				usb_log_error("Cannot power on port %zu: %s.\n",
@@ -314,5 +364,12 @@
 	}
 
-	// TODO: Make sure that there is enough data and the cast is correct
+	if (usb_device->descriptors.configuration_size
+	    < sizeof(usb_standard_configuration_descriptor_t)) {
+	    usb_log_error("Configuration descriptor is not big enough"
+	        " to fit standard configuration descriptor.\n");
+	    return EOVERFLOW;
+	}
+
+	// TODO: Make sure that the cast is correct
 	usb_standard_configuration_descriptor_t *config_descriptor
 	    = (usb_standard_configuration_descriptor_t *)
@@ -337,9 +394,9 @@
  *
  * This means either to power off the hub or power it on.
- * @param hub_info hub instance
+ * @param hub_dev hub instance
  * @param status hub status bitmask
  * @return error code
  */
-static void usb_hub_over_current(const usb_hub_info_t *hub_info,
+static void usb_hub_over_current(const usb_hub_dev_t *hub_dev,
     usb_hub_status_t status)
 {
@@ -351,8 +408,8 @@
 		/* Over-current condition is gone, it is safe to turn the
 		 * ports on. */
-		size_t port;
-		for (port = 1; port <= hub_info->port_count; ++port) {
+		for (size_t port = 0; port < hub_dev->port_count; ++port) {
 			const int opResult = usb_hub_port_set_feature(
-			    &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER);
+			    &hub_dev->ports[port], USB_HUB_FEATURE_PORT_POWER);
+			// TODO: consider power policy here
 			if (opResult != EOK) {
 				usb_log_warning(
@@ -364,5 +421,5 @@
 	}
 	const int opResult = usb_request_clear_feature(
-	    &hub_info->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS,
+	    &hub_dev->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS,
 	    USB_REQUEST_RECIPIENT_DEVICE,
 	    USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0);
@@ -378,12 +435,12 @@
  *
  * The change can be either in the over-current condition or local-power change.
- * @param hub_info hub instance
- */
-static void usb_hub_global_interrupt(const usb_hub_info_t *hub_info)
-{
-	assert(hub_info);
-	assert(hub_info->usb_device);
+ * @param hub_dev hub instance
+ */
+static void usb_hub_global_interrupt(const usb_hub_dev_t *hub_dev)
+{
+	assert(hub_dev);
+	assert(hub_dev->usb_device);
 	usb_log_debug("Global interrupt on a hub\n");
-	usb_pipe_t *control_pipe = &hub_info->usb_device->ctrl_pipe;
+	usb_pipe_t *control_pipe = &hub_dev->usb_device->ctrl_pipe;
 
 	usb_hub_status_t status;
@@ -406,5 +463,5 @@
 	/* Handle status changes */
 	if (status & USB_HUB_STATUS_C_OVER_CURRENT) {
-		usb_hub_over_current(hub_info, status);
+		usb_hub_over_current(hub_dev, status);
 	}
 
@@ -438,13 +495,13 @@
  * callback called from hub polling fibril when the fibril terminates
  *
- * Should perform a cleanup - deletes hub_info.
+ * Does not perform cleanup, just marks the hub as not running.
  * @param device usb device afected
  * @param was_error indicates that the fibril is stoped due to an error
- * @param data pointer to usb_hub_info_t structure
+ * @param data pointer to usb_hub_dev_t structure
  */
 static void usb_hub_polling_terminated_callback(usb_device_t *device,
     bool was_error, void *data)
 {
-	usb_hub_info_t *hub = data;
+	usb_hub_dev_t *hub = data;
 	assert(hub);
 
@@ -460,6 +517,5 @@
 	 */
 	if (hub->pending_ops_count > 0) {
-		size_t port;
-		for (port = 0; port < hub->port_count; port++) {
+		for (size_t port = 0; port < hub->port_count; ++port) {
 			usb_hub_port_reset_fail(&hub->ports[port]);
 		}
@@ -471,9 +527,5 @@
 	}
 	fibril_mutex_unlock(&hub->pending_ops_mutex);
-
-	usb_device_destroy(hub->usb_device);
-
-	free(hub->ports);
-	free(hub);
+	hub->running = false;
 }
 /**
Index: uspace/drv/bus/usb/usbhub/usbhub.h
===================================================================
--- uspace/drv/bus/usb/usbhub/usbhub.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbhub/usbhub.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -52,14 +52,11 @@
 
 /** Information about attached hub. */
-struct usb_hub_info_t {
+struct usb_hub_dev {
 	/** Number of ports. */
 	size_t port_count;
-
-	/** Attached device handles, for each port one */
+	/** Port structures, one for each port */
 	usb_hub_port_t *ports;
-
 	/** Connection to hcd */
 	usb_hc_connection_t connection;
-
 	/** Generic usb device data*/
 	usb_device_t *usb_device;
@@ -76,7 +73,12 @@
 	/** Condition variable for pending_ops_count. */
 	fibril_condvar_t pending_ops_cv;
+	/** Pointer to devman usbhub function. */
+	ddf_fun_t *hub_fun;
+	/** Status indicator */
+	bool running;
 };
 
-int usb_hub_add_device(usb_device_t *usb_dev);
+int usb_hub_device_add(usb_device_t *usb_dev);
+int usb_hub_device_gone(usb_device_t *usb_dev);
 
 bool hub_port_changes_callback(usb_device_t *dev,
Index: uspace/drv/bus/usb/usbmast/main.c
===================================================================
--- uspace/drv/bus/usb/usbmast/main.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbmast/main.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -87,5 +87,5 @@
  * @return Error code.
  */
-static int usbmast_add_device(usb_device_t *dev)
+static int usbmast_device_add(usb_device_t *dev)
 {
 	int rc;
@@ -94,5 +94,5 @@
 
 	/* Allocate softstate */
-	mdev = ddf_dev_data_alloc(dev->ddf_dev, sizeof(usbmast_dev_t));
+	dev->driver_data = mdev = malloc(sizeof(usbmast_dev_t));
 	if (mdev == NULL) {
 		usb_log_error("Failed allocating softstate.\n");
@@ -103,6 +103,5 @@
 	mdev->usb_dev = dev;
 
-	usb_log_info("Initializing mass storage `%s'.\n",
-	    dev->ddf_dev->name);
+	usb_log_info("Initializing mass storage `%s'.\n", dev->ddf_dev->name);
 	usb_log_debug(" Bulk in endpoint: %d [%zuB].\n",
 	    dev->pipes[BULK_IN_EP].pipe->endpoint_no,
@@ -295,5 +294,5 @@
 /** USB mass storage driver ops. */
 static usb_driver_ops_t usbmast_driver_ops = {
-	.add_device = usbmast_add_device,
+	.device_add = usbmast_device_add,
 };
 
Index: uspace/drv/bus/usb/usbmid/main.c
===================================================================
--- uspace/drv/bus/usb/usbmid/main.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbmid/main.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -49,5 +49,5 @@
  * @return Error code.
  */
-static int usbmid_add_device(usb_device_t *dev)
+static int usbmid_device_add(usb_device_t *dev)
 {
 	usb_log_info("Taking care of new MID `%s'.\n", dev->ddf_dev->name);
@@ -68,5 +68,5 @@
 /** USB MID driver ops. */
 static usb_driver_ops_t mid_driver_ops = {
-	.add_device = usbmid_add_device,
+	.device_add = usbmid_device_add,
 };
 
Index: uspace/drv/bus/usb/usbmouse/main.c
===================================================================
--- uspace/drv/bus/usb/usbmouse/main.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/usbmouse/main.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -50,5 +50,5 @@
  *
  */
-static int usbmouse_add_device(usb_device_t *dev)
+static int usbmouse_device_add(usb_device_t *dev)
 {
 	int rc = usb_mouse_create(dev);
@@ -80,5 +80,5 @@
 /** USB mouse driver ops. */
 static usb_driver_ops_t mouse_driver_ops = {
-	.add_device = usbmouse_add_device,
+	.device_add = usbmouse_device_add,
 };
 
Index: uspace/drv/bus/usb/vhc/hub.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/drv/bus/usb/vhc/hub.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -81,5 +81,5 @@
 }
 
-static int pretend_port_rest(int unused, void *unused2)
+static int pretend_port_rest(void *unused2)
 {
 	return EOK;
@@ -114,8 +114,6 @@
 
 	ddf_fun_t *hub_dev;
-	rc = usb_hc_new_device_wrapper(hc_dev->dev, &hc_conn,
-	    USB_SPEED_FULL,
-	    pretend_port_rest, 0, NULL,
-	    NULL, NULL, &rh_ops, hc_dev, &hub_dev);
+	rc = usb_hc_new_device_wrapper(hc_dev->dev, &hc_conn, USB_SPEED_FULL,
+	    pretend_port_rest, NULL, NULL, &rh_ops, hc_dev, &hub_dev);
 	if (rc != EOK) {
 		usb_log_fatal("Failed to create root hub: %s.\n",
Index: uspace/lib/usb/include/usb/hc.h
===================================================================
--- uspace/lib/usb/include/usb/hc.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usb/include/usb/hc.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -53,5 +53,5 @@
 
 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *,
-    ddf_dev_t *);
+    const ddf_dev_t *);
 int usb_hc_connection_initialize(usb_hc_connection_t *, devman_handle_t);
 
Index: uspace/lib/usb/src/hc.c
===================================================================
--- uspace/lib/usb/src/hc.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usb/src/hc.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -50,5 +50,5 @@
  */
 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
-    ddf_dev_t *device)
+    const ddf_dev_t *device)
 {
 	assert(connection);
Index: uspace/lib/usbdev/include/usb/dev/driver.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/driver.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/include/usb/dev/driver.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -96,5 +96,5 @@
 	usb_device_descriptors_t descriptors;
 
-	/** Generic DDF device backing this one. */
+	/** Generic DDF device backing this one. RO: DO NOT TOUCH!*/
 	ddf_dev_t *ddf_dev;
 	/** Custom driver data.
@@ -112,6 +112,10 @@
 /** USB driver ops. */
 typedef struct {
-	/** Callback when new device is about to be controlled by the driver. */
-	int (*add_device)(usb_device_t *);
+	/** Callback when a new device was added to the system. */
+	int (*device_add)(usb_device_t *);
+	/** Callback when a device is about to be removed from the system. */
+	int (*device_rem)(usb_device_t *);
+	/** Callback when a device was removed from the system. */
+	int (*device_gone)(usb_device_t *);
 } usb_driver_ops_t;
 
@@ -163,8 +167,8 @@
 
 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
-int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
+int usb_device_create_pipes(const ddf_dev_t *, usb_device_connection_t *,
     usb_endpoint_description_t **, uint8_t *, size_t, int, int,
     usb_endpoint_mapping_t **, size_t *);
-int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
+int usb_device_destroy_pipes(const ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
 int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);
 void usb_device_destroy(usb_device_t *);
Index: uspace/lib/usbdev/include/usb/dev/hub.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/hub.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/include/usb/dev/hub.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -38,11 +38,11 @@
 #define LIBUSBDEV_HUB_H_
 
+#include <ddf/driver.h>
 #include <sys/types.h>
 #include <usb/hc.h>
 
 int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
-    int (*)(int, void *), int, void *,
-    usb_address_t *, devman_handle_t *,
-    ddf_dev_ops_t *, void *, ddf_fun_t **);
+    int (*)(void *), void *, usb_address_t *, ddf_dev_ops_t *, void *,
+    ddf_fun_t **);
 
 /** Info about device attached to host controller.
@@ -55,11 +55,11 @@
 	/** Device address. */
 	usb_address_t address;
-	/** Devman handle of the device. */
-	devman_handle_t handle;
-} usb_hc_attached_device_t;
+	/** DDF function (external) of the device. */
+	ddf_fun_t *fun;
+} usb_hub_attached_device_t;
 
 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
 int usb_hc_register_device(usb_hc_connection_t *,
-    const usb_hc_attached_device_t *);
+    const usb_hub_attached_device_t *);
 int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t);
 
Index: uspace/lib/usbdev/include/usb/dev/pipes.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/pipes.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/include/usb/dev/pipes.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -159,9 +159,9 @@
     usb_device_connection_t *, usb_hc_connection_t *);
 int usb_device_connection_initialize_from_device(usb_device_connection_t *,
-    ddf_dev_t *);
+    const ddf_dev_t *);
 int usb_device_connection_initialize(usb_device_connection_t *,
     devman_handle_t, usb_address_t);
 
-int usb_device_get_assigned_interface(ddf_dev_t *);
+int usb_device_get_assigned_interface(const ddf_dev_t *);
 
 int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *,
@@ -185,6 +185,6 @@
 int usb_pipe_control_read(usb_pipe_t *, const void *, size_t,
     void *, size_t, size_t *);
-int usb_pipe_control_write(usb_pipe_t *, void *, size_t,
-    void *, size_t);
+int usb_pipe_control_write(usb_pipe_t *, const void *, size_t,
+    const void *, size_t);
 
 #endif
Index: uspace/lib/usbdev/include/usb/dev/recognise.h
===================================================================
--- uspace/lib/usbdev/include/usb/dev/recognise.h	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/include/usb/dev/recognise.h	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -51,5 +51,5 @@
 
 int usb_device_register_child_in_devman(usb_address_t, devman_handle_t,
-    ddf_dev_t *, devman_handle_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
+    ddf_dev_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
 
 #endif
Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/src/devdrv.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -41,8 +41,12 @@
 #include <assert.h>
 
-static int generic_add_device(ddf_dev_t *);
+static int generic_device_add(ddf_dev_t *);
+static int generic_device_remove(ddf_dev_t *);
+static int generic_device_gone(ddf_dev_t *);
 
 static driver_ops_t generic_driver_ops = {
-	.add_device = generic_add_device
+	.add_device = generic_device_add,
+	.dev_remove = generic_device_remove,
+	.dev_gone = generic_device_gone,
 };
 static driver_t generic_driver = {
@@ -123,17 +127,17 @@
 	return EOK;
 }
-
-/** Callback when new device is supposed to be controlled by this driver.
- *
- * This callback is a wrapper for USB specific version of @c add_device.
+/*----------------------------------------------------------------------------*/
+/** Callback when a new device is supposed to be controlled by this driver.
+ *
+ * This callback is a wrapper for USB specific version of @c device_add.
  *
  * @param gen_dev Device structure as prepared by DDF.
  * @return Error code.
  */
-int generic_add_device(ddf_dev_t *gen_dev)
+int generic_device_add(ddf_dev_t *gen_dev)
 {
 	assert(driver);
 	assert(driver->ops);
-	assert(driver->ops->add_device);
+	assert(driver->ops->device_add);
 
 	int rc;
@@ -147,8 +151,46 @@
 		return rc;
 	}
-
-	return driver->ops->add_device(dev);
-}
-
+	gen_dev->driver_data = dev;
+
+	return driver->ops->device_add(dev);
+}
+/*----------------------------------------------------------------------------*/
+/** Callback when a device is supposed to be removed from the system.
+ *
+ * This callback is a wrapper for USB specific version of @c device_remove.
+ *
+ * @param gen_dev Device structure as prepared by DDF.
+ * @return Error code.
+ */
+int generic_device_remove(ddf_dev_t *gen_dev)
+{
+	assert(driver);
+	assert(driver->ops);
+	if (driver->ops->device_rem == NULL)
+		return ENOTSUP;
+	/* Just tell the driver to stop whatever it is doing, keep structures */
+	return driver->ops->device_rem(gen_dev->driver_data);
+}
+/*----------------------------------------------------------------------------*/
+/** Callback when a device was removed from the system.
+ *
+ * This callback is a wrapper for USB specific version of @c device_gone.
+ *
+ * @param gen_dev Device structure as prepared by DDF.
+ * @return Error code.
+ */
+int generic_device_gone(ddf_dev_t *gen_dev)
+{
+	assert(driver);
+	assert(driver->ops);
+	if (driver->ops->device_gone == NULL)
+		return ENOTSUP;
+	const int ret = driver->ops->device_gone(gen_dev->driver_data);
+	if (ret == EOK)
+		usb_device_destroy(gen_dev->driver_data);
+
+	return ret;
+}
+/*----------------------------------------------------------------------------*/
 /** Destroy existing pipes of a USB device.
  *
@@ -275,5 +317,5 @@
  * @return Error code.
  */
-int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire,
+int usb_device_create_pipes(const ddf_dev_t *dev, usb_device_connection_t *wire,
     usb_endpoint_description_t **endpoints,
     uint8_t *config_descr, size_t config_descr_size,
@@ -349,5 +391,7 @@
 	}
 
-	usb_hc_connection_close(&hc_conn);
+	if (usb_hc_connection_close(&hc_conn) != EOK)
+		usb_log_warning("usb_device_create_pipes(): "
+		    "Failed to close connection.\n");
 
 	*pipes_ptr = pipes;
@@ -371,5 +415,7 @@
 	}
 
-	usb_hc_connection_close(&hc_conn);
+	if (usb_hc_connection_close(&hc_conn) != EOK)
+		usb_log_warning("usb_device_create_pipes(): "
+		    "Failed to close connection.\n");
 
 	/*
@@ -395,5 +441,5 @@
  * @param[in] pipes_count Number of endpoints.
  */
-int usb_device_destroy_pipes(ddf_dev_t *dev,
+int usb_device_destroy_pipes(const ddf_dev_t *dev,
     usb_endpoint_mapping_t *pipes, size_t pipes_count)
 {
@@ -426,5 +472,7 @@
 	}
 
-	usb_hc_connection_close(&hc_conn);
+	if (usb_hc_connection_close(&hc_conn) != EOK)
+		usb_log_warning("usb_device_destroy_pipes(): "
+		    "Failed to close connection.\n");
 
 	free(pipes);
@@ -545,14 +593,10 @@
 	/* Ignore errors and hope for the best. */
 	usb_device_destroy_pipes(dev->ddf_dev, dev->pipes, dev->pipes_count);
-	if (dev->descriptors.configuration != NULL) {
-		free(dev->descriptors.configuration);
-	}
+	free(dev->descriptors.configuration);
 
 	if (dev->alternate_interfaces != NULL) {
-		if (dev->alternate_interfaces->alternatives != NULL) {
-			free(dev->alternate_interfaces->alternatives);
-		}
-		free(dev->alternate_interfaces);
-	}
+		free(dev->alternate_interfaces->alternatives);
+	}
+	free(dev->alternate_interfaces);
 
 	free(dev);
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/src/hub.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -37,4 +37,5 @@
 #include <usb/dev/request.h>
 #include <usb/dev/recognise.h>
+#include <usb/debug.h>
 #include <usbhc_iface.h>
 #include <errno.h>
@@ -57,5 +58,6 @@
 		assert((conn)); \
 		if (!usb_hc_connection_is_opened((conn))) { \
-			return ENOENT; \
+			usb_log_error("Connection not open.\n"); \
+			return ENOTCONN; \
 		} \
 	} while (false)
@@ -95,5 +97,5 @@
  */
 int usb_hc_register_device(usb_hc_connection_t * connection,
-    const usb_hc_attached_device_t *attached_device)
+    const usb_hub_attached_device_t *attached_device)
 {
 	CHECK_CONNECTION(connection);
@@ -105,5 +107,5 @@
 	int rc = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
 	    IPC_M_USBHC_BIND_ADDRESS,
-	    attached_device->address, attached_device->handle);
+	    attached_device->address, attached_device->fun->handle);
 	async_exchange_end(exch);
 	
@@ -155,8 +157,6 @@
  * The @p enable_port function is expected to enable signaling on given
  * port.
- * The two arguments to it can have arbitrary meaning
- * (the @p port_no is only a suggestion)
- * and are not touched at all by this function
- * (they are passed as is to the @p enable_port function).
+ * The argument can have arbitrary meaning and it is not touched at all
+ * by this function (it is passed as is to the @p enable_port function).
  *
  * If the @p enable_port fails (i.e. does not return EOK), the device
@@ -175,8 +175,6 @@
  * @param[in] enable_port Function for enabling signaling through the port the
  *	device is attached to.
- * @param[in] port_no Port number (passed through to @p enable_port).
  * @param[in] arg Any data argument to @p enable_port.
  * @param[out] assigned_address USB address of the device.
- * @param[out] assigned_handle Devman handle of the new device.
  * @param[in] dev_ops Child device ops.
  * @param[in] new_dev_data Arbitrary pointer to be stored in the child
@@ -194,6 +192,5 @@
 int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection,
     usb_speed_t dev_speed,
-    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
-    usb_address_t *assigned_address, devman_handle_t *assigned_handle,
+    int (*enable_port)(void *arg), void *arg, usb_address_t *assigned_address,
     ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
 {
@@ -224,6 +221,6 @@
 	usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
 	if (dev_addr < 0) {
-		usb_hc_connection_close(&hc_conn);
-		return EADDRNOTAVAIL;
+		rc = EADDRNOTAVAIL;
+		goto close_connection;
 	}
 
@@ -279,5 +276,5 @@
 	 * device address.
 	 */
-	rc = enable_port(port_no, arg);
+	rc = enable_port(arg);
 	if (rc != EOK) {
 		goto leave_release_default_address;
@@ -320,8 +317,7 @@
 	 */
 	/* FIXME: create device_register that will get opened ctrl pipe. */
-	devman_handle_t child_handle;
+	ddf_fun_t *child_fun;
 	rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
-	    parent, &child_handle,
-	    dev_ops, new_dev_data, new_fun);
+	    parent, dev_ops, new_dev_data, &child_fun);
 	if (rc != EOK) {
 		rc = ESTALL;
@@ -332,7 +328,7 @@
 	 * And now inform the host controller about the handle.
 	 */
-	usb_hc_attached_device_t new_device = {
+	usb_hub_attached_device_t new_device = {
 		.address = dev_addr,
-		.handle = child_handle
+		.fun = child_fun,
 	};
 	rc = usb_hc_register_device(&hc_conn, &new_device);
@@ -341,6 +337,5 @@
 		goto leave_release_free_address;
 	}
-	
-	usb_hc_connection_close(&hc_conn);
+
 
 	/*
@@ -350,11 +345,10 @@
 		*assigned_address = dev_addr;
 	}
-	if (assigned_handle != NULL) {
-		*assigned_handle = child_handle;
-	}
-
-	return EOK;
-
-
+	if (new_fun != NULL) {
+		*new_fun = child_fun;
+	}
+
+	rc = EOK;
+	goto close_connection;
 
 	/*
@@ -368,5 +362,8 @@
 	usb_hc_unregister_device(&hc_conn, dev_addr);
 
-	usb_hc_connection_close(&hc_conn);
+close_connection:
+	if (usb_hc_connection_close(&hc_conn) != EOK)
+		usb_log_warning("usb_hc_new_device_wrapper(): Failed to close "
+		    "connection.\n");
 
 	return rc;
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/src/pipes.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -52,5 +52,5 @@
  * @return USB address or error code.
  */
-static usb_address_t get_my_address(async_sess_t *sess, ddf_dev_t *dev)
+static usb_address_t get_my_address(async_sess_t *sess, const ddf_dev_t *dev)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
@@ -78,5 +78,5 @@
  * @return Interface number (negative code means any).
  */
-int usb_device_get_assigned_interface(ddf_dev_t *device)
+int usb_device_get_assigned_interface(const ddf_dev_t *device)
 {
 	async_sess_t *parent_sess =
@@ -108,5 +108,5 @@
  */
 int usb_device_connection_initialize_from_device(
-    usb_device_connection_t *connection, ddf_dev_t *dev)
+    usb_device_connection_t *connection, const ddf_dev_t *dev)
 {
 	assert(connection);
Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/src/pipesio.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -469,6 +469,6 @@
  */
 static int usb_pipe_control_write_no_check(usb_pipe_t *pipe,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size)
+    const void *setup_buffer, size_t setup_buffer_size,
+    const void *data_buffer, size_t data_buffer_size)
 {
 	/* Ensure serialization over the phone. */
@@ -536,6 +536,6 @@
  */
 int usb_pipe_control_write(usb_pipe_t *pipe,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size)
+    const void *setup_buffer, size_t setup_buffer_size,
+    const void *data_buffer, size_t data_buffer_size)
 {
 	assert(pipe);
Index: uspace/lib/usbdev/src/recognise.c
===================================================================
--- uspace/lib/usbdev/src/recognise.c	(revision cff3fb6c3220d53e3f075f4b038425266c3ad1ad)
+++ uspace/lib/usbdev/src/recognise.c	(revision d0831260f96e59ff797b0d656b9fa8395ac472de)
@@ -339,5 +339,4 @@
  * @param[in] hc_handle Handle of the host controller.
  * @param[in] parent Parent device.
- * @param[out] child_handle Handle of the child device.
  * @param[in] dev_ops Child device ops.
  * @param[in] dev_data Arbitrary pointer to be stored in the child
@@ -348,6 +347,5 @@
  */
 int usb_device_register_child_in_devman(usb_address_t address,
-    devman_handle_t hc_handle,
-    ddf_dev_t *parent, devman_handle_t *child_handle,
+    devman_handle_t hc_handle, ddf_dev_t *parent,
     ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
 {
@@ -414,8 +412,4 @@
 	}
 
-	if (child_handle != NULL) {
-		*child_handle = child->handle;
-	}
-
 	if (child_fun != NULL) {
 		*child_fun = child;
