Index: uspace/lib/usb/include/usb/hcdhubd.h
===================================================================
--- uspace/lib/usb/include/usb/hcdhubd.h	(revision 1dd264b4d94337e364b4cca33058331c32ba879d)
+++ uspace/lib/usb/include/usb/hcdhubd.h	(revision 2cb65715d0ed6e1e5320c16c6c26044ba9f8afcd)
@@ -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(usb_hc_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 1dd264b4d94337e364b4cca33058331c32ba879d)
+++ uspace/lib/usb/src/hcdhubd.c	(revision 2cb65715d0ed6e1e5320c16c6c26044ba9f8afcd)
@@ -105,6 +105,5 @@
  * @return Error code.
  */
-int usb_hcd_add_root_hub(usb_hc_device_t *dev)
-{
+int usb_hcd_add_root_hub(usb_hc_device_t *dev) {
 	char *id;
 	int rc = asprintf(&id, "usb&hc=%s&hub", hc_driver->name);
@@ -129,8 +128,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;
 
@@ -156,8 +154,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) {
@@ -197,8 +195,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);
 
 	/*
@@ -209,5 +206,5 @@
 
 	struct child_device_info *child_info
-	    = malloc(sizeof(struct child_device_info));
+			= malloc(sizeof (struct child_device_info));
 
 	child_info->parent = parent;
@@ -233,10 +230,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 1dd264b4d94337e364b4cca33058331c32ba879d)
+++ uspace/lib/usb/src/hcdhubd_private.h	(revision 2cb65715d0ed6e1e5320c16c6c26044ba9f8afcd)
@@ -48,4 +48,29 @@
 int usb_add_hub_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 1dd264b4d94337e364b4cca33058331c32ba879d)
+++ uspace/lib/usb/src/hcdrv.c	(revision 2cb65715d0ed6e1e5320c16c6c26044ba9f8afcd)
@@ -50,7 +50,21 @@
 usb_hc_driver_t *hc_driver = NULL;
 
+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) {
@@ -59,4 +73,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;
Index: uspace/lib/usb/src/hubdrv.c
===================================================================
--- uspace/lib/usb/src/hubdrv.c	(revision 1dd264b4d94337e364b4cca33058331c32ba879d)
+++ uspace/lib/usb/src/hubdrv.c	(revision 2cb65715d0ed6e1e5320c16c6c26044ba9f8afcd)
@@ -113,10 +113,9 @@
 	usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
 	//get parent device
-	/// @TODO this code is not correct
 	device_t * my_hcd = device;
 	while (my_hcd->parent)
 		my_hcd = my_hcd->parent;
 	//dev->
-	printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
+	printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
 	//we add the hub into the first hc
 	//link_t *link_hc = hc_list.next;
@@ -135,6 +134,12 @@
  */
 int usb_add_hub_device(device_t *dev) {
-	usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
-	set_hub_address(hc, 5);
+	//usb_hc_device_t *hc = list_get_instance(hc_list.next, usb_hc_device_t, link);
+	assert(dev->parent);
+	usb_hc_device_t *hc = (usb_hc_device_t*)dev->parent->driver_data;
+	usb_address_t addr =usb_use_free_address(hc);
+	if(addr<0){
+		printf("[hcdhubd] ERROR: cannot find an address \n");
+	}
+	set_hub_address(hc, addr);
 
 	check_hub_changes();
@@ -151,5 +156,5 @@
 		my_hcd = my_hcd->parent;
 	//dev->
-	printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
+	printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
 	my_hcd = dev;
 	while (my_hcd->parent)
@@ -157,5 +162,5 @@
 	//dev->
 
-	printf("%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
+	printf("[hcdhubd]%s: owner hcd found: %s\n", hc_driver->name, my_hcd->name);
 
 	//create the hub structure
@@ -183,5 +188,5 @@
  */
 static void set_hub_address(usb_hc_device_t *hc, usb_address_t address) {
-	printf("%s: setting hub address to %d\n", hc->generic->name, address);
+	printf("[hcdhubd]%s: setting hub address to %d\n", hc->generic->name, address);
 	usb_target_t target = {0, 0};
 	usb_handle_t handle;
@@ -217,5 +222,6 @@
 	}
 
-	printf("%s: hub address changed\n", hc->generic->name);
+	printf("[hcdhubd]%s: hub address changed successfully to %d\n",
+			hc->generic->name, address);
 }
 
