Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision 5e07cbc0dbf74b36e7b0332f98d3d8be06a0e9de)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision 0cd80894622812e65d3abac4dcc0e5151ae6b43d)
@@ -127,15 +127,16 @@
 	assert(hub_fun);
 
-	const usb_address_t hub_address =
-	    usb_device_manager_get_free_address(
-	        &instance->generic.dev_manager, USB_SPEED_FULL);
-	if (hub_address <= 0) {
+	/* Try to get address 1 for root hub. */
+	instance->rh.address = 1;
+	int ret = usb_device_manager_request_address(
+	    &instance->generic.dev_manager, &instance->rh.address, false,
+	    USB_SPEED_FULL);
+	if (ret != EOK) {
 		usb_log_error("Failed to get OHCI root hub address: %s\n",
-		    str_error(hub_address));
-		return hub_address;
-	}
-	instance->rh.address = hub_address;
-	usb_device_manager_bind(
-	    &instance->generic.dev_manager, hub_address, hub_fun->handle);
+		    str_error(ret));
+		return ret;
+	}
+	usb_device_manager_bind_address(&instance->generic.dev_manager,
+	    instance->rh.address, hub_fun->handle);
 
 #define CHECK_RET_UNREG_RETURN(ret, message...) \
@@ -143,13 +144,14 @@
 	usb_log_error(message); \
 	usb_endpoint_manager_remove_ep( \
-	    &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, \
-	    NULL, NULL);\
-	usb_device_manager_release( \
-	    &instance->generic.dev_manager, hub_address); \
+	    &instance->generic.ep_manager, instance->rh.address, 0, \
+	    USB_DIRECTION_BOTH, NULL, NULL); \
+	usb_device_manager_release_address( \
+	    &instance->generic.dev_manager, instance->rh.address); \
 	return ret; \
 } else (void)0
-	int ret = usb_endpoint_manager_add_ep(
-	    &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH,
-	    USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0, NULL, NULL);
+	ret = usb_endpoint_manager_add_ep(
+	    &instance->generic.ep_manager, instance->rh.address, 0,
+	    USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
+	    0, NULL, NULL);
 	CHECK_RET_UNREG_RETURN(ret,
 	    "Failed to register root hub control endpoint: %s.\n",
Index: uspace/drv/bus/usb/vhc/connhost.c
===================================================================
--- uspace/drv/bus/usb/vhc/connhost.c	(revision 5e07cbc0dbf74b36e7b0332f98d3d8be06a0e9de)
+++ uspace/drv/bus/usb/vhc/connhost.c	(revision 0cd80894622812e65d3abac4dcc0e5151ae6b43d)
@@ -62,8 +62,9 @@
 	VHC_DATA(vhc, fun);
 
-	usb_address_t addr = usb_device_manager_get_free_address(
-	    &vhc->dev_manager, USB_SPEED_HIGH);
-	if (addr < 0) {
-		return addr;
+	usb_address_t addr = 1;
+	const int ret = usb_device_manager_request_address(
+	    &vhc->dev_manager, &addr, false, USB_SPEED_HIGH);
+	if (ret < 0) {
+		return ret;
 	}
 
@@ -88,5 +89,5 @@
 	usb_log_debug("Binding handle %" PRIun " to address %d.\n",
 	    handle, address);
-	usb_device_manager_bind(&vhc->dev_manager, address, handle);
+	usb_device_manager_bind_address(&vhc->dev_manager, address, handle);
 
 	return EOK;
@@ -118,5 +119,5 @@
 	VHC_DATA(vhc, fun);
 	usb_log_debug("Releasing address %d...\n", address);
-	usb_device_manager_release(&vhc->dev_manager, address);
+	usb_device_manager_release_address(&vhc->dev_manager, address);
 
 	return ENOTSUP;
Index: uspace/lib/usbhost/include/usb/host/usb_device_manager.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_device_manager.h	(revision 5e07cbc0dbf74b36e7b0332f98d3d8be06a0e9de)
+++ uspace/lib/usbhost/include/usb/host/usb_device_manager.h	(revision 0cd80894622812e65d3abac4dcc0e5151ae6b43d)
@@ -68,11 +68,11 @@
     usb_device_manager_t *instance, usb_speed_t max_speed);
 
-usb_address_t usb_device_manager_get_free_address(
-    usb_device_manager_t *instance, usb_speed_t speed);
+int usb_device_manager_request_address(usb_device_manager_t *instance,
+    usb_address_t *address, bool strict, usb_speed_t speed);
 
-int usb_device_manager_bind(usb_device_manager_t *instance,
+int usb_device_manager_bind_address(usb_device_manager_t *instance,
     usb_address_t address, devman_handle_t handle);
 
-int usb_device_manager_release(usb_device_manager_t *instance,
+int usb_device_manager_release_address(usb_device_manager_t *instance,
     usb_address_t address);
 
Index: uspace/lib/usbhost/src/iface.c
===================================================================
--- uspace/lib/usbhost/src/iface.c	(revision 5e07cbc0dbf74b36e7b0332f98d3d8be06a0e9de)
+++ uspace/lib/usbhost/src/iface.c	(revision 0cd80894622812e65d3abac4dcc0e5151ae6b43d)
@@ -105,10 +105,6 @@
 
 	usb_log_debug("Address request speed: %s.\n", usb_str_speed(speed));
-	*address =
-	    usb_device_manager_get_free_address(&hcd->dev_manager, speed);
-	usb_log_debug("Address request with result: %d.\n", *address);
-	if (*address <= 0)
-		return *address;
-	return EOK;
+	return usb_device_manager_request_address(
+	    &hcd->dev_manager, address, false, speed);
 }
 /*----------------------------------------------------------------------------*/
@@ -128,5 +124,6 @@
 
 	usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
-	return usb_device_manager_bind(&hcd->dev_manager, address, handle);
+	return usb_device_manager_bind_address(
+	    &hcd->dev_manager, address, handle);
 }
 /*----------------------------------------------------------------------------*/
@@ -160,5 +157,5 @@
 	assert(hcd);
 	usb_log_debug("Address release %d.\n", address);
-	usb_device_manager_release(&hcd->dev_manager, address);
+	usb_device_manager_release_address(&hcd->dev_manager, address);
 	return EOK;
 }
