Index: pace/app/netstart/self_test.c
===================================================================
--- uspace/app/netstart/self_test.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ 	(revision )
@@ -1,334 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 net
- * @{
- */
-
-/** @file
- * Networking self-tests implementation.
- *
- */
-
-#include <errno.h>
-#include <malloc.h>
-#include <stdio.h>
-
-#include <net_checksum.h>
-#include <adt/int_map.h>
-#include <adt/char_map.h>
-#include <adt/generic_char_map.h>
-#include <adt/measured_strings.h>
-#include <adt/dynamic_fifo.h>
-
-#include "self_test.h"
-
-/** Test the statement, compare the result and evaluate.
- *
- * @param[in] statement The statement to test.
- * @param[in] result    The expected result.
- *
- */
-#define TEST(statement, result) \
-	do { \
-		printf("\n\t%s == %s", #statement, #result); \
-		if ((statement) != (result)) { \
-			printf("\tfailed\n"); \
-			fprintf(stderr, "\nNetwork self-test failed\n"); \
-			return EINVAL; \
-		} else \
-			printf("\tOK"); \
-	} while (0)
-
-#define XMALLOC(var, type) \
-	do { \
-		(var) = (type *) malloc(sizeof(type)); \
-		if ((var) == NULL) { \
-			fprintf(stderr, "\nMemory allocation error\n"); \
-			return ENOMEM; \
-		} \
-	} while (0)
-
-GENERIC_CHAR_MAP_DECLARE(int_char_map, int);
-GENERIC_CHAR_MAP_IMPLEMENT(int_char_map, int);
-
-GENERIC_FIELD_DECLARE(int_field, int);
-GENERIC_FIELD_IMPLEMENT(int_field, int);
-
-INT_MAP_DECLARE(int_map, int);
-INT_MAP_IMPLEMENT(int_map, int);
-
-/** Self-test start function.
- *
- * Run all self-tests.
- *
- * @returns EOK on success.
- * @returns The first error occurred.
- *
- */
-int self_test(void)
-{
-	printf("Running networking self-tests\n");
-	
-	printf("\nChar map test");
-	char_map_t cm;
-	
-	TEST(char_map_update(&cm, "ucho", 0, 3), EINVAL);
-	TEST(char_map_initialize(&cm), EOK);
-	TEST(char_map_exclude(&cm, "bla", 0), CHAR_MAP_NULL);
-	TEST(char_map_find(&cm, "bla", 0), CHAR_MAP_NULL);
-	TEST(char_map_add(&cm, "bla", 0, 1), EOK);
-	TEST(char_map_find(&cm, "bla", 0), 1);
-	TEST(char_map_add(&cm, "bla", 0, 10), EEXISTS);
-	TEST(char_map_update(&cm, "bla", 0, 2), EOK);
-	TEST(char_map_find(&cm, "bla", 0), 2);
-	TEST(char_map_update(&cm, "ucho", 0, 2), EOK);
-	TEST(char_map_exclude(&cm, "bla", 0), 2);
-	TEST(char_map_exclude(&cm, "bla", 0), CHAR_MAP_NULL);
-	TEST(char_map_find(&cm, "ucho", 0), 2);
-	TEST(char_map_update(&cm, "ucho", 0, 3), EOK);
-	TEST(char_map_find(&cm, "ucho", 0), 3);
-	TEST(char_map_add(&cm, "blabla", 0, 5), EOK);
-	TEST(char_map_find(&cm, "blabla", 0), 5);
-	TEST(char_map_add(&cm, "bla", 0, 6), EOK);
-	TEST(char_map_find(&cm, "bla", 0), 6);
-	TEST(char_map_exclude(&cm, "bla", 0), 6);
-	TEST(char_map_find(&cm, "bla", 0), CHAR_MAP_NULL);
-	TEST(char_map_find(&cm, "blabla", 0), 5);
-	TEST(char_map_add(&cm, "auto", 0, 7), EOK);
-	TEST(char_map_find(&cm, "auto", 0), 7);
-	TEST(char_map_add(&cm, "kara", 0, 8), EOK);
-	TEST(char_map_find(&cm, "kara", 0), 8);
-	TEST(char_map_add(&cm, "nic", 0, 9), EOK);
-	TEST(char_map_find(&cm, "nic", 0), 9);
-	TEST(char_map_find(&cm, "blabla", 0), 5);
-	TEST(char_map_add(&cm, "micnicnic", 5, 9), EOK);
-	TEST(char_map_find(&cm, "micni", 0), 9);
-	TEST(char_map_find(&cm, "micnicn", 5), 9);
-	TEST(char_map_add(&cm, "\x10\x0\x2\x2", 4, 15), EOK);
-	TEST(char_map_find(&cm, "\x10\x0\x2\x2", 4), 15);
-	
-	TEST((char_map_destroy(&cm), EOK), EOK);
-	TEST(char_map_update(&cm, "ucho", 0, 3), EINVAL);
-	
-	printf("\nCRC computation test");
-	uint32_t value;
-	
-	TEST(value = ~compute_crc32(~0, "123456789", 8 * 9), 0xcbf43926);
-	TEST(value = ~compute_crc32(~0, "1", 8), 0x83dcefb7);
-	TEST(value = ~compute_crc32(~0, "12", 8 * 2), 0x4f5344cd);
-	TEST(value = ~compute_crc32(~0, "123", 8 * 3), 0x884863d2);
-	TEST(value = ~compute_crc32(~0, "1234", 8 * 4), 0x9be3e0a3);
-	TEST(value = ~compute_crc32(~0, "12345678", 8 * 8), 0x9ae0daaf);
-	TEST(value = ~compute_crc32(~0, "ahoj pane", 8 * 9), 0x5fc3d706);
-	
-	printf("\nDynamic fifo test");
-	dyn_fifo_t fifo;
-	
-	TEST(dyn_fifo_push(&fifo, 1, 0), EINVAL);
-	TEST(dyn_fifo_initialize(&fifo, 1), EOK);
-	TEST(dyn_fifo_push(&fifo, 1, 0), EOK);
-	TEST(dyn_fifo_pop(&fifo), 1);
-	TEST(dyn_fifo_pop(&fifo), ENOENT);
-	TEST(dyn_fifo_push(&fifo, 2, 1), EOK);
-	TEST(dyn_fifo_push(&fifo, 3, 1), ENOMEM);
-	TEST(dyn_fifo_push(&fifo, 3, 0), EOK);
-	TEST(dyn_fifo_pop(&fifo), 2);
-	TEST(dyn_fifo_pop(&fifo), 3);
-	TEST(dyn_fifo_push(&fifo, 4, 2), EOK);
-	TEST(dyn_fifo_push(&fifo, 5, 2), EOK);
-	TEST(dyn_fifo_push(&fifo, 6, 2), ENOMEM);
-	TEST(dyn_fifo_push(&fifo, 6, 5), EOK);
-	TEST(dyn_fifo_push(&fifo, 7, 5), EOK);
-	TEST(dyn_fifo_pop(&fifo), 4);
-	TEST(dyn_fifo_pop(&fifo), 5);
-	TEST(dyn_fifo_push(&fifo, 8, 5), EOK);
-	TEST(dyn_fifo_push(&fifo, 9, 5), EOK);
-	TEST(dyn_fifo_push(&fifo, 10, 6), EOK);
-	TEST(dyn_fifo_push(&fifo, 11, 6), EOK);
-	TEST(dyn_fifo_pop(&fifo), 6);
-	TEST(dyn_fifo_pop(&fifo), 7);
-	TEST(dyn_fifo_push(&fifo, 12, 6), EOK);
-	TEST(dyn_fifo_push(&fifo, 13, 6), EOK);
-	TEST(dyn_fifo_push(&fifo, 14, 6), ENOMEM);
-	TEST(dyn_fifo_push(&fifo, 14, 8), EOK);
-	TEST(dyn_fifo_pop(&fifo), 8);
-	TEST(dyn_fifo_pop(&fifo), 9);
-	TEST(dyn_fifo_pop(&fifo), 10);
-	TEST(dyn_fifo_pop(&fifo), 11);
-	TEST(dyn_fifo_pop(&fifo), 12);
-	TEST(dyn_fifo_pop(&fifo), 13);
-	TEST(dyn_fifo_pop(&fifo), 14);
-	TEST(dyn_fifo_destroy(&fifo), EOK);
-	TEST(dyn_fifo_push(&fifo, 1, 0), EINVAL);
-	
-	printf("\nGeneric char map test");
-	
-	int *x;
-	int *y;
-	int *z;
-	int *u;
-	int *v;
-	int *w;
-	
-	XMALLOC(x, int);
-	XMALLOC(y, int);
-	XMALLOC(z, int);
-	XMALLOC(u, int);
-	XMALLOC(v, int);
-	XMALLOC(w, int);
-	
-	int_char_map_t icm;
-	icm.magic = 0;
-	
-	TEST(int_char_map_add(&icm, "ucho", 0, z), EINVAL);
-	TEST(int_char_map_initialize(&icm), EOK);
-	TEST((int_char_map_exclude(&icm, "bla", 0), EOK), EOK);
-	TEST(int_char_map_find(&icm, "bla", 0), NULL);
-	TEST(int_char_map_add(&icm, "bla", 0, x), EOK);
-	TEST(int_char_map_find(&icm, "bla", 0), x);
-	TEST(int_char_map_add(&icm, "bla", 0, y), EEXISTS);
-	TEST((int_char_map_exclude(&icm, "bla", 0), EOK), EOK);
-	TEST((int_char_map_exclude(&icm, "bla", 0), EOK), EOK);
-	TEST(int_char_map_add(&icm, "blabla", 0, v), EOK);
-	TEST(int_char_map_find(&icm, "blabla", 0), v);
-	TEST(int_char_map_add(&icm, "bla", 0, w), EOK);
-	TEST(int_char_map_find(&icm, "bla", 0), w);
-	TEST((int_char_map_exclude(&icm, "bla", 0), EOK), EOK);
-	TEST(int_char_map_find(&icm, "bla", 0), NULL);
-	TEST(int_char_map_find(&icm, "blabla", 0), v);
-	TEST(int_char_map_add(&icm, "auto", 0, u), EOK);
-	TEST(int_char_map_find(&icm, "auto", 0), u);
-	TEST((int_char_map_destroy(&icm), EOK), EOK);
-	TEST(int_char_map_add(&icm, "ucho", 0, z), EINVAL);
-	
-	printf("\nGeneric field test");
-	
-	XMALLOC(x, int);
-	XMALLOC(y, int);
-	XMALLOC(z, int);
-	XMALLOC(u, int);
-	XMALLOC(v, int);
-	XMALLOC(w, int);
-	
-	int_field_t gf;
-	gf.magic = 0;
-	
-	TEST(int_field_add(&gf, x), EINVAL);
-	TEST(int_field_count(&gf), -1);
-	TEST(int_field_initialize(&gf), EOK);
-	TEST(int_field_count(&gf), 0);
-	TEST(int_field_get_index(&gf, 1), NULL);
-	TEST(int_field_add(&gf, x), 0);
-	TEST(int_field_get_index(&gf, 0), x);
-	TEST((int_field_exclude_index(&gf, 0), EOK), EOK);
-	TEST(int_field_get_index(&gf, 0), NULL);
-	TEST(int_field_add(&gf, y), 1);
-	TEST(int_field_get_index(&gf, 1), y);
-	TEST(int_field_add(&gf, z), 2);
-	TEST(int_field_get_index(&gf, 2), z);
-	TEST(int_field_get_index(&gf, 1), y);
-	TEST(int_field_count(&gf), 3);
-	TEST(int_field_add(&gf, u), 3);
-	TEST(int_field_get_index(&gf, 3), u);
-	TEST(int_field_add(&gf, v), 4);
-	TEST(int_field_get_index(&gf, 4), v);
-	TEST(int_field_add(&gf, w), 5);
-	TEST(int_field_get_index(&gf, 5), w);
-	TEST(int_field_count(&gf), 6);
-	TEST((int_field_exclude_index(&gf, 1), EOK), EOK);
-	TEST(int_field_get_index(&gf, 1), NULL);
-	TEST(int_field_get_index(&gf, 3), u);
-	TEST((int_field_exclude_index(&gf, 7), EOK), EOK);
-	TEST(int_field_get_index(&gf, 3), u);
-	TEST(int_field_get_index(&gf, 5), w);
-	TEST((int_field_exclude_index(&gf, 4), EOK), EOK);
-	TEST(int_field_get_index(&gf, 4), NULL);
-	TEST((int_field_destroy(&gf), EOK), EOK);
-	TEST(int_field_count(&gf), -1);
-	
-	printf("\nInt map test");
-	
-	XMALLOC(x, int);
-	XMALLOC(y, int);
-	XMALLOC(z, int);
-	XMALLOC(u, int);
-	XMALLOC(v, int);
-	XMALLOC(w, int);
-	
-	int_map_t im;
-	im.magic = 0;
-	
-	TEST(int_map_add(&im, 1, x), EINVAL);
-	TEST(int_map_count(&im), -1);
-	TEST(int_map_initialize(&im), EOK);
-	TEST(int_map_count(&im), 0);
-	TEST(int_map_find(&im, 1), NULL);
-	TEST(int_map_add(&im, 1, x), 0);
-	TEST(int_map_find(&im, 1), x);
-	TEST((int_map_exclude(&im, 1), EOK), EOK);
-	TEST(int_map_find(&im, 1), NULL);
-	TEST(int_map_add(&im, 1, y), 1);
-	TEST(int_map_find(&im, 1), y);
-	TEST(int_map_add(&im, 4, z), 2);
-	TEST(int_map_get_index(&im, 2), z);
-	TEST(int_map_find(&im, 4), z);
-	TEST(int_map_find(&im, 1), y);
-	TEST(int_map_count(&im), 3);
-	TEST(int_map_add(&im, 2, u), 3);
-	TEST(int_map_find(&im, 2), u);
-	TEST(int_map_add(&im, 3, v), 4);
-	TEST(int_map_find(&im, 3), v);
-	TEST(int_map_get_index(&im, 4), v);
-	TEST(int_map_add(&im, 6, w), 5);
-	TEST(int_map_find(&im, 6), w);
-	TEST(int_map_count(&im), 6);
-	TEST((int_map_exclude(&im, 1), EOK), EOK);
-	TEST(int_map_find(&im, 1), NULL);
-	TEST(int_map_find(&im, 2), u);
-	TEST((int_map_exclude(&im, 7), EOK), EOK);
-	TEST(int_map_find(&im, 2), u);
-	TEST(int_map_find(&im, 6), w);
-	TEST((int_map_exclude_index(&im, 4), EOK), EOK);
-	TEST(int_map_get_index(&im, 4), NULL);
-	TEST(int_map_find(&im, 3), NULL);
-	TEST((int_map_destroy(&im), EOK), EOK);
-	TEST(int_map_count(&im), -1);
-	
-	printf("\nMeasured strings test");
-	
-	measured_string_ref string =
-	    measured_string_create_bulk("I am a measured string!", 0);
-	printf("\n%x, %s at %x of %d\n", string, string->value, string->value,
-	    string->length);
-	
-	return EOK;
-}
-
-/** @}
- */
Index: pace/app/netstart/self_test.h
===================================================================
--- uspace/app/netstart/self_test.h	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * 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 net
- * @{
- */
-
-#ifndef __SELF_TEST_H__
-#define __SELF_TEST_H__
-
-extern int self_test(void);
-
-#endif
-
-/** @}
- */
Index: uspace/drv/uhci/main.c
===================================================================
--- uspace/drv/uhci/main.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/drv/uhci/main.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -27,4 +27,5 @@
  */
 #include <usb/hcdhubd.h>
+#include <usb_iface.h>
 #include <usb/debug.h>
 #include <errno.h>
@@ -32,6 +33,20 @@
 #include "uhci.h"
 
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
+{
+	/* This shall be called only for the UHCI itself. */
+	assert(dev->parent == NULL);
+
+	*handle = dev->handle;
+	return EOK;
+}
+
+static usb_iface_t hc_usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle
+};
+
 static device_ops_t uhci_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &uhci_iface,
+	.interfaces[USB_DEV_IFACE] = &hc_usb_iface,
+	.interfaces[USBHC_DEV_IFACE] = &uhci_iface
 };
 
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/drv/usbhub/usbhub.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -37,5 +37,5 @@
 #include <errno.h>
 
-#include <usbhc_iface.h>
+#include <usb_iface.h>
 #include <usb/usbdrv.h>
 #include <usb/descriptor.h>
@@ -46,4 +46,12 @@
 #include "usbhub_private.h"
 #include "port_status.h"
+
+static usb_iface_t hub_usb_iface = {
+	.get_hc_handle = usb_drv_find_hc
+};
+
+static device_ops_t hub_device_ops = {
+	.interfaces[USB_DEV_IFACE] = &hub_usb_iface
+};
 
 //*********************************************
@@ -135,8 +143,12 @@
 	 * connected devices.
 	 */
+	dev->ops = &hub_device_ops;
 
 	//create the hub structure
 	//get hc connection
-	int hc = usb_drv_hc_connect(dev, 0);
+	int hc = usb_drv_hc_connect_auto(dev, 0);
+	if (hc < 0) {
+		return hc;
+	}
 
 	usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
@@ -464,5 +476,5 @@
 		 * Connect to respective HC.
 		 */
-		int hc = usb_drv_hc_connect(hub_info->device, 0);
+		int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
 		if (hc < 0) {
 			continue;
Index: uspace/drv/usbkbd/main.c
===================================================================
--- uspace/drv/usbkbd/main.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/drv/usbkbd/main.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -190,5 +190,5 @@
 	// get phone to my HC and save it as my parent's phone
 	// TODO: maybe not a good idea if DDF will use parent_phone
-	kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0);
+	kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
 
 	kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
@@ -325,5 +325,5 @@
 	 * Not supported yet, skip..
 	 */
-//	int phone = usb_drv_hc_connect(dev, 0);
+//	int phone = usb_drv_hc_connect_auto(dev, 0);
 //	if (phone < 0) {
 //		/*
Index: uspace/drv/vhc/hcd.c
===================================================================
--- uspace/drv/vhc/hcd.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/drv/vhc/hcd.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -46,4 +46,5 @@
 
 #include <usb/usb.h>
+#include <usb_iface.h>
 #include "vhcd.h"
 #include "hc.h"
@@ -52,6 +53,20 @@
 #include "conn.h"
 
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
+{
+	/* This shall be called only for VHC device. */
+	assert(dev->parent == NULL);
+
+	*handle = dev->handle;
+	return EOK;
+}
+
+static usb_iface_t hc_usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle
+};
+
 static device_ops_t vhc_ops = {
 	.interfaces[USBHC_DEV_IFACE] = &vhc_iface,
+	.interfaces[USB_DEV_IFACE] = &hc_usb_iface,
 	.default_handler = default_connection_handler
 };
