Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/mkbd/main.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -44,5 +44,4 @@
 #include <devman.h>
 #include <loc.h>
-#include <usb/dev/hub.h>
 #include <usbhid_iface.h>
 #include <usb/dev/pipes.h>
@@ -224,5 +223,5 @@
 	devman_handle_t dev_handle = 0;
 	
-	int rc = usb_resolve_device_handle(devpath, NULL, NULL, &dev_handle);
+	int rc = usb_resolve_device_handle(devpath, &dev_handle);
 	if (rc != EOK) {
 		printf("Device not found or not of USB kind: %s.\n",
Index: uspace/app/usbinfo/Makefile
===================================================================
--- uspace/app/usbinfo/Makefile	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/usbinfo/Makefile	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -43,5 +43,4 @@
 SOURCES = \
 	desctree.c \
-	dev.c \
 	dump.c \
 	hid.c \
Index: uspace/app/usbinfo/dev.c
===================================================================
--- uspace/app/usbinfo/dev.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ 	(revision )
@@ -1,131 +1,0 @@
-/*
- * 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 usbinfo
- * @{
- */
-/**
- * @file
- * Representation of queried device.
- */
-#include <usb/dev.h>
-#include <usb/hc.h>
-#include <errno.h>
-#include <str_error.h>
-#include <usb/dev/request.h>
-#include "usbinfo.h"
-
-usbinfo_device_t *prepare_device(const char *name,
-    devman_handle_t hc_handle, usb_address_t dev_addr)
-{
-	usbinfo_device_t *dev = malloc(sizeof(usbinfo_device_t));
-	if (dev == NULL) {
-		fprintf(stderr, NAME ": memory allocation failed.\n");
-		return NULL;
-	}
-
-	int rc;
-	bool transfer_started = false;
-
-	usb_hc_connection_initialize(&dev->hc_conn, hc_handle);
-
-	rc = usb_device_connection_initialize(
-	    &dev->wire, &dev->hc_conn, dev_addr);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to create connection to device %s: %s.\n",
-		    name, str_error(rc));
-		goto leave;
-	}
-
-	rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
-	    &dev->wire);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to create default control pipe to %s: %s.\n",
-		    name, str_error(rc));
-		goto leave;
-	}
-
-	rc = usb_pipe_probe_default_control(&dev->ctrl_pipe);
-	if (rc != EOK) {
-		if (rc == ENOENT) {
-			fprintf(stderr, NAME ": " \
-			    "device %s not present or malfunctioning.\n",
-			    name);
-		} else {
-			fprintf(stderr, NAME ": " \
-			    "probing default control pipe of %s failed: %s.\n",
-			    name, str_error(rc));
-		}
-		goto leave;
-	}
-
-	usb_pipe_start_long_transfer(&dev->ctrl_pipe);
-	transfer_started = true;
-
-	rc = usb_request_get_device_descriptor(&dev->ctrl_pipe,
-	    &dev->device_descriptor);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to retrieve device descriptor of %s: %s.\n",
-		    name, str_error(rc));
-		goto leave;
-	}
-
-	rc = usb_request_get_full_configuration_descriptor_alloc(
-	    &dev->ctrl_pipe, 0, (void **)&dev->full_configuration_descriptor,
-	    &dev->full_configuration_descriptor_size);
-	if (rc != EOK) {
-		fprintf(stderr, NAME ": " \
-		    "failed to retrieve configuration descriptor of %s: %s.\n",
-		    name, str_error(rc));
-		goto leave;
-	}
-
-	return dev;
-
-
-leave:
-	if (transfer_started) {
-		usb_pipe_end_long_transfer(&dev->ctrl_pipe);
-	}
-
-	free(dev);
-
-	return NULL;
-}
-
-void destroy_device(usbinfo_device_t *dev)
-{
-	usb_pipe_end_long_transfer(&dev->ctrl_pipe);
-	free(dev);
-}
-
-/** @}
- */
Index: uspace/app/usbinfo/hid.c
===================================================================
--- uspace/app/usbinfo/hid.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/usbinfo/hid.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -36,4 +36,5 @@
 #include <stdio.h>
 #include <str_error.h>
