Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -57,44 +57,41 @@
 /** Reserve default USB address.
  * @param[in] exch IPC communication exchange
+ * @return Error code.
+ */
+int usbhc_reserve_default_address(async_exch_t *exch)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_1_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_RESERVE_DEFAULT_ADDRESS);
+}
+
+/** Release default USB address.
+ *
+ * @param[in] exch IPC communication exchange
+ *
+ * @return Error code.
+ */
+int usbhc_release_default_address(async_exch_t *exch)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_1_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
+}
+
+/**
+ * Trigger USB device enumeration
+ *
+ * @param[in] exch IPC communication exchange
+ * @param[in] port Port number at which the device is attached
  * @param[in] speed Communication speed of the newly attached device
+ *
  * @return Error code.
  */
-int usbhc_reserve_default_address(async_exch_t *exch, usb_speed_t speed)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed);
-}
-
-/** Release default USB address.
- *
- * @param[in] exch IPC communication exchange
- *
- * @return Error code.
- *
- */
-int usbhc_release_default_address(async_exch_t *exch)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_1_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
-}
-
-/** Trigger USB device enumeration
- *
- * @param[in]  exch   IPC communication exchange
- * @param[out] handle Identifier of the newly added device (if successful)
- *
- * @return Error code.
- *
- */
-int usbhc_device_enumerate(async_exch_t *exch, unsigned port)
-{
-	if (!exch)
-		return EBADMEM;
-	const int ret = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USB_DEVICE_ENUMERATE, port);
+int usbhc_device_enumerate(async_exch_t *exch, unsigned port, usb_speed_t speed)
+{
+	if (!exch)
+		return EBADMEM;
+	const int ret = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USB_DEVICE_ENUMERATE, port, speed);
 	return ret;
 }
@@ -310,6 +307,5 @@
 	}
 
-	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
-	const int ret = usbhc_iface->reserve_default_address(fun, speed);
+	const int ret = usbhc_iface->reserve_default_address(fun);
 	async_answer_0(callid, ret);
 }
@@ -340,5 +336,6 @@
 
 	const unsigned port = DEV_IPC_GET_ARG1(*call);
-	const int ret = usbhc_iface->device_enumerate(fun, port);
+	usb_speed_t speed = DEV_IPC_GET_ARG2(*call);
+	const int ret = usbhc_iface->device_enumerate(fun, port, speed);
 	async_answer_0(callid, ret);
 }
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -80,9 +80,9 @@
 } usb_endpoint_descriptors_t;
 
-extern int usbhc_reserve_default_address(async_exch_t *, usb_speed_t);
+extern int usbhc_reserve_default_address(async_exch_t *);
 extern int usbhc_release_default_address(async_exch_t *);
 
-extern int usbhc_device_enumerate(async_exch_t *, unsigned port);
-extern int usbhc_device_remove(async_exch_t *, unsigned port);
+extern int usbhc_device_enumerate(async_exch_t *, unsigned, usb_speed_t);
+extern int usbhc_device_remove(async_exch_t *, unsigned);
 
 extern int usbhc_register_endpoint(async_exch_t *, usb_pipe_desc_t *, const usb_endpoint_descriptors_t *);
@@ -99,8 +99,8 @@
 /** USB device communication interface. */
 typedef struct {
-	int (*reserve_default_address)(ddf_fun_t *, usb_speed_t);
+	int (*reserve_default_address)(ddf_fun_t *);
 	int (*release_default_address)(ddf_fun_t *);
 
-	int (*device_enumerate)(ddf_fun_t *, unsigned);
+	int (*device_enumerate)(ddf_fun_t *, unsigned, usb_speed_t);
 	int (*device_remove)(ddf_fun_t *, unsigned);
 
Index: uspace/lib/usbhost/include/usb/host/bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bus.h	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/usbhost/include/usb/host/bus.h	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -140,6 +140,7 @@
 	const bus_ops_t *ops;
 
-	/* Reserving default address - USB_SPEED_MAX when free. */
-	usb_speed_t default_address_speed;
+	/* Reserving default address */
+	device_t *default_address_owner;
+	fibril_condvar_t default_address_cv;
 
 	/* This structure is meant to be extended by overriding. */
@@ -169,6 +170,6 @@
 int bus_endpoint_remove(endpoint_t *);
 
-int bus_reserve_default_address(bus_t *, usb_speed_t);
-void bus_release_default_address(bus_t *);
+int bus_reserve_default_address(bus_t *, device_t *);
+void bus_release_default_address(bus_t *, device_t *);
 
 #endif
Index: uspace/lib/usbhost/include/usb/host/ddf_helpers.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -48,5 +48,5 @@
 int hcd_setup_virtual_root_hub(hc_device_t *);
 
-device_t *hcd_ddf_fun_create(hc_device_t *);
+device_t *hcd_ddf_fun_create(hc_device_t *, usb_speed_t);
 void hcd_ddf_fun_destroy(device_t *);
 
Index: uspace/lib/usbhost/src/bus.c
===================================================================
--- uspace/lib/usbhost/src/bus.c	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/usbhost/src/bus.c	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -60,5 +60,4 @@
 	fibril_mutex_initialize(&bus->guard);
 	bus->device_size = device_size;
-	bus->default_address_speed = USB_SPEED_MAX;
 }
 
@@ -495,17 +494,18 @@
  * The speed is then used for devices enumerated while the address is reserved.
  */