Index: uspace/drv/vhc/hub.c
===================================================================
--- uspace/drv/vhc/hub.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/drv/vhc/hub.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -79,5 +79,5 @@
 	device_t *hc_dev = (device_t *) arg;
 
-	int hc = usb_drv_hc_connect(hc_dev, IPC_FLAG_BLOCKING);
+	int hc = usb_drv_hc_connect(hc_dev, hc_dev->handle, IPC_FLAG_BLOCKING);
 	if (hc < 0) {
 		printf(NAME ": failed to register root hub\n");
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -39,4 +39,6 @@
 	CHAR_DEV_IFACE,
 
+	/** Interface provided by any USB device. */
+	USB_DEV_IFACE,
 	/** Interface provided by USB host controller. */
 	USBHC_DEV_IFACE,
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/drv/Makefile	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -36,4 +36,5 @@
 	generic/dev_iface.c \
 	generic/remote_res.c \
+	generic/remote_usb.c \
 	generic/remote_usbhc.c \
 	generic/remote_char.c
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/drv/generic/dev_iface.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -39,4 +39,5 @@
 #include "remote_res.h"
 #include "remote_char.h"
+#include "remote_usb.h"
 #include "remote_usbhc.h"
 
@@ -45,4 +46,5 @@
 		&remote_res_iface,
 		&remote_char_iface,
+		&remote_usb_iface,
 		&remote_usbhc_iface
 	}
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
+++ uspace/lib/drv/generic/remote_usb.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+#include "usb_iface.h"
+#include "driver.h"
+
+
+static void remote_usb_get_hc_handle(device_t *, void *, ipc_callid_t, ipc_call_t *);
+//static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
+
+/** Remote USB interface operations. */
+static remote_iface_func_ptr_t remote_usb_iface_ops [] = {
+	remote_usb_get_hc_handle
+};
+
+/** Remote USB interface structure.
+ */
+remote_iface_t remote_usb_iface = {
+	.method_count = sizeof(remote_usb_iface_ops) /
+	    sizeof(remote_usb_iface_ops[0]),
+	.methods = remote_usb_iface_ops
+};
+
+
+void remote_usb_get_hc_handle(device_t *device, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	usb_iface_t *usb_iface = (usb_iface_t *) iface;
+
+	if (usb_iface->get_hc_handle == NULL) {
+		ipc_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	devman_handle_t handle;
+	int rc = usb_iface->get_hc_handle(device, &handle);
+	if (rc != EOK) {
+		ipc_answer_0(callid, rc);
+	}
+
+	ipc_answer_1(callid, EOK, (sysarg_t) handle);
+}
+
+
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -59,5 +59,5 @@
 //static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
 
-/** Remote USB interface operations. */
+/** Remote USB host controller interface operations. */
 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
 	remote_usbhc_get_address,
@@ -84,5 +84,5 @@
 };
 