+#include <usb/debug.h>
 #include <usb/classes/classes.h>
 #include <usb/dev/request.h>
@@ -50,5 +51,5 @@
 
 typedef struct {
-	usbinfo_device_t *dev;
+	usb_device_t *usb_dev;
 	hid_dump_type_t dump_type;
 	usb_standard_interface_descriptor_t *last_iface;
@@ -211,33 +212,35 @@
 
 	retrieve_and_dump_hid_report(context->dump_type,
-	    &context->dev->ctrl_pipe, context->last_iface->interface_number,
-	    report_size);
-}
-
-
-void dump_hidreport_raw(usbinfo_device_t *dev)
+	    usb_device_get_default_pipe(context->usb_dev),
+	    context->last_iface->interface_number, report_size);
+}
+
+
+void dump_hidreport_raw(usb_device_t *usb_dev)
 {
 	descriptor_walk_context_t context = {
-		.dev = dev,
+		.usb_dev = usb_dev,
 		.dump_type = HID_DUMP_RAW,
 		.last_iface = NULL
 	};
 
-	usb_dp_walk_simple(dev->full_configuration_descriptor,
-	    dev->full_configuration_descriptor_size,
+	usb_dp_walk_simple(
+	    usb_device_descriptors(usb_dev)->full_config,
+	    usb_device_descriptors(usb_dev)->full_config_size,
 	    usb_dp_standard_descriptor_nesting,
 	    descriptor_walk_callback, &context);
 }
 
-void dump_hidreport_usages(usbinfo_device_t *dev)
+void dump_hidreport_usages(usb_device_t *usb_dev)
 {
 	descriptor_walk_context_t context = {
-		.dev = dev,
+		.usb_dev = usb_dev,
 		.dump_type = HID_DUMP_USAGES,
 		.last_iface = NULL
 	};
 
-	usb_dp_walk_simple(dev->full_configuration_descriptor,
-	    dev->full_configuration_descriptor_size,
+	usb_dp_walk_simple(
+	    usb_device_descriptors(usb_dev)->full_config,
+	    usb_device_descriptors(usb_dev)->full_config_size,
 	    usb_dp_standard_descriptor_nesting,
 	    descriptor_walk_callback, &context);
Index: uspace/app/usbinfo/info.c
===================================================================
--- uspace/app/usbinfo/info.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/usbinfo/info.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -37,4 +37,5 @@
 #include <str_error.h>
 #include <errno.h>
+#include <usb/debug.h>
 #include <usb/dev/pipes.h>
 #include <usb/dev/recognise.h>
@@ -44,9 +45,9 @@
 #include "usbinfo.h"
 
-void dump_short_device_identification(usbinfo_device_t *dev)
+void dump_short_device_identification(usb_device_t *usb_dev)
 {
 	printf("%sDevice 0x%04x by vendor 0x%04x\n", get_indent(0),
-	    (int) dev->device_descriptor.product_id,
-	    (int) dev->device_descriptor.vendor_id);
+	    usb_device_descriptors(usb_dev)->device.product_id,
+	    usb_device_descriptors(usb_dev)->device.vendor_id);
 }
 
@@ -66,5 +67,6 @@
 	}
 
-	usbinfo_device_t *dev = (usbinfo_device_t *) arg;
+	usb_device_t *usb_dev = arg;
+	assert(usb_dev);
 
 	usb_standard_interface_descriptor_t *iface
@@ -80,28 +82,28 @@
 	match_id_list_t matches;
 	init_match_ids(&matches);
-	usb_device_create_match_ids_from_interface(&dev->device_descriptor,
-	    iface, &matches);
+	usb_device_create_match_ids_from_interface(
+	    &usb_device_descriptors(usb_dev)->device, iface, &matches);
 	dump_match_ids(&matches, get_indent(1));
 	clean_match_ids(&matches);
 }
 