Index: uspace/lib/usbhost/src/usb_device_manager.c
===================================================================
--- uspace/lib/usbhost/src/usb_device_manager.c	(revision 5e07cbc0dbf74b36e7b0332f98d3d8be06a0e9de)
+++ uspace/lib/usbhost/src/usb_device_manager.c	(revision 0cd80894622812e65d3abac4dcc0e5151ae6b43d)
@@ -38,4 +38,30 @@
 #include <usb/host/usb_device_manager.h>
 
+/** Get a free USB address
+ *
+ * @param[in] instance Device manager structure to use.
+ * @param[in] speed Speed of the device requiring address.
+ * @return Free address, or error code.
+ */
+static usb_address_t usb_device_manager_get_free_address(
+    usb_device_manager_t *instance)
+{
+
+	usb_address_t new_address = instance->last_address;
+	do {
+		new_address = (new_address + 1) % USB_ADDRESS_COUNT;
+		if (new_address == USB_ADDRESS_DEFAULT)
+			new_address = 1;
+		if (new_address == instance->last_address) {
+			return ENOSPC;
+		}
+	} while (instance->devices[new_address].occupied);
+
+	assert(new_address != USB_ADDRESS_DEFAULT);
+	instance->last_address = new_address;
+
+	return new_address;
+}
+/*----------------------------------------------------------------------------*/
 /** Initialize device manager structure.
  *
@@ -54,7 +80,4 @@
 		instance->devices[i].speed = USB_SPEED_MAX;
 	}
-	// TODO: is this hack enough?
-	// (it is needed to allow smooth registration at default address)
-	instance->devices[0].occupied = true;
 	instance->last_address = 0;
 	instance->max_speed = max_speed;
@@ -62,40 +85,43 @@
 }
 /*----------------------------------------------------------------------------*/
-/** Get a free USB address
- *
- * @param[in] instance Device manager structure to use.
- * @param[in] speed Speed of the device requiring address.
- * @return Free address, or error code.
- */
-usb_address_t usb_device_manager_get_free_address(
-    usb_device_manager_t *instance, usb_speed_t speed)
-{
-	assert(instance);
+/** Request USB address.
+ * @param instance usb_device_manager
+ * @param address Pointer to requested address value, place to store new address
+ * @parma strict Fail if the requested address is not available.
+ * @return Error code.
+ * @note Default address is only available in strict mode.
+ */
+int usb_device_manager_request_address(usb_device_manager_t *instance,
+    usb_address_t *address, bool strict, usb_speed_t speed)
+{
+	assert(instance);
+	assert(address);
 	if (speed > instance->max_speed)
 		return ENOTSUP;
-	fibril_mutex_lock(&instance->guard);
-
-	usb_address_t new_address = instance->last_address;
-	do {
-		++new_address;
-		if (new_address > USB11_ADDRESS_MAX)
-			new_address = 1; // NOTE it should be safe to put 0 here
-			                 // TODO Use mod
-		if (new_address == instance->last_address) {
+
+	if ((*address) < 0 || (*address) >= USB_ADDRESS_COUNT)
+		return EINVAL;
+
+	fibril_mutex_lock(&instance->guard);
+	/* Only grant default address to strict requests */
+	if (( (*address) == USB_ADDRESS_DEFAULT) && !strict) {
+		*address = instance->last_address;
+	}
+
+	if (instance->devices[*address].occupied) {
+		if (strict) {
 			fibril_mutex_unlock(&instance->guard);
-			return ENOSPC;
+			return ENOENT;
 		}
-	} while (instance->devices[new_address].occupied);
-
-	assert(new_address != USB_ADDRESS_DEFAULT);
-	assert(instance->devices[new_address].occupied == false);
-	assert(instance->devices[new_address].handle == 0);
-
-	instance->devices[new_address].occupied = true;
-	instance->devices[new_address].speed = speed;
-	instance->last_address = new_address;
-
-	fibril_mutex_unlock(&instance->guard);
-	return new_address;
+		*address = usb_device_manager_get_free_address(instance);
+	}
+	assert(instance->devices[*address].occupied == false);
+	assert(instance->devices[*address].handle == 0);
+
+	instance->devices[*address].occupied = true;
+	instance->devices[*address].speed = speed;
+
+	fibril_mutex_unlock(&instance->guard);
+	return EOK;
 }
 /*----------------------------------------------------------------------------*/
@@ -107,5 +133,5 @@
  * @return Error code.
  */
-int usb_device_manager_bind(usb_device_manager_t *instance,
+int usb_device_manager_bind_address(usb_device_manager_t *instance,
     usb_address_t address, devman_handle_t handle)
 {
@@ -137,5 +163,5 @@
  * @return Error code.
  */
-int usb_device_manager_release(
+int usb_device_manager_release_address(
     usb_device_manager_t *instance, usb_address_t address)
 {
