Index: uspace/lib/usbhost/include/usb/host/ddf_helpers.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision be554d93f05571fa5597ccecb0a2446a0d28043d)
+++ uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision b99518342d813d6feafc58b7a12e787053a9f106)
@@ -46,5 +46,6 @@
     usb_speed_t max_speed, size_t bw, bw_count_func_t bw_count);
 int hcd_ddf_setup_root_hub(ddf_dev_t *dev, usb_speed_t speed);
-int hcd_ddf_new_device(ddf_dev_t *device);
+int hcd_ddf_new_device(ddf_dev_t *device, usb_address_t *address);
+int hcd_ddf_remove_device(ddf_dev_t *device, usb_address_t address);
 
 hcd_t *dev_to_hcd(ddf_dev_t *dev);
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision be554d93f05571fa5597ccecb0a2446a0d28043d)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision b99518342d813d6feafc58b7a12e787053a9f106)
@@ -51,4 +51,5 @@
 	ddf_fun_t *hc_fun;
 	list_t devices;
+	fibril_mutex_t guard;
 } hc_dev_t;
 
@@ -73,5 +74,5 @@
 	usb_address_t address;
 	usb_speed_t speed;
-	devman_handle_t handle;
+	devman_handle_t hc_handle;
 } usb_dev_t;
 
@@ -82,5 +83,5 @@
  * @return Error code.
  */
-static int rh_get_my_address(ddf_fun_t *fun, usb_address_t *address)
+static int get_my_address(ddf_fun_t *fun, usb_address_t *address)
 {
 	assert(fun);
@@ -98,5 +99,5 @@
  * @return Error code.
  */
-static int rh_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
+static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
 {
 	assert(fun);
@@ -104,5 +105,5 @@
 	if (handle != NULL) {
 		usb_dev_t *usb_dev = ddf_fun_data_get(fun);
-		*handle = usb_dev->handle;
+		*handle = usb_dev->hc_handle;
 	}
 	return EOK;
@@ -111,6 +112,6 @@
 /** Root hub USB interface */
 static usb_iface_t usb_iface = {
-	.get_hc_handle = rh_get_hc_handle,
-	.get_my_address = rh_get_my_address,
+	.get_hc_handle = get_hc_handle,
+	.get_my_address = get_my_address,
 };
 /** Standard USB RH options (RH interface) */
@@ -146,14 +147,4 @@
 };
 
-static const usb_device_request_setup_packet_t set_address = {
-	.request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST
-	    | (USB_REQUEST_TYPE_STANDARD << 5)
-	    | USB_REQUEST_RECIPIENT_DEVICE,
-	.request = USB_DEVREQ_GET_DESCRIPTOR,
-	.value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8),
-	.index = uint16_host2usb(0),
-	.length = uint16_host2usb(CTRL_PIPE_MIN_PACKET_SIZE),
-};
-
 int hcd_ddf_add_usb_device(ddf_dev_t *parent,
     usb_address_t address, usb_speed_t speed, const char *name,
@@ -182,5 +173,5 @@
 	info->address = address;
 	info->speed = speed;
-	info->handle = hc_handle;
+	info->hc_handle = hc_handle;
 	info->fun = fun;
 	link_initialize(&info->link);
@@ -207,5 +198,4 @@
 	return EOK;
 }
-
 
 #define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \
@@ -227,5 +217,5 @@
 	add_match_id(list, mid); \
 } while (0)
-		
+
 
 /* This is a copy of lib/usbdev/src/recognise.c */
@@ -259,5 +249,5 @@
 }
 
-int hcd_ddf_new_device(ddf_dev_t *device)
+int hcd_ddf_remove_device(ddf_dev_t *device, usb_address_t id)
 {
 	assert(device);
@@ -265,5 +255,34 @@
 	hcd_t *hcd = dev_to_hcd(device);
 	assert(hcd);
-	
+
+	hc_dev_t *hc_dev = dev_to_hc_dev(device);
+	assert(hc_dev);
+
+	fibril_mutex_lock(&hc_dev->guard);
+
+	usb_dev_t *victim = NULL;
+
+	list_foreach(hc_dev->devices, it) {
+		victim = list_get_instance(it, usb_dev_t, link);
+		if (victim->address == id)
+			break;
+	}
+	if (victim && victim->address == id) {
+		list_remove(&victim->link);
+		fibril_mutex_unlock(&hc_dev->guard);
+		ddf_fun_unbind(victim->fun);
+		ddf_fun_destroy(victim->fun);
+		return EOK;
+	}
+	return ENOENT;
+}
+
+int hcd_ddf_new_device(ddf_dev_t *device, usb_address_t *id)
+{
+	assert(device);
+
+	hcd_t *hcd = dev_to_hcd(device);
+	assert(hcd);
+
 	usb_speed_t speed = USB_SPEED_MAX;
 
@@ -329,5 +348,4 @@
 	    SET_ADDRESS(target.address);
 
-	// TODO CALLBACKS
 	got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
 	    NULL, 0, *(uint64_t *)&set_address, "set address");
@@ -345,5 +363,4 @@
 	    GET_DEVICE_DESC(sizeof(desc));
 
-	// TODO CALLBACKS
 	got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,
 	    &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
@@ -354,5 +371,5 @@
 		return got < 0 ? got : EOVERFLOW;
 	}
-	
+
 	/* Create match ids from the device descriptor */
 	match_id_list_t mids;
@@ -365,8 +382,6 @@
 		return ret;
 	}
-	
-		
-
-	/* Register device */	
+
+	/* Register device */
 	ret = hcd_ddf_add_usb_device(device, address, speed, NULL, &mids);
 	clean_match_ids(&mids);
@@ -376,4 +391,6 @@
 		return ret;
 	}
+	if (ret == EOK && id)
+		*id = target.address;
 
 	return ret;
@@ -393,5 +410,5 @@
 
 	hcd_reserve_default_address(hcd, speed);
-	const int ret = hcd_ddf_new_device(device);
+	const int ret = hcd_ddf_new_device(device, NULL);
 	hcd_release_default_address(hcd);
 	return ret;
@@ -416,4 +433,5 @@
 	}
 	list_initialize(&instance->devices);
+	fibril_mutex_initialize(&instance->guard);
 
 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