-void dump_device_match_ids(usbinfo_device_t *dev)
+void dump_device_match_ids(usb_device_t *usb_dev)
 {
 	match_id_list_t matches;
 	init_match_ids(&matches);
 	usb_device_create_match_ids_from_device_descriptor(
-	    &dev->device_descriptor, &matches);
+		&usb_device_descriptors(usb_dev)->device, &matches);
 	printf("%sDevice match ids (0x%04x by 0x%04x, %s)\n", get_indent(0),
-	    (int) dev->device_descriptor.product_id,
-	    (int) dev->device_descriptor.vendor_id,
-	    usb_str_class(dev->device_descriptor.device_class));
+	    usb_device_descriptors(usb_dev)->device.product_id,
+	    usb_device_descriptors(usb_dev)->device.vendor_id,
+	    usb_str_class(usb_device_descriptors(usb_dev)->device.device_class));
 	dump_match_ids(&matches, get_indent(1));
 	clean_match_ids(&matches);
 
-	usb_dp_walk_simple(dev->full_configuration_descriptor,
-	    dev->full_configuration_descriptor_size,
+	usb_dp_walk_simple(
+	    usb_device_descriptors(usb_dev)->full_config,
+	    usb_device_descriptors(usb_dev)->full_config_size,
 	    usb_dp_standard_descriptor_nesting,
-	    dump_match_ids_from_interface,
-	    dev);
+	    dump_match_ids_from_interface, usb_dev);
 }
 
@@ -224,24 +226,28 @@
 }
 