-int bus_reserve_default_address(bus_t *bus, usb_speed_t speed)
+int bus_reserve_default_address(bus_t *bus, device_t *dev)
 {
 	assert(bus);
 
+	int err;
 	fibril_mutex_lock(&bus->guard);
-	if (bus->default_address_speed != USB_SPEED_MAX) {
-		fibril_mutex_unlock(&bus->guard);
-		return EAGAIN;
+	if (bus->default_address_owner != NULL) {
+		err = (bus->default_address_owner == dev) ? EINVAL : EAGAIN;
 	} else {
-		bus->default_address_speed = speed;
-		fibril_mutex_unlock(&bus->guard);
-		return EOK;
-	}
+		bus->default_address_owner = dev;
+		err = EOK;
+	}
+	fibril_mutex_unlock(&bus->guard);
+	return err;
 }
 
@@ -513,8 +513,15 @@
  * Release the default address.
  */
-void bus_release_default_address(bus_t *bus)
+void bus_release_default_address(bus_t *bus, device_t *dev)
 {
 	assert(bus);
-	bus->default_address_speed = USB_SPEED_MAX;
+
+	fibril_mutex_lock(&bus->guard);
+	if (bus->default_address_owner != dev) {
+		usb_log_error("Device %d tried to release address, which is not reserved for it.", dev->address);
+	} else {
+		bus->default_address_owner = NULL;
+	}
+	fibril_mutex_unlock(&bus->guard);
 }
 
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -117,7 +117,6 @@
  *
  * @param fun DDF function of the device (hub) requesting the address.
- * @param speed An USB speed of the device for which the address is reserved.
- */
-static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
+ */
+static int reserve_default_address(ddf_fun_t *fun)
 {
 	assert(fun);
@@ -128,7 +127,6 @@
 	assert(dev);
 
-	usb_log_debug("Device %d requested default address at %s speed",
-	    dev->address, usb_str_speed(speed));
-	return bus_reserve_default_address(hcd->bus, speed);
+	usb_log_debug("Device %d requested default address", dev->address);
+	return bus_reserve_default_address(hcd->bus, dev);
 }
 
@@ -148,5 +146,5 @@
 
 	usb_log_debug("Device %d released default address", dev->address);
-	bus_release_default_address(hcd->bus);
+	bus_release_default_address(hcd->bus, dev);
 
 	return EOK;
@@ -157,6 +155,7 @@
  *
  * @param fun DDF function of the device (hub) requesting the address.
- */
-static int device_enumerate(ddf_fun_t *fun, unsigned port)
+ * @param speed USB speed of the new device
+ */
+static int device_enumerate(ddf_fun_t *fun, unsigned port, usb_speed_t speed)
 {
 	assert(fun);
@@ -170,8 +169,8 @@
 	int err;
 
-	usb_log_debug("Hub %d reported a new USB device on port: %u",
-	    hub->address, port);
-
-	device_t *dev = hcd_ddf_fun_create(hcd);
+	usb_log_debug("Hub %d reported a new %s device on port: %u",
+	    hub->address, usb_str_speed(speed), port);
+
+	device_t *dev = hcd_ddf_fun_create(hcd, speed);
 	if (!dev) {
 		usb_log_error("Failed to create USB device function.");
@@ -181,4 +180,5 @@
 	dev->hub = hub;
 	dev->port = port;
+	dev->speed = speed;
 
 	if ((err = bus_device_enumerate(dev))) {
@@ -380,5 +380,5 @@
 }
 
-device_t *hcd_ddf_fun_create(hc_device_t *hc)
+device_t *hcd_ddf_fun_create(hc_device_t *hc, usb_speed_t speed)
 {
 	/* Create DDF function for the new device */
@@ -398,4 +398,5 @@
 	bus_device_init(dev, hc->bus);
 	dev->fun = fun;
+	dev->speed = speed;
 	return dev;
 }
@@ -464,13 +465,8 @@
 	assert(hcd);
 
-	if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) {
-		usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err));
-		return err;
-	}
-
-	device_t *dev = hcd_ddf_fun_create(hcd);
+	device_t *dev = hcd_ddf_fun_create(hcd, USB_SPEED_MAX);
 	if (!dev) {
 		usb_log_error("Failed to create function for the root hub.");
-		goto err_default_address;
+		return ENOMEM;
 	}
 
@@ -488,5 +484,4 @@
 	}
 
-	bus_release_default_address(hcd->bus);
 	return EOK;
 
@@ -495,6 +490,4 @@
 err_usb_dev:
 	hcd_ddf_fun_destroy(dev);
-err_default_address:
-	bus_release_default_address(hcd->bus);
 	return err;
 }
Index: uspace/lib/usbhost/src/usb2_bus.c
===================================================================
--- uspace/lib/usbhost/src/usb2_bus.c	(revision 47e9494c5eb0d77e3f73d832708572c5ada9398e)
+++ uspace/lib/usbhost/src/usb2_bus.c	(revision eeca8a6576e862d2b94e31531749315d4d938507)
@@ -190,8 +190,4 @@
 	usb2_bus_t *bus = bus_to_usb2_bus(dev->bus);
 
-	/* The speed of the new device was reported by the hub when reserving
-	 * default address.
-	 */
-	dev->speed = bus->base.default_address_speed;
 	usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
 
