Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/Makefile	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -121,4 +121,5 @@
 		drv/uhci-hcd \
 		drv/uhci-rhd \
+		drv/usbflbk \
 		drv/usbhid \
 		drv/usbhub \
@@ -140,4 +141,5 @@
 		drv/uhci-hcd \
 		drv/uhci-rhd \
+		drv/usbflbk \
 		drv/usbhid \
 		drv/usbhub \
Index: uspace/app/usbinfo/info.c
===================================================================
--- uspace/app/usbinfo/info.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/app/usbinfo/info.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -109,8 +109,9 @@
     usb_standard_device_descriptor_t *descriptor)
 {
-	printf("%sDevice (0x%04x by 0x%04x, %s)\n", prefix,
+	printf("%sDevice (0x%04x by 0x%04x, %s, %zu configurations)\n", prefix,
 	    (int) descriptor->product_id,
 	    (int) descriptor->vendor_id,
-	    usb_str_class(descriptor->device_class));
+	    usb_str_class(descriptor->device_class),
+	    (size_t) descriptor->configuration_count);
 }
 
@@ -118,6 +119,7 @@
     usb_standard_configuration_descriptor_t *descriptor)
 {
-	printf("%sConfiguration #%d\n", prefix,
-	    (int) descriptor->configuration_number);
+	printf("%sConfiguration #%d (%zu interfaces)\n", prefix,
+	    (int) descriptor->configuration_number,
+	    (size_t) descriptor->interface_count);
 }
 
@@ -125,9 +127,10 @@
     usb_standard_interface_descriptor_t *descriptor)
 {
-	printf("%sInterface #%d (%s, 0x%02x, 0x%02x)\n", prefix,
+	printf("%sInterface #%d (%s, 0x%02x, 0x%02x), alternate %d\n", prefix,
 	    (int) descriptor->interface_number,
 	    usb_str_class(descriptor->interface_class),
 	    (int) descriptor->interface_subclass,
-	    (int) descriptor->interface_protocol);
+	    (int) descriptor->interface_protocol,
+	    (int) descriptor->alternate_setting);
 }
 
Index: uspace/doc/doxygroups.h
===================================================================
--- uspace/doc/doxygroups.h	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/doc/doxygroups.h	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -274,3 +274,13 @@
 	 */
 