-void dump_descriptor_tree_brief(usbinfo_device_t *dev)
-{
-	dump_descriptor_tree_callback((uint8_t *)&dev->device_descriptor,
+void dump_descriptor_tree_brief(usb_device_t *usb_dev)
+{
+	dump_descriptor_tree_callback(
+	    (const uint8_t *)&usb_device_descriptors(usb_dev)->device,
 	    (size_t) -1, NULL);
-	usb_dp_walk_simple(dev->full_configuration_descriptor,
-	    dev->full_configuration_descriptor_size,
+
+	usb_dp_walk_simple(
+	    usb_device_descriptors(usb_dev)->full_config,
+	    usb_device_descriptors(usb_dev)->full_config_size,
 	    usb_dp_standard_descriptor_nesting,
-	    dump_descriptor_tree_callback,
-	    NULL);
-}
-
-void dump_descriptor_tree_full(usbinfo_device_t *dev)
-{
-	dump_descriptor_tree_callback((uint8_t *)&dev->device_descriptor,
-	    (size_t) -1, dev);
-	usb_dp_walk_simple(dev->full_configuration_descriptor,
-	    dev->full_configuration_descriptor_size,
+	    dump_descriptor_tree_callback, NULL);
+}
+
+void dump_descriptor_tree_full(usb_device_t *usb_dev)
+{
+	dump_descriptor_tree_callback(
+	    (const uint8_t *)&usb_device_descriptors(usb_dev)->device,
+	    (size_t) -1, usb_dev);
+
+	usb_dp_walk_simple(
+	    usb_device_descriptors(usb_dev)->full_config,
+	    usb_device_descriptors(usb_dev)->full_config_size,
 	    usb_dp_standard_descriptor_nesting,
-	    dump_descriptor_tree_callback,
-	    dev);
+	    dump_descriptor_tree_callback, usb_dev);
 }
 
@@ -285,15 +291,17 @@
 
 
-void dump_strings(usbinfo_device_t *dev)
+void dump_strings(usb_device_t *usb_dev)
 {
 	/* Find used indexes. Devices with more than 64 strings are very rare.*/
 	uint64_t str_mask = 0;
-	find_string_indexes_callback((uint8_t *)&dev->device_descriptor, 0,
+	find_string_indexes_callback(
+	    (const uint8_t *)&usb_device_descriptors(usb_dev)->device, 0,
 	    &str_mask);
-	usb_dp_walk_simple(dev->full_configuration_descriptor,
-	    dev->full_configuration_descriptor_size,
+
+	usb_dp_walk_simple(
+	    usb_device_descriptors(usb_dev)->full_config,
+	    usb_device_descriptors(usb_dev)->full_config_size,
 	    usb_dp_standard_descriptor_nesting,
-	    find_string_indexes_callback,
-	    &str_mask);
+	    find_string_indexes_callback, &str_mask);
 
 	if (str_mask == 0) {
@@ -305,6 +313,6 @@
 	l18_win_locales_t *langs;
 	size_t langs_count;
-	int rc = usb_request_get_supported_languages(&dev->ctrl_pipe,
-	    &langs, &langs_count);
+	int rc = usb_request_get_supported_languages(
+	    usb_device_get_default_pipe(usb_dev), &langs, &langs_count);
 	if (rc != EOK) {
 		fprintf(stderr,
@@ -334,5 +342,6 @@
 			}
 			char *string = NULL;
-			rc = usb_request_get_string(&dev->ctrl_pipe, idx, lang,
+			rc = usb_request_get_string(
+			    usb_device_get_default_pipe(usb_dev), idx, lang,
 			    &string);
 			if ((rc != EOK) && (rc != EEMPTY)) {
@@ -351,46 +360,36 @@
 
 
-void dump_status(usbinfo_device_t *dev)
+void dump_status(usb_device_t *usb_dev)
 {
 	int rc;
-	uint16_t device_status = 0;
-	uint16_t ctrl_pipe_status = 0;
+	uint16_t status = 0;
 
 	/* Device status first. */
-	rc = usb_request_get_status(&dev->ctrl_pipe,
-	    USB_REQUEST_RECIPIENT_DEVICE, 0,
-	    &device_status);
+	rc = usb_request_get_status(usb_device_get_default_pipe(usb_dev),
+	    USB_REQUEST_RECIPIENT_DEVICE, 0, &status);
 	if (rc != EOK) {
 		printf("%sFailed to get device status: %s.\n",
 		    get_indent(0), str_error(rc));
-		goto try_ctrl_pipe_status;
-	}
-
-	printf("%sDevice status 0x%04x: power=%s, remote-wakeup=%s.\n",
-	    get_indent(0),
-	    device_status,
-	    device_status & USB_DEVICE_STATUS_SELF_POWERED ? "self" : "bus",
-	    device_status & USB_DEVICE_STATUS_REMOTE_WAKEUP ? "yes" : "no");
+	} else {
+		printf("%sDevice status 0x%04x: power=%s, remote-wakeup=%s.\n",
+		    get_indent(0), status,
+		    status & USB_DEVICE_STATUS_SELF_POWERED ? "self" : "bus",
+		    status & USB_DEVICE_STATUS_REMOTE_WAKEUP ? "yes" : "no");
+	}
 
 	/* Interface is not interesting, skipping ;-). */
 
 	/* Control endpoint zero. */
-try_ctrl_pipe_status:
-	rc = usb_request_get_status(&dev->ctrl_pipe,
-	    USB_REQUEST_RECIPIENT_ENDPOINT, 0,
-	    &ctrl_pipe_status);
+	status = 0;
+	rc = usb_request_get_status(usb_device_get_default_pipe(usb_dev),
+	    USB_REQUEST_RECIPIENT_ENDPOINT, 0, &status);
 	if (rc != EOK) {
 		printf("%sFailed to get control endpoint status: %s.\n",
 		    get_indent(0), str_error(rc));
-		goto leave;
-	}
-
-	printf("%sControl endpoint zero status %04X: halted=%s.\n",
-	    get_indent(0),
-	    ctrl_pipe_status,
-	    ctrl_pipe_status & USB_ENDPOINT_STATUS_HALTED ? "yes" : "no");
-
-leave:
-	return;
+	} else {
+		printf("%sControl endpoint zero status %04X: halted=%s.\n",
+		    get_indent(0), status,
+		    status & USB_ENDPOINT_STATUS_HALTED ? "yes" : "no");
+	}
 }
 
Index: uspace/app/usbinfo/list.c
===================================================================
--- uspace/app/usbinfo/list.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/usbinfo/list.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -44,48 +44,86 @@
 #include <devman.h>
 #include <loc.h>
-#include <usb/dev/hub.h>
-#include <usb/hc.h>
+#include <usb_iface.h>
 
 #include "usbinfo.h"
 
-#define MAX_USB_ADDRESS USB11_ADDRESS_MAX
 #define MAX_PATH_LENGTH 1024
 
-static void print_found_hc(service_id_t sid, const char *path)
+static void print_usb_device(devman_handle_t handle)
 {
-	printf("Bus %" PRIun ": %s\n", sid, path);
-}
-static void print_found_dev(usb_address_t addr, const char *path)
-{
-	printf("  Device %02d: %s\n", addr, path);
+	char path[MAX_PATH_LENGTH];
+	int rc = devman_fun_get_path(handle, path, MAX_PATH_LENGTH);
+	if (rc != EOK) {
+		printf(NAME "Failed to get path for device %"PRIun"\n", handle);
+		return;
+	}
+	printf("\tDevice %" PRIun ": %s\n", handle, path);
 }
 
-static void print_hc_devices(devman_handle_t hc_handle)
+static void print_usb_bus(service_id_t svc)
 {
-	int rc;
-	usb_hc_connection_t conn;
-
-	usb_hc_connection_initialize(&conn, hc_handle);
-	rc = usb_hc_connection_open(&conn);
+	devman_handle_t hc_handle = 0;
+	int rc = devman_fun_sid_to_handle(svc, &hc_handle);
 	if (rc != EOK) {
-		printf(NAME ": failed to connect to HC: %s.\n",
-		    str_error(rc));
+		printf(NAME ": Error resolving handle of HC with SID %"
+		    PRIun ", skipping.\n", svc);
 		return;
 	}
-	usb_address_t addr;
-	for (addr = 1; addr < MAX_USB_ADDRESS; addr++) {
-		devman_handle_t dev_handle;
-		rc = usb_hc_get_handle_by_address(&conn, addr, &dev_handle);
-		if (rc != EOK) {
-			continue;
-		}
-		char path[MAX_PATH_LENGTH];
-		rc = devman_fun_get_path(dev_handle, path, MAX_PATH_LENGTH);
-		if (rc != EOK) {
-			continue;
-		}
-		print_found_dev(addr, path);
+
+	char path[MAX_PATH_LENGTH];
+	rc = devman_fun_get_path(hc_handle, path, sizeof(path));
+	if (rc != EOK) {
+		printf(NAME ": Error resolving path of HC with SID %"
+		    PRIun ", skipping.\n", svc);
+		return;
 	}
-	usb_hc_connection_close(&conn);
+	printf("Bus %" PRIun ": %s\n", svc, path);
+
+	/* Construct device's path.
+	 * That's "hc function path" - ( '/' + "hc function name" ) */
+	// TODO replace this with something sane
+
+	/* Get function name */
+	char name[10];
+	rc = devman_fun_get_name(hc_handle, name, sizeof(name));
+	if (rc != EOK) {
+		printf(NAME ": Error resolving name of HC with SID %"
+		    PRIun ", skipping.\n", svc);
+		return;
+	}
+
+	/* Get handle of parent device */
+	devman_handle_t fh;
+	path[str_size(path) - str_size(name) - 1] = '\0';
+	rc = devman_fun_get_handle(path, &fh, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf(NAME ": Error resolving parent handle of HC with"
+		    " SID %" PRIun ", skipping.\n", svc);
+		return;
+	}
+
+	/* Get child handle */
+	devman_handle_t dh;
+	rc = devman_fun_get_child(fh, &dh);
+	if (rc != EOK) {
+		printf(NAME ": Error resolving parent handle of HC with"
+		    " SID %" PRIun ", skipping.\n", svc);
+		return;
+	}
+	
+	devman_handle_t *fhs = 0;
+	size_t count;
+	rc = devman_dev_get_functions(dh, &fhs, &count);
+	if (rc != EOK) {
+		printf(NAME ": Error siblings of HC with"
+		    " SID %" PRIun ", skipping.\n", svc);
+		return;
+	}
+
+	for (size_t i = 0; i < count; ++i) {
+		if (fhs[i] != hc_handle)
+			print_usb_device(fhs[i]);
+	}
+	free(fhs);
 }
 
@@ -95,5 +133,4 @@
 	service_id_t *svcs;
 	size_t count;
-	size_t i;
 	int rc;
 
@@ -111,21 +148,6 @@
 	}
 
-	for (i = 0; i < count; i++) {
-		devman_handle_t hc_handle = 0;
-		int rc = usb_ddf_get_hc_handle_by_sid(svcs[i], &hc_handle);
-		if (rc != EOK) {
-			printf(NAME ": Error resolving handle of HC with SID %"
-			    PRIun ", skipping.\n", svcs[i]);
-			continue;
-		}
-		char path[MAX_PATH_LENGTH];
-		rc = devman_fun_get_path(hc_handle, path, MAX_PATH_LENGTH);
-		if (rc != EOK) {
-			printf(NAME ": Error resolving path of HC with SID %"
-			    PRIun ", skipping.\n", svcs[i]);
-			continue;
-		}
-		print_found_hc(svcs[i], path);
-		print_hc_devices(hc_handle);
+	for (unsigned i = 0; i < count; ++i) {
+		print_usb_bus(svcs[i]);
 	}
 
Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/usbinfo/main.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -43,5 +43,4 @@
 #include <devman.h>
 #include <loc.h>
-#include <usb/hc.h>
 #include <usb/dev.h>
 #include <usb/dev/pipes.h>
@@ -198,8 +197,6 @@
 
 		/* The initialization is here only to make compiler happy. */
-		devman_handle_t hc_handle = 0;
-		usb_address_t dev_addr = 0;
-		int rc = usb_resolve_device_handle(devpath,
-		    &hc_handle, &dev_addr, NULL);
+		devman_handle_t handle = 0;
+		int rc = usb_resolve_device_handle(devpath, &handle);
 		if (rc != EOK) {
 			fprintf(stderr, NAME ": device `%s' not found "
@@ -209,7 +206,7 @@
 		}
 
-		usbinfo_device_t *dev = prepare_device(devpath,
-		    hc_handle, dev_addr);
-		if (dev == NULL) {
+		usb_device_t *usb_dev = usb_device_create(handle);
+
+		if (usb_dev == NULL) {
 			continue;
 		}
@@ -221,11 +218,10 @@
 		while (actions[action].opt != 0) {
 			if (actions[action].active) {
-				actions[action].action(dev);
+				actions[action].action(usb_dev);
 			}
 			action++;
 		}
 
-		/* Destroy the control pipe (close the session etc.). */
-		destroy_device(dev);
+		usb_device_destroy(usb_dev);
 	}
 
Index: uspace/app/usbinfo/usbinfo.h
===================================================================
--- uspace/app/usbinfo/usbinfo.h	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/usbinfo/usbinfo.h	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -38,21 +38,11 @@
 #include <usb/usb.h>
 #include <usb/descriptor.h>
-#include <usb/dev/pipes.h>
-#include <usb/debug.h>
+#include <usb/dev/device.h>
 #include <usb/dev/dp.h>
 #include <ipc/devman.h>
 
 typedef struct {
-	usb_hc_connection_t hc_conn;
-	usb_device_connection_t wire;
-	usb_pipe_t ctrl_pipe;
-	usb_standard_device_descriptor_t device_descriptor;
-	uint8_t *full_configuration_descriptor;
-	size_t full_configuration_descriptor_size;
-} usbinfo_device_t;
-
-typedef struct {
 	int opt;
-	void (*action)(usbinfo_device_t *dev);
+	void (*action)(usb_device_t *usb_dev);
 	bool active;
 } usbinfo_action_t;
@@ -72,7 +62,4 @@
 }
 
-usbinfo_device_t *prepare_device(const char *, devman_handle_t, usb_address_t);
-void destroy_device(usbinfo_device_t *);
-
 typedef void (*dump_descriptor_in_tree_t)(const uint8_t *, size_t, void *);
 void browse_descriptor_tree(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
@@ -81,13 +68,12 @@
 void list(void);
 
-void dump_short_device_identification(usbinfo_device_t *);
-void dump_device_match_ids(usbinfo_device_t *);
-void dump_descriptor_tree_brief(usbinfo_device_t *);
-void dump_descriptor_tree_full(usbinfo_device_t *);
-void dump_strings(usbinfo_device_t *);
-void dump_status(usbinfo_device_t *);
-void dump_hidreport_raw(usbinfo_device_t *);
-void dump_hidreport_usages(usbinfo_device_t *);
-
+void dump_short_device_identification(usb_device_t *);
+void dump_device_match_ids(usb_device_t *);
+void dump_descriptor_tree_brief(usb_device_t *);
+void dump_descriptor_tree_full(usb_device_t *);
+void dump_strings(usb_device_t *);
+void dump_status(usb_device_t *);
+void dump_hidreport_raw(usb_device_t *);
+void dump_hidreport_usages(usb_device_t *);
 
 #endif
Index: uspace/app/vuhid/device.c
===================================================================
--- uspace/app/vuhid/device.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/vuhid/device.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -60,5 +60,5 @@
 static int on_data_to_device(usbvirt_device_t *dev,
     usb_endpoint_t ep, usb_transfer_type_t tr_type,
-    void *data, size_t data_size)
+    const void *data, size_t data_size)
 {
 	vuhid_data_t *vuhid = dev->device_data;
@@ -254,7 +254,6 @@
 
 	/* Extend existing extra descriptors with these ones. */
-	usbvirt_device_configuration_extras_t *extra_descriptors
-	    = dev->descriptors->configuration->extra;
-	extra_descriptors = realloc(extra_descriptors,
+	usbvirt_device_configuration_extras_t *extra_descriptors;
+	extra_descriptors = realloc(dev->descriptors->configuration->extra,
 	    sizeof(usbvirt_device_configuration_extras_t)
 	    * (dev->descriptors->configuration->extra_count + descr_count));
Index: uspace/app/vuhid/hids/bootkbd.c
===================================================================
--- uspace/app/vuhid/hids/bootkbd.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/vuhid/hids/bootkbd.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -102,5 +102,5 @@
 
 static int on_data_out(vuhid_interface_t *iface,
-    void *buffer, size_t buffer_size)
+    const void *buffer, size_t buffer_size)
 {
 	if (buffer_size == 0) {
Index: uspace/app/vuhid/main.c
===================================================================
--- uspace/app/vuhid/main.c	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/vuhid/main.c	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -40,4 +40,5 @@
 #include <errno.h>
 #include <str_error.h>
+#include <getopt.h>
 
 #include <usb/usb.h>
@@ -52,26 +53,19 @@
 #include "stdreq.h"
 
+#define DEFAULT_CONTROLLER   "/virt/usbhc/ctl"
+
 static usbvirt_control_request_handler_t endpoint_zero_handlers[] = {
 	{
-		.req_direction = USB_DIRECTION_IN,
-		.req_type = USB_REQUEST_TYPE_STANDARD,
-		.req_recipient = USB_REQUEST_RECIPIENT_INTERFACE,
-		.request = USB_DEVREQ_GET_DESCRIPTOR,
+		STD_REQ_IN(USB_REQUEST_RECIPIENT_INTERFACE, USB_DEVREQ_GET_DESCRIPTOR),
 		.name = "Get_Descriptor",
 		.callback = req_get_descriptor
 	},
 	{
-		.req_direction = USB_DIRECTION_OUT,
-		.req_recipient = USB_REQUEST_RECIPIENT_INTERFACE,
-		.req_type = USB_REQUEST_TYPE_CLASS,
-		.request = USB_HIDREQ_SET_PROTOCOL,
+		CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_INTERFACE, USB_HIDREQ_SET_PROTOCOL),
 		.name = "Set_Protocol",
 		.callback = req_set_protocol
 	},
 	{
-		.req_direction = USB_DIRECTION_OUT,
-		.req_recipient = USB_REQUEST_RECIPIENT_INTERFACE,
-		.req_type = USB_REQUEST_TYPE_CLASS,
-		.request = USB_HIDREQ_SET_REPORT,
+		CLASS_REQ_OUT(USB_REQUEST_RECIPIENT_INTERFACE, USB_HIDREQ_SET_REPORT),
 		.name = "Set_Report",
 		.callback = req_set_report
@@ -151,7 +145,68 @@
 
 
+static struct option long_options[] = {
+	{"help", optional_argument, NULL, 'h'},
+	{"controller", required_argument, NULL, 'c' },
+	{"list", no_argument, NULL, 'l' },
+	{0, 0, NULL, 0}
+};
+static const char *short_options = "hc:l";
+
+static void print_help(const char* name, const char* module)
+{
+	if (module == NULL) {
+		/* Default help */
+		printf("Usage: %s [options] device.\n", name);
+		printf("\t-h, --help [device]\n");
+		printf("\t\to With no argument print this help and exit.\n");
+		printf("\t\to With argument print device specific help and exit.\n");
+		printf("\t-l, --list \n\t\tPrint list of available devices.\n");
+		printf("\t-c, --controller \n\t\t"
+		    "Use provided virtual hc instead of default (%s)\n",
+		    DEFAULT_CONTROLLER);
+		return;
+	}
+	printf("HELP for module %s\n", module);
+}
+
+static void print_list(void)
+{
+	printf("Available devices:\n");
+	for (vuhid_interface_t **i = available_hid_interfaces; *i != NULL; ++i)
+	{
+		printf("\t`%s'\t%s\n", (*i)->id, (*i)->name);
+	}
+
+}
+
+static const char *controller = DEFAULT_CONTROLLER;
+
 int main(int argc, char * argv[])
 {
-	int rc;
+
+	if (argc == 1) {
+		print_help(*argv, NULL);
+		return 0;
+	}
+
+	int opt = 0;
+	while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) > 0) {
+		switch (opt)
+		{
+		case 'h':
+			print_help(*argv, optarg);
+			return 0;
+		case 'c':
+			controller = optarg;
+			break;
+		case 'l':
+			print_list();
+			return 0;
+		case -1:
+		default:
+			break;
+		}
+	}
+
 
 	log_init("vuhid");
@@ -161,7 +216,6 @@
 
 	/* Determine which interfaces to initialize. */
-	int i;
-	for (i = 1; i < argc; i++) {
-		rc = add_interface_by_id(available_hid_interfaces, argv[i],
+	for (int i = optind; i < argc; i++) {
+		int rc = add_interface_by_id(available_hid_interfaces, argv[i],
 		    &hid_dev);
 		if (rc != EOK) {
@@ -173,5 +227,5 @@
 	}
 
-	for (i = 0; i < (int) hid_dev.descriptors->configuration->extra_count; i++) {
+	for (int i = 0; i < (int) hid_dev.descriptors->configuration->extra_count; i++) {
 		usb_log_debug("Found extra descriptor: %s.\n",
 		    usb_debug_str_buffer(
@@ -181,12 +235,12 @@
 	}
 
-	rc = usbvirt_device_plug(&hid_dev, "/virt/usbhc/hc");
+	const int rc = usbvirt_device_plug(&hid_dev, controller);
 	if (rc != EOK) {
-		printf("Unable to start communication with VHCD: %s.\n",
-		    str_error(rc));
+		printf("Unable to start communication with VHCD `%s': %s.\n",
+		    controller, str_error(rc));
 		return rc;
 	}
 	
-	printf("Connected to VHCD...\n");
+	printf("Connected to VHCD `%s'...\n", controller);
 
 	wait_for_interfaces_death(&hid_dev);
Index: uspace/app/vuhid/virthid.h
===================================================================
--- uspace/app/vuhid/virthid.h	(revision 5c65e613de52e725ff215514fe39a8d1428767d2)
+++ uspace/app/vuhid/virthid.h	(revision d1df3818a95cee3c47bd9d726fdc58f9a8df71bc)
@@ -71,5 +71,5 @@
 
 	int (*on_data_in)(vuhid_interface_t *, void *, size_t, size_t *);
-	int (*on_data_out)(vuhid_interface_t *, void *, size_t);
+	int (*on_data_out)(vuhid_interface_t *, const void *, size_t);
 	void (*live)(vuhid_interface_t *);
 
