Index: uspace/lib/usb/include/usb/hcdhubd.h
===================================================================
--- uspace/lib/usb/include/usb/hcdhubd.h	(revision 43178271ecca79c7c77563dbd2a252faa9b39f82)
+++ uspace/lib/usb/include/usb/hcdhubd.h	(revision 36c410e0479cfedf76affb9d3299a08fb1692755)
@@ -116,4 +116,21 @@
 } usb_hcd_transfer_ops_t;
 
+/**
+ * @brief structure holding information about free and used addresses
+ *
+ * This structure should not be used outside usb hcd driver.
+ * You better consider it to be 'private'.
+ */
+typedef struct {
+	/** lower bound included in the interval */
+	usb_address_t lower_bound;
+
+	/** upper bound, excluded from the interval */
+	usb_address_t upper_bound;
+
+	/** */
+	link_t link;
+}usb_address_list_t;
+
 struct usb_hc_device {
 	/** Transfer operations. */
@@ -131,4 +148,7 @@
 	/** List of hubs operating from this HC. */
 	link_t hubs;
+
+	/** Structure with free and used addresses */
+	link_t addresses;
 
 	/** Link to other driven HCs. */
@@ -148,4 +168,21 @@
 int usb_hcd_add_root_hub(device_t *dev);
 
+/**
+ * find first not yet used address on this host controller and use it
+ * @param this_hcd
+ * @return number in the range of allowed usb addresses or
+ *     a negative number if not succesful
+ */
+usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd);
+
+/**
+ * @brief free the address in the address space of this hcd.
+ *
+ * if address is not used, nothing happens
+ * @param this_hcd
+ * @param addr
+ */
+void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr );
+
 
 /*
Index: uspace/lib/usb/src/hcdhubd.c
===================================================================
--- uspace/lib/usb/src/hcdhubd.c	(revision 43178271ecca79c7c77563dbd2a252faa9b39f82)
+++ uspace/lib/usb/src/hcdhubd.c	(revision 36c410e0479cfedf76affb9d3299a08fb1692755)
@@ -114,8 +114,7 @@
 
 /** Adds a child device fibril worker. */