-
+	/**
+	 * @defgroup drvusbfallback USB fallback driver.
+	 * @ingroup usb
+	 * @brief Fallback driver for any USB device.
+	 * @details
+	 * The purpose of this driver is to simplify querying of unknown
+	 * devices from within HelenOS (without a driver, no node at all
+	 * may appear under /dev/devices).
+	 */
+
+
Index: uspace/drv/usbflbk/Makefile
===================================================================
--- uspace/drv/usbflbk/Makefile	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
+++ uspace/drv/usbflbk/Makefile	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2011 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+BINARY = usbflbk
+
+SOURCES = \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/usbflbk/main.c
===================================================================
--- uspace/drv/usbflbk/main.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
+++ uspace/drv/usbflbk/main.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbfallback
+ * @{
+ */
+/**
+ * @file
+ * Main routines of USB fallback driver.
+ */
+#include <usb/devdrv.h>
+#include <usb/debug.h>
+#include <errno.h>
+#include <str_error.h>
+
+#define NAME "usbflbk"
+
+/** Callback when new device is attached and recognized by DDF.
+ *
+ * @param dev Representation of a generic DDF device.
+ * @return Error code.
+ */
+static int usbfallback_add_device(usb_device_t *dev)
+{
+	int rc;
+	const char *fun_name = "ctl";
+
+	ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
+	    fun_name);
+	if (ctl_fun == NULL) {
+		usb_log_error("Failed to create control function.\n");
+		return ENOMEM;
+	}
+	rc = ddf_fun_bind(ctl_fun);
+	if (rc != EOK) {
+		usb_log_error("Failed to bind control function: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+
+	usb_log_info("Pretending to control %s `%s'" \
+	    " (node `%s', handle %llu).\n",
+	    dev->interface_no < 0 ? "device" : "interface",
+	    dev->ddf_dev->name, fun_name, dev->ddf_dev->handle);
+
+	return EOK;
+}
+
+/** USB fallback driver ops. */
+static usb_driver_ops_t usbfallback_driver_ops = {
+	.add_device = usbfallback_add_device,
+};
+
+/** USB fallback driver. */
+static usb_driver_t usbfallback_driver = {
+	.name = NAME,
+	.ops = &usbfallback_driver_ops,
+	.endpoints = NULL
+};
+
+int main(int argc, char *argv[])
+{
+	usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
+
+	return usb_driver_main(&usbfallback_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/usbflbk/usbflbk.ma
===================================================================
--- uspace/drv/usbflbk/usbflbk.ma	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
+++ uspace/drv/usbflbk/usbflbk.ma	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -0,0 +1,2 @@
+10 usb&fallback
+10 usb&interface&fallback
Index: uspace/drv/usbhub/main.c
===================================================================
--- uspace/drv/usbhub/main.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/drv/usbhub/main.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -36,32 +36,43 @@
 #include <stdio.h>
 
+#include <usb/devdrv.h>
+#include <usb/classes/classes.h>
+
 #include "usbhub.h"
 #include "usbhub_private.h"
 
 
-usb_general_list_t usb_hub_list;
-fibril_mutex_t usb_hub_list_lock;
-
-static driver_ops_t hub_driver_ops = {
-	.add_device = usb_add_hub_device,
+usb_endpoint_description_t hub_status_change_endpoint_description = {
+	.transfer_type = USB_TRANSFER_INTERRUPT,
+	.direction = USB_DIRECTION_IN,
+	.interface_class = USB_CLASS_HUB,
+	.interface_subclass = 0,
+	.interface_protocol = 0,
+	.flags = 0
 };
 
-static driver_t hub_driver = {
+
+static usb_driver_ops_t usb_hub_driver_ops = {
+	.add_device = usb_hub_add_device
+};
+
+static usb_driver_t usb_hub_driver = {
 	.name = "usbhub",
-	.driver_ops = &hub_driver_ops
+	.ops = &usb_hub_driver_ops
 };
+
 
 int main(int argc, char *argv[])
 {
 	usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
-	dprintf(USB_LOG_LEVEL_INFO, "starting hub driver");
+	usb_log_info("starting hub driver\n");
 
-	//this is probably not needed anymore
-	fibril_mutex_initialize(&usb_hub_list_lock);
-	fibril_mutex_lock(&usb_hub_list_lock);
-	usb_lst_init(&usb_hub_list);
-	fibril_mutex_unlock(&usb_hub_list_lock);
 	
-	return ddf_driver_main(&hub_driver);
+	usb_hub_driver.endpoints = (usb_endpoint_description_t**)
+			malloc(2 * sizeof(usb_endpoint_description_t*));
+	usb_hub_driver.endpoints[0] = &hub_status_change_endpoint_description;
+	usb_hub_driver.endpoints[1] = NULL;
+
+	return usb_driver_main(&usb_hub_driver);
 }
 
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/drv/usbhub/usbhub.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -53,21 +53,4 @@
 #include "usb/classes/classes.h"
 
-static ddf_dev_ops_t hub_device_ops = {
-	.interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
-};
-
-/** Hub status-change endpoint description
- *
- * For more see usb hub specification in 11.15.1 of
- */
-static usb_endpoint_description_t status_change_endpoint_description = {
-	.transfer_type = USB_TRANSFER_INTERRUPT,
-	.direction = USB_DIRECTION_IN,
-	.interface_class = USB_CLASS_HUB,
-	.interface_subclass = 0,
-	.interface_protocol = 0,
-	.flags = 0
-};
-
 int usb_hub_control_loop(void * hub_info_param){
 	usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
@@ -78,5 +61,5 @@
 		async_usleep(1000 * 1000 );/// \TODO proper number once
 	}
-	usb_log_error("something in ctrl loop went wrong, errno %d",errorCode);
+	usb_log_error("something in ctrl loop went wrong, errno %d\n",errorCode);
 
 	return 0;
@@ -91,70 +74,99 @@
 
 /**
- * Initialize connnections to host controller, device, and device
- * control endpoint
- * @param hub
- * @param device
+ * create usb_hub_info_t structure
+ *
+ * Does only basic copying of known information into new structure.
+ * @param usb_dev usb device structure
+ * @return basic usb_hub_info_t structure
+ */
+static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
+	usb_hub_info_t * result = usb_new(usb_hub_info_t);
+	if(!result) return NULL;
+	result->usb_device = usb_dev;
+	result->status_change_pipe = usb_dev->pipes[0].pipe;
+	result->control_pipe = &usb_dev->ctrl_pipe;
+	result->is_default_address_used = false;
+	return result;
+}
+
+/**
+ * Load hub-specific information into hub_info structure.
+ *
+ * Particularly read port count and initialize structure holding port
+ * information.
+ * This function is hub-specific and should be run only after the hub is
+ * configured using usb_hub_set_configuration function.
+ * @param hub_info pointer to structure with usb hub data
+ * @return error code
+ */
+static int usb_hub_get_hub_specific_info(usb_hub_info_t * hub_info){
+	// get hub descriptor
+	usb_log_debug("creating serialized descriptor\n");
+	void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
+	usb_hub_descriptor_t * descriptor;
+
+	/* this was one fix of some bug, should not be needed anymore
+	int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
+	if(opResult!=EOK){
+		usb_log_error("could not set default configuration, errno %d",opResult);
+		return opResult;
+	}
+	 */
+	size_t received_size;
+	int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe,
+			USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
+			USB_DESCTYPE_HUB,
+			0, 0, serialized_descriptor,
+			USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
+
+	if (opResult != EOK) {
+		usb_log_error("failed when receiving hub descriptor, badcode = %d\n",
+				opResult);
+		free(serialized_descriptor);
+		return opResult;
+	}
+	usb_log_debug2("deserializing descriptor\n");
+	descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
+	if(descriptor==NULL){
+		usb_log_warning("could not deserialize descriptor \n");
+		return opResult;
+	}
+	usb_log_info("setting port count to %d\n",descriptor->ports_count);
+	hub_info->port_count = descriptor->ports_count;
+	hub_info->attached_devs = (usb_hc_attached_device_t*)
+	    malloc((hub_info->port_count+1) * sizeof(usb_hc_attached_device_t));
+	int i;
+	for(i=0;i<hub_info->port_count+1;++i){
+		hub_info->attached_devs[i].handle=0;
+		hub_info->attached_devs[i].address=0;
+	}
+	usb_log_debug2("freeing data\n");
+	free(serialized_descriptor);
+	free(descriptor->devices_removable);
+	free(descriptor);
+	return EOK;
+}
+/**
+ * Set configuration of hub
+ *
+ * Check whether there is at least one configuration and sets the first one.
+ * This function should be run prior to running any hub-specific action.
+ * @param hub_info
  * @return
  */
-static int usb_hub_init_communication(usb_hub_info_t * hub){
-	usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle);
-	int opResult;
-	opResult = usb_device_connection_initialize_from_device(
-			&hub->device_connection,
-			hub->device);
-	if(opResult != EOK){
-		usb_log_error("could not initialize connection to hc, errno %d",opResult);
-		return opResult;
-	}
-	usb_log_debug("Initializing USB wire abstraction.\n");
-	opResult = usb_hc_connection_initialize_from_device(&hub->connection,
-			hub->device);
-	if(opResult != EOK){
-		usb_log_error("could not initialize connection to device, errno %d",
-				opResult);
-		return opResult;
-	}
-	usb_log_debug("Initializing default control pipe.\n");
-	opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
-            &hub->device_connection);
-	if(opResult != EOK){
-		usb_log_error("could not initialize connection to device endpoint, errno %d",
-				opResult);
-		return opResult;
-	}
-
-	opResult = usb_endpoint_pipe_probe_default_control(&hub->endpoints.control);
-	if (opResult != EOK) {
-		usb_log_error("failed probing endpoint 0, %d", opResult);
-		return opResult;
-	}
-
-	return EOK;
-}
-
-/**
- * When entering this function, hub->endpoints.control should be active.
- * @param hub
- * @return
- */
-static int usb_hub_process_configuration_descriptors(
-	usb_hub_info_t * hub){
-	if(hub==NULL) {
-		return EINVAL;
-	}
-	int opResult;
-	
+static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
 	//device descriptor
 	usb_standard_device_descriptor_t std_descriptor;
-	opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
+	int opResult = usb_request_get_device_descriptor(
+		&hub_info->usb_device->ctrl_pipe,
 	    &std_descriptor);
 	if(opResult!=EOK){
-		usb_log_error("could not get device descriptor, %d",opResult);
-		return opResult;
-	}
-	usb_log_info("hub has %d configurations",
+		usb_log_error("could not get device descriptor, %d\n",opResult);
+		return opResult;
+	}
+	usb_log_info("hub has %d configurations\n",
 			std_descriptor.configuration_count);
 	if(std_descriptor.configuration_count<1){
-		usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE");
+		usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n");
 		//shouldn`t I return?
 	}
@@ -164,5 +176,5 @@
 	size_t descriptors_size = 0;
 	opResult = usb_request_get_full_configuration_descriptor_alloc(
-	    &hub->endpoints.control, 0,
+	    &hub_info->usb_device->ctrl_pipe, 0,
 	    (void **) &descriptors, &descriptors_size);
 	if (opResult != EOK) {
@@ -175,5 +187,5 @@
 
 	/* Set configuration. */
-	opResult = usb_request_set_configuration(&hub->endpoints.control,
+	opResult = usb_request_set_configuration(&hub_info->usb_device->ctrl_pipe,
 	    config_descriptor->configuration_number);
 
@@ -183,162 +195,55 @@
 		return opResult;
 	}
-	usb_log_debug("\tused configuration %d",
+	usb_log_debug("\tused configuration %d\n",
 			config_descriptor->configuration_number);
-
-	usb_endpoint_mapping_t endpoint_mapping[1] = {
-		{
-			.pipe = &hub->endpoints.status_change,
-			.description = &status_change_endpoint_description,
-			.interface_no =
-			    usb_device_get_assigned_interface(hub->device)
-		}
-	};
-	opResult = usb_endpoint_pipe_initialize_from_configuration(
-	    endpoint_mapping, 1,
-	    descriptors, descriptors_size,
-	    &hub->device_connection);
-	if (opResult != EOK) {
-		usb_log_error("Failed to initialize status change pipe: %s",
-		    str_error(opResult));
-		return opResult;
-	}
-	if (!endpoint_mapping[0].present) {
-		usb_log_error("Not accepting device, " \
-		    "cannot understand what is happenning");
-		return EREFUSED;
-	}
-
 	free(descriptors);
 	return EOK;
+}
+
+/**
+ * Initialize hub device driver fibril
+ *
+ * Creates hub representation and fibril that periodically checks hub`s status.
+ * Hub representation is passed to the fibril.
+ * @param usb_dev generic usb device information
+ * @return error code
+ */
+int usb_hub_add_device(usb_device_t * usb_dev){
+	if(!usb_dev) return EINVAL;
+	usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
+	//create hc connection
+	usb_log_debug("Initializing USB wire abstraction.\n");
+	int opResult = usb_hc_connection_initialize_from_device(
+			&hub_info->connection,
+			hub_info->usb_device->ddf_dev);
+	if(opResult != EOK){
+		usb_log_error("could not initialize connection to device, errno %d\n",
+				opResult);
+		free(hub_info);
+		return opResult;
+	}
 	
-}
-
-
-/**
- * Create hub representation from device information.
- * @param device
- * @return pointer to created structure or NULL in case of error
- */
-usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
-	usb_hub_info_t* result = usb_new(usb_hub_info_t);
-	result->device = device;
-	int opResult;
-	opResult = usb_hub_init_communication(result);
-	if(opResult != EOK){
-		free(result);
-		return NULL;
-	}
-
-	//result->device = device;
-	result->port_count = -1;
-	result->device = device;
-	result->is_default_address_used = false;
-
-	//result->usb_device = usb_new(usb_hcd_attached_device_info_t);
-	size_t received_size;
-
-	// get hub descriptor
-	usb_log_debug("creating serialized descripton");
-	void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
-	usb_hub_descriptor_t * descriptor;
-	usb_log_debug("starting control transaction");
-	usb_endpoint_pipe_start_session(&result->endpoints.control);
-	opResult = usb_request_set_configuration(&result->endpoints.control, 1);
-	assert(opResult == EOK);
-
-	opResult = usb_request_get_descriptor(&result->endpoints.control,
-			USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
-			USB_DESCTYPE_HUB,
-			0, 0, serialized_descriptor,
-			USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
-	usb_endpoint_pipe_end_session(&result->endpoints.control);
-
-	if (opResult != EOK) {
-		usb_log_error("failed when receiving hub descriptor, badcode = %d",
-				opResult);
-		free(serialized_descriptor);
-		free(result);
-		return NULL;
-	}
-	usb_log_debug2("deserializing descriptor");
-	descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
-	if(descriptor==NULL){
-		usb_log_warning("could not deserialize descriptor ");
-		free(result);
-		return NULL;
-	}
-
-	usb_log_info("setting port count to %d",descriptor->ports_count);
-	result->port_count = descriptor->ports_count;
-	result->attached_devs = (usb_hc_attached_device_t*)
-	    malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
-	int i;
-	for(i=0;i<result->port_count+1;++i){
-		result->attached_devs[i].handle=0;
-		result->attached_devs[i].address=0;
-	}
-	usb_log_debug2("freeing data");
-	free(serialized_descriptor);
-	free(descriptor->devices_removable);
-	free(descriptor);
-
-	//finish
-
-	usb_log_info("hub info created");
-
-	return result;
-}
-
-/**
- * Create hub representation and add it into hub list
- * @param dev
- * @return
- */
-int usb_add_hub_device(ddf_dev_t *dev) {
-	usb_log_info("add_hub_device(handle=%d)", (int) dev->handle);
-
-	//dev->ops = &hub_device_ops;
-	(void) hub_device_ops;
-
-	usb_hub_info_t * hub_info = usb_create_hub_info(dev);
-	if(!hub_info){
-		return EINTR;
-	}
-
-	int opResult;
-
-	//perform final configurations
-	usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
-	// process descriptors
-	opResult = usb_hub_process_configuration_descriptors(hub_info);
-	if(opResult != EOK){
-		usb_log_error("could not get configuration descriptors, %d",
-				opResult);
-		return opResult;
-	}
-	//power ports
-	usb_device_request_setup_packet_t request;
-	int port;
-	for (port = 1; port < hub_info->port_count+1; ++port) {
-		usb_hub_set_power_port_request(&request, port);
-		opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control,
-				&request,sizeof(usb_device_request_setup_packet_t), NULL, 0);
-		usb_log_info("powering port %d",port);
-		if (opResult != EOK) {
-			usb_log_warning("something went wrong when setting hub`s %dth port", port);
-		}
-	}
-	//ports powered, hub seems to be enabled
-	usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
-
-	//add the hub to list
-	//is this needed now?
-	fibril_mutex_lock(&usb_hub_list_lock);
-	usb_lst_append(&usb_hub_list, hub_info);
-	fibril_mutex_unlock(&usb_hub_list_lock);
-	usb_log_debug("hub info added to list");
-
+	usb_endpoint_pipe_start_session(hub_info->control_pipe);
+	//set hub configuration
+	opResult = usb_hub_set_configuration(hub_info);
+	if(opResult!=EOK){
+		usb_log_error("could not set hub configuration, errno %d\n",opResult);
+		free(hub_info);
+		return opResult;
+	}
+	//get port count and create attached_devs
+	opResult = usb_hub_get_hub_specific_info(hub_info);
+	if(opResult!=EOK){
+		usb_log_error("could not set hub configuration, errno %d\n",opResult);
+		free(hub_info);
+		return opResult;
+	}
+	usb_endpoint_pipe_end_session(hub_info->control_pipe);
+
+
+	/// \TODO what is this?
 	usb_log_debug("adding to ddf");
-	ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub");
+	ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
+			fun_exposed, "hub");
 	assert(hub_fun != NULL);
 	hub_fun->ops = NULL;
@@ -349,4 +254,5 @@
 	assert(rc == EOK);
 
+	//create fibril for the hub control loop
 	fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
 	if (fid == 0) {
@@ -355,17 +261,7 @@
 	}
 	fibril_add_ready(fid);
-
 	usb_log_debug("hub fibril created");
-	//(void)hub_info;
-	//usb_hub_check_hub_changes();
-	
-	usb_log_info("hub dev added");
-	//address is lost...
-	usb_log_debug("\taddress %d, has %d ports ",
-			//hub_info->endpoints.control.,
-			hub_info->port_count);
-
+	usb_log_debug("has %d ports ",hub_info->port_count);
 	return EOK;
-	//return ENOTSUP;
 }
 
@@ -388,5 +284,5 @@
 	int opResult = usb_hc_release_default_address(&hub->connection);
 	if(opResult!=EOK){
-		usb_log_error("could not release default address, errno %d",opResult);
+		usb_log_error("could not release default address, errno %d\n",opResult);
 		return opResult;
 	}
@@ -405,18 +301,18 @@
 	//if this hub already uses default address, it cannot request it once more
 	if(hub->is_default_address_used) return;
-	int opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
+	usb_log_info("some connection changed\n");
+	assert(hub->control_pipe->hc_phone);
+	int opResult = usb_hub_clear_port_feature(hub->control_pipe,
 				port, USB_HUB_FEATURE_C_PORT_CONNECTION);
 	if(opResult != EOK){
-		usb_log_warning("could not clear port-change-connection flag");
-	}
-
+		usb_log_warning("could not clear port-change-connection flag\n");
+	}
 	usb_device_request_setup_packet_t request;
-	usb_log_info("some connection changed");
-	assert(hub->endpoints.control.hc_phone);
+	
 	//get default address
 	opResult = usb_hc_reserve_default_address(&hub->connection, speed);
 	
 	if (opResult != EOK) {
-		usb_log_warning("cannot assign default address, it is probably used %d",
+		usb_log_warning("cannot assign default address, it is probably used %d\n",
 				opResult);
 		return;
@@ -426,10 +322,10 @@
 	usb_hub_set_reset_port_request(&request, port);
 	opResult = usb_endpoint_pipe_control_write(
-			&hub->endpoints.control,
+			hub->control_pipe,
 			&request,sizeof(usb_device_request_setup_packet_t),
 			NULL, 0
 			);
 	if (opResult != EOK) {
-		usb_log_error("something went wrong when reseting a port %d",opResult);
+		usb_log_error("something went wrong when reseting a port %d\n",opResult);
 		//usb_hub_release_default_address(hc);
 		usb_hub_release_default_address(hub);
@@ -445,13 +341,13 @@
  */
 static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
-		uint16_t port, bool isLowSpeed) {
+		uint16_t port, usb_speed_t speed) {
 
 	int opResult;
-	usb_log_info("finalizing add device");
-	opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
+	usb_log_info("finalizing add device\n");
+	opResult = usb_hub_clear_port_feature(hub->control_pipe,
 	    port, USB_HUB_FEATURE_C_PORT_RESET);
 
 	if (opResult != EOK) {
-		usb_log_error("failed to clear port reset feature");
+		usb_log_error("failed to clear port reset feature\n");
 		usb_hub_release_default_address(hub);
 		return;
@@ -468,7 +364,4 @@
 			&new_device_connection);
 	usb_endpoint_pipe_probe_default_control(&new_device_pipe);
-	/// \TODO get highspeed info
-	usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
-
 
 	/* Request address from host controller. */
@@ -478,10 +371,10 @@
 			);
 	if (new_device_address < 0) {
-		usb_log_error("failed to get free USB address");
+		usb_log_error("failed to get free USB address\n");
 		opResult = new_device_address;
 		usb_hub_release_default_address(hub);
 		return;
 	}
-	usb_log_info("setting new address %d",new_device_address);
+	usb_log_info("setting new address %d\n",new_device_address);
 	//opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
 	//    new_device_address);
@@ -490,5 +383,5 @@
 	usb_endpoint_pipe_end_session(&new_device_pipe);
 	if (opResult != EOK) {
-		usb_log_error("could not set address for new device %d",opResult);
+		usb_log_error("could not set address for new device %d\n",opResult);
 		usb_hub_release_default_address(hub);
 		return;
@@ -505,9 +398,9 @@
 	//??
     opResult = usb_device_register_child_in_devman(new_device_address,
-            hub->connection.hc_handle, hub->device, &child_handle,
+            hub->connection.hc_handle, hub->usb_device->ddf_dev, &child_handle,
             NULL, NULL, NULL);
 
 	if (opResult != EOK) {
-		usb_log_error("could not start driver for new device %d",opResult);
+		usb_log_error("could not start driver for new device %d\n",opResult);
 		return;
 	}
@@ -520,8 +413,8 @@
 			&hub->attached_devs[port]);
 	if (opResult != EOK) {
-		usb_log_error("could not assign address of device in hcd %d",opResult);
-		return;
-	}
-	usb_log_info("new device address %d, handle %zu",
+		usb_log_error("could not assign address of device in hcd %d\n",opResult);
+		return;
+	}
+	usb_log_info("new device address %d, handle %zu\n",
 	    new_device_address, child_handle);
 
@@ -537,8 +430,8 @@
     usb_hub_info_t * hub,uint16_t port) {
 
-	int opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
+	int opResult = usb_hub_clear_port_feature(hub->control_pipe,
 				port, USB_HUB_FEATURE_C_PORT_CONNECTION);
 	if(opResult != EOK){
-		usb_log_warning("could not clear port-change-connection flag");
+		usb_log_warning("could not clear port-change-connection flag\n");
 	}
 	/** \TODO remove device from device manager - not yet implemented in
@@ -559,5 +452,5 @@
 		 */
 	}else{
-		usb_log_warning("this is strange, disconnected device had no address");
+		usb_log_warning("this is strange, disconnected device had no address\n");
 		//device was disconnected before it`s port was reset - return default address
 		usb_hub_release_default_address(hub);
@@ -577,8 +470,8 @@
 		uint16_t port){
 	int opResult;
-	opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
+	opResult = usb_hub_clear_port_feature(hub->control_pipe,
 	    port, USB_HUB_FEATURE_PORT_POWER);
 	if(opResult!=EOK){
-		usb_log_error("cannot power off port %d;  %d",
+		usb_log_error("cannot power off port %d;  %d\n",
 				port, opResult);
 	}
@@ -593,7 +486,7 @@
 static void usb_hub_process_interrupt(usb_hub_info_t * hub, 
         uint16_t port) {
-	usb_log_debug("interrupt at port %d", port);
+	usb_log_debug("interrupt at port %d\n", port);
 	//determine type of change
-	usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
+	usb_endpoint_pipe_t *pipe = hub->control_pipe;
 	
 	int opResult;
@@ -612,9 +505,9 @@
 			);
 	if (opResult != EOK) {
-		usb_log_error("could not get port status");
+		usb_log_error("could not get port status\n");
 		return;
 	}
 	if (rcvd_size != sizeof (usb_port_status_t)) {
-		usb_log_error("received status has incorrect size");
+		usb_log_error("received status has incorrect size\n");
 		return;
 	}
@@ -622,5 +515,5 @@
 	if (usb_port_connect_change(&status)) {
 		if (usb_port_dev_connected(&status)) {
-			usb_log_info("some connection changed");
+			usb_log_info("some connection changed\n");
 			usb_hub_init_add_device(hub, port, usb_port_speed(&status));
 		} else {
@@ -634,5 +527,5 @@
 			usb_hub_over_current(hub,port);
 		}else{
-			usb_log_info("over current condition was auto-resolved on port %d",
+			usb_log_info("over current condition was auto-resolved on port %d\n",
 					port);
 		}
@@ -642,7 +535,7 @@
 		usb_log_info("port reset complete");
 		if (usb_port_enabled(&status)) {
-			usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));
+			usb_hub_finalize_add_device(hub, port, usb_port_speed(&status));
 		} else {
-			usb_log_warning("port reset, but port still not enabled");
+			usb_log_warning("port reset, but port still not enabled\n");
 		}
 	}
@@ -653,9 +546,8 @@
 	usb_port_set_dev_connected(&status, false);
 	if (status>>16) {
-		usb_log_info("there was some unsupported change on port %d: %X",
+		usb_log_info("there was some unsupported change on port %d: %X\n",
 				port,status);
 
 	}
-	/// \TODO handle other changes - is there any?
 }
 
@@ -668,7 +560,8 @@
 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
 	int opResult;
-	opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
+	opResult = usb_endpoint_pipe_start_session(
+			hub_info->status_change_pipe);
 	if(opResult != EOK){
-		usb_log_error("could not initialize communication for hub; %d",
+		usb_log_error("could not initialize communication for hub; %d\n",
 				opResult);
 		return opResult;
@@ -686,5 +579,5 @@
 	 */
 	opResult = usb_endpoint_pipe_read(
-			&hub_info->endpoints.status_change,
+			hub_info->status_change_pipe,
 			change_bitmap, byte_length, &actual_size
 			);
@@ -692,21 +585,21 @@
 	if (opResult != EOK) {
 		free(change_bitmap);
-		usb_log_warning("something went wrong while getting status of hub");
-		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+		usb_log_warning("something went wrong while getting status of hub\n");
+		usb_endpoint_pipe_end_session(hub_info->status_change_pipe);
 		return opResult;
 	}
 	unsigned int port;
-	opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
-	if(opResult!=EOK){
-		usb_log_error("could not start control pipe session %d", opResult);
-		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+	opResult = usb_endpoint_pipe_start_session(hub_info->control_pipe);
+	if(opResult!=EOK){
+		usb_log_error("could not start control pipe session %d\n", opResult);
+		usb_endpoint_pipe_end_session(hub_info->status_change_pipe);
 		return opResult;
 	}
 	opResult = usb_hc_connection_open(&hub_info->connection);
 	if(opResult!=EOK){
-		usb_log_error("could not start host controller session %d",
+		usb_log_error("could not start host controller session %d\n",
 				opResult);
-		usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
-		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+		usb_endpoint_pipe_end_session(hub_info->control_pipe);
+		usb_endpoint_pipe_end_session(hub_info->status_change_pipe);
 		return opResult;
 	}
@@ -722,6 +615,6 @@
 	}
 	usb_hc_connection_close(&hub_info->connection);
-	usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
-	usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+	usb_endpoint_pipe_end_session(hub_info->control_pipe);
+	usb_endpoint_pipe_end_session(hub_info->status_change_pipe);
 	free(change_bitmap);
 	return EOK;
Index: uspace/drv/usbhub/usbhub.h
===================================================================
--- uspace/drv/usbhub/usbhub.h	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/drv/usbhub/usbhub.h	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -45,11 +45,21 @@
 
 #include <usb/pipes.h>
+#include <usb/devdrv.h>
+
+
+/** Hub status-change endpoint description
+ *
+ * For more see usb hub specification in 11.15.1 of
+ */
+extern usb_endpoint_description_t hub_status_change_endpoint_description;
+
+
 
 /* Hub endpoints. */
-typedef struct {
+/*typedef struct {
         usb_endpoint_pipe_t control;
         usb_endpoint_pipe_t status_change;
 } usb_hub_endpoints_t;
-
+*/
 
 
@@ -58,19 +68,36 @@
 	/** Number of ports. */
 	int port_count;
+
 	/** attached device handles, for each port one */
 	usb_hc_attached_device_t * attached_devs;
-	/** General usb device info. */
-	//usb_hcd_attached_device_info_t * usb_device;
-	/** General device info*/
-	ddf_dev_t * device;
+	
 	/** connection to hcd */
-	//usb_device_connection_t connection;
 	usb_hc_connection_t connection;
-	/** */
-	usb_device_connection_t device_connection;
-	/** hub endpoints */
-	usb_hub_endpoints_t endpoints;
 
+	/** default address is used indicator
+	 *
+	 * If default address is requested by this device, it cannot
+	 * be requested by the same hub again, otherwise a deadlock will occur.
+	 */
 	bool is_default_address_used;
+
+	/** convenience pointer to status change pipe
+	 *
+	 * Status change pipe is initialized in usb_device structure. This is
+	 * pointer into this structure, so that it does not have to be
+	 * searched again and again for the 'right pipe'.
+	 */
+	usb_endpoint_pipe_t * status_change_pipe;
+
+	/** convenience pointer to control pipe
+	 *
+	 * Control pipe is initialized in usb_device structure. This is
+	 * pointer into this structure, so that it does not have to be
+	 * searched again and again for the 'right pipe'.
+	 */
+	usb_endpoint_pipe_t * control_pipe;
+
+	/** generic usb device data*/
+	usb_device_t * usb_device;
 } usb_hub_info_t;
 
@@ -80,11 +107,4 @@
  */
 int usb_hub_control_loop(void * hub_info_param);
-
-/** Callback when new hub device is detected.
- *
- * @param dev New device.
- * @return Error code.
- */
-int usb_add_hub_device(ddf_dev_t *dev);
 
 /**
@@ -97,6 +117,5 @@
 
 
-
-
+int usb_hub_add_device(usb_device_t * usb_dev);
 
 #endif
Index: uspace/drv/usbhub/usbhub_private.h
===================================================================
--- uspace/drv/usbhub/usbhub_private.h	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/drv/usbhub/usbhub_private.h	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -58,13 +58,4 @@
 
 
-//************
-//
-// convenience debug printf for usb hub
-//
-//************
-#define dprintf(level, format, ...) \
-	usb_log_printf((level), format "\n", ##__VA_ARGS__)
-
-
 /**
  * Create hub structure instance
@@ -77,47 +68,4 @@
  */
 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device);
-
-/** List of hubs maanged by this driver */
-extern usb_general_list_t usb_hub_list;
-
-/** Lock for hub list*/
-extern fibril_mutex_t usb_hub_list_lock;
-
-
-/**
- * Perform complete control read transaction
- *
- * Manages all three steps of transaction: setup, read and finalize
- * @param phone
- * @param target
- * @param request Request packet
- * @param rcvd_buffer Received data
- * @param rcvd_size
- * @param actual_size Actual size of received data
- * @return error code
- */
-/*
-int usb_drv_sync_control_read(
-    usb_endpoint_pipe_t *pipe,
-    usb_device_request_setup_packet_t * request,
-    void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
-);*/
-
-/**
- * Perform complete control write transaction
- *
- * Manages all three steps of transaction: setup, write and finalize
- * @param phone
- * @param target
- * @param request Request packet to send data
- * @param sent_buffer
- * @param sent_size
- * @return error code
- */
-/*int usb_drv_sync_control_write(
-    usb_endpoint_pipe_t *pipe,
-    usb_device_request_setup_packet_t * request,
-    void * sent_buffer, size_t sent_size
-);*/
 
 /**
@@ -163,5 +111,5 @@
 
 /**
- * @brief create uint8_t array with serialized descriptor
+ * create uint8_t array with serialized descriptor
  *
  * @param descriptor
@@ -171,5 +119,5 @@
 
 /**
- * @brief create deserialized desriptor structure out of serialized descriptor
+ * create deserialized desriptor structure out of serialized descriptor
  *
  * The serialized descriptor must be proper usb hub descriptor,
Index: uspace/drv/usbhub/utils.c
===================================================================
--- uspace/drv/usbhub/utils.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/drv/usbhub/utils.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -88,5 +88,5 @@
 
 	if (sdescriptor[1] != USB_DESCTYPE_HUB) {
-		dprintf(1,"[usb_hub] wrong descriptor %x\n",sdescriptor[1]);
+		usb_log_warning("trying to deserialize wrong descriptor %x\n",sdescriptor[1]);
 		return NULL;
 	}
@@ -103,5 +103,5 @@
 			? 1 : 0);
 	result->devices_removable = (uint8_t*) malloc(var_size);
-	//printf("[usb_hub] getting removable devices data \n");
+
 	size_t i;
 	for (i = 0; i < var_size; ++i) {
@@ -111,92 +111,4 @@
 }
 
-//control transactions
-/*
-int usb_drv_sync_control_read(
-    int phone, usb_target_t target,
-    usb_device_request_setup_packet_t * request,
-    void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
-) {
-	usb_handle_t handle;
-	int opResult;
-	//setup
-	opResult = usb_drv_async_control_read_setup(phone, target,
-	    request, sizeof (usb_device_request_setup_packet_t),
-	    &handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	opResult = usb_drv_async_wait_for(handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	//read
-	opResult = usb_drv_async_control_read_data(phone, target,
-			rcvd_buffer, rcvd_size, actual_size,
-			&handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	opResult = usb_drv_async_wait_for(handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	//finalize
-	opResult = usb_drv_async_control_read_status(phone, target,
-			&handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	opResult = usb_drv_async_wait_for(handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	return EOK;
-}
-
-int usb_drv_sync_control_write(
-    int phone, usb_target_t target,
-    usb_device_request_setup_packet_t * request,
-    void * sent_buffer, size_t sent_size
-) {
-	usb_handle_t handle;
-	int opResult;
-	//setup
-	opResult = usb_drv_async_control_write_setup(phone, target,
-	    request, sizeof (usb_device_request_setup_packet_t),
-	    &handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	opResult = usb_drv_async_wait_for(handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	//write
-	opResult = usb_drv_async_control_write_data(phone, target,
-			sent_buffer, sent_size,
-			&handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	opResult = usb_drv_async_wait_for(handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	//finalize
-	opResult = usb_drv_async_control_write_status(phone, target,
-	    &handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	opResult = usb_drv_async_wait_for(handle);
-	if (opResult != EOK) {
-		return opResult;
-	}
-	return EOK;
-}
-
-*/
-
 
 
Index: uspace/lib/usb/include/usb/devdrv.h
===================================================================
--- uspace/lib/usb/include/usb/devdrv.h	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/lib/usb/include/usb/devdrv.h	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -79,5 +79,10 @@
 	 */
 	const char *name;
-	/** Expected endpoints description. */
+	/** Expected endpoints description, excluding default control endpoint.
+	 *
+	 * It MUST be of size expected_enpoints_count(excluding default ctrl) + 1
+	 * where the last record MUST BE NULL, otherwise catastrophic things may
+	 * happen.
+	 */
 	usb_endpoint_description_t **endpoints;
 	/** Driver ops. */
Index: uspace/lib/usb/src/devdrv.c
===================================================================
--- uspace/lib/usb/src/devdrv.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/lib/usb/src/devdrv.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -206,5 +206,5 @@
  * @return Error code.
  */
-static int initialize_pipes(usb_driver_t *drv, usb_device_t *dev)
+static int initialize_pipes(usb_device_t *dev)
 {
 	int rc;
@@ -284,5 +284,5 @@
 	dev->driver_data = NULL;
 
-	rc = initialize_pipes(driver, dev);
+	rc = initialize_pipes(dev);
 	if (rc != EOK) {
 		free(dev);
Index: uspace/lib/usb/src/pipes.c
===================================================================
--- uspace/lib/usb/src/pipes.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/lib/usb/src/pipes.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -42,4 +42,6 @@
 #include <assert.h>
 
+#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
+
 /** Tell USB address assigned to given device.
  *
@@ -150,9 +152,28 @@
 	}
 
-	my_address = get_my_address(parent_phone, dev);
-	if (my_address < 0) {
-		rc = my_address;
-		goto leave;
-	}
+	/*
+	 * Asking for "my" address may require several attempts.
+	 * That is because following scenario may happen:
+	 *  - parent driver (i.e. driver of parent device) announces new device
+	 *    and devman launches current driver
+	 *  - parent driver is preempted and thus does not send address-handle
+	 *    binding to HC driver
+	 *  - this driver gets here and wants the binding
+	 *  - the HC does not know the binding yet and thus it answers ENOENT
+	 *  So, we need to wait for the HC to learn the binding.
+	 */
+	do {
+		my_address = get_my_address(parent_phone, dev);
+
+		if (my_address == ENOENT) {
+			/* Be nice, let other fibrils run and try again. */
+			async_usleep(IPC_AGAIN_DELAY);
+		} else if (my_address < 0) {
+			/* Some other problem, no sense trying again. */
+			rc = my_address;
+			goto leave;
+		}
+
+	} while (my_address < 0);
 
 	rc = usb_device_connection_initialize(connection,
Index: uspace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision 81dce9f771a48fddabf8296e844817d7c79b4879)
+++ uspace/lib/usb/src/recognise.c	(revision 2e1d5d702aa16e31df05fdd7e11092c7133b880a)
@@ -247,4 +247,7 @@
 #undef VENDOR_ONLY_FMT
 #undef VENDOR_ONLY_ARGS
+
+	/* As a last resort, try fallback driver. */
+	ADD_MATCHID_OR_RETURN(matches, 10, "usb&interface&fallback");
 
 	return EOK;
@@ -291,4 +294,7 @@
 	}
 	
+	/* As a last resort, try fallback driver. */
+	ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback");
+
 	return EOK;
 }