-/** Remote USB interface structure.
+/** Remote USB host controller interface structure.
  */
 remote_iface_t remote_usbhc_iface = {
Index: uspace/lib/drv/include/remote_usb.h
===================================================================
--- uspace/lib/drv/include/remote_usb.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
+++ uspace/lib/drv/include/remote_usb.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 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 libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USB_H_
+#define LIBDRV_REMOTE_USB_H_
+
+remote_iface_t remote_usb_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
+++ uspace/lib/drv/include/usb_iface.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 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 libdrv usb
+ * @{
+ */
+/** @file
+ * @brief USB interface definition.
+ */
+
+#ifndef LIBDRV_USB_IFACE_H_
+#define LIBDRV_USB_IFACE_H_
+
+#include "driver.h"
+#include <usb/usb.h>
+typedef enum {
+	/** Tell devman handle of device host controller.
+	 * Parameters:
+	 * - none
+	 * Answer:
+	 * - EOK - request processed without errors
+	 * - ENOTSUP - this indicates invalid USB driver
+	 * Parameters of the answer:
+	 * - devman handle of HC caller is physically connected to
+	 */
+	IPC_M_USB_GET_HOST_CONTROLLER_HANDLE
+} usb_iface_funcs_t;
+
+/** USB device communication interface. */
+typedef struct {
+	int (*get_hc_handle)(device_t *, devman_handle_t *);
+} usb_iface_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief USB interface definition.
+ * @brief USB host controller interface definition.
  */
 
@@ -226,5 +226,5 @@
     usbhc_iface_transfer_in_callback_t, void *);
 
-/** USB devices communication interface. */
+/** USB host controller communication interface. */
 typedef struct {
 	int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
Index: uspace/lib/packet/include/net_byteorder.h
===================================================================
--- uspace/lib/packet/include/net_byteorder.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
+++ uspace/lib/packet/include/net_byteorder.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Host - network byte order manipulation functions.
+ */
+
+#ifndef __NET_BYTEORDER_H__
+#define __NET_BYTEORDER_H__
+
+#include <byteorder.h>
+#include <sys/types.h>
+
+
+/** Converts the given short number (16 bit) from the host byte order to the network byte order (big endian).
+ *  @param[in] number The number in the host byte order to be converted.
+ *  @returns The number in the network byte order.
+ */
+#define htons(number)		host2uint16_t_be(number)
+
+/** Converts the given long number (32 bit) from the host byte order to the network byte order (big endian).
+ *  @param[in] number The number in the host byte order to be converted.
+ *  @returns The number in the network byte order.
+ */
+#define htonl(number)		host2uint32_t_be(number)
+
+/** Converts the given short number (16 bit) from the network byte order (big endian) to the host byte order.
+ *  @param[in] number The number in the network byte order to be converted.
+ *  @returns The number in the host byte order.
+ */
+#define ntohs(number) 	uint16_t_be2host(number)
+
+/** Converts the given long number (32 bit) from the network byte order (big endian) to the host byte order.
+ *  @param[in] number The number in the network byte order to be converted.
+ *  @returns The number in the host byte order.
+ */
+#define ntohl(number)		uint32_t_be2host(number)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/packet/include/net_err.h
===================================================================
--- uspace/lib/packet/include/net_err.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
+++ uspace/lib/packet/include/net_err.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * 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 net
+ * @{
+ */
+
+/** @file
+ * Common error processing codes and routines.
+ */
+
+#ifndef __NET_ERR_H__
+#define __NET_ERR_H__
+
+#include <errno.h>
+
+#ifdef CONFIG_DEBUG
+	#include <stdio.h>
+	#include <str_error.h>
+#endif
+
+/** An actual stored error code.
+ *
+ */
+#define ERROR_CODE  error_check_return_value
+
+/** An error processing routines declaration.
+ *
+ * This has to be declared in the block where the error processing
+ * is desired.
+ *
+ */
+#define ERROR_DECLARE  int ERROR_CODE
+
+/** Store the value as an error code and checks if an error occurred.
+ *
+ * @param[in] value The value to be checked. May be a function call.
+ * @return False if the value indicates success (EOK).
+ * @return True otherwise.
+ *
+ */
+#ifdef CONFIG_DEBUG
+
+#define ERROR_OCCURRED(value) \
+	(((ERROR_CODE = (value)) != EOK) \
+	&& ({ \
+		fprintf(stderr, "libsocket error at %s:%d (%s)\n", \
+		__FILE__, __LINE__, str_error(ERROR_CODE)); \
+		1; \
+	}))
+
+#else
+
+#define ERROR_OCCURRED(value)  ((ERROR_CODE = (value)) != EOK)
+
+#endif
+
+/** Error propagation
+ *
+ * Check if an error occurred and immediately exit the actual
+ * function returning the error code.
+ *
+ * @param[in] value The value to be checked. May be a function call.
+ *
+ */
+
+#define ERROR_PROPAGATE(value) \
+	if (ERROR_OCCURRED(value)) \
+		return ERROR_CODE
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/packet/include/socket_errno.h
===================================================================
--- uspace/lib/packet/include/socket_errno.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
+++ uspace/lib/packet/include/socket_errno.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * 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 net
+ *  @{
+ */
+
+/** @file
+ *  Socket error codes.
+ *  Based on BSD.
+ */
+
+#ifndef __NET_SOCKET_ERR_H__
+#define __NET_SOCKET_ERR_H__
+
+#include <errno.h>
+
+/** @name Socket error codes definitions
+ */
+/*@{*/
+
+////#define EINTR			(-10004)
+////#define EBADF			(-10009)
+//#define EACCES			(-10013)
+//#define EFAULT			(-10014)
+////#define EINVAL			(-10022)
+////#define EMFILE			(-10024)
+//#define EWOULDBLOCK		(-10035)
+
+/** An API function is called while another blocking function is in progress.
+ */
+#define EINPROGRESS		(-10036)
+
+//#define EALREADY		(-10037)
+
+/** The socket identifier is not valid.
+ */
+#define ENOTSOCK		(-10038)
+
+/** The destination address required.
+ */
+#define EDESTADDRREQ	(-10039)
+
+//#define EMSGSIZE		(-10040)
+//#define EPROTOTYPE		(-10041)
+//#define ENOPROTOOPT		(-10042)
+
+/** Protocol is not supported.
+ */
+#define EPROTONOSUPPORT	(-10043)
+
+/** Socket type is not supported.
+ */
+#define ESOCKTNOSUPPORT	(-10044)
+
+//#define EOPNOTSUPP		(-10045)
+
+/** Protocol family is not supported.
+ */
+#define EPFNOSUPPORT	(-10046)
+
+/** Address family is not supported.
+ */
+#define EAFNOSUPPORT	(-10047)
+
+/** Address is already in use.
+ */
+#define EADDRINUSE		(-10048)
+
+//#define EADDRNOTAVAIL	(-10049)
+/* May be reported at any time if the implementation detects an underlying failure.
+ */
+//#define ENETDOWN		(-10050)
+//#define ENETUNREACH		(-10051)
+//#define ENETRESET		(-10052)
+//#define ECONNABORTED	(-10053)
+//#define ECONNRESET		(-10054)
+//#define ENOBUFS			(-10055)
+//#define EISCONN			(-10056)
+
+/** The socket is not connected or bound.
+ */
+#define ENOTCONN		(-10057)
+
+//#define ESHUTDOWN		(-10058)
+//#define ETOOMANYREFS	(-10059)
+//#define ETIMEDOUT		(-10060)
+//#define ECONNREFUSED	(-10061)
+//#define ELOOP			(-10062)
+////#define ENAMETOOLONG	(-10063)
+//#define EHOSTDOWN		(-10064)
+//#define EHOSTUNREACH	(-10065)
+//#define HOST_NOT_FOUND	(-11001)
+
+/** The requested operation was not performed.
+ *  Try again later.
+ */
+#define TRY_AGAIN		(-11002)
+
+//#define NO_RECOVERY		(-11003)
+
+/** No data.
+ */
+#define NO_DATA			(-11004)
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/usb/include/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/include/usb/usbdrv.h	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/usb/include/usb/usbdrv.h	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -41,5 +41,7 @@
 #include <usb/descriptor.h>
 
-int usb_drv_hc_connect(device_t *, unsigned int);
+int usb_drv_find_hc(device_t *, devman_handle_t *);
+int usb_drv_hc_connect(device_t *, devman_handle_t, unsigned int);
+int usb_drv_hc_connect_auto(device_t *, unsigned int);
 
 int usb_drv_reserve_default_address(int);
Index: uspace/lib/usb/src/hcdhubd.c
===================================================================
--- uspace/lib/usb/src/hcdhubd.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/usb/src/hcdhubd.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -36,4 +36,5 @@
 #include <usb/devreq.h>
 #include <usbhc_iface.h>
+#include <usb_iface.h>
 #include <usb/descriptor.h>
 #include <driver.h>
@@ -45,4 +46,33 @@
 #include "hcdhubd_private.h"
 
+
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
+{
+	assert(dev);
+	assert(dev->parent != NULL);
+
+	device_t *parent = dev->parent;
+
+	if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
+		usb_iface_t *usb_iface
+		    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
+		assert(usb_iface != NULL);
+		if (usb_iface->get_hc_handle) {
+			int rc = usb_iface->get_hc_handle(parent, handle);
+			return rc;
+		}
+	}
+
+	return ENOTSUP;
+}
+
+static usb_iface_t usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle
+};
+
+static device_ops_t child_ops = {
+	.interfaces[USB_DEV_IFACE] = &usb_iface
+};
+
 /** Callback when new device is detected and must be handled by this driver.
  *
@@ -129,4 +159,6 @@
 	}
 	child->name = child_info->name;
+	child->parent = child_info->parent;
+	child->ops = &child_ops;
 
 	match_id = create_match_id();
Index: uspace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/usb/src/recognise.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -33,4 +33,5 @@
  * @brief Functions for recognising kind of attached devices.
  */
+#include <usb_iface.h>
 #include <usb/usbdrv.h>
 #include <usb/classes/classes.h>
@@ -38,4 +39,31 @@
 #include <errno.h>
 
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
+{
+	assert(dev);
+	assert(dev->parent != NULL);
+
+	device_t *parent = dev->parent;
+
+	if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
+		usb_iface_t *usb_iface
+		    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
+		assert(usb_iface != NULL);
+		if (usb_iface->get_hc_handle) {
+			int rc = usb_iface->get_hc_handle(parent, handle);
+			return rc;
+		}
+	}
+
+	return ENOTSUP;
+}
+
+static usb_iface_t usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle
+};
+
+static device_ops_t child_ops = {
+	.interfaces[USB_DEV_IFACE] = &usb_iface
+};
 
 #define BCD_INT(a) (((unsigned int)(a)) / 256)