-static int fibril_add_child_device(void *arg)
-{
+static int fibril_add_child_device(void *arg) {
 	struct child_device_info *child_info
-	    = (struct child_device_info *) arg;
+			= (struct child_device_info *) arg;
 	int rc;
 
@@ -141,8 +140,8 @@
 
 	printf("%s: adding child device `%s' with match \"%s\"\n",
-	    hc_driver->name, child->name, match_id->id);
+			hc_driver->name, child->name, match_id->id);
 	rc = child_device_register(child, child_info->parent);
 	printf("%s: child device `%s' registration: %s\n",
-	    hc_driver->name, child->name, str_error(rc));
+			hc_driver->name, child->name, str_error(rc));
 
 	if (rc != EOK) {
@@ -182,8 +181,7 @@
  */
 int usb_hc_add_child_device(device_t *parent, const char *name,
-    const char *match_id, bool create_fibril)
-{
+		const char *match_id, bool create_fibril) {
 	printf("%s: about to add child device `%s' (%s)\n", hc_driver->name,
-	    name, match_id);
+			name, match_id);
 
 	/*
@@ -194,5 +192,5 @@
 
 	struct child_device_info *child_info
-	    = malloc(sizeof(struct child_device_info));
+			= malloc(sizeof (struct child_device_info));
 
 	child_info->parent = parent;
@@ -218,10 +216,93 @@
  * @return USB device address or error code.
  */
-usb_address_t usb_get_address_by_handle(devman_handle_t handle)
-{
+usb_address_t usb_get_address_by_handle(devman_handle_t handle) {
 	/* TODO: search list of attached devices. */
 	return ENOENT;
 }
 
+usb_address_t usb_use_free_address(usb_hc_device_t * this_hcd) {
+	//is there free address?
+	link_t * addresses = &this_hcd->addresses;
+	if (list_empty(addresses)) return -1;
+	link_t * link_addr = addresses;
+	bool found = false;
+	usb_address_list_t * range = NULL;
+	while (!found) {
+		link_addr = link_addr->next;
+		if (link_addr == addresses) return -2;
+		range = list_get_instance(link_addr,
+				usb_address_list_t, link);
+		if (range->upper_bound - range->lower_bound > 0) {
+			found = true;
+		}
+	}
+	//now we have interval
+	int result = range->lower_bound;
+	++(range->lower_bound);
+	if (range->upper_bound - range->lower_bound == 0) {
+		list_remove(&range->link);
+		free(range);
+	}
+	return result;
+}
+
+void usb_free_used_address(usb_hc_device_t * this_hcd, usb_address_t addr) {
+	//check range
+	if (addr < usb_lowest_address || addr > usb_highest_address)
+		return;
+	link_t * addresses = &this_hcd->addresses;
+	link_t * link_addr = addresses;
+	//find 'good' interval
+	usb_address_list_t * found_range = NULL;
+	bool found = false;
+	while (!found) {
+		link_addr = link_addr->next;
+		if (link_addr == addresses) {
+			found = true;
+		} else {
+			usb_address_list_t * range = list_get_instance(link_addr,
+					usb_address_list_t, link);
+			if (	(range->lower_bound - 1 == addr) ||
+					(range->upper_bound == addr)) {
+				found = true;
+				found_range = range;
+			}
+			if (range->lower_bound - 1 > addr) {
+				found = true;
+			}
+
+		}
+	}
+	if (found_range == NULL) {
+		//no suitable range found
+		usb_address_list_t * result_range =
+				(usb_address_list_t*) malloc(sizeof (usb_address_list_t));
+		result_range->lower_bound = addr;
+		result_range->upper_bound = addr + 1;
+		list_insert_before(&result_range->link, link_addr);
+	} else {
+		//we have good range
+		if (found_range->lower_bound - 1 == addr) {
+			--found_range->lower_bound;
+		} else {
+			//only one possible case
+			++found_range->upper_bound;
+			if (found_range->link.next != addresses) {
+				usb_address_list_t * next_range =
+						list_get_instance( &found_range->link.next,
+						usb_address_list_t, link);
+				//check neighbour range
+				if (next_range->lower_bound == addr + 1) {
+					//join ranges
+					found_range->upper_bound = next_range->upper_bound;
+					list_remove(&next_range->link);
+					free(next_range);
+				}
+			}
+		}
+	}
+
+}
+
 /**
  * @}
Index: uspace/lib/usb/src/hcdhubd_private.h
===================================================================
--- uspace/lib/usb/src/hcdhubd_private.h	(revision 43178271ecca79c7c77563dbd2a252faa9b39f82)
+++ uspace/lib/usb/src/hcdhubd_private.h	(revision 36c410e0479cfedf76affb9d3299a08fb1692755)
@@ -47,4 +47,29 @@
 int usb_add_hc_device(device_t *);
 
+/** lowest allowed usb address */
+extern int usb_lowest_address;
+
+/** highest allowed usb address */
+extern int usb_highest_address;
+
+/**
+ * @brief initialize address list of given hcd
+ *
+ * This function should be used only for hcd initialization.
+ * It creates interval list of free addresses, thus it is initialized as
+ * list with one interval with whole address space. Using an address shrinks
+ * the interval, freeing an address extends an interval or creates a
+ * new one. 
+ *
+ * @param hcd
+ * @return
+ */
+void  usb_create_address_list(usb_hc_device_t * hcd);
+
+
+
+
+
+
 #endif
 /**
Index: uspace/lib/usb/src/hcdrv.c
===================================================================
--- uspace/lib/usb/src/hcdrv.c	(revision 43178271ecca79c7c77563dbd2a252faa9b39f82)
+++ uspace/lib/usb/src/hcdrv.c	(revision 36c410e0479cfedf76affb9d3299a08fb1692755)
@@ -55,7 +55,21 @@
 usb_hc_driver_t *hc_driver = &hc_driver_fake;
 
+int usb_lowest_address = 1;
+
+int usb_highest_address = 255;
+
 static device_ops_t usb_device_ops = {
 	.interfaces[USBHC_DEV_IFACE] = &usbhc_interface
 };
+
+
+void usb_create_address_list(usb_hc_device_t * hcd){
+	list_initialize(&hcd->addresses);
+	usb_address_list_t * range =
+			(usb_address_list_t*)malloc(sizeof(usb_address_list_t));
+	range->lower_bound = usb_lowest_address;
+	range->upper_bound = usb_highest_address + 1;
+	list_append(&range->link, &hcd->addresses);
+}
 
 static usb_hc_device_t *usb_hc_device_create(device_t *dev) {
@@ -64,4 +78,5 @@
 	list_initialize(&hc_dev->link);
 	list_initialize(&hc_dev->hubs);
+	usb_create_address_list(hc_dev);
 	list_initialize(&hc_dev->attached_devices);
 	hc_dev->transfer_ops = NULL;