@@ -285,5 +313,7 @@
 		goto failure;
 	}
+	child->parent = parent;
 	child->name = child_name;
+	child->ops = &child_ops;
 	
 	rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address);
Index: uspace/lib/usb/src/usbdrv.c
===================================================================
--- uspace/lib/usb/src/usbdrv.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/lib/usb/src/usbdrv.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -35,4 +35,5 @@
 #include <usb/usbdrv.h>
 #include <usbhc_iface.h>
+#include <usb_iface.h>
 #include <errno.h>
 #include <str_error.h>
@@ -54,4 +55,53 @@
 } transfer_info_t;
 
+/** Find handle of host controller the device is physically attached to.
+ *
+ * @param[in] dev Device looking for its host controller.
+ * @param[out] handle Host controller devman handle.
+ * @return Error code.
+ */
+int usb_drv_find_hc(device_t *dev, devman_handle_t *handle)
+{
+	if (dev == NULL) {
+		return EBADMEM;
+	}
+	if (handle == NULL) {
+		return EBADMEM;
+	}
+
+	int parent_phone = devman_parent_device_connect(dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (parent_phone < 0) {
+		return parent_phone;
+	}
+
+	devman_handle_t h;
+	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
+
+	ipc_hangup(parent_phone);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	*handle = h;
+
+	return EOK;
+}
+
+/** Connect to host controller the device is physically attached to.
+ *
+ * @param dev Device asking for connection.
+ * @param hc_handle Devman handle of the host controller.
+ * @param flags Connection flags (blocking connection).
+ * @return Phone to the HC or error code.
+ */
+int usb_drv_hc_connect(device_t *dev, devman_handle_t hc_handle,
+    unsigned int flags)
+{
+	return devman_device_connect(hc_handle, flags);
+}
+
 /** Connect to host controller the device is physically attached to.
  *
@@ -60,24 +110,18 @@
  * @return Phone to corresponding HC or error code.
  */
-int usb_drv_hc_connect(device_t *dev, unsigned int flags)
-{
+int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags)
+{
+	int rc;
+	devman_handle_t hc_handle;
+
 	/*
 	 * Call parent hub to obtain device handle of respective HC.
 	 */
-
-	/*
-	 * FIXME: currently we connect always to virtual host controller.
-	 */
-	int rc;
-	devman_handle_t handle;
-
-	rc = devman_device_get_handle("/virt/usbhc", &handle, flags);
+	rc = usb_drv_find_hc(dev, &hc_handle);
 	if (rc != EOK) {
 		return rc;
 	}
 	
-	int phone = devman_device_connect(handle, flags);
-
-	return phone;
+	return usb_drv_hc_connect(dev, hc_handle, flags);
 }
 
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision ae1f70ec89abbdbd299b59710e8ae5be5f7e3505)
+++ uspace/srv/devman/main.c	(revision 8f8a0cd66d82dc0f39e3ccc0ff2eb654c731d249)
@@ -458,6 +458,7 @@
 	
 	if (driver == NULL) {
-		printf(NAME ": devman_forward error - the device is not in %" PRIun
-		    " usable state.\n", handle);
+		printf(NAME ": devman_forward error - the device %" PRIun \
+		    " (%s) is not in usable state.\n",
+		    handle, dev->pathname);
 		ipc_answer_0(iid, ENOENT);
 		return;
