Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -179,4 +179,7 @@
 ifeq ($(UARCH),amd64)
 	LIBS += lib/usb
+	LIBS += lib/usbhost
+	LIBS += lib/usbdev
+	LIBS += lib/usbhid
 	LIBS += lib/usbvirt
 endif
@@ -184,4 +187,7 @@
 ifeq ($(UARCH),ia32)
 	LIBS += lib/usb
+	LIBS += lib/usbhost
+	LIBS += lib/usbdev
+	LIBS += lib/usbhid
 	LIBS += lib/usbvirt
 endif
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/Makefile.common	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -88,4 +88,7 @@
 
 LIBUSB_PREFIX = $(LIB_PREFIX)/usb
+LIBUSBHOST_PREFIX = $(LIB_PREFIX)/usbhost
+LIBUSBDEV_PREFIX = $(LIB_PREFIX)/usbdev
+LIBUSBHID_PREFIX = $(LIB_PREFIX)/usbhid
 LIBUSBVIRT_PREFIX = $(LIB_PREFIX)/usbvirt
 LIBDRV_PREFIX = $(LIB_PREFIX)/drv
Index: uspace/app/lsusb/Makefile
===================================================================
--- uspace/app/lsusb/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/lsusb/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -30,6 +30,12 @@
 BINARY = lsusb
 
-LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBDRV_PREFIX)/include
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
 
 SOURCES = \
Index: uspace/app/lsusb/main.c
===================================================================
--- uspace/app/lsusb/main.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/lsusb/main.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -44,10 +44,51 @@
 #include <devman.h>
 #include <devmap.h>
+#include <usb/hub.h>
 #include <usb/host.h>
 
 #define NAME "lsusb"
 
-#define MAX_FAILED_ATTEMPTS 4
+#define MAX_FAILED_ATTEMPTS 10
 #define MAX_PATH_LENGTH 1024
+
+static void print_found_hc(size_t class_index, const char *path)
+{
+	// printf(NAME ": host controller %zu is `%s'.\n", class_index, path);
+	printf("Bus %02zu: %s\n", class_index, path);
+}
+static void print_found_dev(usb_address_t addr, const char *path)
+{
+	// printf(NAME ":     device with address %d is `%s'.\n", addr, path);
+	printf("  Device %02d: %s\n", addr, path);
+}
+
+static void print_hc_devices(devman_handle_t hc_handle)
+{
+	int rc;
+	usb_hc_connection_t conn;
+
+	usb_hc_connection_initialize(&conn, hc_handle);
+	rc = usb_hc_connection_open(&conn);
+	if (rc != EOK) {
+		printf(NAME ": failed to connect to HC: %s.\n",
+		    str_error(rc));
+		return;
+	}
+	usb_address_t addr;
+	for (addr = 1; addr < 5; 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_get_device_path(dev_handle, path, MAX_PATH_LENGTH);
+		if (rc != EOK) {
+			continue;
+		}
+		print_found_dev(addr, path);
+	}
+	usb_hc_connection_close(&conn);
+}
 
 int main(int argc, char *argv[])
@@ -69,6 +110,6 @@
 			continue;
 		}
-		printf(NAME ": host controller %zu is `%s'.\n",
-		    class_index, path);
+		print_found_hc(class_index, path);
+		print_hc_devices(hc_handle);
 	}
 
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/tester/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -31,10 +31,6 @@
 BINARY = tester
 
-LIBS += $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBUSB_PREFIX)/include
-
 SOURCES = \
 	tester.c \
-	adt/usbaddrkeep.c \
 	thread/thread1.c \
 	print/print1.c \
Index: pace/app/tester/adt/usbaddrkeep.c
===================================================================
--- uspace/app/tester/adt/usbaddrkeep.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/*
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <usb/addrkeep.h>
-#include <errno.h>
-#include "../tester.h"
-
-#define MAX_ADDRESS 5
-
-
-const char *test_usbaddrkeep(void)
-{
-	int rc;
-	usb_address_keeping_t addresses;
-
-	TPRINTF("Initializing addresses keeping structure...\n");
-	usb_address_keeping_init(&addresses, MAX_ADDRESS);
-	
-	TPRINTF("Requesting address...\n");
-	usb_address_t addr = usb_address_keeping_request(&addresses);
-	TPRINTF("Address assigned: %d\n", (int) addr);
-	if (addr != 1) {
-		return "have not received expected address 1";
-	}
-
-	TPRINTF("Releasing not assigned address...\n");
-	rc = usb_address_keeping_release(&addresses, 2);
-	if (rc != ENOENT) {
-		return "have not received expected ENOENT";
-	}
-
-	TPRINTF("Releasing acquired address...\n");
-	rc = usb_address_keeping_release(&addresses, addr);
-	if (rc != EOK) {
-		return "have not received expected EOK";
-	}
-
-	return NULL;
-}
Index: pace/app/tester/adt/usbaddrkeep.def
===================================================================
--- uspace/app/tester/adt/usbaddrkeep.def	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"usbaddrkeep",
-	"USB address keeping structure",
-	&test_usbaddrkeep,
-	true
-},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/tester/tester.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -64,5 +64,4 @@
 #include "mm/mapping1.def"
 #include "hw/serial/serial1.def"
-#include "adt/usbaddrkeep.def"
 #include "hw/misc/virtchar1.def"
 #include "devs/devman1.def"
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/tester/tester.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -80,5 +80,4 @@
 extern const char *test_mapping1(void);
 extern const char *test_serial1(void);
-extern const char *test_usbaddrkeep(void);
 extern const char *test_virtchar1(void);
 extern const char *test_devman1(void);
Index: uspace/app/usbinfo/Makefile
===================================================================
--- uspace/app/usbinfo/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/usbinfo/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -30,6 +30,12 @@
 BINARY = usbinfo
 
-LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBDRV_PREFIX)/include
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS = \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
 
 SOURCES = \
Index: uspace/app/usbinfo/dev.c
===================================================================
--- uspace/app/usbinfo/dev.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/usbinfo/dev.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -40,6 +40,6 @@
 #include "usbinfo.h"
 
-usbinfo_device_t *prepare_device(devman_handle_t hc_handle,
-    usb_address_t dev_addr)
+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));
@@ -55,6 +55,6 @@
 	if (rc != EOK) {
 		fprintf(stderr,
-		    NAME ": failed to create connection to the device: %s.\n",
-		    str_error(rc));
+		    NAME ": failed to create connection to device %s: %s.\n",
+		    name, str_error(rc));
 		goto leave;
 	}
@@ -64,6 +64,6 @@
 	if (rc != EOK) {
 		fprintf(stderr,
-		    NAME ": failed to create default control pipe: %s.\n",
-		    str_error(rc));
+		    NAME ": failed to create default control pipe to %s: %s.\n",
+		    name, str_error(rc));
 		goto leave;
 	}
@@ -71,7 +71,13 @@
 	rc = usb_pipe_probe_default_control(&dev->ctrl_pipe);
 	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": probing default control pipe failed: %s.\n",
-		    str_error(rc));
+		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;
 	}
@@ -84,6 +90,6 @@
 	if (rc != EOK) {
 		fprintf(stderr,
-		    NAME ": failed to retrieve device descriptor: %s.\n",
-		    str_error(rc));
+		    NAME ": failed to retrieve device descriptor of %s: %s.\n",
+		    name, str_error(rc));
 		goto leave;
 	}
@@ -93,7 +99,7 @@
 	    &dev->full_configuration_descriptor_size);
 	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to retrieve configuration descriptor: %s.\n",
-		    str_error(rc));
+		fprintf(stderr, NAME ": " \
+		    "failed to retrieve configuration descriptor of %s: %s.\n",
+		    name, str_error(rc));
 		goto leave;
 	}
Index: uspace/app/usbinfo/info.c
===================================================================
--- uspace/app/usbinfo/info.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/usbinfo/info.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -41,5 +41,4 @@
 #include <usb/request.h>
 #include <usb/classes/classes.h>
-#include <usb/classes/hid.h>
 #include <usb/classes/hub.h>
 #include "usbinfo.h"
Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/usbinfo/main.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -46,4 +46,5 @@
 #include <usb/pipes.h>
 #include <usb/host.h>
+#include <usb/driver.h>
 #include "usbinfo.h"
 
@@ -308,5 +309,6 @@
 		}
 
-		usbinfo_device_t *dev = prepare_device(hc_handle, dev_addr);
+		usbinfo_device_t *dev = prepare_device(devpath,
+		    hc_handle, dev_addr);
 		if (dev == NULL) {
 			continue;
Index: uspace/app/usbinfo/usbinfo.h
===================================================================
--- uspace/app/usbinfo/usbinfo.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/usbinfo/usbinfo.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -71,5 +71,5 @@
 }
 
-usbinfo_device_t *prepare_device(devman_handle_t, usb_address_t);
+usbinfo_device_t *prepare_device(const char *, devman_handle_t, usb_address_t);
 void destroy_device(usbinfo_device_t *);
 
Index: uspace/app/vuhid/Makefile
===================================================================
--- uspace/app/vuhid/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/app/vuhid/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -34,7 +34,11 @@
 LIBS = \
 	$(LIBUSBVIRT_PREFIX)/libusbvirt.a \
+	$(LIBUSBHID_PREFIX)/libusbhid.a \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
 	$(LIBUSB_PREFIX)/libusb.a
 EXTRA_CFLAGS = \
 	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBUSBHID_PREFIX)/include \
 	-I$(LIBUSBVIRT_PREFIX)/include \
 	-I$(LIBDRV_PREFIX)/include
Index: uspace/drv/ehci-hcd/Makefile
===================================================================
--- uspace/drv/ehci-hcd/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ehci-hcd/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBHOST_PREFIX)/libusbhost.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBHOST_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = ehci-hcd
 
Index: uspace/drv/ehci-hcd/hc_iface.c
===================================================================
--- uspace/drv/ehci-hcd/hc_iface.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ehci-hcd/hc_iface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -106,4 +106,19 @@
 }
 
+/** Find device handle by USB address.
+ *
+ * @param[in] fun DDF function that was called.
+ * @param[in] address Address in question.
+ * @param[out] handle Where to store device handle if found.
+ * @return Error code.
+ */
+static int find_by_address(ddf_fun_t *fun, usb_address_t address,
+    devman_handle_t *handle)
+{
+	UNSUPPORTED("find_by_address");
+
+	return ENOTSUP;
+}
+
 /** Release previously requested address.
  *
@@ -321,4 +336,5 @@
 	.request_address = request_address,
 	.bind_address = bind_address,
+	.find_by_address = find_by_address,
 	.release_address = release_address,
 
Index: uspace/drv/ehci-hcd/pci.c
===================================================================
--- uspace/drv/ehci-hcd/pci.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ehci-hcd/pci.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -54,5 +54,6 @@
 
 #define CMD_OFFSET 0x0
-#define CONFIGFLAG_OFFSET 0x40
+#define STS_OFFSET 0x4
+#define CFG_OFFSET 0x40
 
 #define USBCMD_RUN 1
@@ -264,7 +265,7 @@
 	 * It would prevent pre-OS code from interfering. */
 	ret = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
-	   IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET, 0);
+	   IPC_M_CONFIG_SPACE_WRITE_32, eecp + USBLEGCTLSTS_OFFSET,
+	   0xe0000000);
 	CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
-	usb_log_debug("Zeroed USBLEGCTLSTS register.\n");
 
 	/* Read again Legacy Support and Control register */
@@ -291,10 +292,12 @@
 	volatile uint32_t *usbcmd =
 	    (uint32_t*)((uint8_t*)registers + operation_offset + CMD_OFFSET);
+	volatile uint32_t *usbsts =
+	    (uint32_t*)((uint8_t*)registers + operation_offset + STS_OFFSET);
 	volatile uint32_t *usbconfigured =
-	    (uint32_t*)((uint8_t*)registers + operation_offset
-	    + CONFIGFLAG_OFFSET);
+	    (uint32_t*)((uint8_t*)registers + operation_offset + CFG_OFFSET);
 	usb_log_debug("USBCMD value: %x.\n", *usbcmd);
 	if (*usbcmd & USBCMD_RUN) {
 		*usbcmd = 0;
+		while (!(*usbsts & (1 << 12))); /*wait until hc is halted */
 		*usbconfigured = 0;
 		usb_log_info("EHCI turned off.\n");
@@ -302,4 +305,6 @@
 		usb_log_info("EHCI was not running.\n");
 	}
+	usb_log_debug("Registers: %x(0x00080000):%x(0x00001000):%x(0x0).\n",
+	    *usbcmd, *usbsts, *usbconfigured);
 
 	async_hangup(parent_phone);
Index: uspace/drv/ohci/Makefile
===================================================================
--- uspace/drv/ohci/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,16 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBHOST_PREFIX)/libusbhost.a \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBUSBHOST_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = ohci
 
Index: uspace/drv/ohci/hc.c
===================================================================
--- uspace/drv/ohci/hc.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/hc.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -40,5 +40,4 @@
 #include <usb/usb.h>
 #include <usb/ddfiface.h>
-#include <usb/usbdevice.h>
 
 #include "hc.h"
@@ -95,6 +94,5 @@
 }
 /*----------------------------------------------------------------------------*/
-int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
-    uintptr_t regs, size_t reg_size, bool interrupts)
+int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts)
 {
 	assert(instance);
Index: uspace/drv/ohci/hc.h
===================================================================
--- uspace/drv/ohci/hc.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/hc.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -77,6 +77,5 @@
 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
 
-int hc_init(hc_t *instance, ddf_fun_t *fun, ddf_dev_t *dev,
-     uintptr_t regs, size_t reg_size, bool interrupts);
+int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
 
 void hc_start_hw(hc_t *instance);
Index: uspace/drv/ohci/hw_struct/endpoint_descriptor.h
===================================================================
--- uspace/drv/ohci/hw_struct/endpoint_descriptor.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/hw_struct/endpoint_descriptor.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -40,5 +40,5 @@
 #include <usb/host/endpoint.h>
 
-#include "utils/malloc32.h"
+#include "../utils/malloc32.h"
 #include "transfer_descriptor.h"
 
Index: uspace/drv/ohci/hw_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/ohci/hw_struct/transfer_descriptor.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/hw_struct/transfer_descriptor.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -33,6 +33,4 @@
  */
 #include <usb/usb.h>
-#include "utils/malloc32.h"
-
 #include "transfer_descriptor.h"
 
Index: uspace/drv/ohci/hw_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/ohci/hw_struct/transfer_descriptor.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/hw_struct/transfer_descriptor.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -37,5 +37,5 @@
 #include <bool.h>
 #include <stdint.h>
-#include "utils/malloc32.h"
+#include "../utils/malloc32.h"
 
 #include "completion_codes.h"
Index: uspace/drv/ohci/iface.c
===================================================================
--- uspace/drv/ohci/iface.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/iface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -122,4 +122,24 @@
 	return EOK;
 }
+
+
+/** Find device handle by address interface function.
+ *
+ * @param[in] fun DDF function that was called.
+ * @param[in] address Address in question.
+ * @param[out] handle Where to store device handle if found.
+ * @return Error code.
+ */
+static int find_by_address(ddf_fun_t *fun, usb_address_t address,
+    devman_handle_t *handle)
+{
+	assert(fun);
+	hc_t *hc = fun_to_hc(fun);
+	assert(hc);
+	bool found =
+	    usb_device_keeper_find_by_address(&hc->manager, address, handle);
+	return found ? EOK : ENOENT;
+}
+
 /*----------------------------------------------------------------------------*/
 /** Release address interface function
@@ -402,4 +422,5 @@
 	.request_address = request_address,
 	.bind_address = bind_address,
+	.find_by_address = find_by_address,
 	.release_address = release_address,
 
Index: uspace/drv/ohci/main.c
===================================================================
--- uspace/drv/ohci/main.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/main.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -43,5 +43,24 @@
 #define NAME "ohci"
 
-static int ohci_add_device(ddf_dev_t *device);
+/** Initializes a new ddf driver instance of OHCI hcd.
+ *
+ * @param[in] device DDF instance of the device to initialize.
+ * @return Error code.
+ */
+static int ohci_add_device(ddf_dev_t *device)
+{
+	usb_log_debug("ohci_add_device() called\n");
+	assert(device);
+
+	int ret = device_setup_ohci(device);
+	if (ret != EOK) {
+		usb_log_error("Failed to initialize OHCI driver: %s.\n",
+		    str_error(ret));
+		return ret;
+	}
+	usb_log_info("Controlling new OHCI device '%s'.\n", device->name);
+
+	return EOK;
+}
 /*----------------------------------------------------------------------------*/
 static driver_ops_t ohci_driver_ops = {
@@ -53,33 +72,4 @@
 	.driver_ops = &ohci_driver_ops
 };
-/*----------------------------------------------------------------------------*/
-/** Initializes a new ddf driver instance of OHCI hcd.
- *
- * @param[in] device DDF instance of the device to initialize.
- * @return Error code.
- */
-int ohci_add_device(ddf_dev_t *device)
-{
-	usb_log_debug("ohci_add_device() called\n");
-	assert(device);
-	ohci_t *ohci = malloc(sizeof(ohci_t));
-	if (ohci == NULL) {
-		usb_log_error("Failed to allocate OHCI driver.\n");
-		return ENOMEM;
-	}
-
-	int ret = ohci_init(ohci, device);
-	if (ret != EOK) {
-		usb_log_error("Failed to initialize OHCI driver: %s.\n",
-		    str_error(ret));
-		return ret;
-	}
-//	device->driver_data = ohci;
-	hc_register_hub(&ohci->hc, ohci->rh_fun);
-
-	usb_log_info("Controlling new OHCI device `%s'.\n", device->name);
-
-	return EOK;
-}
 /*----------------------------------------------------------------------------*/
 /** Initializes global driver structures (NONE).
Index: uspace/drv/ohci/ohci.c
===================================================================
--- uspace/drv/ohci/ohci.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/ohci.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -44,4 +44,21 @@
 #include "iface.h"
 #include "pci.h"
+#include "hc.h"
+#include "root_hub.h"
+
+typedef struct ohci {
+	ddf_fun_t *hc_fun;
+	ddf_fun_t *rh_fun;
+
+	hc_t hc;
+	rh_t rh;
+} ohci_t;
+
+static inline ohci_t * dev_to_ohci(ddf_dev_t *dev)
+{
+	assert(dev);
+	assert(dev->driver_data);
+	return dev->driver_data;
+}
 
 /** IRQ handling callback, identifies device
@@ -53,9 +70,7 @@
 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
 {
-	assert(dev);
-	assert(dev->driver_data);
-	hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
-	uint16_t status = IPC_GET_ARG1(*call);
+	hc_t *hc = &dev_to_ohci(dev)->hc;
 	assert(hc);
+	const uint16_t status = IPC_GET_ARG1(*call);
 	hc_interrupt(hc, status);
 }
@@ -71,5 +86,5 @@
 {
 	assert(fun);
-	usb_device_keeper_t *manager = &((ohci_t*)fun->dev->driver_data)->hc.manager;
+	usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
 
 	usb_address_t addr = usb_device_keeper_find(manager, handle);
@@ -94,13 +109,14 @@
     ddf_fun_t *fun, devman_handle_t *handle)
 {
-	assert(handle);
-	ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun;
-	assert(hc_fun != NULL);
-
-	*handle = hc_fun->handle;
+	assert(fun);
+	ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun;
+	assert(hc_fun);
+
+	if (handle != NULL)
+		*handle = hc_fun->handle;
 	return EOK;
 }
 /*----------------------------------------------------------------------------*/
-/** This iface is generic for both RH and HC. */
+/** Root hub USB interface */
 static usb_iface_t usb_iface = {
 	.get_hc_handle = usb_iface_get_hc_handle,
@@ -108,8 +124,10 @@
 };
 /*----------------------------------------------------------------------------*/
+/** Standard USB HC options (HC interface) */
 static ddf_dev_ops_t hc_ops = {
 	.interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
 };
 /*----------------------------------------------------------------------------*/
+/** Standard USB RH options (RH interface) */
 static ddf_dev_ops_t rh_ops = {
 	.interfaces[USB_DEV_IFACE] = &usb_iface,
@@ -118,6 +136,6 @@
 /** Initialize hc and rh ddf structures and their respective drivers.
  *
+ * @param[in] device DDF instance of the device to use.
  * @param[in] instance OHCI structure to use.
- * @param[in] device DDF instance of the device to use.
  *
  * This function does all the preparatory work for hc and rh drivers:
@@ -127,34 +145,55 @@
  *  - registers interrupt handler
  */
-int ohci_init(ohci_t *instance, ddf_dev_t *device)
-{
-	assert(instance);
-	instance->hc_fun = NULL;
+int device_setup_ohci(ddf_dev_t *device)
+{
+	ohci_t *instance = malloc(sizeof(ohci_t));
+	if (instance == NULL) {
+		usb_log_error("Failed to allocate OHCI driver.\n");
+		return ENOMEM;
+	}
+
+#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
+if (ret != EOK) { \
+	if (instance->hc_fun) { \
+		instance->hc_fun->ops = NULL; \
+		instance->hc_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->hc_fun); \
+	} \
+	if (instance->rh_fun) { \
+		instance->rh_fun->ops = NULL; \
+		instance->rh_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->rh_fun); \
+	} \
+	free(instance); \
+	usb_log_error(message); \
+	return ret; \
+} else (void)0
+
 	instance->rh_fun = NULL;
-#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
-if (ret != EOK) { \
-	usb_log_error(message); \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) \
-		ddf_fun_destroy(instance->rh_fun); \
-	return ret; \
-}
-
-	uintptr_t mem_reg_base = 0;
-	size_t mem_reg_size = 0;
+	instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
+	int ret = instance->hc_fun ? EOK : ENOMEM;
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n");
+	instance->hc_fun->ops = &hc_ops;
+	instance->hc_fun->driver_data = &instance->hc;
+
+	instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
+	ret = instance->rh_fun ? EOK : ENOMEM;
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n");
+	instance->rh_fun->ops = &rh_ops;
+
+	uintptr_t reg_base = 0;
+	size_t reg_size = 0;
 	int irq = 0;
 
-	int ret =
-	    pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+	ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to get memory addresses for %" PRIun ": %s.\n",
 	    device->handle, str_error(ret));
 	usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
-	    (void *) mem_reg_base, mem_reg_size, irq);
+	    (void *) reg_base, reg_size, irq);
 
 	bool interrupts = false;
 #ifdef CONFIG_USBHC_NO_INTERRUPTS
-	usb_log_warning("Interrupts disabled in OS config, " \
+	usb_log_warning("Interrupts disabled in OS config, "
 	    "falling back to polling.\n");
 #else
@@ -163,5 +202,5 @@
 		usb_log_warning("Failed to enable interrupts: %s.\n",
 		    str_error(ret));
-		usb_log_info("HW interrupts not available, " \
+		usb_log_info("HW interrupts not available, "
 		    "falling back to polling.\n");
 	} else {
@@ -171,34 +210,12 @@
 #endif
 
-	instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
-	ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed(%d) to create HC function.\n", ret);
-
-	ret = hc_init(&instance->hc, instance->hc_fun, device,
-	    mem_reg_base, mem_reg_size, interrupts);
-	CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
-	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc;
-	ret = ddf_fun_bind(instance->hc_fun);
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed(%d) to bind OHCI device function: %s.\n",
-	    ret, str_error(ret));
-	ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed to add OHCI to HC class: %s.\n", str_error(ret));
-
-#undef CHECK_RET_HC_RETURN
+	ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
 
 #define CHECK_RET_FINI_RETURN(ret, message...) \
 if (ret != EOK) { \
-	usb_log_error(message); \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) \
-		ddf_fun_destroy(instance->rh_fun); \
 	hc_fini(&instance->hc); \
-	return ret; \
-}
+	CHECK_RET_DEST_FREE_RETURN(ret, message); \
+} else (void)0
 
 	/* It does no harm if we register this on polling */
@@ -208,17 +225,20 @@
 	    "Failed(%d) to register interrupt handler.\n", ret);
 
-	instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
-	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
+	ret = ddf_fun_bind(instance->hc_fun);
 	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to create root hub function.\n", ret);
-
-
-	instance->rh_fun->ops = &rh_ops;
-	instance->rh_fun->driver_data = NULL;
-	
+	    "Failed(%d) to bind OHCI device function: %s.\n",
+	    ret, str_error(ret));
+
+	ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed to add OHCI to HC class: %s.\n", str_error(ret));
+
 	device->driver_data = instance;
 
 	hc_start_hw(&instance->hc);
+	hc_register_hub(&instance->hc, instance->rh_fun);
 	return EOK;
+
+#undef CHECK_RET_DEST_FUN_RETURN
 #undef CHECK_RET_FINI_RETURN
 }
Index: uspace/drv/ohci/ohci.h
===================================================================
--- uspace/drv/ohci/ohci.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/ohci.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -38,16 +38,5 @@
 #include <ddf/driver.h>
 
-#include "hc.h"
-#include "root_hub.h"
-
-typedef struct ohci {
-	ddf_fun_t *hc_fun;
-	ddf_fun_t *rh_fun;
-
-	hc_t hc;
-	rh_t rh;
-} ohci_t;
-
-int ohci_init(ohci_t *instance, ddf_dev_t *device);
+int device_setup_ohci(ddf_dev_t *device);
 
 #endif
Index: uspace/drv/ohci/pci.c
===================================================================
--- uspace/drv/ohci/pci.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/pci.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -58,5 +58,8 @@
     uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no)
 {
-	assert(dev != NULL);
+	assert(dev);
+	assert(mem_reg_address);
+	assert(mem_reg_size);
+	assert(irq_no);
 
 	int parent_phone = devman_parent_device_connect(dev->handle,
Index: uspace/drv/ohci/root_hub.c
===================================================================
--- uspace/drv/ohci/root_hub.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/ohci/root_hub.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -237,5 +237,5 @@
 		return ENOMEM;
 
-	usb_log_info("OHCI root hub with %d ports initialized.\n",
+	usb_log_info("OHCI root hub with %zu ports initialized.\n",
 	    instance->port_count);
 
Index: uspace/drv/uhci-hcd/Makefile
===================================================================
--- uspace/drv/uhci-hcd/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBHOST_PREFIX)/libusbhost.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBHOST_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = uhci-hcd
 
Index: uspace/drv/uhci-hcd/hc.c
===================================================================
--- uspace/drv/uhci-hcd/hc.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/hc.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -60,5 +60,4 @@
  *
  * @param[in] instance Memory place to initialize.
- * @param[in] fun DDF function.
  * @param[in] regs Address of I/O control registers.
  * @param[in] size Size of I/O control registers.
@@ -69,6 +68,5 @@
  * interrupt fibrils.
  */
-int hc_init(hc_t *instance, ddf_fun_t *fun,
-    void *regs, size_t reg_size, bool interrupts)
+int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interrupts)
 {
 	assert(reg_size >= sizeof(regs_t));
Index: uspace/drv/uhci-hcd/hc.h
===================================================================
--- uspace/drv/uhci-hcd/hc.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/hc.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -136,6 +136,5 @@
 } hc_t;
 
-int hc_init(hc_t *instance, ddf_fun_t *fun,
-    void *regs, size_t reg_size, bool interupts);
+int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
 
 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);
Index: uspace/drv/uhci-hcd/hw_struct/queue_head.h
===================================================================
--- uspace/drv/uhci-hcd/hw_struct/queue_head.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/hw_struct/queue_head.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -38,5 +38,5 @@
 #include "link_pointer.h"
 #include "transfer_descriptor.h"
-#include "utils/malloc32.h"
+#include "../utils/malloc32.h"
 
 /** This structure is defined in UHCI design guide p. 31 */
Index: uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c
===================================================================
--- uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -36,5 +36,5 @@
 
 #include "transfer_descriptor.h"
-#include "utils/malloc32.h"
+#include "../utils/malloc32.h"
 
 /** Initialize Transfer Descriptor
Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/iface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -122,4 +122,23 @@
 	return EOK;
 }
+
+/** Find device handle by address interface function.
+ *
+ * @param[in] fun DDF function that was called.
+ * @param[in] address Address in question.
+ * @param[out] handle Where to store device handle if found.
+ * @return Error code.
+ */
+static int find_by_address(ddf_fun_t *fun, usb_address_t address,
+    devman_handle_t *handle)
+{
+	assert(fun);
+	hc_t *hc = fun_to_hc(fun);
+	assert(hc);
+	bool found =
+	    usb_device_keeper_find_by_address(&hc->manager, address, handle);
+	return found ? EOK : ENOENT;
+}
+
 /*----------------------------------------------------------------------------*/
 /** Release address interface function
@@ -352,4 +371,5 @@
 	.request_address = request_address,
 	.bind_address = bind_address,
+	.find_by_address = find_by_address,
 	.release_address = release_address,
 
Index: uspace/drv/uhci-hcd/main.c
===================================================================
--- uspace/drv/uhci-hcd/main.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/main.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -64,11 +64,5 @@
 	assert(device);
 
-	uhci_t *uhci = malloc(sizeof(uhci_t));
-	if (uhci == NULL) {
-		usb_log_error("Failed to allocate UHCI driver.\n");
-		return ENOMEM;
-	}
-
-	int ret = uhci_init(uhci, device);
+	int ret = device_setup_uhci(device);
 	if (ret != EOK) {
 		usb_log_error("Failed to initialize UHCI driver: %s.\n",
@@ -76,6 +70,4 @@
 		return ret;
 	}
-	device->driver_data = uhci;
-
 	usb_log_info("Controlling new UHCI device '%s'.\n", device->name);
 
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -44,4 +44,28 @@
 #include "pci.h"
 
+#include "hc.h"
+#include "root_hub.h"
+
+/** Structure representing both functions of UHCI hc, USB host controller
+ * and USB root hub */
+typedef struct uhci {
+	/** Pointer to DDF represenation of UHCI host controller */
+	ddf_fun_t *hc_fun;
+	/** Pointer to DDF represenation of UHCI root hub */
+	ddf_fun_t *rh_fun;
+
+	/** Internal driver's represenation of UHCI host controller */
+	hc_t hc;
+	/** Internal driver's represenation of UHCI root hub */
+	rh_t rh;
+} uhci_t;
+
+static inline uhci_t * dev_to_uhci(ddf_dev_t *dev)
+{
+	assert(dev);
+	assert(dev->driver_data);
+	return dev->driver_data;
+}
+/*----------------------------------------------------------------------------*/
 /** IRQ handling callback, forward status from call to diver structure.
  *
@@ -69,8 +93,7 @@
 {
 	assert(fun);
-	usb_device_keeper_t *manager =
-	    &((uhci_t*)fun->dev->driver_data)->hc.manager;
-
+	usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
 	usb_address_t addr = usb_device_keeper_find(manager, handle);
+
 	if (addr < 0) {
 		return addr;
@@ -93,9 +116,10 @@
     ddf_fun_t *fun, devman_handle_t *handle)
 {
-	assert(handle);
-	ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun;
-	assert(hc_fun != NULL);
-
-	*handle = hc_fun->handle;
+	assert(fun);
+	ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
+	assert(hc_fun);
+
+	if (handle != NULL)
+		*handle = hc_fun->handle;
 	return EOK;
 }
@@ -126,5 +150,5 @@
 static hw_res_ops_t hw_res_iface = {
 	.get_resource_list = get_resource_list,
-	.enable_interrupt = NULL
+	.enable_interrupt = NULL,
 };
 /*----------------------------------------------------------------------------*/
@@ -146,33 +170,55 @@
  *  - registers interrupt handler
  */
-int uhci_init(uhci_t *instance, ddf_dev_t *device)
-{
-	assert(instance);
-	instance->hc_fun = NULL;
+int device_setup_uhci(ddf_dev_t *device)
+{
+	assert(device);
+	uhci_t *instance = malloc(sizeof(uhci_t));
+	if (instance == NULL) {
+		usb_log_error("Failed to allocate OHCI driver.\n");
+		return ENOMEM;
+	}
+
+#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
+if (ret != EOK) { \
+	if (instance->hc_fun) \
+		instance->hc_fun->ops = NULL; \
+		instance->hc_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->hc_fun); \
+	if (instance->rh_fun) {\
+		instance->rh_fun->ops = NULL; \
+		instance->rh_fun->driver_data = NULL; \
+		ddf_fun_destroy(instance->rh_fun); \
+	} \
+	free(instance); \
+	usb_log_error(message); \
+	return ret; \
+} else (void)0
+
 	instance->rh_fun = NULL;
-#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
-if (ret != EOK) { \
-	usb_log_error(message); \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) \
-		ddf_fun_destroy(instance->rh_fun); \
-	return ret; \
-}
-
-	uintptr_t io_reg_base = 0;
-	size_t io_reg_size = 0;
+	instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
+	int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
+	instance->hc_fun->ops = &hc_ops;
+	instance->hc_fun->driver_data = &instance->hc;
+
+	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
+	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
+	CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
+	instance->rh_fun->ops = &rh_ops;
+	instance->rh_fun->driver_data = &instance->rh;
+
+	uintptr_t reg_base = 0;
+	size_t reg_size = 0;
 	int irq = 0;
 
-	int ret =
-	    pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+	ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
+	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed to get I/O addresses for %" PRIun ": %s.\n",
 	    device->handle, str_error(ret));
 	usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
-	    (void *) io_reg_base, io_reg_size, irq);
+	    (void *) reg_base, reg_size, irq);
 
 	ret = pci_disable_legacy(device);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
 
@@ -194,36 +240,15 @@
 #endif
 
-	instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
-	ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed(%d) to create HC function: %s.\n", ret, str_error(ret));
-
-	ret = hc_init(&instance->hc, instance->hc_fun,
-	    (void*)io_reg_base, io_reg_size, interrupts);
-	CHECK_RET_DEST_FUN_RETURN(ret,
+
+	ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
+	CHECK_RET_DEST_FREE_RETURN(ret,
 	    "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret));
-
-	instance->hc_fun->ops = &hc_ops;
-	instance->hc_fun->driver_data = &instance->hc;
-	ret = ddf_fun_bind(instance->hc_fun);
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed(%d) to bind UHCI device function: %s.\n",
-	    ret, str_error(ret));
-	ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
-	CHECK_RET_DEST_FUN_RETURN(ret,
-	    "Failed to add UHCI to HC class: %s.\n", str_error(ret));
-
-#undef CHECK_RET_HC_RETURN
 
 #define CHECK_RET_FINI_RETURN(ret, message...) \
 if (ret != EOK) { \
-	usb_log_error(message); \
-	if (instance->hc_fun) \
-		ddf_fun_destroy(instance->hc_fun); \
-	if (instance->rh_fun) \
-		ddf_fun_destroy(instance->rh_fun); \
 	hc_fini(&instance->hc); \
+	CHECK_RET_DEST_FREE_RETURN(ret, message); \
 	return ret; \
-}
+} else (void)0
 
 	/* It does no harm if we register this on polling */
@@ -234,9 +259,12 @@
 	    ret, str_error(ret));
 
-	instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
-	ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
-	CHECK_RET_FINI_RETURN(ret,
-	    "Failed(%d) to create root hub function: %s.\n",
+	ret = ddf_fun_bind(instance->hc_fun);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed(%d) to bind UHCI device function: %s.\n",
 	    ret, str_error(ret));
+
+	ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
+	CHECK_RET_FINI_RETURN(ret,
+	    "Failed to add UHCI to HC class: %s.\n", str_error(ret));
 
 	ret = rh_init(&instance->rh, instance->rh_fun,
@@ -245,10 +273,9 @@
 	    "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
 
-	instance->rh_fun->ops = &rh_ops;
-	instance->rh_fun->driver_data = &instance->rh;
 	ret = ddf_fun_bind(instance->rh_fun);
 	CHECK_RET_FINI_RETURN(ret,
 	    "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
 
+	device->driver_data = instance;
 	return EOK;
 #undef CHECK_RET_FINI_RETURN
Index: uspace/drv/uhci-hcd/uhci.h
===================================================================
--- uspace/drv/uhci-hcd/uhci.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-hcd/uhci.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -38,22 +38,5 @@
 #include <ddf/driver.h>
 
-#include "hc.h"
-#include "root_hub.h"
-
-/** Structure representing both functions of UHCI hc, USB host controller
- * and USB root hub */
-typedef struct uhci {
-	/** Pointer to DDF represenation of UHCI host controller */
-	ddf_fun_t *hc_fun;
-	/** Pointer to DDF represenation of UHCI root hub */
-	ddf_fun_t *rh_fun;
-
-	/** Internal driver's represenation of UHCI host controller */
-	hc_t hc;
-	/** Internal driver's represenation of UHCI root hub */
-	rh_t rh;
-} uhci_t;
-
-int uhci_init(uhci_t *instance, ddf_dev_t *device);
+int device_setup_uhci(ddf_dev_t *device);
 #endif
 /**
Index: uspace/drv/uhci-rhd/Makefile
===================================================================
--- uspace/drv/uhci-rhd/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-rhd/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = uhci-rhd
 
Index: uspace/drv/uhci-rhd/port.c
===================================================================
--- uspace/drv/uhci-rhd/port.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/uhci-rhd/port.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -32,11 +32,11 @@
  * @brief UHCI root hub port routines
  */
-#include <libarch/ddi.h> /* pio_read and pio_write */
+#include <libarch/ddi.h>  /* pio_read and pio_write */
+#include <fibril_synch.h> /* async_usleep */
 #include <errno.h>
 #include <str_error.h>
-#include <fibril_synch.h>
 
 #include <usb/usb.h>    /* usb_address_t */
-#include <usb/hub.h>
+#include <usb/hub.h>    /* usb_hc_new_device_wrapper */
 #include <usb/debug.h>
 
@@ -212,11 +212,5 @@
 
 	/*
-	 * The host then waits for at least 100 ms to allow completion of
-	 * an insertion process and for power at the device to become stable.
-	 */
-	async_usleep(100000);
-
-	/*
-	 * Resets from root ports should be nominally 50ms
+	 * Resets from root ports should be nominally 50ms (USB spec 7.1.7.3)
 	 */
 	{
@@ -229,12 +223,17 @@
 		port_status &= ~STATUS_IN_RESET;
 		uhci_port_write_status(port, port_status);
-		usb_log_debug("%s: Reset Signal stop.\n", port->id_string);
-	}
-
-	/* the reset recovery time 10ms */
-	async_usleep(10000);
-
+		while (uhci_port_read_status(port) & STATUS_IN_RESET);
+		// TODO: find a better way to waste time (it should be less than
+		// 10ms, if we reschedule it takes too much time (random
+		// interrupts can be solved by multiple attempts).
+		usb_log_debug2("%s: Reset Signal stop.\n", port->id_string);
+	}
 	/* Enable the port. */
 	uhci_port_set_enabled(port, true);
+
+	/* Reset recovery period,
+	 * devices do not have to respond during this period
+	 */
+	async_usleep(10000);
 	return EOK;
 }
@@ -255,8 +254,11 @@
 	usb_log_debug("%s: Detected new device.\n", port->id_string);
 
+	int ret, count = 0;
 	usb_address_t dev_addr;
-	int ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
-	    speed, uhci_port_reset_enable, port->number, port,
-	    &dev_addr, &port->attached_device, NULL, NULL, NULL);
+	do {
+		ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
+		    speed, uhci_port_reset_enable, port->number, port,
+		    &dev_addr, &port->attached_device, NULL, NULL, NULL);
+	} while (ret != EOK && ++count < 4);
 
 	if (ret != EOK) {
@@ -313,5 +315,4 @@
 	/* Wait for port to become enabled */
 	do {
-		async_usleep(1000);
 		port_status = uhci_port_read_status(port);
 	} while ((port_status & STATUS_CONNECTED) &&
Index: uspace/drv/usbflbk/Makefile
===================================================================
--- uspace/drv/usbflbk/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbflbk/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = usbflbk
 
Index: uspace/drv/usbhid/Makefile
===================================================================
--- uspace/drv/usbhid/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbhid/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,17 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBHID_PREFIX)/libusbhid.a \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I. \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBUSBHID_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = usbhid
 
Index: uspace/drv/usbhub/Makefile
===================================================================
--- uspace/drv/usbhub/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbhub/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = usbhub
 
Index: uspace/drv/usbkbd/Makefile
===================================================================
--- uspace/drv/usbkbd/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbkbd/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,17 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBHID_PREFIX)/libusbhid.a \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I. \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBUSBHID_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = usbkbd
 
Index: uspace/drv/usbmast/Makefile
===================================================================
--- uspace/drv/usbmast/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbmast/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,9 +28,18 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+
 BINARY = usbmast
 
 SOURCES = \
+	inquiry.c \
 	main.c \
 	mast.c
Index: uspace/drv/usbmast/inquiry.c
===================================================================
--- uspace/drv/usbmast/inquiry.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/drv/usbmast/inquiry.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,193 @@
+/*
+ * 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 drvusbmast
+ * @{
+ */
+/**
+ * @file
+ * Main routines of USB mass storage driver.
+ */
+#include <usb/devdrv.h>
+#include <usb/debug.h>
+#include <usb/classes/classes.h>
+#include <usb/classes/massstor.h>
+#include <errno.h>
+#include <str_error.h>
+#include <str.h>
+#include <ctype.h>
+#include "cmds.h"
+#include "scsi.h"
+#include "mast.h"
+
+#define BITS_GET_MASK(type, bitcount) (((type)(1 << (bitcount)))-1)
+#define BITS_GET_MID_MASK(type, bitcount, offset) \
+	((type)( BITS_GET_MASK(type, (bitcount) + (offset)) - BITS_GET_MASK(type, bitcount) ))
+#define BITS_GET(type, number, bitcount, offset) \
+	((type)( (number) & (BITS_GET_MID_MASK(type, bitcount, offset)) ) >> (offset))
+
+#define INQUIRY_RESPONSE_LENGTH 36
+
+#define STR_UNKNOWN "<unknown>"
+
+/** String constants for SCSI peripheral device types. */
+static const char *str_peripheral_device_types[] = {
+	"direct-access device",
+	"sequential-access device",
+	"printer device",
+	"processor device",
+	"write-once device",
+	"CDROM device",
+	"scanner device",
+	"optical memory device",
+	"medium changer",
+	"communications device",
+	"graphic arts pre-press device",
+	"graphic arts pre-press device",
+	"storage array controller device",
+	"enclosure services device",
+	"simplified direct-access device",
+	"optical card reader/writer device",
+	"bridging expander",
+	"object-based storage device",
+	"automation driver interface",
+	STR_UNKNOWN, // 0x13
+	STR_UNKNOWN, // 0x14
+	STR_UNKNOWN, // 0x15
+	STR_UNKNOWN, // 0x16
+	STR_UNKNOWN, // 0x17
+	STR_UNKNOWN, // 0x18
+	STR_UNKNOWN, // 0x19
+	STR_UNKNOWN, // 0x1A
+	STR_UNKNOWN, // 0x1B
+	STR_UNKNOWN, // 0x1C
+	STR_UNKNOWN, // 0x1D
+	"well-known logical unit",
+	"uknown or no device state"
+};
+#define str_peripheral_device_types_count \
+	(sizeof(str_peripheral_device_types)/sizeof(str_peripheral_device_types[0]))
+
+/** Get string representation for SCSI peripheral device type.
+ *
+ * See for example here for a list
+ * http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type.
+ *
+ * @param type SCSI peripheral device type code.
+ * @return String representation.
+ */
+const char *usb_str_masstor_scsi_peripheral_device_type(int type)
+{
+	if ((type < 0)
+	    || ((size_t)type >= str_peripheral_device_types_count)) {
+		return STR_UNKNOWN;
+	}
+	return str_peripheral_device_types[type];
+}
+
+/** Trim trailing spaces from a string (rewrite with string terminator).
+ *
+ * @param name String to be trimmed (in-out parameter).
+ */
+static void trim_trailing_spaces(char *name)
+{
+	size_t len = str_length(name);
+	while ((len > 0) && isspace((int) name[len - 1])) {
+		name[len - 1] = 0;
+		len--;
+	}
+}
+
+/** Perform SCSI INQUIRY command on USB mass storage device.
+ *
+ * @param dev USB device.
+ * @param bulk_in_idx Index (in dev->pipes) of bulk in pipe.
+ * @param bulk_out_idx Index of bulk out pipe.
+ * @param inquiry_result Where to store parsed inquiry result.
+ * @return Error code.
+ */
+int usb_massstor_inquiry(usb_device_t *dev,
+    size_t bulk_in_idx, size_t bulk_out_idx,
+    usb_massstor_inquiry_result_t *inquiry_result)
+{
+	scsi_cmd_inquiry_t inquiry = {
+		.op_code = 0x12,
+		.lun_evpd = 0,
+		.page_code = 0,
+		.alloc_length = host2uint16_t_be(INQUIRY_RESPONSE_LENGTH),
+		.ctrl = 0
+	};
+	size_t response_len;
+	uint8_t response[INQUIRY_RESPONSE_LENGTH];
+
+	int rc;
+
+	rc = usb_massstor_data_in(dev, bulk_in_idx, bulk_out_idx,
+	    0xDEADBEEF, 0, (uint8_t *) &inquiry, sizeof(inquiry),
+	    response, INQUIRY_RESPONSE_LENGTH, &response_len);
+
+	if (rc != EOK) {
+		usb_log_error("Failed to probe device %s using %s: %s.\n",
+		   dev->ddf_dev->name, "SCSI:INQUIRY", str_error(rc));
+		return rc;
+	}
+
+	if (response_len < 8) {
+		usb_log_error("The SCSI response is too short.\n");
+		return ERANGE;
+	}
+
+	/*
+	 * This is an ugly part of the code. We will parse the returned
+	 * data by hand and try to get as many useful data as possible.
+	 */
+	bzero(inquiry_result, sizeof(*inquiry_result));
+
+	/* This shall be returned by all devices. */
+	inquiry_result->peripheral_device_type
+	    = BITS_GET(uint8_t, response[0], 5, 0);
+	inquiry_result->removable = BITS_GET(uint8_t, response[1], 1, 7);
+
+	if (response_len < 32) {
+		return EOK;
+	}
+
+	str_ncpy(inquiry_result->vendor_id, 9,
+	    (const char *) &response[8], 8);
+	trim_trailing_spaces(inquiry_result->vendor_id);
+
+	str_ncpy(inquiry_result->product_and_revision, 12,
+	    (const char *) &response[16], 11);
+	trim_trailing_spaces(inquiry_result->product_and_revision);
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/usbmast/main.c
===================================================================
--- uspace/drv/usbmast/main.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbmast/main.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -75,65 +75,4 @@
 };
 
-#define BITS_GET_MASK(type, bitcount) (((type)(1 << (bitcount)))-1)
-#define BITS_GET_MID_MASK(type, bitcount, offset) \
-	((type)( BITS_GET_MASK(type, (bitcount) + (offset)) - BITS_GET_MASK(type, bitcount) ))
-#define BITS_GET(type, number, bitcount, offset) \
-	((type)( (number) & (BITS_GET_MID_MASK(type, bitcount, offset)) ) >> (offset))
-
-#define INQUIRY_RESPONSE_LENGTH 35
-
-static void try_inquiry(usb_device_t *dev)
-{
-	scsi_cmd_inquiry_t inquiry = {
-		.op_code = 0x12,
-		.lun_evpd = 0,
-		.page_code = 0,
-		.alloc_length = INQUIRY_RESPONSE_LENGTH,
-		.ctrl = 0
-	};
-	size_t response_len;
-	uint8_t response[INQUIRY_RESPONSE_LENGTH];
-
-	int rc;
-
-	rc = usb_massstor_data_in(GET_BULK_IN(dev), GET_BULK_OUT(dev),
-	    0xDEADBEEF, 0, (uint8_t *) &inquiry, sizeof(inquiry),
-	    response, INQUIRY_RESPONSE_LENGTH, &response_len);
-
-	if (rc != EOK) {
-		usb_log_error("Failed to probe device %s using %s: %s.\n",
-		   dev->ddf_dev->name, "SCSI:INQUIRY", str_error(rc));
-		return;
-	}
-
-	if (response_len < 8) {
-		usb_log_error("The SCSI response is too short.\n");
-		return;
-	}
-
-	/*
-	 * This is an ugly part of the code. We will parse the returned
-	 * data by hand and try to get as many useful data as possible.
-	 */
-	int device_type = BITS_GET(uint8_t, response[0], 5, 0);
-	int removable = BITS_GET(uint8_t, response[1], 1, 7);
-
-	usb_log_info("SCSI information for device `%s':\n", dev->ddf_dev->name);
-	usb_log_info("  - peripheral device type: %d\n", device_type);
-	usb_log_info("  - removable: %s\n", removable ? "yes" : "no");
-
-	if (response_len < 32) {
-		return;
-	}
-
-	char dev_vendor[9];
-	str_ncpy(dev_vendor, 9, (const char *) &response[8], 8);
-	usb_log_info("  - vendor: '%s'\n", dev_vendor);
-
-	char dev_product[9];
-	str_ncpy(dev_product, 9, (const char *) &response[16], 8);
-	usb_log_info("  - product: '%s'\n", dev_vendor);
-}
-
 /** Callback when new device is attached and recognized as a mass storage.
  *
@@ -168,5 +107,21 @@
 	    (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size);
 
-	try_inquiry(dev);
+	size_t lun_count = usb_masstor_get_lun_count(dev);
+
+	usb_massstor_inquiry_result_t inquiry;
+	rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry);
+	if (rc != EOK) {
+		usb_log_warning("Failed to inquiry device `%s': %s.\n",
+		    dev->ddf_dev->name, str_error(rc));
+		return EOK;
+	}
+
+	usb_log_info("Mass storage `%s': " \
+	    "`%s' by `%s' is %s (%s), %zu LUN(s).\n",
+	    dev->ddf_dev->name,
+	    inquiry.product_and_revision, inquiry.vendor_id,
+	    usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type),
+	    inquiry.removable ? "removable" : "non-removable",
+	    lun_count);
 
 	return EOK;
Index: uspace/drv/usbmast/mast.c
===================================================================
--- uspace/drv/usbmast/mast.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbmast/mast.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -40,4 +40,5 @@
 #include <str_error.h>
 #include <usb/debug.h>
+#include <usb/request.h>
 
 bool usb_mast_verbose = true;
@@ -63,5 +64,6 @@
  * @return Error code.
  */
-int usb_massstor_data_in(usb_pipe_t *bulk_in_pipe, usb_pipe_t *bulk_out_pipe,
+int usb_massstor_data_in(usb_device_t *dev,
+    size_t bulk_in_pipe_index, size_t bulk_out_pipe_index,
     uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size,
     void *in_buffer, size_t in_buffer_size, size_t *received_size)
@@ -69,4 +71,6 @@
 	int rc;
 	size_t act_size;
+	usb_pipe_t *bulk_in_pipe = dev->pipes[bulk_in_pipe_index].pipe;
+	usb_pipe_t *bulk_out_pipe = dev->pipes[bulk_out_pipe_index].pipe;
 
 	/* Prepare CBW - command block wrapper */
@@ -135,4 +139,83 @@
 }
 
+/** Perform bulk-only mass storage reset.
+ *
+ * @param dev Device to be reseted.
+ * @return Error code.
+ */
+int usb_massstor_reset(usb_device_t *dev)
+{
+	return usb_control_request_set(&dev->ctrl_pipe,
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
+	    0xFF, 0, dev->interface_no, NULL, 0);
+}
+
+/** Perform complete reset recovery of bulk-only mass storage.
+ *
+ * Notice that no error is reported because if this fails, the error
+ * would reappear on next transaction somehow.
+ *
+ * @param dev Device to be reseted.
+ * @param bulk_in_idx Index of bulk in pipe.
+ * @param bulk_out_idx Index of bulk out pipe.
+ */
+void usb_massstor_reset_recovery(usb_device_t *dev,
+    size_t bulk_in_idx, size_t bulk_out_idx)
+{
+	/* We would ignore errors here because if this fails
+	 * we are doomed anyway and any following transaction would fail.
+	 */
+	usb_massstor_reset(dev);
+	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe);
+	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe);
+}
+
+/** Get max LUN of a mass storage device.
+ *
+ * @see usb_masstor_get_lun_count
+ *
+ * @warning Error from this command does not necessarily indicate malfunction
+ * of the device. Device does not need to support this request.
+ * You shall rather use usb_masstor_get_lun_count.
+ *
+ * @param dev Mass storage device.
+ * @return Error code of maximum LUN (index, not count).
+ */
+int usb_massstor_get_max_lun(usb_device_t *dev)
+{
+	uint8_t max_lun;
+	size_t data_recv_len;
+	int rc = usb_control_request_get(&dev->ctrl_pipe,
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
+	    0xFE, 0, dev->interface_no, &max_lun, 1, &data_recv_len);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (data_recv_len != 1) {
+		return EEMPTY;
+	}
+	return (int) max_lun;
+}
+
+/** Get number of LUNs supported by mass storage device.
+ *
+ * @warning This function hides any error during the request
+ * (typically that shall not be a problem).
+ *
+ * @param dev Mass storage device.
+ * @return Number of LUNs.
+ */
+size_t usb_masstor_get_lun_count(usb_device_t *dev)
+{
+	int max_lun = usb_massstor_get_max_lun(dev);
+	if (max_lun < 0) {
+		max_lun = 1;
+	} else {
+		max_lun++;
+	}
+
+	return (size_t) max_lun;
+}
+
 /**
  * @}
Index: uspace/drv/usbmast/mast.h
===================================================================
--- uspace/drv/usbmast/mast.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbmast/mast.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -40,7 +40,30 @@
 #include <usb/usb.h>
 #include <usb/pipes.h>
+#include <usb/devdrv.h>
 
-int usb_massstor_data_in(usb_pipe_t *, usb_pipe_t *, uint32_t, uint8_t,
-    void *, size_t, void *, size_t, size_t *);
+/** Result of SCSI INQUIRY command.
+ * This is already parsed structure, not the original buffer returned by
+ * the device.
+ */
+typedef struct {
+	/** SCSI peripheral device type. */
+	int peripheral_device_type;
+	/** Whether the device is removable. */
+	bool removable;
+	/** Vendor ID string. */
+	char vendor_id[9];
+	/** Product ID and product revision string. */
+	char product_and_revision[12];
+} usb_massstor_inquiry_result_t;
+
+int usb_massstor_data_in(usb_device_t *dev, size_t, size_t,
+    uint32_t, uint8_t, void *, size_t, void *, size_t, size_t *);
+int usb_massstor_reset(usb_device_t *);
+void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t);
+int usb_massstor_get_max_lun(usb_device_t *);
+size_t usb_masstor_get_lun_count(usb_device_t *);
+int usb_massstor_inquiry(usb_device_t *, size_t, size_t,
+    usb_massstor_inquiry_result_t *);
+const char *usb_str_masstor_scsi_peripheral_device_type(int);
 
 #endif
Index: uspace/drv/usbmid/Makefile
===================================================================
--- uspace/drv/usbmid/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbmid/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,14 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include
+
+LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
+	
 BINARY = usbmid
 
Index: uspace/drv/usbmouse/Makefile
===================================================================
--- uspace/drv/usbmouse/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/usbmouse/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -28,6 +28,15 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
+
+LIBS = \
+	$(LIBUSBHID_PREFIX)/libusbhid.a \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSB_PREFIX)/libusb.a \
+	$(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBUSBHID_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include
 
 BINARY = usbmouse
Index: uspace/drv/vhc/Makefile
===================================================================
--- uspace/drv/vhc/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/vhc/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -29,4 +29,6 @@
 USPACE_PREFIX = ../..
 LIBS = \
+	$(LIBUSBDEV_PREFIX)/libusbdev.a \
+	$(LIBUSBHOST_PREFIX)/libusbhost.a \
 	$(LIBUSB_PREFIX)/libusb.a \
 	$(LIBUSBVIRT_PREFIX)/libusbvirt.a \
@@ -34,4 +36,6 @@
 EXTRA_CFLAGS += \
 	-I$(LIBUSBVIRT_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBUSBHOST_PREFIX)/include \
 	-I$(LIBUSB_PREFIX)/include \
 	-I$(LIBDRV_PREFIX)/include
Index: uspace/drv/vhc/connhost.c
===================================================================
--- uspace/drv/vhc/connhost.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/drv/vhc/connhost.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -94,4 +94,20 @@
 }
 
+/** Find device handle by address interface function.
+ *
+ * @param[in] fun DDF function that was called.
+ * @param[in] address Address in question.
+ * @param[out] handle Where to store device handle if found.
+ * @return Error code.
+ */
+static int find_by_address(ddf_fun_t *fun, usb_address_t address,
+    devman_handle_t *handle)
+{
+	VHC_DATA(vhc, fun);
+	bool found =
+	    usb_device_keeper_find_by_address(&vhc->dev_keeper, address, handle);
+	return found ? EOK : ENOENT;
+}
+
 /** Release previously requested address.
  *
@@ -444,4 +460,5 @@
 	.request_address = request_address,
 	.bind_address = bind_address,
+	.find_by_address = find_by_address,
 	.release_address = release_address,
 
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -52,4 +52,5 @@
 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_find_by_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -61,4 +62,5 @@
 	remote_usbhc_request_address,
 	remote_usbhc_bind_address,
+	remote_usbhc_find_by_address,
 	remote_usbhc_release_address,
 
@@ -163,4 +165,25 @@
 }
 
+void remote_usbhc_find_by_address(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
+
+	if (!usb_iface->find_by_address) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
+	devman_handle_t handle;
+	int rc = usb_iface->find_by_address(fun, address, &handle);
+
+	if (rc == EOK) {
+		async_answer_1(callid, EOK, handle);
+	} else {
+		async_answer_0(callid, rc);
+	}
+}
+
 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
@@ -302,4 +325,5 @@
 	async_transaction_t *trans = async_transaction_create(callid);
 	if (trans == NULL) {
+		async_answer_0(data_callid, ENOMEM);
 		async_answer_0(callid, ENOMEM);
 		return;
@@ -314,4 +338,5 @@
 
 	if (rc != EOK) {
+		async_answer_0(data_callid, rc);
 		async_answer_0(callid, rc);
 		async_transaction_destroy(trans);
@@ -460,4 +485,5 @@
 	async_transaction_t *trans = async_transaction_create(callid);
 	if (trans == NULL) {
+		async_answer_0(data_callid, ENOMEM);
 		async_answer_0(callid, ENOMEM);
 		free(setup_packet);
@@ -469,4 +495,5 @@
 	trans->buffer = malloc(data_len);
 	if (trans->buffer == NULL) {
+		async_answer_0(data_callid, ENOMEM);
 		async_answer_0(callid, ENOMEM);
 		async_transaction_destroy(trans);
@@ -480,4 +507,5 @@
 
 	if (rc != EOK) {
+		async_answer_0(data_callid, rc);
 		async_answer_0(callid, rc);
 		async_transaction_destroy(trans);
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/drv/include/usb_iface.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -49,4 +49,19 @@
 	 * - arbitrary error code if returned by remote implementation
 	 * - EOK - handle found, first parameter contains the USB address
+	 *
+	 * The handle must be the one used for binding USB address with
+	 * it (IPC_M_USBHC_BIND_ADDRESS), otherwise the host controller
+	 * (that this request would eventually reach) would not be able
+	 * to find it.
+	 * The problem is that this handle is actually assigned to the
+	 * function inside driver of the parent device (usually hub driver).
+	 * To bypass this problem, the initial caller specify handle as
+	 * zero and the first parent assigns the actual value.
+	 * See usb_iface_get_address_hub_child_impl() implementation
+	 * that could be assigned to device ops of a child device of in a
+	 * hub driver.
+	 * For example, the USB multi interface device driver (MID)
+	 * passes this initial zero without any modification because the
+	 * handle must be resolved by its parent.
 	 */
 	IPC_M_USB_GET_ADDRESS,
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -105,4 +105,13 @@
 	IPC_M_USBHC_BIND_ADDRESS,
 
+	/** Get handle binded with given USB address.
+	 * Parameters
+	 * - USB address
+	 * Answer:
+	 * - EOK - address binded, first parameter is the devman handle
+	 * - ENOENT - address is not in use at the moment
+	 */
+	IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
+
 	/** Release address in use.
 	 * Arguments:
@@ -207,4 +216,5 @@
 	int (*request_address)(ddf_fun_t *, usb_speed_t, usb_address_t *);
 	int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t);
+	int (*find_by_address)(ddf_fun_t *, usb_address_t, devman_handle_t *);
 	int (*release_address)(ddf_fun_t *, usb_address_t);
 
Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/usb/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -29,37 +29,16 @@
 USPACE_PREFIX = ../..
 LIBRARY = libusb
-LIBS = $(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -Iinclude
+EXTRA_CFLAGS += \
+	-I$(LIBDRV_PREFIX)/include \
+	-Iinclude
 
 SOURCES = \
-	src/addrkeep.c \
-	src/altiface.c \
 	src/class.c \
 	src/ddfiface.c \
 	src/debug.c \
-	src/devdrv.c \
-	src/devpoll.c \
-	src/dp.c \
+	src/driver.c \
 	src/dump.c \
-	src/hidiface.c \
-	src/hidpath.c \
-	src/hidparser.c \
-	src/hiddescriptor.c \
 	src/host.c \
-	src/hub.c \
-	src/pipepriv.c \
-	src/pipes.c \
-	src/pipesinit.c \
-	src/pipesio.c \
-	src/recognise.c \
-	src/request.c \
-	src/usb.c \
-	src/usbdevice.c \
-	src/hidreq.c \
-	src/hidreport.c \
-	src/host/device_keeper.c \
-	src/host/batch.c \
-	src/host/endpoint.c \
-	src/host/usb_endpoint_manager.c
+	src/usb.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: pace/lib/usb/include/usb/addrkeep.h
===================================================================
--- uspace/lib/usb/include/usb/addrkeep.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,86 +1,0 @@
-/*
- * 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 libusb
- * @{
- */
-/** @file
- * USB address keeping for host controller drivers.
- */
-#ifndef LIBUSB_ADDRKEEP_H_
-#define LIBUSB_ADDRKEEP_H_
-
-#include <usb/usb.h>
-#include <fibril_synch.h>
-#include <devman.h>
-
-/** Info about used address. */
-typedef struct {
-	/** Linked list member. */
-	link_t link;
-	/** Address. */
-	usb_address_t address;
-	/** Corresponding devman handle. */
-	devman_handle_t devman_handle;
-} usb_address_keeping_used_t;
-
-/** Structure for keeping track of free and used USB addresses. */
-typedef struct {
-	/** Head of list of used addresses. */
-	link_t used_addresses;
-	/** Upper bound for USB addresses. */
-	usb_address_t max_address;
-	/** Mutex protecting used address. */
-	fibril_mutex_t used_addresses_guard;
-	/** Condition variable for used addresses. */
-	fibril_condvar_t used_addresses_condvar;
-
-	/** Condition variable mutex for default address. */
-	fibril_mutex_t default_condvar_guard;
-	/** Condition variable for default address. */
-	fibril_condvar_t default_condvar;
-	/** Whether is default address available. */
-	bool default_available;
-} usb_address_keeping_t;
-
-void usb_address_keeping_init(usb_address_keeping_t *, usb_address_t);
-
-void usb_address_keeping_reserve_default(usb_address_keeping_t *);
-void usb_address_keeping_release_default(usb_address_keeping_t *);
-
-usb_address_t usb_address_keeping_request(usb_address_keeping_t *);
-int usb_address_keeping_release(usb_address_keeping_t *, usb_address_t);
-void usb_address_keeping_devman_bind(usb_address_keeping_t *, usb_address_t,
-    devman_handle_t);
-usb_address_t usb_address_keeping_find(usb_address_keeping_t *,
-    devman_handle_t);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*
- * 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 libusb
- * @{
- */
-/** @file
- * @brief USB HID device related types.
- */
-#ifndef LIBUSB_HID_H_
-#define LIBUSB_HID_H_
-
-#include <usb/usb.h>
-#include <usb/classes/hidparser.h>
-#include <usb/descriptor.h>
-
-/** USB/HID device requests. */
-typedef enum {
-	USB_HIDREQ_GET_REPORT = 1,
-	USB_HIDREQ_GET_IDLE = 2,
-	USB_HIDREQ_GET_PROTOCOL = 3,
-	/* Values 4 to 8 are reserved. */
-	USB_HIDREQ_SET_REPORT = 9,
-	USB_HIDREQ_SET_IDLE = 10,
-	USB_HIDREQ_SET_PROTOCOL = 11
-} usb_hid_request_t;
-
-typedef enum {
-	USB_HID_PROTOCOL_BOOT = 0,
-	USB_HID_PROTOCOL_REPORT = 1
-} usb_hid_protocol_t;
-
-/** USB/HID subclass constants. */
-typedef enum {
-	USB_HID_SUBCLASS_NONE = 0,
-	USB_HID_SUBCLASS_BOOT = 1
-} usb_hid_subclass_t;
-
-/** USB/HID interface protocols. */
-typedef enum {
-	USB_HID_PROTOCOL_NONE = 0,
-	USB_HID_PROTOCOL_KEYBOARD = 1,
-	USB_HID_PROTOCOL_MOUSE = 2
-} usb_hid_iface_protocol_t;
-
-/** Part of standard USB HID descriptor specifying one class descriptor.
- *
- * (See HID Specification, p.22)
- */
-typedef struct {
-	/** Type of class-specific descriptor (Report or Physical). */
-	uint8_t type;
-	/** Length of class-specific descriptor in bytes. */
-	uint16_t length;
-} __attribute__ ((packed)) usb_standard_hid_class_descriptor_info_t;
-
-/** Standard USB HID descriptor.
- *
- * (See HID Specification, p.22)
- * 
- * It is actually only the "header" of the descriptor, it does not contain
- * the last two mandatory fields (type and length of the first class-specific
- * descriptor).
- */
-typedef struct {
-	/** Total size of this descriptor in bytes. 
-	 *
-	 * This includes all class-specific descriptor info - type + length 
-	 * for each descriptor.
-	 */
-	uint8_t length;
-	/** Descriptor type (USB_DESCTYPE_HID). */
-	uint8_t descriptor_type;
-	/** HID Class Specification release. */
-	uint16_t spec_release;
-	/** Country code of localized hardware. */
-	uint8_t country_code;
-	/** Total number of class-specific (i.e. Report and Physical) 
-	 * descriptors. 
-	 *
-	 * @note There is always only one Report descriptor.
-	 */
-	uint8_t class_desc_count;
-	/** First mandatory class descriptor (Report) info. */
-	usb_standard_hid_class_descriptor_info_t report_desc_info;
-} __attribute__ ((packed)) usb_standard_hid_descriptor_t;
-
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hid/iface.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid/iface.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,47 +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 libusb
- * @{
- */
-/** @file
- * Client functions for accessing USB HID interface.
- */
-#ifndef LIBUSB_CLASSES_HID_IFACE_H_
-#define LIBUSB_CLASSES_HID_IFACE_H_
-
-#include <sys/types.h>
-
-int usbhid_dev_get_event_length(int);
-int usbhid_dev_get_event(int, uint16_t *, uint16_t *, size_t, size_t *,
-    unsigned int);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hid/utled.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid/utled.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,122 +1,0 @@
-/*
- * Copyright (c) 2010 Lubos Slovak
- * 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 libusb
- * @{
- */
-/** @file
- * @brief USB HID Usage Tables - LED page.
- */
-#ifndef LIBUSB_UTLED_H_
-#define LIBUSB_UTLED_H_
-
-typedef enum {
-	USB_HID_LED_UNDEFINED = 0,
-	USB_HID_LED_NUM_LOCK,
-	USB_HID_LED_CAPS_LOCK,
-	USB_HID_LED_SCROLL_LOCK,
-	USB_HID_LED_COMPOSE,
-	USB_HID_LED_KANA,
-	USB_HID_LED_POWER,
-	USB_HID_LED_SHIFT,
-	USB_HID_LED_DND,
-	USB_HID_LED_MUTE,
-	USB_HID_LED_TONE_ENABLE,
-	USB_HID_LED_HIGH_CUT_FILTER,
-	USB_HID_LED_LOW_CUT_FILTER,
-	USB_HID_LED_EQ_ENABLE,
-	USB_HID_LED_SOUND_FIELD_ON,
-	USB_HID_LED_SURROUND_ON,
-	USB_HID_LED_REPEAT,
-	USB_HID_LED_STEREO,
-	USB_HID_LED_SAMPLING_RATE_DETECT,
-	USB_HID_LED_SPINNING,
-	USB_HID_LED_CAV,
-	USB_HID_LED_CLV,
-	USB_HID_LED_RECORDING_FORMAT_DETECT,
-	USB_HID_LED_OFF_HOOK,
-	USB_HID_LED_RING,
-	USB_HID_LED_MESSAGE_WAITING,
-	USB_HID_LED_DATA_MODE,
-	USB_HID_LED_BATTERY_OPERATION,
-	USB_HID_LED_BATTERY_OK,
-	USB_HID_LED_BATTERY_LOW,
-	USB_HID_LED_SPEAKER,
-	USB_HID_LED_HEAD_SET,
-	USB_HID_LED_HOLD,
-	USB_HID_LED_MICRO,
-	USB_HID_LED_COVERAGE,
-	USB_HID_LED_NIGHT_MODE,
-	USB_HID_LED_SEND_CALLS,
-	USB_HID_LED_CALL_PICKUP,
-	USB_HID_LED_CONFERENCE,
-	USB_HID_LED_STAND_BY,
-	USB_HID_LED_CAMERA_ON,
-	USB_HID_LED_CAMERA_OFF,
-	USB_HID_LED_ON_LINE,
-	USB_HID_LED_OFF_LINE,
-	USB_HID_LED_BUSY,
-	USB_HID_LED_READY,
-	USB_HID_LED_PAPER_OUT,
-	USB_HID_LED_PAPER_JAM,
-	USB_HID_LED_REMOTE,
-	USB_HID_LED_FORWARD,
-	USB_HID_LED_REVERSE,
-	USB_HID_LED_STOP,
-	USB_HID_LED_REWIND,
-	USB_HID_LED_FAST_FORWARD,
-	USB_HID_LED_PLAY,
-	USB_HID_LED_PAUSE,
-	USB_HID_LED_RECORD,
-	USB_HID_LED_ERROR,
-	USB_HID_LED_USAGE_SELECTED_IND,
-	USB_HID_LED_USAGE_IN_USE_IND,
-	USB_HID_LED_USAGE_MULTI_MODE_IND,
-	USB_HID_LED_IND_ON,
-	USB_HID_LED_IND_FLASH,
-	USB_HID_LED_IND_SLOW_BLINK,
-	USB_HID_LED_IND_FAST_BLINK,
-	USB_HID_LED_IND_OFF,
-	USB_HID_LED_FLASH_ON_TIME,
-	USB_HID_LED_SLOW_BLINK_ON_TIME,
-	USB_HID_LED_SLOW_BLINK_OFF_TIME,
-	USB_HID_LED_FAST_BLINK_ON_TIME,
-	USB_HID_LED_FAST_BLINK_OFF_TIME,
-	USB_HID_LED_USAGE_IND_COLOR,
-	USB_HID_LED_IND_RED,
-	USB_HID_LED_IND_GREEN,
-	USB_HID_LED_IND_AMBER,
-	USB_HID_LED_GENERIC_IND,
-	USB_HID_LED_SYSTEM_SUSPEND,
-	USB_HID_LED_EXTERNAL_POWER
-} usb_hid_usage_led_t;
-
-#endif /* LIBUSB_UTLED_H_ */
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hid_report_items.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid_report_items.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,106 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * @brief USB HID parser.
- */
-#ifndef LIBUSB_HID_REPORT_ITEMS_H_
-#define LIBUSB_HID_REPORT_ITEMS_H_
-
-#include <stdint.h>
-
-/**
- * Item prefix
- */
-#define USB_HID_ITEM_SIZE(data) 	((uint8_t)(data & 0x3))
-#define USB_HID_ITEM_TAG(data) 		((uint8_t)((data & 0xF0) >> 4))
-#define USB_HID_ITEM_TAG_CLASS(data)	((uint8_t)((data & 0xC) >> 2))
-#define USB_HID_ITEM_IS_LONG(data)	(data == 0xFE)
-
-
-/**
- * Input/Output/Feature Item flags
- */
-/** Constant (1) / Variable (0) */
-#define USB_HID_ITEM_FLAG_CONSTANT(flags) 	((flags & 0x1) == 0x1)
-/** Variable (1) / Array (0) */
-#define USB_HID_ITEM_FLAG_VARIABLE(flags) 	((flags & 0x2) == 0x2)
-/** Absolute / Relative*/
-#define USB_HID_ITEM_FLAG_RELATIVE(flags) 	((flags & 0x4) == 0x4)
-/** Wrap / No Wrap */
-#define USB_HID_ITEM_FLAG_WRAP(flags)		((flags & 0x8) == 0x8)
-#define USB_HID_ITEM_FLAG_LINEAR(flags)		((flags & 0x10) == 0x10)
-#define USB_HID_ITEM_FLAG_PREFERRED(flags)	((flags & 0x20) == 0x20)
-#define USB_HID_ITEM_FLAG_POSITION(flags)	((flags & 0x40) == 0x40)
-#define USB_HID_ITEM_FLAG_VOLATILE(flags)	((flags & 0x80) == 0x80)
-#define USB_HID_ITEM_FLAG_BUFFERED(flags)	((flags & 0x100) == 0x100)
-
-/* MAIN ITEMS */
-#define USB_HID_TAG_CLASS_MAIN				0x0
-#define USB_HID_REPORT_TAG_INPUT			0x8
-#define USB_HID_REPORT_TAG_OUTPUT			0x9
-#define USB_HID_REPORT_TAG_FEATURE			0xB
-#define USB_HID_REPORT_TAG_COLLECTION		0xA
-#define USB_HID_REPORT_TAG_END_COLLECTION	0xC
-
-/* GLOBAL ITEMS */
-#define USB_HID_TAG_CLASS_GLOBAL			0x1
-#define USB_HID_REPORT_TAG_USAGE_PAGE		0x0
-#define USB_HID_REPORT_TAG_LOGICAL_MINIMUM	0x1
-#define USB_HID_REPORT_TAG_LOGICAL_MAXIMUM	0x2
-#define USB_HID_REPORT_TAG_PHYSICAL_MINIMUM 0x3
-#define USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM 0x4
-#define USB_HID_REPORT_TAG_UNIT_EXPONENT	0x5
-#define USB_HID_REPORT_TAG_UNIT				0x6
-#define USB_HID_REPORT_TAG_REPORT_SIZE		0x7
-#define USB_HID_REPORT_TAG_REPORT_ID		0x8
-#define USB_HID_REPORT_TAG_REPORT_COUNT		0x9
-#define USB_HID_REPORT_TAG_PUSH				0xA
-#define USB_HID_REPORT_TAG_POP				0xB
-
-
-/* LOCAL ITEMS */
-#define USB_HID_TAG_CLASS_LOCAL					0x2
-#define USB_HID_REPORT_TAG_USAGE				0x0
-#define USB_HID_REPORT_TAG_USAGE_MINIMUM		0x1
-#define USB_HID_REPORT_TAG_USAGE_MAXIMUM		0x2
-#define USB_HID_REPORT_TAG_DESIGNATOR_INDEX		0x3
-#define USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM	0x4
-#define USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM	0x5
-#define USB_HID_REPORT_TAG_STRING_INDEX			0x7
-#define USB_HID_REPORT_TAG_STRING_MINIMUM		0x8
-#define USB_HID_REPORT_TAG_STRING_MAXIMUM		0x9
-#define USB_HID_REPORT_TAG_DELIMITER			0xA
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hiddescriptor.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hiddescriptor.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * USB HID report descriptor and report data parser
- */
-#ifndef LIBUSB_HIDDESCRIPTOR_H_
-#define LIBUSB_HIDDESCRIPTOR_H_
-
-#include <stdint.h>
-#include <adt/list.h>
-#include <usb/classes/hid_report_items.h>
-#include <usb/classes/hidpath.h>
-#include <usb/classes/hidtypes.h>
-
-
-/*
- * Descriptor parser functions
- */
-
-/** */
-int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 
-                                    const uint8_t *data, size_t size);
-
-/** */
-void usb_hid_free_report(usb_hid_report_t *report);
-
-/** */
-void usb_hid_descriptor_print(usb_hid_report_t *report);
-
-
-int usb_hid_report_init(usb_hid_report_t *report);
-int usb_hid_report_append_fields(usb_hid_report_t *report, 
-                                 usb_hid_report_item_t *report_item);
-
-usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type);
-int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
-int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
-int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
-int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
-
-void usb_hid_descriptor_print_list(link_t *head);
-void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
-void usb_hid_free_report_list(link_t *head);
-usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
-uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
-
-usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path);
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,90 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * USB HID report descriptor and report data parser
- */
-#ifndef LIBUSB_HIDPARSER_H_
-#define LIBUSB_HIDPARSER_H_
-
-#include <stdint.h>
-#include <adt/list.h>
-#include <usb/classes/hid_report_items.h>
-#include <usb/classes/hidpath.h>
-#include <usb/classes/hidtypes.h>
-#include <usb/classes/hiddescriptor.h>
-
-
-/*
- * Input report parser functions
- */
-/** */
-int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 
-                         size_t size, uint8_t *report_id);
-
-/** */
-size_t usb_hid_report_input_length(const usb_hid_report_t *report,
-	usb_hid_report_path_t *path, int flags);
-
-/*
- * Output report parser functions
- */
-/** Allocates output report buffer*/
-uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 
-                               uint8_t report_id);
-
-/** Frees output report buffer*/
-void usb_hid_report_output_free(uint8_t *output);
-
-/** Returns size of output for given usage path */
-size_t usb_hid_report_output_size(usb_hid_report_t *report,
-                                  usb_hid_report_path_t *path, int flags);
-
-/** Makes the output report buffer by translated given data */
-int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 
-                                    uint8_t *buffer, size_t size);
-
-/** */
-usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 
-                                                   usb_hid_report_field_t *field, 
-                                                   usb_hid_report_path_t *path, 
-                                                   int flags, 
-                                                   usb_hid_report_type_t type);
-
-/** */
-uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, 
-                                     uint8_t report_id, 
-                                     usb_hid_report_type_t type);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidpath.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidpath.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,118 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * USB HID report descriptor and report data parser
- */
-#ifndef LIBUSB_HIDPATH_H_
-#define LIBUSB_HIDPATH_H_
-
-#include <usb/classes/hidparser.h>
-#include <stdint.h>
-#include <adt/list.h>
-
-/**
- * Description of path of usage pages and usages in report descriptor
- */
-/** Wanted usage path must be exactly the same as the searched one */
-#define USB_HID_PATH_COMPARE_STRICT		0
-/** Wanted usage path must be the suffix in the searched one */
-#define USB_HID_PATH_COMPARE_END		1
-/** */
-#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY	2
-/** Searched usage page must be prefix of the other one */
-#define USB_HID_PATH_COMPARE_BEGIN		4
-/** Searched couple of usage page and usage can be anywhere in usage path */
-#define USB_HID_PATH_COMPARE_ANYWHERE		8
-
-
-/** Collection usage path structure */
-typedef struct {
-	/** */
-	uint32_t usage_page;
-	/** */	
-	uint32_t usage;
-
-	uint8_t flags;
-	/** */
-	link_t link;
-} usb_hid_report_usage_path_t;
-
-/** */
-typedef struct {
-	/** */	
-	int depth;	
-	uint8_t report_id;
-	
-	/** */	
-	link_t link; /* list */
-
-	link_t head; /* head of list of usage paths */
-
-} usb_hid_report_path_t;
-
-/** */
-usb_hid_report_path_t *usb_hid_report_path(void);
-
-/** */
-void usb_hid_report_path_free(usb_hid_report_path_t *path);
-
-/** */
-int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, 
-                                      uint8_t report_id);
-
-/** */
-int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 
-                                    int32_t usage_page, int32_t usage);
-
-/** */
-void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);
-
-/** */
-void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);
-
-/** */
-void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, 
-                                  int32_t tag, int32_t data);
-
-/** */
-int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 
-                                      usb_hid_report_path_t *path, int flags);
-
-/** */
-usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path);
-
-void usb_hid_print_usage_path(usb_hid_report_path_t *path);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidreport.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidreport.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,65 +1,0 @@
-/*
- * Copyright (c) 2011 Lubos Slovak
- * 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 libusb
- * @{
- */
-/** @file
- * USB HID report parser initialization from descriptors.
- */
-
-#ifndef LIBUSB_HIDREPORT_H_
-#define LIBUSB_HIDREPORT_H_
-
-#include <usb/devdrv.h>
-#include <usb/classes/hidparser.h>
-
-/**
- * Retrieves the Report descriptor from the USB device and initializes the
- * report parser.
- *
- * \param dev USB device representing a HID device.
- * \param parser HID Report parser.
- *
- * \retval EOK if successful.
- * \retval EINVAL if one of the parameters is not given (is NULL).
- * \retval ENOENT if there are some descriptors missing.
- * \retval ENOMEM if an error with allocation occured.
- * \retval EINVAL if the Report descriptor's size does not match the size 
- *         from the interface descriptor.
- * \return Other value inherited from function usb_pipe_start_session(),
- *         usb_pipe_end_session() or usb_request_get_descriptor().
- */
-int usb_hid_process_report_descriptor(usb_device_t *dev, 
-    usb_hid_report_t *report);
-
-#endif /* LIBUSB_HIDREPORT_H_ */
-
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidreq.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidreq.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,69 +1,0 @@
-/*
- * Copyright (c) 2011 Lubos Slovak
- * 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 libusb
- * @{
- */
-/** @file
- * HID class-specific requests.
- */
-
-#ifndef USB_KBD_HIDREQ_H_
-#define USB_KBD_HIDREQ_H_
-
-#include <stdint.h>
-
-#include <usb/classes/hid.h>
-#include <usb/pipes.h>
-
-/*----------------------------------------------------------------------------*/
-
-int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
-    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size);
-
-int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 
-    usb_hid_protocol_t protocol);
-
-int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration);
-
-int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 
-    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 
-    size_t *actual_size);
-
-int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 
-    usb_hid_protocol_t *protocol);
-
-int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration);
-
-/*----------------------------------------------------------------------------*/
-
-#endif /* USB_KBD_HIDREQ_H_ */
-
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidtypes.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidtypes.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,210 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * USB HID report descriptor and report data parser
- */
-#ifndef LIBUSB_HIDTYPES_H_
-#define LIBUSB_HIDTYPES_H_
-
-#include <stdint.h>
-#include <adt/list.h>
-
-#define USB_HID_MAX_USAGES	20
-
-#define USB_HID_UINT32_TO_INT32(x, size)	((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
-#define USB_HID_INT32_TO_UINT32(x, size)	(((x) < 0 ) ? ((1 << (size)) + (x)) : (x))
-
-
-typedef enum {
-	USB_HID_REPORT_TYPE_INPUT = 1,
-	USB_HID_REPORT_TYPE_OUTPUT = 2,
-	USB_HID_REPORT_TYPE_FEATURE = 3
-} usb_hid_report_type_t;
-
-
-typedef struct {
-	/** */
-	int report_count;
-	link_t reports;		/** list of usb_hid_report_description_t */
-
-	link_t collection_paths;
-	int collection_paths_count;
-
-	int use_report_ids;
-	uint8_t last_report_id;
-	
-} usb_hid_report_t;
-
-typedef struct {
-	uint8_t report_id;
-	usb_hid_report_type_t type;
-
-	size_t bit_length;
-	size_t item_length;
-	
-	link_t report_items;	/** list of report items (fields) */
-
-	link_t link;
-} usb_hid_report_description_t;
-
-typedef struct {
-
-	int offset;
-	size_t size;
-
-	uint16_t usage_page;
-	uint16_t usage;
-
-	uint8_t item_flags;
-	usb_hid_report_path_t *collection_path;
-
-	int32_t logical_minimum;
-	int32_t logical_maximum;
-	int32_t physical_minimum;
-	int32_t physical_maximum;
-	uint32_t usage_minimum;
-	uint32_t usage_maximum;
-	uint32_t unit;
-	uint32_t unit_exponent;
-	
-
-	int32_t value;
-
-	link_t link;
-} usb_hid_report_field_t;
-
-
-
-/**
- * state table
- */
-typedef struct {
-	/** report id */	
-	int32_t id;
-	
-	/** */
-	uint16_t extended_usage_page;
-	uint32_t usages[USB_HID_MAX_USAGES];
-	int usages_count;
-
-	/** */
-	uint32_t usage_page;
-
-	/** */	
-	uint32_t usage_minimum;
-	/** */	
-	uint32_t usage_maximum;
-	/** */	
-	int32_t logical_minimum;
-	/** */	
-	int32_t logical_maximum;
-	/** */	
-	int32_t size;
-	/** */	
-	int32_t count;
-	/** */	
-	size_t offset;
-	/** */	
-	int32_t unit_exponent;
-	/** */	
-	int32_t unit;
-
-	/** */
-	uint32_t string_index;
-	/** */	
-	uint32_t string_minimum;
-	/** */	
-	uint32_t string_maximum;
-	/** */	
-	uint32_t designator_index;
-	/** */	
-	uint32_t designator_minimum;
-	/** */	
-	uint32_t designator_maximum;
-	/** */	
-	int32_t physical_minimum;
-	/** */	
-	int32_t physical_maximum;
-
-	/** */	
-	uint8_t item_flags;
-
-	usb_hid_report_type_t type;
-
-	/** current collection path*/	
-	usb_hid_report_path_t *usage_path;
-	/** */	
-	link_t link;
-
-	int in_delimiter;
-} usb_hid_report_item_t;
-
-/** HID parser callbacks for IN items. */
-typedef struct {
-	/** Callback for keyboard.
-	 *
-	 * @param key_codes Array of pressed key (including modifiers).
-	 * @param count Length of @p key_codes.
-	 * @param arg Custom argument.
-	 */
-	void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t report_id, void *arg);
-} usb_hid_report_in_callbacks_t;
-
-
-typedef enum {
-	USB_HID_MOD_LCTRL = 0x01,
-	USB_HID_MOD_LSHIFT = 0x02,
-	USB_HID_MOD_LALT = 0x04,
-	USB_HID_MOD_LGUI = 0x08,
-	USB_HID_MOD_RCTRL = 0x10,
-	USB_HID_MOD_RSHIFT = 0x20,
-	USB_HID_MOD_RALT = 0x40,
-	USB_HID_MOD_RGUI = 0x80,
-	USB_HID_MOD_COUNT = 8
-} usb_hid_modifiers_t;
-
-static const usb_hid_modifiers_t 
-    usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = {
-	USB_HID_MOD_LCTRL,
-	USB_HID_MOD_LSHIFT,
-	USB_HID_MOD_LALT,
-	USB_HID_MOD_LGUI,
-	USB_HID_MOD_RCTRL,
-	USB_HID_MOD_RSHIFT,
-	USB_HID_MOD_RALT,
-	USB_HID_MOD_RGUI
-};
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidut.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidut.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,73 +1,0 @@
-/*
- * 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 libusb
- * @{
- */
-/** @file
- * @brief USB HID Usage Tables.
- */
-#ifndef LIBUSB_HIDUT_H_
-#define LIBUSB_HIDUT_H_
-
-/** USB/HID Usage Pages. */
-typedef enum {
-	USB_HIDUT_PAGE_GENERIC_DESKTOP = 1,
-	USB_HIDUT_PAGE_SIMULATION = 2,
-	USB_HIDUT_PAGE_VR = 3,
-	USB_HIDUT_PAGE_SPORT = 4,
-	USB_HIDUT_PAGE_GAME = 5,
-	USB_HIDUT_PAGE_GENERIC_DEVICE = 6,
-	USB_HIDUT_PAGE_KEYBOARD = 7,
-	USB_HIDUT_PAGE_LED = 8,
-	USB_HIDUT_PAGE_BUTTON = 9,
-	USB_HIDUT_PAGE_ORDINAL = 0x0a,
-	USB_HIDUT_PAGE_TELEPHONY_DEVICE = 0x0b,
-	USB_HIDUT_PAGE_CONSUMER = 0x0c
-} usb_hidut_usage_page_t;
-
-/** Usages for Generic Desktop Page. */
-typedef enum {
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_POINTER = 1,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE = 2,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_JOYSTICK = 4,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_GAMEPAD = 5,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD = 6,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_X = 0x30,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_Y = 0x31,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL = 0x38
-	/* USB_HIDUT_USAGE_GENERIC_DESKTOP_ = , */
-	
-} usb_hidut_usage_generic_desktop_t;
-
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/classes/hidutkbd.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidutkbd.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,175 +1,0 @@
-/*
- * 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 libusb
- * @{
- */
-/** @file
- * @brief USB HID key codes.
- * @details
- * This is not a typical header as by default it is equal to empty file.
- * However, by cleverly defining the USB_HIDUT_KBD_KEY you can use it
- * to generate conversion tables etc.
- *
- * For example, this creates enum for known keys:
- * @code
-#define USB_HIDUT_KBD_KEY(name, usage_id, l, lc, l1, l2) \
-	USB_KBD_KEY_##name = usage_id,
-typedef enum {
-	#include <usb/hidutkbd.h>
-} usb_key_code_t;
- @endcode
- *
- * Maybe, it might be better that you would place such enums into separate
- * files and create them as separate step before compiling to allow tools
- * such as Doxygen get the definitions right.
- *
- * @warning This file does not include guard to prevent multiple inclusions
- * into a single file.
- */
-
-
-#ifndef USB_HIDUT_KBD_KEY
-/** Declare keyboard key.
- * @param name Key name (identifier).
- * @param usage_id Key code (see Keyboard/Keypad Page (0x07) in HUT1.12.
- * @param letter Corresponding character (0 if not applicable).
- * @param letter_caps Corresponding character with Caps on.
- * @param letter_mod1 Corresponding character with modifier #1 on.
- * @param letter_mod2 Corresponding character with modifier #2 on.
- */
-#define USB_HIDUT_KBD_KEY(name, usage_id, letter, letter_caps, letter_mod1, letter_mod2)
-
-#endif
-
-#define __NONPRINT(name, usage_id) \
-	USB_HIDUT_KBD_KEY(name, usage_id, 0, 0, 0, 0)
-
-/* US alphabet letters */
-USB_HIDUT_KBD_KEY(A, 0x04, 'a', 'A', 0, 0)
-USB_HIDUT_KBD_KEY(B, 0x05, 'b', 'B', 0, 0)
-USB_HIDUT_KBD_KEY(C, 0x06, 'c', 'C', 0, 0)
-USB_HIDUT_KBD_KEY(D, 0x07, 'd', 'D', 0, 0)
-USB_HIDUT_KBD_KEY(E, 0x08, 'e', 'E', 0, 0)
-USB_HIDUT_KBD_KEY(F, 0x09, 'f', 'F', 0, 0)
-USB_HIDUT_KBD_KEY(G, 0x0A, 'g', 'G', 0, 0)
-USB_HIDUT_KBD_KEY(H, 0x0B, 'h', 'H', 0, 0)
-USB_HIDUT_KBD_KEY(I, 0x0C, 'i', 'I', 0, 0)
-USB_HIDUT_KBD_KEY(J, 0x0D, 'j', 'J', 0, 0)
-USB_HIDUT_KBD_KEY(K, 0x0E, 'k', 'K', 0, 0)
-USB_HIDUT_KBD_KEY(L, 0x0F, 'l', 'L', 0, 0)
-USB_HIDUT_KBD_KEY(M, 0x10, 'm', 'M', 0, 0)
-USB_HIDUT_KBD_KEY(N, 0x11, 'n', 'N', 0, 0)
-USB_HIDUT_KBD_KEY(O, 0x12, 'o', 'O', 0, 0)
-USB_HIDUT_KBD_KEY(P, 0x13, 'p', 'P', 0, 0)
-USB_HIDUT_KBD_KEY(Q, 0x14, 'q', 'Q', 0, 0)
-USB_HIDUT_KBD_KEY(R, 0x15, 'r', 'R', 0, 0)
-USB_HIDUT_KBD_KEY(S, 0x16, 's', 'S', 0, 0)
-USB_HIDUT_KBD_KEY(T, 0x17, 't', 'T', 0, 0)
-USB_HIDUT_KBD_KEY(U, 0x18, 'u', 'U', 0, 0)
-USB_HIDUT_KBD_KEY(V, 0x19, 'v', 'V', 0, 0)
-USB_HIDUT_KBD_KEY(W, 0x1A, 'w', 'W', 0, 0)
-USB_HIDUT_KBD_KEY(X, 0x1B, 'x', 'X', 0, 0)
-USB_HIDUT_KBD_KEY(Y, 0x1C, 'y', 'Y', 0, 0)
-USB_HIDUT_KBD_KEY(Z, 0x1D, 'z', 'Z', 0, 0)
-
-/* Keyboard digits */
-USB_HIDUT_KBD_KEY(1, 0x1E, '1', '!', 0, 0)
-USB_HIDUT_KBD_KEY(2, 0x1F, '2', '@', 0, 0)
-USB_HIDUT_KBD_KEY(3, 0x20, '3', '#', 0, 0)
-USB_HIDUT_KBD_KEY(4, 0x21, '4', '$', 0, 0)
-USB_HIDUT_KBD_KEY(5, 0x22, '5', '%', 0, 0)
-USB_HIDUT_KBD_KEY(6, 0x23, '6', '^', 0, 0)
-USB_HIDUT_KBD_KEY(7, 0x24, '7', '&', 0, 0)
-USB_HIDUT_KBD_KEY(8, 0x25, '8', '*', 0, 0)
-USB_HIDUT_KBD_KEY(9, 0x26, '9', '(', 0, 0)
-USB_HIDUT_KBD_KEY(0, 0x27, '0', ')', 0, 0)
-
-/* More-or-less typewriter command keys */
-USB_HIDUT_KBD_KEY(ENTER, 0x28, '\n', 0, 0, 0)
-USB_HIDUT_KBD_KEY(ESCAPE, 0x29, 0, 0, 0, 0)
-USB_HIDUT_KBD_KEY(BACKSPACE, 0x2A, '\b', 0, 0, 0)
-USB_HIDUT_KBD_KEY(TAB, 0x2B, '\t', 0, 0, 0)
-USB_HIDUT_KBD_KEY(SPACE, 0x2C, ' ', 0, 0, 0)
-
-/* Special (printable) characters */
-USB_HIDUT_KBD_KEY(DASH, 0x2D, '-', '_', 0, 0)
-USB_HIDUT_KBD_KEY(EQUALS, 0x2E, '=', '+', 0, 0)
-USB_HIDUT_KBD_KEY(LEFT_BRACKET, 0x2F, '[', '{', 0, 0)
-USB_HIDUT_KBD_KEY(RIGHT_BRACKET, 0x30, ']', '}', 0, 0)
-USB_HIDUT_KBD_KEY(BACKSLASH, 0x31, '\\', '|', 0, 0)
-USB_HIDUT_KBD_KEY(HASH, 0x32, '#', '~', 0, 0)
-USB_HIDUT_KBD_KEY(SEMICOLON, 0x33, ';', ':', 0, 0)
-USB_HIDUT_KBD_KEY(APOSTROPHE, 0x34, '\'', '"', 0, 0)
-USB_HIDUT_KBD_KEY(GRAVE_ACCENT, 0x35, '`', '~', 0, 0)
-USB_HIDUT_KBD_KEY(COMMA, 0x36, ',', '<', 0, 0)
-USB_HIDUT_KBD_KEY(PERIOD, 0x37, '.', '>', 0, 0)
-USB_HIDUT_KBD_KEY(SLASH, 0x38, '/', '?', 0, 0)
-
-USB_HIDUT_KBD_KEY(CAPS_LOCK, 0x39, 0, 0, 0, 0)
-
-/* Function keys */
-__NONPRINT( F1, 0x3A)
-__NONPRINT( F2, 0x3B)
-__NONPRINT( F3, 0x3C)
-__NONPRINT( F4, 0x3D)
-__NONPRINT( F5, 0x3E)
-__NONPRINT( F6, 0x3F)
-__NONPRINT( F7, 0x40)
-__NONPRINT( F8, 0x41)
-__NONPRINT( F9, 0x42)
-__NONPRINT(F10, 0x43)
-__NONPRINT(F11, 0x44)
-__NONPRINT(F12, 0x45)
-
-/* Cursor movement keys & co. */
-__NONPRINT(PRINT_SCREEN, 0x46)
-__NONPRINT(SCROLL_LOCK, 0x47)
-__NONPRINT(PAUSE, 0x48)
-__NONPRINT(INSERT, 0x49)
-__NONPRINT(HOME, 0x4A)
-__NONPRINT(PAGE_UP, 0x4B)
-__NONPRINT(DELETE, 0x4C)
-__NONPRINT(END, 0x4D)
-__NONPRINT(PAGE_DOWN, 0x4E)
-__NONPRINT(RIGHT_ARROW, 0x4F)
-__NONPRINT(LEFT_ARROW, 0x50)
-__NONPRINT(DOWN_ARROW, 0x51)
-__NONPRINT(UP_ARROW, 0x52)
-
-
-
-
-/* USB_HIDUT_KBD_KEY(, 0x, '', '', 0, 0) */
-
-#undef __NONPRINT
-
-/**
- * @}
- */
-
Index: uspace/lib/usb/include/usb/ddfiface.h
===================================================================
--- uspace/lib/usb/include/usb/ddfiface.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/usb/include/usb/ddfiface.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -37,5 +37,4 @@
 
 #include <sys/types.h>
-#include <usb/usbdevice.h>
 #include <usb_iface.h>
 
Index: uspace/lib/usb/include/usb/descriptor.h
===================================================================
--- uspace/lib/usb/include/usb/descriptor.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/usb/include/usb/descriptor.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -167,4 +167,46 @@
 } __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
 
+/** Part of standard USB HID descriptor specifying one class descriptor.
+ *
+ * (See HID Specification, p.22)
+ */
+typedef struct {
+	/** Type of class-specific descriptor (Report or Physical). */
+	uint8_t type;
+	/** Length of class-specific descriptor in bytes. */
+	uint16_t length;
+} __attribute__ ((packed)) usb_standard_hid_class_descriptor_info_t;
+
+/** Standard USB HID descriptor.
+ *
+ * (See HID Specification, p.22)
+ *
+ * It is actually only the "header" of the descriptor, it does not contain
+ * the last two mandatory fields (type and length of the first class-specific
+ * descriptor).
+ */
+typedef struct {
+	/** Total size of this descriptor in bytes.
+	 *
+	 * This includes all class-specific descriptor info - type + length
+	 * for each descriptor.
+	 */
+	uint8_t length;
+	/** Descriptor type (USB_DESCTYPE_HID). */
+	uint8_t descriptor_type;
+	/** HID Class Specification release. */
+	uint16_t spec_release;
+	/** Country code of localized hardware. */
+	uint8_t country_code;
+	/** Total number of class-specific (i.e. Report and Physical)
+	 * descriptors.
+	 *
+	 * @note There is always only one Report descriptor.
+	 */
+	uint8_t class_desc_count;
+	/** First mandatory class descriptor (Report) info. */
+	usb_standard_hid_class_descriptor_info_t report_desc_info;
+} __attribute__ ((packed)) usb_standard_hid_descriptor_t;
+
 #endif
 /**
Index: pace/lib/usb/include/usb/devdrv.h
===================================================================
--- uspace/lib/usb/include/usb/devdrv.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,178 +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 libusb
- * @{
- */
-/** @file
- * USB device driver framework.
- */
-#ifndef LIBUSB_DEVDRV_H_
-#define LIBUSB_DEVDRV_H_
-
-#include <usb/pipes.h>
-
-/** Descriptors for USB device. */
-typedef struct {
-	/** Standard device descriptor. */
-	usb_standard_device_descriptor_t device;
-	/** Full configuration descriptor of current configuration. */
-	uint8_t *configuration;
-	size_t configuration_size;
-} usb_device_descriptors_t;
-
-/** Wrapper for data related to alternate interface setting.
- * The pointers will typically point inside configuration descriptor and
- * thus you shall not deallocate them.
- */
-typedef struct {
-	/** Interface descriptor. */
-	usb_standard_interface_descriptor_t *interface;
-	/** Pointer to start of descriptor tree bound with this interface. */
-	uint8_t *nested_descriptors;
-	/** Size of data pointed by nested_descriptors in bytes. */
-	size_t nested_descriptors_size;
-} usb_alternate_interface_descriptors_t;
-
-/** Alternate interface settings. */
-typedef struct {
-	/** Array of alternate interfaces descriptions. */
-	usb_alternate_interface_descriptors_t *alternatives;
-	/** Size of @c alternatives array. */
-	size_t alternative_count;
-	/** Index of currently selected one. */
-	size_t current;
-} usb_alternate_interfaces_t;
-
-/** USB device structure. */
-typedef struct {
-	/** The default control pipe. */
-	usb_pipe_t ctrl_pipe;
-	/** Other endpoint pipes.
-	 * This is an array of other endpoint pipes in the same order as
-	 * in usb_driver_t.
-	 */
-	usb_endpoint_mapping_t *pipes;
-	/** Number of other endpoint pipes. */
-	size_t pipes_count;
-	/** Current interface.
-	 * Usually, drivers operate on single interface only.
-	 * This item contains the value of the interface or -1 for any.
-	 */
-	int interface_no;
-
-	/** Alternative interfaces.
-	 * Set to NULL when the driver controls whole device
-	 * (i.e. more (or any) interfaces).
-	 */
-	usb_alternate_interfaces_t *alternate_interfaces;
-
-	/** Some useful descriptors. */
-	usb_device_descriptors_t descriptors;
-
-	/** Generic DDF device backing this one. */
-	ddf_dev_t *ddf_dev;
-	/** Custom driver data.
-	 * Do not use the entry in generic device, that is already used
-	 * by the framework.
-	 */
-	void *driver_data;
-
-	/** Connection backing the pipes.
-	 * Typically, you will not need to use this attribute at all.
-	 */
-	usb_device_connection_t wire;
-} usb_device_t;
-
-/** USB driver ops. */
-typedef struct {
-	/** Callback when new device is about to be controlled by the driver. */
-	int (*add_device)(usb_device_t *);
-} usb_driver_ops_t;
-
-/** USB driver structure. */
-typedef struct {
-	/** Driver name.
-	 * This name is copied to the generic driver name and must be exactly
-	 * the same as the directory name where the driver executable resides.
-	 */
-	const char *name;
-	/** Expected endpoints description.
-	 * This description shall exclude default control endpoint (pipe zero)
-	 * and must be NULL terminated.
-	 * When only control endpoint is expected, you may set NULL directly
-	 * without creating one item array containing NULL.
-	 *
-	 * When the driver expect single interrupt in endpoint,
-	 * the initialization may look like this:
-\code
-static usb_endpoint_description_t poll_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 usb_endpoint_description_t *hub_endpoints[] = {
-	&poll_endpoint_description,
-	NULL
-};
-
-static usb_driver_t hub_driver = {
-	.endpoints = hub_endpoints,
-	...
-};
-\endcode
-	 */
-	usb_endpoint_description_t **endpoints;
-	/** Driver ops. */
-	usb_driver_ops_t *ops;
-} usb_driver_t;
-
-int usb_driver_main(usb_driver_t *);
-
-int usb_device_select_interface(usb_device_t *, uint8_t,
-    usb_endpoint_description_t **);
-
-int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
-int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
-    usb_endpoint_description_t **, uint8_t *, size_t, int, int,
-    usb_endpoint_mapping_t **, size_t *);
-int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
-int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);
-
-size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
-int usb_alternate_interfaces_create(uint8_t *, size_t, int,
-    usb_alternate_interfaces_t **);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/devpoll.h
===================================================================
--- uspace/lib/usb/include/usb/devpoll.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,99 +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 libusb
- * @{
- */
-/** @file
- * USB device polling functions.
- */
-#ifndef LIBUSB_DEVPOLL_H_
-#define LIBUSB_DEVPOLL_H_
-
-#include <usb/devdrv.h>
-#include <time.h>
-
-typedef struct {
-	/** Level of debugging messages from auto polling.
-	 * 0 - nothing
-	 * 1 - inform about errors and polling start/end
-	 * 2 - also dump every retrieved buffer
-	 */
-	int debug;
-	/** Maximum number of consecutive errors before polling termination. */
-	size_t max_failures;
-	/** Delay between poll requests in milliseconds.
-	 * Set to negative value to use value from endpoint descriptor.
-	 */
-	int delay;
-	/** Whether to automatically try to clear the HALT feature after
-	 * the endpoint stalls.
-	 */
-	bool auto_clear_halt;
-	/** Callback when data arrives.
-	 *
-	 * @param dev Device that was polled.
-	 * @param data Data buffer (in USB endianness).
-	 * @param data_size Size of the @p data buffer in bytes.
-	 * @param arg Custom argument.
-	 * @return Whether to continue in polling.
-	 */
-	bool (*on_data)(usb_device_t *dev, uint8_t *data, size_t data_size,
-	    void *arg);
-	/** Callback when polling is terminated.
-	 *
-	 * @param dev Device where the polling was terminated.
-	 * @param due_to_errors Whether polling stopped due to several failures.
-	 * @param arg Custom argument.
-	 */
-	void (*on_polling_end)(usb_device_t *dev, bool due_to_errors,
-	    void *arg);
-	/** Callback when error occurs.
-	 *
-	 * @param dev Device where error occurred.
-	 * @param err_code Error code (as returned from usb_pipe_read).
-	 * @param arg Custom argument.
-	 * @return Whether to continue in polling.
-	 */
-	bool (*on_error)(usb_device_t *dev, int err_code, void *arg);
-} usb_device_auto_polling_t;
-
-int usb_device_auto_polling(usb_device_t *, size_t, usb_device_auto_polling_t *,
-    size_t, void *);
-
-typedef bool (*usb_polling_callback_t)(usb_device_t *,
-    uint8_t *, size_t, void *);
-typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
-
-int usb_device_auto_poll(usb_device_t *, size_t,
-    usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/dp.h
===================================================================
--- uspace/lib/usb/include/usb/dp.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,85 +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 libusb
- * @{
- */
-/** @file
- * USB descriptor parser.
- */
-#ifndef LIBUSB_DP_H_
-#define LIBUSB_DP_H_
-
-#include <sys/types.h>
-#include <usb/usb.h>
-#include <usb/descriptor.h>
-
-/** USB descriptors nesting.
- * The nesting describes the logical tree USB descriptors form
- * (e.g. that endpoint descriptor belongs to interface or that
- * interface belongs to configuration).
- *
- * See usb_descriptor_type_t for descriptor constants.
- */
-typedef struct {
-	/** Child descriptor id. */
-	int child;
-	/** Parent descriptor id. */
-	int parent;
-} usb_dp_descriptor_nesting_t;
-
-extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
-
-/** Descriptor parser structure. */
-typedef struct {
-	/** Used descriptor nesting. */
-	usb_dp_descriptor_nesting_t *nesting;
-} usb_dp_parser_t;
-
-/** Descriptor parser data. */
-typedef struct {
-	/** Data to be parsed. */
-	uint8_t *data;
-	/** Size of input data in bytes. */
-	size_t size;
-	/** Custom argument. */
-	void *arg;
-} usb_dp_parser_data_t;
-
-uint8_t *usb_dp_get_nested_descriptor(usb_dp_parser_t *,
-    usb_dp_parser_data_t *, uint8_t *);
-uint8_t *usb_dp_get_sibling_descriptor(usb_dp_parser_t *,
-    usb_dp_parser_data_t *, uint8_t *, uint8_t *);
-
-void usb_dp_walk_simple(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
-    void (*)(uint8_t *, size_t, void *), void *);
-
-#endif
-/**
- * @}
- */
Index: uspace/lib/usb/include/usb/driver.h
===================================================================
--- uspace/lib/usb/include/usb/driver.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usb/include/usb/driver.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,46 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Common definitions for USB drivers.
+ */
+#ifndef LIBUSB_DRIVER_H_
+#define LIBUSB_DRIVER_H_
+
+#include <sys/types.h>
+#include <ipc/devman.h>
+
+int usb_hc_find(devman_handle_t, devman_handle_t *);
+
+#endif
+/**
+ * @}
+ */
Index: pace/lib/usb/include/usb/host/batch.h
===================================================================
--- uspace/lib/usb/include/usb/host/batch.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,101 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libusb
- * @{
- */
-/** @file
- * USB transfer transaction structures.
- */
-#ifndef LIBUSB_HOST_BATCH_H
-#define LIBUSB_HOST_BATCH_H
-
-#include <adt/list.h>
-
-#include <usbhc_iface.h>
-#include <usb/usb.h>
-#include <usb/host/endpoint.h>
-
-typedef struct usb_transfer_batch usb_transfer_batch_t;
-struct usb_transfer_batch {
-	endpoint_t *ep;
-	link_t link;
-	usbhc_iface_transfer_in_callback_t callback_in;
-	usbhc_iface_transfer_out_callback_t callback_out;
-	void *arg;
-	char *buffer;
-	char *data_buffer;
-	size_t buffer_size;
-	char *setup_buffer;
-	size_t setup_size;
-	size_t transfered_size;
-	void (*next_step)(usb_transfer_batch_t *);
-	int error;
-	ddf_fun_t *fun;
-	void *private_data;
-	void (*private_data_dtor)(void *p_data);
-};
-
-void usb_transfer_batch_init(
-    usb_transfer_batch_t *instance,
-    endpoint_t *ep,
-    char *buffer,
-    char *data_buffer,
-    size_t buffer_size,
-    char *setup_buffer,
-    size_t setup_size,
-    usbhc_iface_transfer_in_callback_t func_in,
-    usbhc_iface_transfer_out_callback_t func_out,
-    void *arg,
-    ddf_fun_t *fun,
-    void *private_data,
-    void (*private_data_dtor)(void *p_data)
-);
-
-void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance);
-void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance);
-void usb_transfer_batch_finish(usb_transfer_batch_t *instance);
-void usb_transfer_batch_dispose(usb_transfer_batch_t *instance);
-
-static inline void usb_transfer_batch_finish_error(
-    usb_transfer_batch_t *instance, int error)
-{
-	assert(instance);
-	instance->error = error;
-	usb_transfer_batch_finish(instance);
-}
-
-static inline usb_transfer_batch_t *usb_transfer_batch_from_link(link_t *l)
-{
-	assert(l);
-	return list_get_instance(l, usb_transfer_batch_t, link);
-}
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/host/device_keeper.h
===================================================================
--- uspace/lib/usb/include/usb/host/device_keeper.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,87 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libusb
- * @{
- */
-/** @file
- * Device keeper structure and functions.
- *
- * Typical USB host controller needs to keep track of various settings for
- * each device that is connected to it.
- * State of toggle bit, device speed etc. etc.
- * This structure shall simplify the management.
- */
-#ifndef LIBUSB_HOST_DEVICE_KEEPER_H
-#define LIBUSB_HOST_DEVICE_KEEPER_H
-
-#include <adt/list.h>
-#include <devman.h>
-#include <fibril_synch.h>
-#include <usb/usb.h>
-#include <usb/host/endpoint.h>
-
-/** Number of USB address for array dimensions. */
-#define USB_ADDRESS_COUNT (USB11_ADDRESS_MAX + 1)
-
-/** Information about attached USB device. */
-struct usb_device_info {
-	usb_speed_t speed;
-	bool occupied;
-	devman_handle_t handle;
-};
-
-/** Host controller device keeper.
- * You shall not access members directly but only using functions below.
- */
-typedef struct {
-	struct usb_device_info devices[USB_ADDRESS_COUNT];
-	fibril_mutex_t guard;
-	usb_address_t last_address;
-} usb_device_keeper_t;
-
-void usb_device_keeper_init(usb_device_keeper_t *instance);
-
-usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
-    usb_speed_t speed);
-
-void usb_device_keeper_bind(usb_device_keeper_t *instance,
-    usb_address_t address, devman_handle_t handle);
-
-void usb_device_keeper_release(usb_device_keeper_t *instance,
-    usb_address_t address);
-
-usb_address_t usb_device_keeper_find(usb_device_keeper_t *instance,
-    devman_handle_t handle);
-
-usb_speed_t usb_device_keeper_get_speed(usb_device_keeper_t *instance,
-    usb_address_t address);
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usb/include/usb/host/endpoint.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,86 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libusb
- * @{
- */
-/** @file
- *
- */
-#ifndef LIBUSB_HOST_ENDPOINT_H
-#define LIBUSB_HOST_ENDPOINT_H
-
-#include <assert.h>
-#include <bool.h>
-#include <adt/list.h>
-#include <fibril_synch.h>
-
-#include <usb/usb.h>
-
-typedef struct endpoint {
-	usb_address_t address;
-	usb_endpoint_t endpoint;
-	usb_direction_t direction;
-	usb_transfer_type_t transfer_type;
-	usb_speed_t speed;
-	size_t max_packet_size;
-	unsigned toggle:1;
-	fibril_mutex_t guard;
-	fibril_condvar_t avail;
-	volatile bool active;
-	struct {
-		void *data;
-		int (*toggle_get)(void *);
-		void (*toggle_set)(void *, int);
-	} hc_data;
-} endpoint_t;
-
-int endpoint_init(endpoint_t *instance, usb_address_t address,
-    usb_endpoint_t endpoint, usb_direction_t direction,
-    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size);
-
-void endpoint_destroy(endpoint_t *instance);
-
-void endpoint_set_hc_data(endpoint_t *instance,
-    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int));
-
-void endpoint_clear_hc_data(endpoint_t *instance);
-
-void endpoint_use(endpoint_t *instance);
-
-void endpoint_release(endpoint_t *instance);
-
-int endpoint_toggle_get(endpoint_t *instance);
-
-void endpoint_toggle_set(endpoint_t *instance, int toggle);
-
-void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target);
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/host/usb_endpoint_manager.h
===================================================================
--- uspace/lib/usb/include/usb/host/usb_endpoint_manager.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,105 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libusb
- * @{
- */
-/** @file
- * Device keeper structure and functions.
- *
- * Typical USB host controller needs to keep track of various settings for
- * each device that is connected to it.
- * State of toggle bit, device speed etc. etc.
- * This structure shall simplify the management.
- */
-#ifndef LIBUSB_HOST_USB_ENDPOINT_MANAGER_H
-#define LIBUSB_HOST_YSB_ENDPOINT_MANAGER_H
-
-#include <adt/hash_table.h>
-#include <fibril_synch.h>
-#include <usb/usb.h>
-#include <usb/host/endpoint.h>
-
-#define BANDWIDTH_TOTAL_USB11 12000000
-#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9)
-
-typedef struct usb_endpoint_manager {
-	hash_table_t ep_table;
-	fibril_mutex_t guard;
-	fibril_condvar_t change;
-	size_t free_bw;
-} usb_endpoint_manager_t;
-
-size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
-    size_t size, size_t max_packet_size);
-
-int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
-    size_t available_bandwidth);
-
-void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance);
-
-int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
-    endpoint_t *ep, size_t data_size);
-
-int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
-
-endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,
-    size_t *bw);
-
-void usb_endpoint_manager_reset_if_need(
-    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
-
-static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
-    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
-    size_t data_size)
-{
-	endpoint_t *ep = malloc(sizeof(endpoint_t));
-	if (ep == NULL)
-		return ENOMEM;
-
-	int ret = endpoint_init(ep, address, endpoint, direction, type, speed,
-	    max_packet_size);
-	if (ret != EOK) {
-		free(ep);
-		return ret;
-	}
-
-	ret = usb_endpoint_manager_register_ep(instance, ep, data_size);
-	if (ret != EOK) {
-		endpoint_destroy(ep);
-		return ret;
-	}
-	return EOK;
-}
-#endif
-/**
- * @}
- */
-
Index: pace/lib/usb/include/usb/hub.h
===================================================================
--- uspace/lib/usb/include/usb/hub.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,69 +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 libusb
- * @{
- */
-/** @file
- * Functions needed by hub drivers.
- *
- * For class specific requests, see usb/classes/hub.h.
- */
-#ifndef LIBUSB_HUB_H_
-#define LIBUSB_HUB_H_
-
-#include <sys/types.h>
-#include <usb/usbdevice.h>
-
-int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
-    int (*)(int, void *), int, void *,
-    usb_address_t *, devman_handle_t *,
-    ddf_dev_ops_t *, void *, ddf_fun_t **);
-
-/** Info about device attached to host controller.
- *
- * This structure exists only to keep the same signature of
- * usb_hc_register_device() when more properties of the device
- * would have to be passed to the host controller.
- */
-typedef struct {
-	/** Device address. */
-	usb_address_t address;
-	/** Devman handle of the device. */
-	devman_handle_t handle;
-} usb_hc_attached_device_t;
-
-usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
-int usb_hc_register_device(usb_hc_connection_t *,
-    const usb_hc_attached_device_t *);
-int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/pipes.h
===================================================================
--- uspace/lib/usb/include/usb/pipes.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,193 +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 libusb
- * @{
- */
-/** @file
- * USB pipes representation.
- */
-#ifndef LIBUSB_PIPES_H_
-#define LIBUSB_PIPES_H_
-
-#include <sys/types.h>
-#include <usb/usb.h>
-#include <usb/usbdevice.h>
-#include <usb/descriptor.h>
-#include <ipc/devman.h>
-#include <ddf/driver.h>
-#include <fibril_synch.h>
-
-/** Abstraction of a physical connection to the device.
- * This type is an abstraction of the USB wire that connects the host and
- * the function (device).
- */
-typedef struct {
-	/** Handle of the host controller device is connected to. */
-	devman_handle_t hc_handle;
-	/** Address of the device. */
-	usb_address_t address;
-} usb_device_connection_t;
-
-/** Abstraction of a logical connection to USB device endpoint.
- * It encapsulates endpoint attributes (transfer type etc.) as well
- * as information about currently running sessions.
- * This endpoint must be bound with existing usb_device_connection_t
- * (i.e. the wire to send data over).
- *
- * Locking order: if you want to lock both mutexes
- * (@c guard and @c hc_phone_mutex), lock @c guard first.
- * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex
- * only.
- */
-typedef struct {
-	/** Guard of the whole pipe. */
-	fibril_mutex_t guard;
-
-	/** The connection used for sending the data. */
-	usb_device_connection_t *wire;
-
-	/** Endpoint number. */
-	usb_endpoint_t endpoint_no;
-
-	/** Endpoint transfer type. */
-	usb_transfer_type_t transfer_type;
-
-	/** Endpoint direction. */
-	usb_direction_t direction;
-
-	/** Maximum packet size for the endpoint. */
-	size_t max_packet_size;
-
-	/** Phone to the host controller.
-	 * Negative when no session is active.
-	 * It is an error to access this member without @c hc_phone_mutex
-	 * being locked.
-	 * If call over the phone is to be made, it must be preceeded by
-	 * call to pipe_add_ref() [internal libusb function].
-	 */
-	int hc_phone;
-
-	/** Guard for serialization of requests over the phone. */
-	fibril_mutex_t hc_phone_mutex;
-
-	/** Number of active transfers over the pipe. */
-	int refcount;
-	/** Number of failed attempts to open the HC phone.
-	 * When user requests usb_pipe_start_long_transfer() and the operation
-	 * fails, there is no way to report this to the user.
-	 * That the soft reference counter is increased to record the attempt.
-	 * When the user then request e.g. usb_pipe_read(), it will try to
-	 * add reference as well.
-	 * If that fails, it is reported to the user. If it is okay, the
-	 * real reference counter is incremented.
-	 * The problem might arise when ending the long transfer (since
-	 * the number of references would be only 1, but logically it shall be
-	 * two).
-	 * Decrementing the soft counter first shall solve this.
-	 */
-	int refcount_soft;
-
-	/** Whether to automatically reset halt on the endpoint.
-	 * Valid only for control endpoint zero.
-	 */
-	bool auto_reset_halt;
-} usb_pipe_t;
-
-
-/** Description of endpoint characteristics. */
-typedef struct {
-	/** Transfer type (e.g. control or interrupt). */
-	usb_transfer_type_t transfer_type;
-	/** Transfer direction (to or from a device). */
-	usb_direction_t direction;
-	/** Interface class this endpoint belongs to (-1 for any). */
-	int interface_class;
-	/** Interface subclass this endpoint belongs to (-1 for any). */
-	int interface_subclass;
-	/** Interface protocol this endpoint belongs to (-1 for any). */
-	int interface_protocol;
-	/** Extra endpoint flags. */
-	unsigned int flags;
-} usb_endpoint_description_t;
-
-/** Mapping of endpoint pipes and endpoint descriptions. */
-typedef struct {
-	/** Endpoint pipe. */
-	usb_pipe_t *pipe;
-	/** Endpoint description. */
-	const usb_endpoint_description_t *description;
-	/** Interface number the endpoint must belong to (-1 for any). */
-	int interface_no;
-	/** Alternate interface setting to choose. */
-	int interface_setting;
-	/** Found descriptor fitting the description. */
-	usb_standard_endpoint_descriptor_t *descriptor;
-	/** Interface descriptor the endpoint belongs to. */
-	usb_standard_interface_descriptor_t *interface;
-	/** Whether the endpoint was actually found. */
-	bool present;
-} usb_endpoint_mapping_t;
-
-int usb_device_connection_initialize_on_default_address(
-    usb_device_connection_t *, usb_hc_connection_t *);
-int usb_device_connection_initialize_from_device(usb_device_connection_t *,
-    ddf_dev_t *);
-int usb_device_connection_initialize(usb_device_connection_t *,
-    devman_handle_t, usb_address_t);
-
-int usb_device_get_assigned_interface(ddf_dev_t *);
-usb_address_t usb_device_get_assigned_address(devman_handle_t);
-
-int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *,
-    usb_endpoint_t, usb_transfer_type_t, size_t, usb_direction_t);
-int usb_pipe_initialize_default_control(usb_pipe_t *,
-    usb_device_connection_t *);
-int usb_pipe_probe_default_control(usb_pipe_t *);
-int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
-    size_t, uint8_t *, size_t, usb_device_connection_t *);
-int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
-    unsigned int, usb_hc_connection_t *);
-int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);
-int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);
-
-void usb_pipe_start_long_transfer(usb_pipe_t *);
-void usb_pipe_end_long_transfer(usb_pipe_t *);
-
-int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *);
-int usb_pipe_write(usb_pipe_t *, void *, size_t);
-
-int usb_pipe_control_read(usb_pipe_t *, void *, size_t,
-    void *, size_t, size_t *);
-int usb_pipe_control_write(usb_pipe_t *, void *, size_t,
-    void *, size_t);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/recognise.h
===================================================================
--- uspace/lib/usb/include/usb/recognise.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,58 +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 libusb
- * @{
- */
-/** @file
- * USB device recognition.
- */
-#ifndef LIBUSB_RECOGNISE_H_
-#define LIBUSB_RECOGNISE_H_
-
-#include <sys/types.h>
-#include <usb/usb.h>
-#include <usb/pipes.h>
-#include <ipc/devman.h>
-
-int usb_device_create_match_ids_from_device_descriptor(
-    const usb_standard_device_descriptor_t *, match_id_list_t *);
-
-int usb_device_create_match_ids_from_interface(
-    const usb_standard_device_descriptor_t *,
-    const usb_standard_interface_descriptor_t *, match_id_list_t *);
-
-int usb_device_create_match_ids(usb_pipe_t *, match_id_list_t *);
-
-int usb_device_register_child_in_devman(usb_address_t, devman_handle_t,
-    ddf_dev_t *, devman_handle_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/request.h
===================================================================
--- uspace/lib/usb/include/usb/request.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,148 +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 libusb
- * @{
- */
-/** @file
- * Standard USB requests.
- */
-#ifndef LIBUSB_REQUEST_H_
-#define LIBUSB_REQUEST_H_
-
-#include <sys/types.h>
-#include <l18n/langs.h>
-#include <usb/usb.h>
-#include <usb/pipes.h>
-#include <usb/descriptor.h>
-
-/** USB device status - device is self powered (opposed to bus powered). */
-#define USB_DEVICE_STATUS_SELF_POWERED ((uint16_t)(1 << 0))
-
-/** USB device status - remote wake-up signaling is enabled. */
-#define USB_DEVICE_STATUS_REMOTE_WAKEUP ((uint16_t)(1 << 1))
-
-/** USB endpoint status - endpoint is halted (stalled). */
-#define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0))
-
-/** USB feature selector - endpoint halt (stall). */
-#define USB_FEATURE_SELECTOR_ENDPOINT_HALT (0)
-
-/** USB feature selector - device remote wake-up. */
-#define USB_FEATURE_SELECTOR_REMOTE_WAKEUP (1)
-
-/** Standard device request. */
-typedef enum {
-	USB_DEVREQ_GET_STATUS = 0,
-	USB_DEVREQ_CLEAR_FEATURE = 1,
-	USB_DEVREQ_SET_FEATURE = 3,
-	USB_DEVREQ_SET_ADDRESS = 5,
-	USB_DEVREQ_GET_DESCRIPTOR = 6,
-	USB_DEVREQ_SET_DESCRIPTOR = 7,
-	USB_DEVREQ_GET_CONFIGURATION = 8,
-	USB_DEVREQ_SET_CONFIGURATION = 9,
-	USB_DEVREQ_GET_INTERFACE = 10,
-	USB_DEVREQ_SET_INTERFACE = 11,
-	USB_DEVREQ_SYNCH_FRAME = 12,
-	USB_DEVREQ_LAST_STD
-} usb_stddevreq_t;
-
-/** Device request setup packet.
- * The setup packet describes the request.
- */
-typedef struct {
-	/** Request type.
-	 * The type combines transfer direction, request type and
-	 * intended recipient.
-	 */
-	uint8_t request_type;
-	/** Request identification. */
-	uint8_t request;
-	/** Main parameter to the request. */
-	union {
-		uint16_t value;
-		/* FIXME: add #ifdefs according to host endianness */
-		struct {
-			uint8_t value_low;
-			uint8_t value_high;
-		};
-	};
-	/** Auxiliary parameter to the request.
-	 * Typically, it is offset to something.
-	 */
-	uint16_t index;
-	/** Length of extra data. */
-	uint16_t length;
-} __attribute__ ((packed)) usb_device_request_setup_packet_t;
-
-int usb_control_request_set(usb_pipe_t *,
-    usb_request_type_t, usb_request_recipient_t, uint8_t,
-    uint16_t, uint16_t, void *, size_t);
-
-int usb_control_request_get(usb_pipe_t *,
-    usb_request_type_t, usb_request_recipient_t, uint8_t,
-    uint16_t, uint16_t, void *, size_t, size_t *);
-
-int usb_request_get_status(usb_pipe_t *, usb_request_recipient_t,
-    uint16_t, uint16_t *);
-int usb_request_clear_feature(usb_pipe_t *, usb_request_type_t,
-    usb_request_recipient_t, uint16_t, uint16_t);
-int usb_request_set_feature(usb_pipe_t *, usb_request_type_t,
-    usb_request_recipient_t, uint16_t, uint16_t);
-int usb_request_set_address(usb_pipe_t *, usb_address_t);
-int usb_request_get_descriptor(usb_pipe_t *, usb_request_type_t,
-    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 
-    size_t *);
-int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t,
-    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void **, size_t *);
-int usb_request_get_device_descriptor(usb_pipe_t *,
-    usb_standard_device_descriptor_t *);
-int usb_request_get_bare_configuration_descriptor(usb_pipe_t *, int,
-    usb_standard_configuration_descriptor_t *);
-int usb_request_get_full_configuration_descriptor(usb_pipe_t *, int,
-    void *, size_t, size_t *);
-int usb_request_get_full_configuration_descriptor_alloc(usb_pipe_t *,
-    int, void **, size_t *);
-int usb_request_set_descriptor(usb_pipe_t *, usb_request_type_t,
-    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t);
-int usb_request_get_configuration(usb_pipe_t *, uint8_t *);
-int usb_request_set_configuration(usb_pipe_t *, uint8_t);
-int usb_request_get_interface(usb_pipe_t *, uint8_t, uint8_t *);
-int usb_request_set_interface(usb_pipe_t *, uint8_t, uint8_t);
-
-int usb_request_get_supported_languages(usb_pipe_t *,
-    l18_win_locales_t **, size_t *);
-int usb_request_get_string(usb_pipe_t *, size_t, l18_win_locales_t,
-    char **);
-
-int usb_request_clear_endpoint_halt(usb_pipe_t *, uint16_t);
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/include/usb/usbdevice.h
===================================================================
--- uspace/lib/usb/include/usb/usbdevice.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,67 +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 libusb
- * @{
- */
-/** @file
- * General communication between device drivers and host controller driver.
- */
-#ifndef LIBUSB_USBDEVICE_H_
-#define LIBUSB_USBDEVICE_H_
-
-#include <sys/types.h>
-#include <ipc/devman.h>
-#include <ddf/driver.h>
-#include <bool.h>
-#include <usb/usb.h>
-
-/** Connection to the host controller driver. */
-typedef struct {
-	/** Devman handle of the host controller. */
-	devman_handle_t hc_handle;
-	/** Phone to the host controller. */
-	int hc_phone;
-} usb_hc_connection_t;
-
-int usb_hc_find(devman_handle_t, devman_handle_t *);
-
-int usb_hc_connection_initialize_from_device(usb_hc_connection_t *,
-    ddf_dev_t *);
-int usb_hc_connection_initialize(usb_hc_connection_t *, devman_handle_t);
-
-int usb_hc_connection_open(usb_hc_connection_t *);
-bool usb_hc_connection_is_opened(const usb_hc_connection_t *);
-int usb_hc_connection_close(usb_hc_connection_t *);
-
-
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/src/addrkeep.c
===================================================================
--- uspace/lib/usb/src/addrkeep.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,347 +1,0 @@
-/*
- * 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 libusb
- * @{
- */
-/** @file
- * @brief Address keeping.
- */
-#include <usb/addrkeep.h>
-#include <errno.h>
-#include <assert.h>
-
-/** For loop over all used addresses in address keeping.
- *
- * @param link Iterator.
- * @param addresses Addresses keeping structure to iterate.
- */
-#define for_all_used_addresses(link, addresses) \
-	for (link = (addresses)->used_addresses.next; \
-	    link != &(addresses)->used_addresses; \
-	    link = link->next)
-
-/** Get instance of usb_address_keeping_used_t. */
-#define used_address_get_instance(lnk) \
-	list_get_instance(lnk, usb_address_keeping_used_t, link)
-
-/** Invalid value of devman handle. */
-#define INVALID_DEVMAN_HANDLE \
-	((devman_handle_t)-1)
-
-/** Creates structure for used USB address.
- *
- * @param address USB address.
- * @return Initialized structure.
- * @retval NULL Out of memory.
- */
-static usb_address_keeping_used_t *usb_address_keeping_used_create(
-    usb_address_t address)
-{
-	usb_address_keeping_used_t *info
-	    = malloc(sizeof(usb_address_keeping_used_t));
-	if (info == NULL) {
-		return NULL;
-	}
-
-	info->address = address;
-	info->devman_handle = INVALID_DEVMAN_HANDLE;
-	list_initialize(&info->link);
-	return info;
-}
-
-/** Destroys structure for used USB address.
- *
- * @param info Structure to be destroyed.
- */
-static void usb_address_keeping_used_destroy(usb_address_keeping_used_t *info)
-{
-	free(info);
-}
-
-/** Find used USB address structure by USB address.
- *
- * It is expected that guard mutex is already locked.
- *
- * @param addresses Address keeping info.
- * @param address Address to be found.
- * @return Structure describing looked for address.
- * @retval NULL Address not found.
- */
-static usb_address_keeping_used_t *usb_address_keeping_used_find_no_lock(
-    usb_address_keeping_t *addresses, usb_address_t address)
-{
-	link_t *link;
-	for_all_used_addresses(link, addresses) {
-		usb_address_keeping_used_t *info
-		    = used_address_get_instance(link);
-
-		if (info->address == address) {
-			return info;
-		}
-	}
-
-	return NULL;
-}
-
-/** Initialize address keeping structure.
- *
- * @param addresses Address keeping info.
- * @param max_address Maximum USB address (exclusive bound).
- */
-void usb_address_keeping_init(usb_address_keeping_t *addresses,
-    usb_address_t max_address)
-{
-	/*
-	 * Items related with used addresses.
-	 */
-	addresses->max_address = max_address;
-	list_initialize(&addresses->used_addresses);
-	fibril_mutex_initialize(&addresses->used_addresses_guard);
-	fibril_condvar_initialize(&addresses->used_addresses_condvar);
-
-	/*
-	 * Items related with default address.
-	 */
-	addresses->default_available = true;
-	fibril_condvar_initialize(&addresses->default_condvar);
-	fibril_mutex_initialize(&addresses->default_condvar_guard);
-}
-
-/** Reserved default USB address.
- *
- * This function blocks until reserved address is available.
- *
- * @see usb_address_keeping_release_default
- *
- * @param addresses Address keeping info.
- */
-void usb_address_keeping_reserve_default(usb_address_keeping_t *addresses)
-{
-	fibril_mutex_lock(&addresses->default_condvar_guard);
-	while (!addresses->default_available) {
-		fibril_condvar_wait(&addresses->default_condvar,
-			&addresses->default_condvar_guard);
-	}
-	addresses->default_available = false;
-	fibril_mutex_unlock(&addresses->default_condvar_guard);
-}
-
-/** Releases default USB address.
- *
- * @see usb_address_keeping_reserve_default
- *
- * @param addresses Address keeping info.
- */
-void usb_address_keeping_release_default(usb_address_keeping_t *addresses)
-{
-	fibril_mutex_lock(&addresses->default_condvar_guard);
-	addresses->default_available = true;
-	fibril_condvar_signal(&addresses->default_condvar);
-	fibril_mutex_unlock(&addresses->default_condvar_guard);
-}
-
-/** Request free address assignment.
- *
- * This function does not block when there are not free addresses to be
- * assigned.
- *
- * @param addresses Address keeping info.
- * @return USB address that could be used or negative error code.
- * @retval ELIMIT No more addresses to assign.
- * @retval ENOMEM Out of memory.
- */
-usb_address_t usb_address_keeping_request(usb_address_keeping_t *addresses)
-{
-	usb_address_t previous_address = 0;
-	usb_address_t free_address = 0;
-
-	fibril_mutex_lock(&addresses->used_addresses_guard);
-	link_t *new_address_position;
-	if (list_empty(&addresses->used_addresses)) {
-		free_address = 1;
-		new_address_position = addresses->used_addresses.next;
-	} else {
-		usb_address_keeping_used_t *first
-		    = used_address_get_instance(addresses->used_addresses.next);
-		previous_address = first->address;
-		
-		for_all_used_addresses(new_address_position, addresses) {
-			usb_address_keeping_used_t *info
-			    = used_address_get_instance(new_address_position);
-			if (info->address > previous_address + 1) {
-				free_address = previous_address + 1;
-				break;
-			}
-			previous_address = info->address;
-		}
-
-		if (free_address == 0) {
-			usb_address_keeping_used_t *last
-			    = used_address_get_instance(addresses->used_addresses.next);
-			free_address = last->address + 1;
-		}
-	}
-
-	if (free_address >= addresses->max_address) {
-		free_address = ELIMIT;
-		goto leave;
-	}
-
-	usb_address_keeping_used_t *used
-	    = usb_address_keeping_used_create(free_address);
-	if (used == NULL) {
-		free_address = ENOMEM;
-		goto leave;
-	}
-
-	list_prepend(&used->link, new_address_position);
-
-leave:
-	fibril_mutex_unlock(&addresses->used_addresses_guard);
-
-	return free_address;
-}
-
-/** Release USB address.
- *
- * @param addresses Address keeping info.
- * @param address Address to be released.
- * @return Error code.
- * @retval ENOENT Address is not in use.
- */
-int usb_address_keeping_release(usb_address_keeping_t *addresses,
-    usb_address_t address)
-{
-	int rc = ENOENT;
-
-	fibril_mutex_lock(&addresses->used_addresses_guard);
-
-	usb_address_keeping_used_t *info
-	    = usb_address_keeping_used_find_no_lock(addresses, address);
-
-	if (info != NULL) {
-		rc = EOK;
-		list_remove(&info->link);
-		usb_address_keeping_used_destroy(info);
-	}
-
-	fibril_mutex_unlock(&addresses->used_addresses_guard);
-
-	return rc;
-}
-
-/** Bind devman handle with USB address.
- *
- * When the @p address is invalid (e.g. no such entry), the request
- * is silently ignored.
- *
- * @param addresses Address keeping info.
- * @param address USB address.
- * @param handle Devman handle.
- */
-void usb_address_keeping_devman_bind(usb_address_keeping_t *addresses,
-    usb_address_t address, devman_handle_t handle)
-{
-	fibril_mutex_lock(&addresses->used_addresses_guard);
-
-	usb_address_keeping_used_t *info
-	    = usb_address_keeping_used_find_no_lock(addresses, address);
-	if (info == NULL) {
-		goto leave;
-	}
-
-	assert(info->address == address);
-	info->devman_handle = handle;
-
-	/*
-	 * Inform that new handle was added.
-	 */
-	fibril_condvar_broadcast(&addresses->used_addresses_condvar);
-
-leave:
-	fibril_mutex_unlock(&addresses->used_addresses_guard);
-}
-
-/** Find address by its devman handle.
- *
- * @param addresses Address keeping info.
- * @param handle Devman handle.
- * @return USB address or negative error code.
- * @retval ENOENT No such address.
- */
-static usb_address_t usb_address_keeping_find_no_lock(
-    usb_address_keeping_t *addresses, devman_handle_t handle)
-{
-	usb_address_t address = ENOENT;
-
-	link_t *link;
-	for_all_used_addresses(link, addresses) {
-		usb_address_keeping_used_t *info
-		    = used_address_get_instance(link);
-
-		if (info->devman_handle == handle) {
-			address = info->address;
-			break;
-		}
-	}
-
-	return address;
-}
-
-/** Find USB address by its devman handle.
- *
- * This function blocks until corresponding address is found.
- *
- * @param addresses Address keeping info.
- * @param handle Devman handle.
- * @return USB address or negative error code.
- */
-usb_address_t usb_address_keeping_find(usb_address_keeping_t *addresses,
-    devman_handle_t handle)
-{
-	usb_address_t address = ENOENT;
-
-	fibril_mutex_lock(&addresses->used_addresses_guard);
-	while (true) {
-		address = usb_address_keeping_find_no_lock(addresses, handle);
-		if (address != ENOENT) {
-			break;
-		}
-		fibril_condvar_wait(&addresses->used_addresses_condvar,
-		    &addresses->used_addresses_guard);
-	}
-
-	fibril_mutex_unlock(&addresses->used_addresses_guard);
-
-	return address;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/altiface.c
===================================================================
--- uspace/lib/usb/src/altiface.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,181 +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 libusb
- * @{
- */
-/** @file
- * Handling alternate interface settings.
- */
-#include <usb/devdrv.h>
-#include <usb/request.h>
-#include <usb/debug.h>
-#include <usb/dp.h>
-#include <errno.h>
-#include <str_error.h>
-#include <assert.h>
-
-/** Count number of alternate settings of a interface.
- *
- * @param config_descr Full configuration descriptor.
- * @param config_descr_size Size of @p config_descr in bytes.
- * @param interface_no Interface number.
- * @return Number of alternate interfaces for @p interface_no interface.
- */
-size_t usb_interface_count_alternates(uint8_t *config_descr,
-    size_t config_descr_size, uint8_t interface_no)
-{
-	assert(config_descr != NULL);
-	assert(config_descr_size > 0);
-
-	usb_dp_parser_t dp_parser = {
-		.nesting = usb_dp_standard_descriptor_nesting
-	};
-	usb_dp_parser_data_t dp_data = {
-		.data = config_descr,
-		.size = config_descr_size,
-		.arg = NULL
-	};
-
-	size_t alternate_count = 0;
-
-	uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
-	    &dp_data, config_descr);
-	while (iface_ptr != NULL) {
-		usb_standard_interface_descriptor_t *iface
-		    = (usb_standard_interface_descriptor_t *) iface_ptr;
-		if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) {
-			if (iface->interface_number == interface_no) {
-				alternate_count++;
-			}
-		}
-		iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
-		    config_descr, iface_ptr);
-	}
-
-	return alternate_count;
-}
-
-/** Create alternate interface representation structure.
- *
- * @param[in] config_descr Configuration descriptor.
- * @param[in] config_descr_size Size of configuration descriptor.
- * @param[in] interface_number Interface number.
- * @param[out] alternates_ptr Where to store pointer to allocated structure.
- * @return Error code.
- */
-int usb_alternate_interfaces_create(uint8_t *config_descr,
-    size_t config_descr_size, int interface_number,
-    usb_alternate_interfaces_t **alternates_ptr)
-{
-	assert(alternates_ptr != NULL);
-	assert(config_descr != NULL);
-	assert(config_descr_size > 0);
-
-	if (interface_number < 0) {
-		alternates_ptr = NULL;
-		return EOK;
-	}
-
-	usb_alternate_interfaces_t *alternates
-	    = malloc(sizeof(usb_alternate_interfaces_t));
-
-	if (alternates == NULL) {
-		return ENOMEM;
-	}
-
-	alternates->alternative_count
-	    = usb_interface_count_alternates(config_descr, config_descr_size,
-	    interface_number);
-
-	if (alternates->alternative_count == 0) {
-		free(alternates);
-		return ENOENT;
-	}
-
-	alternates->alternatives = malloc(alternates->alternative_count
-	    * sizeof(usb_alternate_interface_descriptors_t));
-	if (alternates->alternatives == NULL) {
-		free(alternates);
-		return ENOMEM;
-	}
-
-	alternates->current = 0;
-
-	usb_dp_parser_t dp_parser = {
-		.nesting = usb_dp_standard_descriptor_nesting
-	};
-	usb_dp_parser_data_t dp_data = {
-		.data = config_descr,
-		.size = config_descr_size,
-		.arg = NULL
-	};
-
-	usb_alternate_interface_descriptors_t *cur_alt_iface
-	    = &alternates->alternatives[0];
-
-	uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
-	    &dp_data, dp_data.data);
-	while (iface_ptr != NULL) {
-		usb_standard_interface_descriptor_t *iface
-		    = (usb_standard_interface_descriptor_t *) iface_ptr;
-		if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE)
-		    || (iface->interface_number != interface_number)) {
-			iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser,
-			    &dp_data,
-			    dp_data.data, iface_ptr);
-			continue;
-		}
-
-		cur_alt_iface->interface = iface;
-		cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface);
-
-		/* Find next interface to count size of nested descriptors. */
-		iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
-		    dp_data.data, iface_ptr);
-		if (iface_ptr == NULL) {
-			uint8_t *next = dp_data.data + dp_data.size;
-			cur_alt_iface->nested_descriptors_size
-			    = next - cur_alt_iface->nested_descriptors;
-		} else {
-			cur_alt_iface->nested_descriptors_size
-			    = iface_ptr - cur_alt_iface->nested_descriptors;
-		}
-
-		cur_alt_iface++;
-	}
-
-	*alternates_ptr = alternates;
-
-	return EOK;
-}
-
-
-/**
- * @}
- */
Index: uspace/lib/usb/src/ddfiface.c
===================================================================
--- uspace/lib/usb/src/ddfiface.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/usb/src/ddfiface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -37,4 +37,5 @@
 #include <async.h>
 #include <usb/ddfiface.h>
+#include <usb/driver.h>
 #include <usb/debug.h>
 #include <errno.h>
Index: pace/lib/usb/src/devdrv.c
===================================================================
--- uspace/lib/usb/src/devdrv.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,537 +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 libusb
- * @{
- */
-/** @file
- * USB device driver framework.
- */
-#include <usb/devdrv.h>
-#include <usb/request.h>
-#include <usb/debug.h>
-#include <usb/dp.h>
-#include <errno.h>
-#include <str_error.h>
-#include <assert.h>
-
-static int generic_add_device(ddf_dev_t *);
-
-static driver_ops_t generic_driver_ops = {
-	.add_device = generic_add_device
-};
-static driver_t generic_driver = {
-	.driver_ops = &generic_driver_ops
-};
-
-static usb_driver_t *driver = NULL;
-
-
-/** Main routine of USB device driver.
- *
- * Under normal conditions, this function never returns.
- *
- * @param drv USB device driver structure.
- * @return Task exit status.
- */
-int usb_driver_main(usb_driver_t *drv)
-{
-	assert(drv != NULL);
-
-	/* Prepare the generic driver. */
-	generic_driver.name = drv->name;
-
-	driver = drv;
-
-	return ddf_driver_main(&generic_driver);
-}
-
-/** Count number of pipes the driver expects.
- *
- * @param drv USB driver.
- * @return Number of pipes (excluding default control pipe).
- */
-static size_t count_other_pipes(usb_endpoint_description_t **endpoints)
-{
-	size_t count = 0;
-	if (endpoints == NULL) {
-		return 0;
-	}
-
-	while (endpoints[count] != NULL) {
-		count++;
-	}
-
-	return count;
-}
-
-/** Initialize endpoint pipes, excluding default control one.
- *
- * @param drv The device driver.
- * @param dev Device to be initialized.
- * @return Error code.
- */
-static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
-    usb_device_t *dev, int alternate_setting)
-{
-	if (endpoints == NULL) {
-		dev->pipes = NULL;
-		dev->pipes_count = 0;
-		return EOK;
-	}
-
-	usb_endpoint_mapping_t *pipes;
-	size_t pipes_count;
-
-	int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,
-	    dev->descriptors.configuration, dev->descriptors.configuration_size,
-	    dev->interface_no, alternate_setting,
-	    &pipes, &pipes_count);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	dev->pipes = pipes;
-	dev->pipes_count = pipes_count;
-
-	return EOK;
-}
-
-/** Callback when new device is supposed to be controlled by this driver.
- *
- * This callback is a wrapper for USB specific version of @c add_device.
- *
- * @param gen_dev Device structure as prepared by DDF.
- * @return Error code.
- */
-int generic_add_device(ddf_dev_t *gen_dev)
-{
-	assert(driver);
-	assert(driver->ops);
-	assert(driver->ops->add_device);
-
-	int rc;
-
-	usb_device_t *dev = NULL;
-	const char *err_msg = NULL;
-	rc = usb_device_create(gen_dev, driver->endpoints, &dev, &err_msg);
-	if (rc != EOK) {
-		usb_log_error("USB device `%s' creation failed (%s): %s.\n",
-		    gen_dev->name, err_msg, str_error(rc));
-		return rc;
-	}
-
-	return driver->ops->add_device(dev);
-}
-
-/** Destroy existing pipes of a USB device.
- *
- * @param dev Device where to destroy the pipes.
- * @return Error code.
- */
-static int destroy_current_pipes(usb_device_t *dev)
-{
-	int rc = usb_device_destroy_pipes(dev->ddf_dev,
-	    dev->pipes, dev->pipes_count);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	dev->pipes = NULL;
-	dev->pipes_count = 0;
-
-	return EOK;
-}
-
-/** Change interface setting of a device.
- * This function selects new alternate setting of an interface by issuing
- * proper USB command to the device and also creates new USB pipes
- * under @c dev->pipes.
- *
- * @warning This function is intended for drivers working at interface level.
- * For drivers controlling the whole device, you need to change interface
- * manually using usb_request_set_interface() and creating new pipes
- * with usb_pipe_initialize_from_configuration().
- *
- * @warning This is a wrapper function that does several operations that
- * can fail and that cannot be rollbacked easily. That means that a failure
- * during the SET_INTERFACE request would result in having a device with
- * no pipes at all (except the default control one). That is because the old
- * pipes needs to be unregistered at HC first and the new ones could not
- * be created.
- *
- * @param dev USB device.
- * @param alternate_setting Alternate setting to choose.
- * @param endpoints New endpoint descriptions.
- * @return Error code.
- */
-int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
-    usb_endpoint_description_t **endpoints)
-{
-	if (dev->interface_no < 0) {
-		return EINVAL;
-	}
-
-	int rc;
-
-	/* Destroy existing pipes. */
-	rc = destroy_current_pipes(dev);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/* Change the interface itself. */
-	rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
-	    alternate_setting);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/* Create new pipes. */
-	rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting);
-
-	return rc;
-}
-
-/** Retrieve basic descriptors from the device.
- *
- * @param[in] ctrl_pipe Control endpoint pipe.
- * @param[out] descriptors Where to store the descriptors.
- * @return Error code.
- */
-int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe,
-    usb_device_descriptors_t *descriptors)
-{
-	assert(descriptors != NULL);
-
-	descriptors->configuration = NULL;
-
-	int rc;
-
-	/* It is worth to start a long transfer. */
-	usb_pipe_start_long_transfer(ctrl_pipe);
-
-	/* Get the device descriptor. */
-	rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
-	if (rc != EOK) {
-		goto leave;
-	}
-
-	/* Get the full configuration descriptor. */
-	rc = usb_request_get_full_configuration_descriptor_alloc(
-	    ctrl_pipe, 0, (void **) &descriptors->configuration,
-	    &descriptors->configuration_size);
-
-leave:
-	usb_pipe_end_long_transfer(ctrl_pipe);
-
-	return rc;
-}
-
-/** Create pipes for a device.
- *
- * This is more or less a wrapper that does following actions:
- * - allocate and initialize pipes
- * - map endpoints to the pipes based on the descriptions
- * - registers endpoints with the host controller
- *
- * @param[in] dev Generic DDF device backing the USB one.
- * @param[in] wire Initialized backing connection to the host controller.
- * @param[in] endpoints Endpoints description, NULL terminated.
- * @param[in] config_descr Configuration descriptor of active configuration.
- * @param[in] config_descr_size Size of @p config_descr in bytes.
- * @param[in] interface_no Interface to map from.
- * @param[in] interface_setting Interface setting (default is usually 0).
- * @param[out] pipes_ptr Where to store array of created pipes
- *	(not NULL terminated).
- * @param[out] pipes_count_ptr Where to store number of pipes
- *	(set to if you wish to ignore the count).
- * @return Error code.
- */
-int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire,
-    usb_endpoint_description_t **endpoints,
-    uint8_t *config_descr, size_t config_descr_size,
-    int interface_no, int interface_setting,
-    usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
-{
-	assert(dev != NULL);
-	assert(wire != NULL);
-	assert(endpoints != NULL);
-	assert(config_descr != NULL);
-	assert(config_descr_size > 0);
-	assert(pipes_ptr != NULL);
-
-	size_t i;
-	int rc;
-
-	size_t pipe_count = count_other_pipes(endpoints);
-	if (pipe_count == 0) {
-		*pipes_ptr = NULL;
-		return EOK;
-	}
-
-	usb_endpoint_mapping_t *pipes
-	    = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
-	if (pipes == NULL) {
-		return ENOMEM;
-	}
-
-	/* Initialize to NULL to allow smooth rollback. */
-	for (i = 0; i < pipe_count; i++) {
-		pipes[i].pipe = NULL;
-	}
-
-	/* Now allocate and fully initialize. */
-	for (i = 0; i < pipe_count; i++) {
-		pipes[i].pipe = malloc(sizeof(usb_pipe_t));
-		if (pipes[i].pipe == NULL) {
-			rc = ENOMEM;
-			goto rollback_free_only;
-		}
-		pipes[i].description = endpoints[i];
-		pipes[i].interface_no = interface_no;
-		pipes[i].interface_setting = interface_setting;
-	}
-
-	/* Find the mapping from configuration descriptor. */
-	rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
-	    config_descr, config_descr_size, wire);
-	if (rc != EOK) {
-		goto rollback_free_only;
-	}
-
-	/* Register the endpoints with HC. */
-	usb_hc_connection_t hc_conn;
-	rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
-	if (rc != EOK) {
-		goto rollback_free_only;
-	}
-
-	rc = usb_hc_connection_open(&hc_conn);
-	if (rc != EOK) {
-		goto rollback_free_only;
-	}
-
-	for (i = 0; i < pipe_count; i++) {
-		if (pipes[i].present) {
-			rc = usb_pipe_register(pipes[i].pipe,
-			    pipes[i].descriptor->poll_interval, &hc_conn);
-			if (rc != EOK) {
-				goto rollback_unregister_endpoints;
-			}
-		}
-	}
-
-	usb_hc_connection_close(&hc_conn);
-
-	*pipes_ptr = pipes;
-	if (pipes_count_ptr != NULL) {
-		*pipes_count_ptr = pipe_count;
-	}
-
-	return EOK;
-
-	/*
-	 * Jump here if something went wrong after endpoints have
-	 * been registered.
-	 * This is also the target when the registration of
-	 * endpoints fails.
-	 */
-rollback_unregister_endpoints:
-	for (i = 0; i < pipe_count; i++) {
-		if (pipes[i].present) {
-			usb_pipe_unregister(pipes[i].pipe, &hc_conn);
-		}
-	}
-
-	usb_hc_connection_close(&hc_conn);
-
-	/*
-	 * Jump here if something went wrong before some actual communication
-	 * with HC. Then the only thing that needs to be done is to free
-	 * allocated memory.
-	 */
-rollback_free_only:
-	for (i = 0; i < pipe_count; i++) {
-		if (pipes[i].pipe != NULL) {
-			free(pipes[i].pipe);
-		}
-	}
-	free(pipes);
-
-	return rc;
-}
-
-/** Destroy pipes previously created by usb_device_create_pipes.
- *
- * @param[in] dev Generic DDF device backing the USB one.
- * @param[in] pipes Endpoint mapping to be destroyed.
- * @param[in] pipes_count Number of endpoints.
- */
-int usb_device_destroy_pipes(ddf_dev_t *dev,
-    usb_endpoint_mapping_t *pipes, size_t pipes_count)
-{
-	assert(dev != NULL);
-	assert(((pipes != NULL) && (pipes_count > 0))
-	    || ((pipes == NULL) && (pipes_count == 0)));
-
-	if (pipes_count == 0) {
-		return EOK;
-	}
-
-	int rc;
-
-	/* Prepare connection to HC to allow endpoint unregistering. */
-	usb_hc_connection_t hc_conn;
-	rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
-	if (rc != EOK) {
-		return rc;
-	}
-	rc = usb_hc_connection_open(&hc_conn);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/* Destroy the pipes. */
-	size_t i;
-	for (i = 0; i < pipes_count; i++) {
-		usb_pipe_unregister(pipes[i].pipe, &hc_conn);
-		free(pipes[i].pipe);
-	}
-
-	usb_hc_connection_close(&hc_conn);
-
-	free(pipes);
-
-	return EOK;
-}
-
-/** Initialize control pipe in a device.
- *
- * @param dev USB device in question.
- * @param errmsg Where to store error context.
- * @return
- */
-static int init_wire_and_ctrl_pipe(usb_device_t *dev, const char **errmsg)
-{
-	int rc;
-
-	rc = usb_device_connection_initialize_from_device(&dev->wire,
-	    dev->ddf_dev);
-	if (rc != EOK) {
-		*errmsg = "device connection initialization";
-		return rc;
-	}
-
-	rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
-	    &dev->wire);
-	if (rc != EOK) {
-		*errmsg = "default control pipe initialization";
-		return rc;
-	}
-
-	return EOK;
-}
-
-
-/** Create new instance of USB device.
- *
- * @param[in] ddf_dev Generic DDF device backing the USB one.
- * @param[in] endpoints NULL terminated array of endpoints (NULL for none).
- * @param[out] dev_ptr Where to store pointer to the new device.
- * @param[out] errstr_ptr Where to store description of context
- *	(in case error occurs).
- * @return Error code.
- */
-int usb_device_create(ddf_dev_t *ddf_dev,
-    usb_endpoint_description_t **endpoints,
-    usb_device_t **dev_ptr, const char **errstr_ptr)
-{
-	assert(dev_ptr != NULL);
-	assert(ddf_dev != NULL);
-
-	int rc;
-
-	usb_device_t *dev = malloc(sizeof(usb_device_t));
-	if (dev == NULL) {
-		*errstr_ptr = "structure allocation";
-		return ENOMEM;
-	}
-
-	// FIXME: proper deallocation in case of errors
-
-	dev->ddf_dev = ddf_dev;
-	dev->driver_data = NULL;
-	dev->descriptors.configuration = NULL;
-	dev->alternate_interfaces = NULL;
-
-	dev->pipes_count = 0;
-	dev->pipes = NULL;
-
-	/* Initialize backing wire and control pipe. */
-	rc = init_wire_and_ctrl_pipe(dev, errstr_ptr);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/* Get our interface. */
-	dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
-
-	/* Retrieve standard descriptors. */
-	rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
-	    &dev->descriptors);
-	if (rc != EOK) {
-		*errstr_ptr = "descriptor retrieval";
-		return rc;
-	}
-
-	/* Create alternate interfaces. */
-	rc = usb_alternate_interfaces_create(dev->descriptors.configuration,
-	    dev->descriptors.configuration_size, dev->interface_no,
-	    &dev->alternate_interfaces);
-	if (rc != EOK) {
-		/* We will try to silently ignore this. */
-		dev->alternate_interfaces = NULL;
-	}
-
-	rc = initialize_other_pipes(endpoints, dev, 0);
-	if (rc != EOK) {
-		*errstr_ptr = "pipes initialization";
-		return rc;
-	}
-
-	*errstr_ptr = NULL;
-	*dev_ptr = dev;
-
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/devpoll.c
===================================================================
--- uspace/lib/usb/src/devpoll.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,317 +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 libusb
- * @{
- */
-/** @file
- * USB device driver framework - automatic interrupt polling.
- */
-#include <usb/devpoll.h>
-#include <usb/request.h>
-#include <usb/debug.h>
-#include <usb/classes/classes.h>
-#include <errno.h>
-#include <str_error.h>
-#include <assert.h>
-
-/** Maximum number of failed consecutive requests before announcing failure. */
-#define MAX_FAILED_ATTEMPTS 3
-
-/** Data needed for polling. */
-typedef struct {
-	int debug;
-	size_t max_failures;
-	useconds_t delay;
-	bool auto_clear_halt;
-	bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *);
-	void (*on_polling_end)(usb_device_t *, bool, void *);
-	bool (*on_error)(usb_device_t *, int, void *);
-
-	usb_device_t *dev;
-	size_t pipe_index;
-	size_t request_size;
-	uint8_t *buffer;
-	void *custom_arg;
-} polling_data_t;
-
-
-/** Polling fibril.
- *
- * @param arg Pointer to polling_data_t.
- * @return Always EOK.
- */
-static int polling_fibril(void *arg)
-{
-	polling_data_t *polling_data = (polling_data_t *) arg;
-	assert(polling_data);
-
-	usb_pipe_t *pipe
-	    = polling_data->dev->pipes[polling_data->pipe_index].pipe;
-	
-	if (polling_data->debug > 0) {
-		usb_endpoint_mapping_t *mapping
-		    = &polling_data->dev->pipes[polling_data->pipe_index];
-		usb_log_debug("Poll%p: started polling of `%s' - " \
-		    "interface %d (%s,%d,%d), %zuB/%zu.\n",
-		    polling_data,
-		    polling_data->dev->ddf_dev->name,
-		    (int) mapping->interface->interface_number,
-		    usb_str_class(mapping->interface->interface_class),
-		    (int) mapping->interface->interface_subclass,
-		    (int) mapping->interface->interface_protocol,
-		    polling_data->request_size, pipe->max_packet_size);
-	}
-
-	size_t failed_attempts = 0;
-	while (failed_attempts <= polling_data->max_failures) {
-		int rc;
-
-		size_t actual_size;
-		rc = usb_pipe_read(pipe, polling_data->buffer,
-		    polling_data->request_size, &actual_size);
-
-		if (polling_data->debug > 1) {
-			if (rc == EOK) {
-				usb_log_debug(
-				    "Poll%p: received: '%s' (%zuB).\n",
-				    polling_data,
-				    usb_debug_str_buffer(polling_data->buffer,
-				        actual_size, 16),
-				    actual_size);
-			} else {
-				usb_log_debug(
-				    "Poll%p: polling failed: %s.\n",
-				    polling_data, str_error(rc));
-			}
-		}
-
-		/* If the pipe stalled, we can try to reset the stall. */
-		if ((rc == ESTALL) && (polling_data->auto_clear_halt)) {
-			/*
-			 * We ignore error here as this is usually a futile
-			 * attempt anyway.
-			 */
-			usb_request_clear_endpoint_halt(
-			    &polling_data->dev->ctrl_pipe,
-			    pipe->endpoint_no);
-		}
-
-		if (rc != EOK) {
-			if (polling_data->on_error != NULL) {
-				bool cont = polling_data->on_error(
-				    polling_data->dev, rc,
-				    polling_data->custom_arg);
-				if (!cont) {
-					failed_attempts
-					    = polling_data->max_failures;
-				}
-			}
-			failed_attempts++;
-			continue;
-		}
-
-		/* We have the data, execute the callback now. */
-		bool carry_on = polling_data->on_data(polling_data->dev,
-		    polling_data->buffer, actual_size,
-		    polling_data->custom_arg);
-
-		if (!carry_on) {
-			failed_attempts = 0;
-			break;
-		}
-
-		/* Reset as something might be only a temporary problem. */
-		failed_attempts = 0;
-
-		/* Take a rest before next request. */
-		async_usleep(polling_data->delay);
-	}
-
-	if (polling_data->on_polling_end != NULL) {
-		polling_data->on_polling_end(polling_data->dev,
-		    failed_attempts > 0, polling_data->custom_arg);
-	}
-
-	if (polling_data->debug > 0) {
-		if (failed_attempts > 0) {
-			usb_log_error(
-			    "Polling of device `%s' terminated: %s.\n",
-			    polling_data->dev->ddf_dev->name,
-			    "recurring failures");
-		} else {
-			usb_log_debug(
-			    "Polling of device `%s' terminated by user.\n",
-			    polling_data->dev->ddf_dev->name
-			);
-		}
-	}
-
-	/* Free the allocated memory. */
-	free(polling_data->buffer);
-	free(polling_data);
-
-	return EOK;
-}
-
-/** Start automatic device polling over interrupt in pipe.
- *
- * @warning It is up to the callback to produce delays between individual
- * requests.
- *
- * @warning There is no guarantee when the request to the device
- * will be sent for the first time (it is possible that this
- * first request would be executed prior to return from this function).
- *
- * @param dev Device to be periodically polled.
- * @param pipe_index Index of the endpoint pipe used for polling.
- * @param callback Callback when data are available.
- * @param request_size How many bytes to ask for in each request.
- * @param terminated_callback Callback when polling is terminated.
- * @param arg Custom argument (passed as is to the callbacks).
- * @return Error code.
- * @retval EOK New fibril polling the device was already started.
- */
-int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
-    usb_polling_callback_t callback, size_t request_size,
-    usb_polling_terminted_callback_t terminated_callback, void *arg)
-{
-	if ((dev == NULL) || (callback == NULL)) {
-		return EBADMEM;
-	}
-	if (request_size == 0) {
-		return EINVAL;
-	}
-	if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
-	    || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
-		return EINVAL;
-	}
-
-	usb_device_auto_polling_t *auto_polling
-	    = malloc(sizeof(usb_device_auto_polling_t));
-	if (auto_polling == NULL) {
-		return ENOMEM;
-	}
-
-	auto_polling->debug = 1;
-	auto_polling->auto_clear_halt = true;
-	auto_polling->delay = 0;
-	auto_polling->max_failures = MAX_FAILED_ATTEMPTS;
-	auto_polling->on_data = callback;
-	auto_polling->on_polling_end = terminated_callback;
-	auto_polling->on_error = NULL;
-
-	int rc = usb_device_auto_polling(dev, pipe_index, auto_polling,
-	   request_size, arg);
-
-	free(auto_polling);
-
-	return rc;
-}
-
-/** Start automatic device polling over interrupt in pipe.
- *
- * The polling settings is copied thus it is okay to destroy the structure
- * after this function returns.
- *
- * @warning There is no guarantee when the request to the device
- * will be sent for the first time (it is possible that this
- * first request would be executed prior to return from this function).
- *
- * @param dev Device to be periodically polled.
- * @param pipe_index Index of the endpoint pipe used for polling.
- * @param polling Polling settings.
- * @param request_size How many bytes to ask for in each request.
- * @param arg Custom argument (passed as is to the callbacks).
- * @return Error code.
- * @retval EOK New fibril polling the device was already started.
- */
-int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
-    usb_device_auto_polling_t *polling,
-    size_t request_size, void *arg)
-{
-	if (dev == NULL) {
-		return EBADMEM;
-	}
-	if (pipe_index >= dev->pipes_count) {
-		return EINVAL;
-	}
-	if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
-	    || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
-		return EINVAL;
-	}
-	if ((polling == NULL) || (polling->on_data == NULL)) {
-		return EBADMEM;
-	}
-
-	polling_data_t *polling_data = malloc(sizeof(polling_data_t));
-	if (polling_data == NULL) {
-		return ENOMEM;
-	}
-
-	/* Fill-in the data. */
-	polling_data->buffer = malloc(sizeof(request_size));
-	if (polling_data->buffer == NULL) {
-		free(polling_data);
-		return ENOMEM;
-	}
-	polling_data->request_size = request_size;
-	polling_data->dev = dev;
-	polling_data->pipe_index = pipe_index;
-	polling_data->custom_arg = arg;
-
-	polling_data->debug = polling->debug;
-	polling_data->max_failures = polling->max_failures;
-	if (polling->delay >= 0) {
-		polling_data->delay = (useconds_t) polling->delay;
-	} else {
-		polling_data->delay = (useconds_t) dev->pipes[pipe_index]
-		    .descriptor->poll_interval;
-	}
-	polling_data->auto_clear_halt = polling->auto_clear_halt;
-
-	polling_data->on_data = polling->on_data;
-	polling_data->on_polling_end = polling->on_polling_end;
-	polling_data->on_error = polling->on_error;
-
-	fid_t fibril = fibril_create(polling_fibril, polling_data);
-	if (fibril == 0) {
-		free(polling_data->buffer);
-		free(polling_data);
-		return ENOMEM;
-	}
-	fibril_add_ready(fibril);
-
-	/* Fibril launched. That fibril will free the allocated data. */
-
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/dp.c
===================================================================
--- uspace/lib/usb/src/dp.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,326 +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 libusb
- * @{
- */
-/**
- * @file
- * USB descriptor parser (implementation).
- *
- * The descriptor parser is a generic parser for structure, where individual
- * items are stored in single buffer and each item begins with length followed
- * by type. These types are organized into tree hierarchy.
- *
- * The parser is able of only two actions: find first child and find next
- * sibling.
- */
-#include <stdio.h>
-#include <str_error.h>
-#include <errno.h>
-#include <assert.h>
-#include <bool.h>
-#include <usb/dp.h>
-#include <usb/descriptor.h>
-
-#define NESTING(parentname, childname) \
-	{ \
-		.child = USB_DESCTYPE_##childname, \
-		.parent = USB_DESCTYPE_##parentname, \
-	}
-#define LAST_NESTING { -1, -1 }
-
-/** Nesting of standard USB descriptors. */
-usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = {
-	NESTING(CONFIGURATION, INTERFACE),
-	NESTING(INTERFACE, ENDPOINT),
-	NESTING(INTERFACE, HUB),
-	NESTING(INTERFACE, HID),
-	NESTING(HID, HID_REPORT),
-	LAST_NESTING
-};
-
-#undef NESTING
-#undef LAST_NESTING
-
-/** Tells whether pointer points inside descriptor data.
- *
- * @param data Parser data.
- * @param ptr Pointer to be verified.
- * @return Whether @p ptr points inside <code>data->data</code> field.
- */
-static bool is_valid_descriptor_pointer(usb_dp_parser_data_t *data,
-    uint8_t *ptr)
-{
-	if (ptr == NULL) {
-		return false;
-	}
-
-	if (ptr < data->data) {
-		return false;
-	}
-
-	if ((size_t)(ptr - data->data) >= data->size) {
-		return false;
-	}
-
-	return true;
-}
-
-/** Get next descriptor regardless of the nesting.
- *
- * @param data Parser data.
- * @param current Pointer to current descriptor.
- * @return Pointer to start of next descriptor.
- * @retval NULL Invalid input or no next descriptor.
- */
-static uint8_t *get_next_descriptor(usb_dp_parser_data_t *data,
-    uint8_t *current)
-{
-	assert(is_valid_descriptor_pointer(data, current));
-
-	uint8_t current_length = *current;
-	uint8_t *next = current + current_length;
-
-	if (!is_valid_descriptor_pointer(data, next)) {
-		return NULL;
-	}
-
-	return next;
-}
-
-/** Get descriptor type.
- *
- * @see usb_descriptor_type_t
- *
- * @param data Parser data.
- * @param start Pointer to start of the descriptor.
- * @return Descriptor type.
- * @retval -1 Invalid input.
- */
-static int get_descriptor_type(usb_dp_parser_data_t *data, uint8_t *start)
-{
-	if (start == NULL) {
-		return -1;
-	}
-
-	start++;
-	if (!is_valid_descriptor_pointer(data, start)) {
-		return -1;
-	} else {
-		return (int) (*start);
-	}
-}
-
-/** Tells whether descriptors could be nested.
- *
- * @param parser Parser.
- * @param child Child descriptor type.
- * @param parent Parent descriptor type.
- * @return Whether @p child could be child of @p parent.
- */
-static bool is_nested_descriptor_type(usb_dp_parser_t *parser,
-    int child, int parent)
-{
-	usb_dp_descriptor_nesting_t *nesting = parser->nesting;
-	while ((nesting->child > 0) && (nesting->parent > 0)) {
-		if ((nesting->child == child) && (nesting->parent == parent)) {
-			return true;
-		}
-		nesting++;
-	}
-	return false;
-}
-
-/** Tells whether descriptors could be nested.
- *
- * @param parser Parser.
- * @param data Parser data.
- * @param child Pointer to child descriptor.
- * @param parent Pointer to parent descriptor.
- * @return Whether @p child could be child of @p parent.
- */
-static bool is_nested_descriptor(usb_dp_parser_t *parser,
-    usb_dp_parser_data_t *data, uint8_t *child, uint8_t *parent)
-{
-	return is_nested_descriptor_type(parser,
-	    get_descriptor_type(data, child),
-	    get_descriptor_type(data, parent));
-}
-
-/** Find first nested descriptor of given parent.
- *
- * @param parser Parser.
- * @param data Parser data.
- * @param parent Pointer to the beginning of parent descriptor.
- * @return Pointer to the beginning of the first nested (child) descriptor.
- * @retval NULL No child descriptor found.
- * @retval NULL Invalid input.
- */
-uint8_t *usb_dp_get_nested_descriptor(usb_dp_parser_t *parser,
-    usb_dp_parser_data_t *data, uint8_t *parent)
-{
-	if (!is_valid_descriptor_pointer(data, parent)) {
-		return NULL;
-	}
-
-	uint8_t *next = get_next_descriptor(data, parent);
-	if (next == NULL) {
-		return NULL;
-	}
-
-	if (is_nested_descriptor(parser, data, next, parent)) {
-		return next;
-	} else {
-		return NULL;
-	}
-}
-
-/** Skip all nested descriptors.
- *
- * @param parser Parser.
- * @param data Parser data.
- * @param parent Pointer to the beginning of parent descriptor.
- * @return Pointer to first non-child descriptor.
- * @retval NULL No next descriptor.
- * @retval NULL Invalid input.
- */
-static uint8_t *skip_nested_descriptors(usb_dp_parser_t *parser,
-    usb_dp_parser_data_t *data, uint8_t *parent)
-{
-	uint8_t *child = usb_dp_get_nested_descriptor(parser, data, parent);
-	if (child == NULL) {
-		return get_next_descriptor(data, parent);
-	}
-	uint8_t *next_child = skip_nested_descriptors(parser, data, child);
-	while (is_nested_descriptor(parser, data, next_child, parent)) {
-		next_child = skip_nested_descriptors(parser, data, next_child);
-	}
-
-	return next_child;
-}
-
-/** Get sibling descriptor.
- *
- * @param parser Parser.
- * @param data Parser data.
- * @param parent Pointer to common parent descriptor.
- * @param sibling Left sibling.
- * @return Pointer to first right sibling of @p sibling.
- * @retval NULL No sibling exist.
- * @retval NULL Invalid input.
- */
-uint8_t *usb_dp_get_sibling_descriptor(usb_dp_parser_t *parser,
-    usb_dp_parser_data_t *data, uint8_t *parent, uint8_t *sibling)
-{
-	if (!is_valid_descriptor_pointer(data, parent)
-	    || !is_valid_descriptor_pointer(data, sibling)) {
-		return NULL;
-	}
-
-	uint8_t *possible_sibling = skip_nested_descriptors(parser, data, sibling);
-	if (possible_sibling == NULL) {
-		return NULL;
-	}
-
-	int parent_type = get_descriptor_type(data, parent);
-	int possible_sibling_type = get_descriptor_type(data, possible_sibling);
-	if (is_nested_descriptor_type(parser, possible_sibling_type, parent_type)) {
-		return possible_sibling;
-	} else {
-		return NULL;
-	}
-}
-
-/** Browser of the descriptor tree.
- *
- * @see usb_dp_walk_simple
- *
- * @param parser Descriptor parser.
- * @param data Data for descriptor parser.
- * @param root Pointer to current root of the tree.
- * @param depth Current nesting depth.
- * @param callback Callback for each found descriptor.
- * @param arg Custom (user) argument.
- */
-static void usb_dp_browse_simple_internal(usb_dp_parser_t *parser,
-    usb_dp_parser_data_t *data, uint8_t *root, size_t depth,
-    void (*callback)(uint8_t *, size_t, void *), void *arg)
-{
-	if (root == NULL) {
-		return;
-	}
-	callback(root, depth, arg);
-	uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
-	do {
-		usb_dp_browse_simple_internal(parser, data, child, depth + 1,
-		    callback, arg);
-		child = usb_dp_get_sibling_descriptor(parser, data,
-		    root, child);
-	} while (child != NULL);
-}
-
-/** Browse flatten descriptor tree.
- *
- * The callback is called with following arguments: pointer to the start
- * of the descriptor (somewhere inside @p descriptors), depth of the nesting
- * (starting from 0 for the first descriptor) and the custom argument.
- * Note that the size of the descriptor is not passed because it can
- * be read from the first byte of the descriptor.
- *
- * @param descriptors Descriptor data.
- * @param descriptors_size Size of descriptor data (in bytes).
- * @param descriptor_nesting Possible descriptor nesting.
- * @param callback Callback for each found descriptor.
- * @param arg Custom (user) argument.
- */
-void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size,
-    usb_dp_descriptor_nesting_t *descriptor_nesting,
-    void (*callback)(uint8_t *, size_t, void *), void *arg)
-{
-	if ((descriptors == NULL) || (descriptors_size == 0)
-	    || (descriptor_nesting == NULL) || (callback == NULL)) {
-		return;
-	}
-
-	usb_dp_parser_data_t data = {
-		.data = descriptors,
-		.size = descriptors_size,
-		.arg = NULL
-	};
-
-	usb_dp_parser_t parser = {
-		.nesting = descriptor_nesting
-	};
-
-	usb_dp_browse_simple_internal(&parser, &data, descriptors,
-	    0, callback, arg);
-}
-
-/** @}
- */
Index: uspace/lib/usb/src/driver.c
===================================================================
--- uspace/lib/usb/src/driver.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usb/src/driver.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,76 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ *
+ */
+#include <devman.h>
+#include <dev_iface.h>
+#include <usb_iface.h>
+#include <usb/driver.h>
+#include <errno.h>
+
+
+/** Find host controller handle that is ancestor of given device.
+ *
+ * @param[in] device_handle Device devman handle.
+ * @param[out] hc_handle Where to store handle of host controller
+ *	controlling device with @p device_handle handle.
+ * @return Error code.
+ */
+int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle)
+{
+	int parent_phone = devman_parent_device_connect(device_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);
+
+	async_hangup(parent_phone);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (hc_handle != NULL) {
+		*hc_handle = h;
+	}
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usb/src/dump.c
===================================================================
--- uspace/lib/usb/src/dump.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/usb/src/dump.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -41,5 +41,4 @@
 #include <usb/descriptor.h>
 #include <usb/classes/classes.h>
-#include <usb/classes/hid.h>
 
 /** Mapping between descriptor id and dumping function. */
Index: pace/lib/usb/src/hiddescriptor.c
===================================================================
--- uspace/lib/usb/src/hiddescriptor.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,789 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * HID report descriptor and report data parser implementation.
- */
-#include <usb/classes/hidparser.h>
-#include <errno.h>
-#include <stdio.h>
-#include <malloc.h>
-#include <mem.h>
-#include <usb/debug.h>
-#include <assert.h>
-
-
-#define OUTSIDE_DELIMITER_SET	0
-#define START_DELIMITER_SET	1
-#define INSIDE_DELIMITER_SET	2
-	
-/** The new report item flag. Used to determine when the item is completly
- * configured and should be added to the report structure
- */
-#define USB_HID_NEW_REPORT_ITEM 1
-
-/** No special action after the report descriptor tag is processed should be
- * done
- */
-#define USB_HID_NO_ACTION	2
-
-#define USB_HID_RESET_OFFSET	3
-
-/** Unknown tag was founded in report descriptor data*/
-#define USB_HID_UNKNOWN_TAG		-99
-
-usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
-{
-	/* find or append current collection path to the list */
-	link_t *path_it = report->collection_paths.next;
-	usb_hid_report_path_t *path = NULL;
-	while(path_it != &report->collection_paths) {
-		path = list_get_instance(path_it, usb_hid_report_path_t, link);
-		
-		if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
-			break;
-		}			
-		path_it = path_it->next;
-	}
-	if(path_it == &report->collection_paths) {
-		path = usb_hid_report_path_clone(cmp_path);			
-		list_append(&path->link, &report->collection_paths);					
-		report->collection_paths_count++;
-
-		return path;
-	}
-	else {
-		return list_get_instance(path_it, usb_hid_report_path_t, link);
-	}
-}
-
-/**
- * Initialize the report descriptor parser structure
- *
- * @param parser Report descriptor parser structure
- * @return Error code
- */
-int usb_hid_report_init(usb_hid_report_t *report)
-{
-	if(report == NULL) {
-		return EINVAL;
-	}
-
-	memset(report, 0, sizeof(usb_hid_report_t));
-	list_initialize(&report->reports);
-	list_initialize(&report->collection_paths);
-
-	report->use_report_ids = 0;
-    return EOK;   
-}
-
-
-/*
- *
- *
- */
-int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
-{
-	usb_hid_report_field_t *field;
-	int i;
-
-	for(i=0; i<report_item->usages_count; i++){
-		usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
-	}
-
-	usb_hid_report_path_t *path = report_item->usage_path;	
-	for(i=0; i<report_item->count; i++){
-
-		field = malloc(sizeof(usb_hid_report_field_t));
-		memset(field, 0, sizeof(usb_hid_report_field_t));
-		list_initialize(&field->link);
-
-		/* fill the attributes */		
-		field->logical_minimum = report_item->logical_minimum;
-		field->logical_maximum = report_item->logical_maximum;
-		field->physical_minimum = report_item->physical_minimum;
-		field->physical_maximum = report_item->physical_maximum;
-
-		field->usage_minimum = report_item->usage_minimum;
-		field->usage_maximum = report_item->usage_maximum;
-		if(report_item->extended_usage_page != 0){
-			field->usage_page = report_item->extended_usage_page;
-		}
-		else {
-			field->usage_page = report_item->usage_page;
-		}
-
-		if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
-			uint32_t usage;
-			if(i < report_item->usages_count){
-				usage = report_item->usages[i];
-			}
-			else {
-				usage = report_item->usages[report_item->usages_count - 1];
-			}
-
-						
-			if((usage & 0xFFFF0000) != 0){
-				field->usage_page = (usage >> 16);					
-				field->usage = (usage & 0xFFFF);
-			}
-			else {
-				field->usage = usage;
-			}
-
-			
-		}	
-
-		if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
-			field->usage = report_item->usage_minimum + i;					
-		}
-		
-		usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page);
-		usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage);
-
-		field->collection_path = usb_hid_report_path_try_insert(report, path);
-
-		field->size = report_item->size;
-		
-		size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8;
-		size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size;
-
-		field->offset = 8 * offset_byte + offset_bit;
-		if(report_item->id != 0) {
-			field->offset += 8;
-			report->use_report_ids = 1;
-		}
-		field->item_flags = report_item->item_flags;
-
-		/* find the right report list*/
-		usb_hid_report_description_t *report_des;
-		report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
-		if(report_des == NULL){
-			report_des = malloc(sizeof(usb_hid_report_description_t));
-			memset(report_des, 0, sizeof(usb_hid_report_description_t));
-
-			report_des->type = report_item->type;
-			report_des->report_id = report_item->id;
-			list_initialize (&report_des->link);
-			list_initialize (&report_des->report_items);
-
-			list_append(&report_des->link, &report->reports);
-			report->report_count++;
-		}
-
-		/* append this field to the end of founded report list */
-		list_append (&field->link, &report_des->report_items);
-		
-		/* update the sizes */
-		report_des->bit_length += field->size;
-		report_des->item_length++;
-
-	}
-
-
-	return EOK;
-}
-
-usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
-{
-	link_t *report_it = report->reports.next;
-	usb_hid_report_description_t *report_des = NULL;
-	
-	while(report_it != &report->reports) {
-		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
-
-		if((report_des->report_id == report_id) && (report_des->type == type)){
-			return report_des;
-		}
-		
-		report_it = report_it->next;
-	}
-
-	return NULL;
-}
-
-/** Parse HID report descriptor.
- *
- * @param parser Opaque HID report parser structure.
- * @param data Data describing the report.
- * @return Error code.
- */
-int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 
-    const uint8_t *data, size_t size)
-{
-	size_t i=0;
-	uint8_t tag=0;
-	uint8_t item_size=0;
-	int class=0;
-	int ret;
-	usb_hid_report_item_t *report_item=0;
-	usb_hid_report_item_t *new_report_item;	
-	usb_hid_report_path_t *usage_path;
-
-	size_t offset_input=0;
-	size_t offset_output=0;
-	size_t offset_feature=0;
-
-	link_t stack;
-	list_initialize(&stack);	
-
-	/* parser structure initialization*/
-	if(usb_hid_report_init(report) != EOK) {
-		return EINVAL;
-	}
-	
-	/*report item initialization*/
-	if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
-		return ENOMEM;
-	}
-	memset(report_item, 0, sizeof(usb_hid_report_item_t));
-	list_initialize(&(report_item->link));	
-
-	/* usage path context initialization */
-	if(!(usage_path=usb_hid_report_path())){
-		return ENOMEM;
-	}
-	usb_hid_report_path_append_item(usage_path, 0, 0);	
-	
-	while(i<size){	
-		if(!USB_HID_ITEM_IS_LONG(data[i])){
-
-			if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
-				return EINVAL;
-			}
-			
-			tag = USB_HID_ITEM_TAG(data[i]);
-			item_size = USB_HID_ITEM_SIZE(data[i]);
-			class = USB_HID_ITEM_TAG_CLASS(data[i]);
-			
-			ret = usb_hid_report_parse_tag(tag,class,data+i+1,
-			                               item_size,report_item, usage_path);
-			switch(ret){
-				case USB_HID_NEW_REPORT_ITEM:
-					// store report item to report and create the new one
-					// store current collection path
-					report_item->usage_path = usage_path;
-					
-					usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);	
-					if(report_item->id != 0){
-						report->use_report_ids = 1;
-					}
-					
-					switch(tag) {
-						case USB_HID_REPORT_TAG_INPUT:
-							report_item->type = USB_HID_REPORT_TYPE_INPUT;
-							report_item->offset = offset_input;
-							offset_input += report_item->count * report_item->size;
-							break;
-						case USB_HID_REPORT_TAG_OUTPUT:
-							report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
-							report_item->offset = offset_output;
-							offset_output += report_item->count * report_item->size;
-
-							break;
-						case USB_HID_REPORT_TAG_FEATURE:
-							report_item->type = USB_HID_REPORT_TYPE_FEATURE;
-							report_item->offset = offset_feature;
-							offset_feature += report_item->count * report_item->size;
-							break;
-						default:
-						    usb_log_debug("\tjump over - tag %X\n", tag);
-						    break;
-					}
-					
-					/* 
-					 * append new fields to the report
-					 * structure 					 
-					 */
-					usb_hid_report_append_fields(report, report_item);
-
-					/* reset local items */
-					usb_hid_report_reset_local_items (report_item);
-
-					break;
-
-				case USB_HID_RESET_OFFSET:
-					offset_input = 0;
-					offset_output = 0;
-					offset_feature = 0;
-					usb_hid_report_path_set_report_id (usage_path, report_item->id);
-					break;
-
-				case USB_HID_REPORT_TAG_PUSH:
-					// push current state to stack
-					new_report_item = usb_hid_report_item_clone(report_item);
-					usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path);
-					new_report_item->usage_path = tmp_path; 
-
-					list_prepend (&new_report_item->link, &stack);
-					break;
-				case USB_HID_REPORT_TAG_POP:
-					// restore current state from stack
-					if(list_empty (&stack)) {
-						return EINVAL;
-					}
-					free(report_item);
-						
-					report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
-					
-					usb_hid_report_usage_path_t *tmp_usage_path;
-					tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
-					
-					usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
-					usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
-
-					usb_hid_report_path_free(report_item->usage_path);
-					list_initialize(&report_item->usage_path->link);
-					list_remove (stack.next);
-					
-					break;
-					
-				default:
-					// nothing special to do					
-					break;
-			}
-
-			/* jump over the processed block */
-			i += 1 + USB_HID_ITEM_SIZE(data[i]);
-		}
-		else{
-			// TBD
-			i += 3 + USB_HID_ITEM_SIZE(data[i+1]);
-		}
-		
-
-	}
-	
-	return EOK;
-}
-
-
-/**
- * Parse one tag of the report descriptor
- *
- * @param Tag to parse
- * @param Report descriptor buffer
- * @param Size of data belongs to this tag
- * @param Current report item structe
- * @return Code of action to be done next
- */
-int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
-{	
-	int ret;
-	
-	switch(class){
-		case USB_HID_TAG_CLASS_MAIN:
-
-			if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
-				return USB_HID_NEW_REPORT_ITEM;
-			}
-			else {
-				/*TODO process the error */
-				return ret;
-			   }
-			break;
-
-		case USB_HID_TAG_CLASS_GLOBAL:	
-			return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
-			break;
-
-		case USB_HID_TAG_CLASS_LOCAL:			
-			return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
-			break;
-		default:
-			return USB_HID_NO_ACTION;
-	}
-}
-
-/**
- * Parse main tags of report descriptor
- *
- * @param Tag identifier
- * @param Data buffer
- * @param Length of data buffer
- * @param Current state table
- * @return Error code
- */
-
-int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
-{
-	usb_hid_report_usage_path_t *path_item;
-	
-	switch(tag)
-	{
-		case USB_HID_REPORT_TAG_INPUT:
-		case USB_HID_REPORT_TAG_OUTPUT:
-		case USB_HID_REPORT_TAG_FEATURE:
-			report_item->item_flags = *data;			
-			return EOK;			
-			break;
-			
-		case USB_HID_REPORT_TAG_COLLECTION:
-			// store collection atributes
-			path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
-			path_item->flags = *data;	
-			
-			// set last item
-			usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page);
-			usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]);
-			
-			// append the new one which will be set by common
-			// usage/usage page
-			usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);	
-			usb_hid_report_reset_local_items (report_item);
-			return USB_HID_NO_ACTION;
-			break;
-			
-		case USB_HID_REPORT_TAG_END_COLLECTION:
-			usb_hid_report_remove_last_item(usage_path);
-			return USB_HID_NO_ACTION;
-			break;
-		default:
-			return USB_HID_NO_ACTION;
-	}
-
-	return EOK;
-}
-
-/**
- * Parse global tags of report descriptor
- *
- * @param Tag identifier
- * @param Data buffer
- * @param Length of data buffer
- * @param Current state table
- * @return Error code
- */
-int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
-{
-	// TODO take care about the bit length of data
-	switch(tag)
-	{
-		case USB_HID_REPORT_TAG_USAGE_PAGE:
-			report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
-			break;
-		case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
-			report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
-			break;
-		case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
-			report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
-			break;
-		case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
-			report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
-			break;			
-		case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
-			report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
-
-			break;
-		case USB_HID_REPORT_TAG_UNIT_EXPONENT:
-			report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_UNIT:
-			report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_REPORT_SIZE:
-			report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_REPORT_COUNT:
-			report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_REPORT_ID:
-			report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
-			return USB_HID_RESET_OFFSET;
-			break;
-		case USB_HID_REPORT_TAG_PUSH:
-		case USB_HID_REPORT_TAG_POP:
-			/* 
-			 * stack operations are done in top level parsing
-			 * function
-			 */
-			return tag;
-			break;
-			
-		default:
-			return USB_HID_NO_ACTION;
-	}
-
-	return EOK;
-}
-
-/**
- * Parse local tags of report descriptor
- *
- * @param Tag identifier
- * @param Data buffer
- * @param Length of data buffer
- * @param Current state table
- * @return Error code
- */
-int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
-                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
-{
-	switch(tag) {
-		case USB_HID_REPORT_TAG_USAGE:
-			switch(report_item->in_delimiter) {
-				case INSIDE_DELIMITER_SET:
-					// nothing to do
-					break;
-				case START_DELIMITER_SET:
-					report_item->in_delimiter = INSIDE_DELIMITER_SET;
-				case OUTSIDE_DELIMITER_SET:
-					report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
-					report_item->usages_count++;
-					break;
-			}
-			break;
-		case USB_HID_REPORT_TAG_USAGE_MINIMUM:
-			if (item_size == 3) {
-				// usage extended usages
-				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
-				report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
-			}
-			else {
-				report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
-			}
-			break;
-		case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
-			if (item_size == 3) {
-				// usage extended usages
-				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
-				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
-			}
-			else {
-				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
-			}
-			break;
-		case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
-			report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
-			report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
-			report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_STRING_INDEX:
-			report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_STRING_MINIMUM:
-			report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-		case USB_HID_REPORT_TAG_STRING_MAXIMUM:
-			report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
-			break;			
-		case USB_HID_REPORT_TAG_DELIMITER:
-			report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
-			break;
-
-		default:
-			return USB_HID_NO_ACTION;
-	}
-
-	return EOK;
-}
-
-/**
- * Converts raw data to uint32 (thats the maximum length of short item data)
- *
- * @param Data buffer
- * @param Size of buffer
- * @return Converted int32 number
- */
-uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size)
-{
-	unsigned int i;
-	uint32_t result;
-
-	result = 0;
-	for(i=0; i<size; i++) {
-		result = (result | (data[i]) << (i*8));
-	}
-
-	return result;
-}
-
-/**
- * Prints content of given list of report items.
- *
- * @param List of report items (usb_hid_report_item_t)
- * @return void
- */
-void usb_hid_descriptor_print_list(link_t *head)
-{
-	usb_hid_report_field_t *report_item;
-	link_t *item;
-
-
-	if(head == NULL || list_empty(head)) {
-	    usb_log_debug("\tempty\n");
-	    return;
-	}
-        
-	for(item = head->next; item != head; item = item->next) {
-                
-		report_item = list_get_instance(item, usb_hid_report_field_t, link);
-
-		usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
-		usb_log_debug("\t\tSIZE: %zu\n", report_item->size);				
-		usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
-		usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);		
-		usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);		
-		usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);				
-		usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
-		usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
-
-		usb_log_debug("\t\tVALUE: %X\n", report_item->value);
-		usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
-		usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
-		
-		//usb_hid_print_usage_path(report_item->collection_path);
-
-		usb_log_debug("\n");		
-
-	}
-
-
-}
-/**
- * Prints content of given report descriptor in human readable format.
- *
- * @param parser Parsed descriptor to print
- * @return void
- */
-void usb_hid_descriptor_print(usb_hid_report_t *report)
-{
-	if(report == NULL) {
-		return;
-	}
-
-	link_t *report_it = report->reports.next;
-	usb_hid_report_description_t *report_des;
-
-	while(report_it != &report->reports) {
-		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
-		usb_log_debug("Report ID: %d\n", report_des->report_id);
-		usb_log_debug("\tType: %d\n", report_des->type);
-		usb_log_debug("\tLength: %zu\n", report_des->bit_length);		
-		usb_log_debug("\tItems: %zu\n", report_des->item_length);		
-
-		usb_hid_descriptor_print_list(&report_des->report_items);
-
-
-		link_t *path_it = report->collection_paths.next;
-		while(path_it != &report->collection_paths) {
-			usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
-			path_it = path_it->next;
-		}
-		
-		report_it = report_it->next;
-	}
-}
-
-/**
- * Releases whole linked list of report items
- *
- * @param head Head of list of report descriptor items (usb_hid_report_item_t)
- * @return void
- */
-void usb_hid_free_report_list(link_t *head)
-{
-	return; 
-	
-	usb_hid_report_item_t *report_item;
-	link_t *next;
-	
-	if(head == NULL || list_empty(head)) {		
-	    return;
-	}
-	
-	next = head->next;
-	while(next != head) {
-	
-	    report_item = list_get_instance(next, usb_hid_report_item_t, link);
-
-		while(!list_empty(&report_item->usage_path->link)) {
-			usb_hid_report_remove_last_item(report_item->usage_path);
-		}
-
-		
-	    next = next->next;
-	    
-	    free(report_item);
-	}
-	
-	return;
-	
-}
-
-/** Frees the HID report descriptor parser structure 
- *
- * @param parser Opaque HID report parser structure
- * @return void
- */
-void usb_hid_free_report(usb_hid_report_t *report)
-{
-	if(report == NULL){
-		return;
-	}
-
-	// free collection paths
-	usb_hid_report_path_t *path;
-	while(!list_empty(&report->collection_paths)) {
-		path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
-		usb_hid_report_path_free(path);		
-	}
-	
-	// free report items
-	usb_hid_report_description_t *report_des;
-	usb_hid_report_field_t *field;
-	while(!list_empty(&report->reports)) {
-		report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
-		list_remove(&report_des->link);
-		
-		while(!list_empty(&report_des->report_items)) {
-			field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
-			list_remove(&field->link);
-
-			free(field);
-		}
-		
-		free(report_des);
-	}
-	
-	return;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/hidiface.c
===================================================================
--- uspace/lib/usb/src/hidiface.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,146 +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 libusb
- * @{
- */
-/** @file
- * Client functions for accessing USB HID interface (implementation).
- */
-#include <dev_iface.h>
-#include <usbhid_iface.h>
-#include <usb/classes/hid/iface.h>
-#include <errno.h>
-#include <str_error.h>
-#include <async.h>
-#include <assert.h>
-
-/** Ask for event array length.
- *
- * @param dev_phone Opened phone to DDF device providing USB HID interface.
- * @return Number of usages returned or negative error code.
- */
-int usbhid_dev_get_event_length(int dev_phone)
-{
-	if (dev_phone < 0) {
-		return EINVAL;
-	}
-
-	sysarg_t len;
-	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
-	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
-	if (rc == EOK) {
-		return (int) len;
-	} else {
-		return rc;
-	}
-}
-
-/** Request for next event from HID device.
- *
- * @param[in] dev_phone Opened phone to DDF device providing USB HID interface.
- * @param[out] usage_pages Where to store usage pages.
- * @param[out] usages Where to store usages (actual data).
- * @param[in] usage_count Length of @p usage_pages and @p usages buffer
- *	(in items, not bytes).
- * @param[out] actual_usage_count Number of usages actually returned by the
- *	device driver.
- * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
- * @return Error code.
- */
-int usbhid_dev_get_event(int dev_phone, uint16_t *usage_pages, uint16_t *usages,
-    size_t usage_count, size_t *actual_usage_count, unsigned int flags)
-{
-	if (dev_phone < 0) {
-		return EINVAL;
-	}
-	if ((usage_pages == NULL) || (usages == NULL)) {
-		return ENOMEM;
-	}
-	if (usage_count == 0) {
-		return EINVAL;
-	}
-
-	size_t buffer_size = sizeof(uint16_t) * usage_count * 2;
-	uint16_t *buffer = malloc(buffer_size);
-	if (buffer == NULL) {
-		return ENOMEM;
-	}
-
-	aid_t opening_request = async_send_2(dev_phone,
-	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
-	    flags, NULL);
-	if (opening_request == 0) {
-		free(buffer);
-		return ENOMEM;
-	}
-
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(dev_phone, buffer, buffer_size,
-	    &data_request_call);
-	if (data_request == 0) {
-		async_wait_for(opening_request, NULL);
-		free(buffer);
-		return ENOMEM;
-	}
-
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-
-	if (data_request_rc != EOK) {
-		/* Prefer return code of the opening request. */
-		if (opening_request_rc != EOK) {
-			return (int) opening_request_rc;
-		} else {
-			return (int) data_request_rc;
-		}
-	}
-
-	if (opening_request_rc != EOK) {
-		return (int) opening_request_rc;
-	}
-
-	size_t actual_size = IPC_GET_ARG2(data_request_call);
-	size_t items = actual_size / 2;
-
-	/* Copy the individual items. */
-	memcpy(usage_pages, buffer, items * sizeof(uint16_t));
-	memcpy(usages, buffer + items, items * sizeof(uint16_t));
-
-	if (actual_usage_count != NULL) {
-		*actual_usage_count = items;
-	}
-
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,606 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * HID report descriptor and report data parser implementation.
- */
-#include <usb/classes/hidparser.h>
-#include <errno.h>
-#include <stdio.h>
-#include <malloc.h>
-#include <mem.h>
-#include <usb/debug.h>
-#include <assert.h>
-
-
-/*
- * Data translation private functions
- */
-uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
-inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
-int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data);
-uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value);
-int usb_pow(int a, int b);
-
-
-// TODO: tohle ma bejt asi jinde
-int usb_pow(int a, int b)
-{
-	switch(b) {
-		case 0:
-			return 1;
-			break;
-		case 1:
-			return a;
-			break;
-		default:
-			return a * usb_pow(a, b-1);
-			break;
-	}
-}
-
-
-
-
-/** Parse and act upon a HID report.
- *
- * @see usb_hid_parse_report_descriptor
- *
- * @param parser Opaque HID report parser structure.
- * @param data Data for the report.
- * @return Error code.
- */ 
-int usb_hid_parse_report(const usb_hid_report_t *report,  
-    const uint8_t *data, size_t size, uint8_t *report_id)
-{
-	link_t *list_item;
-	usb_hid_report_field_t *item;
-
-	usb_hid_report_description_t *report_des;
-	usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
-
-	if(report == NULL) {
-		return EINVAL;
-	}
-
-	if(report->use_report_ids != 0) {
-		*report_id = data[0];
-	}	
-	else {
-		*report_id = 0;
-	}
-
-
-	report_des = usb_hid_report_find_description(report, *report_id, type);
-
-	/* read data */
-	list_item = report_des->report_items.next;	   
-	while(list_item != &(report_des->report_items)) {
-
-		item = list_get_instance(list_item, usb_hid_report_field_t, link);
-
-		if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
-			
-			if(USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) {
-
-				// array
-				item->value = usb_hid_translate_data(item, data);
-			    item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
-			}
-			else {
-				// variable item
-				item->value = usb_hid_translate_data(item, data);				
-			}				
-		}
-		list_item = list_item->next;
-	}
-	   
-	return EOK;
-	
-}
-
-/**
- * Translate data from the report as specified in report descriptor item
- *
- * @param item Report descriptor item with definition of translation
- * @param data Data to translate
- * @param j Index of processed field in report descriptor item
- * @return Translated data
- */
-int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data)
-{
-	int resolution;
-	int offset;
-	int part_size;
-	
-	int32_t value=0;
-	int32_t mask;
-	const uint8_t *foo;
-
-	// now only shot tags are allowed
-	if(item->size > 32) {
-		return 0;
-	}
-
-	if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
-		item->physical_minimum = item->logical_minimum;
-		item->physical_maximum = item->logical_maximum;			
-	}
-	
-
-	if(item->physical_maximum == item->physical_minimum){
-	    resolution = 1;
-	}
-	else {
-	    resolution = (item->logical_maximum - item->logical_minimum) / 
-		((item->physical_maximum - item->physical_minimum) * 
-		(usb_pow(10,(item->unit_exponent))));
-	}
-
-	offset = item->offset;
-	// FIXME
-	if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) {
-		
-		part_size = ((offset+item->size)%8);
-
-		size_t i=0;
-		for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){
-			if(i == (size_t)(offset/8)) {
-				// the higher one
-				foo = data + i;
-				mask =  ((1 << (item->size-part_size))-1);
-				value = (*foo & mask) << part_size;
-			}
-			else if(i == ((offset+item->size-1)/8)){
-				// the lower one
-				foo = data + i;
-				mask =  ((1 << part_size)-1) << (8-part_size);
-				value += ((*foo & mask) >> (8-part_size));
-			}
-			else {
-				value = value << 8;
-				value += *(data + 1);
-			}
-		}
-	}
-	else {		
-		foo = data+(offset/8);
-		mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
-		value = (*foo & mask) >> (8-((offset%8)+item->size));
-	}
-
-	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
-		value = USB_HID_UINT32_TO_INT32(value, item->size);
-	}
-
-	return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
-	
-}
-
-/**
- * Returns number of items in input report which are accessible by given usage path
- *
- * @param parser Opaque report descriptor structure
- * @param path Usage path specification
- * @param flags Usage path comparison flags
- * @return Number of items in input report
- */
-size_t usb_hid_report_input_length(const usb_hid_report_t *report,
-	usb_hid_report_path_t *path, int flags)
-{	
-	
-	size_t ret = 0;
-
-	if(report == NULL) {
-		return 0;
-	}
-
-	usb_hid_report_description_t *report_des;
-	report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
-	if(report_des == NULL) {
-		return 0;
-	}
-
-	link_t *field_it = report_des->report_items.next;
-	usb_hid_report_field_t *field;
-	while(field_it != &report_des->report_items) {
-
-		field = list_get_instance(field_it, usb_hid_report_field_t, link);
-		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
-			
-			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
-			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
-				ret++;
-			}
-			usb_hid_report_remove_last_item (field->collection_path);
-		}
-		
-		field_it = field_it->next;
-	}
-
-	return ret;
-	}
-
-/*** OUTPUT API **/
-
-/** 
- * Allocates output report buffer for output report
- *
- * @param parser Report parsed structure
- * @param size Size of returned buffer
- * @param report_id Report id of created output report
- * @return Returns allocated output buffer for specified output
- */
-uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id)
-{
-	if(report == NULL) {
-		*size = 0;
-		return NULL;
-	}
-
-	link_t *report_it = report->reports.next;
-	usb_hid_report_description_t *report_des = NULL;
-	while(report_it != &report->reports) {
-		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
-		if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
-			break;
-		}
-
-		report_it = report_it->next;
-	}
-
-	if(report_des == NULL){
-		*size = 0;
-		return NULL;
-	}
-	else {
-		*size = (report_des->bit_length + (8 - 1))/8;
-		uint8_t *ret = malloc((*size) * sizeof(uint8_t));
-		memset(ret, 0, (*size) * sizeof(uint8_t));
-		return ret;
-	}
-}
-
-
-/** Frees output report buffer
- *
- * @param output Output report buffer
- * @return void
- */
-void usb_hid_report_output_free(uint8_t *output)
-
-{
-	if(output != NULL) {
-		free (output);
-	}
-}
-
-/** Returns size of output for given usage path 
- *
- * @param parser Opaque report parser structure
- * @param path Usage path specified which items will be thought for the output
- * @param flags Flags of usage path structure comparison
- * @return Number of items matching the given usage path
- */
-size_t usb_hid_report_output_size(usb_hid_report_t *report,
-                                  usb_hid_report_path_t *path, int flags)
-{
-	size_t ret = 0;	
-	usb_hid_report_description_t *report_des;
-
-	if(report == NULL) {
-		return 0;
-	}
-
-	report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
-	if(report_des == NULL){
-		return 0;
-	}
-	
-	link_t *field_it = report_des->report_items.next;
-	usb_hid_report_field_t *field;
-	while(field_it != &report_des->report_items) {
-
-		field = list_get_instance(field_it, usb_hid_report_field_t, link);
-		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){
-			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
-			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
-				ret++;
-			}
-			usb_hid_report_remove_last_item (field->collection_path);
-		}
-		
-		field_it = field_it->next;
-	}
-
-	return ret;
-	
-}
-
-/** Makes the output report buffer for data given in the report structure
- *
- * @param parser Opaque report parser structure
- * @param path Usage path specifing which parts of output will be set
- * @param flags Usage path structure comparison flags
- * @param buffer Output buffer
- * @param size Size of output buffer
- * @return Error code
- */
-int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,
-                                    uint8_t *buffer, size_t size)
-{
-	link_t *item;	
-	int32_t value=0;
-	int offset;
-	int length;
-	int32_t tmp_value;
-	
-	if(report == NULL) {
-		return EINVAL;
-	}
-
-	if(report->use_report_ids != 0) {
-		buffer[0] = report_id;		
-	}
-
-	usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
-	
-	usb_hid_report_description_t *report_des;
-	report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT);
-	if(report_des == NULL){
-		return EINVAL;
-	}
-
-	usb_hid_report_field_t *report_item;	
-	item = report_des->report_items.next;	
-	while(item != &report_des->report_items) {
-		report_item = list_get_instance(item, usb_hid_report_field_t, link);
-
-			if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
-					
-				// array
-				value = usb_hid_translate_data_reverse(report_item, report_item->value);
-				offset = report_item->offset;
-				length = report_item->size;
-			}
-			else {
-				// variable item
-				value  = usb_hid_translate_data_reverse(report_item, report_item->value);
-				offset = report_item->offset;
-				length = report_item->size;
-			}
-
-			if((offset/8) == ((offset+length-1)/8)) {
-				// je to v jednom bytu
-				if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
-					break; // TODO ErrorCode
-				}
-
-				size_t shift = 8 - offset%8 - length;
-
-				value = value << shift;							
-				value = value & (((1 << length)-1) << shift);
-				
-				uint8_t mask = 0;
-				mask = 0xff - (((1 << length) - 1) << shift);
-				buffer[offset/8] = (buffer[offset/8] & mask) | value;
-			}
-			else {
-				int i = 0;
-				uint8_t mask = 0;
-				for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
-					if(i == (offset/8)) {
-						tmp_value = value;
-						tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);				
-						tmp_value = tmp_value << (offset%8);
-	
-						mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
-						buffer[i] = (buffer[i] & mask) | tmp_value;			
-					}
-					else if (i == ((offset + length -1)/8)) {
-						
-						value = value >> (length - ((offset + length) % 8));
-						value = value & ((1 << (length - ((offset + length) % 8))) - 1);
-				
-						mask = (1 << (length - ((offset + length) % 8))) - 1;
-						buffer[i] = (buffer[i] & mask) | value;
-					}
-					else {
-						buffer[i] = value & (0xFF << i);
-					}
-				}
-			}
-
-
-		// reset value
-		report_item->value = 0;
-		
-		item = item->next;
-	}
-	
-	usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
-
-	return EOK;
-}
-
-/**
- * Translate given data for putting them into the outoput report
- * @param item Report item structure
- * @param value Value to translate
- * @return ranslated value
- */
-uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value)
-{
-	int ret=0;
-	int resolution;
-
-	if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) {
-		ret = item->logical_minimum;
-	}
-
-	if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
-		item->physical_minimum = item->logical_minimum;
-		item->physical_maximum = item->logical_maximum;			
-	}
-	
-
-	if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) {
-
-		// variable item
-		if(item->physical_maximum == item->physical_minimum){
-		    resolution = 1;
-		}
-		else {
-		    resolution = (item->logical_maximum - item->logical_minimum) /
-			((item->physical_maximum - item->physical_minimum) *
-			(usb_pow(10,(item->unit_exponent))));
-		}
-
-		ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
-	}
-	else {
-		// bitmapa
-		if(value == 0) {
-			ret = 0;
-		}
-		else {
-			size_t bitmap_idx = (value - item->usage_minimum);
-			ret = 1 << bitmap_idx;
-		}
-	}
-
-	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
-		return USB_HID_INT32_TO_UINT32(ret, item->size);
-	}
-	return (int32_t)ret;
-}
-
-usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item)
-{
-	usb_hid_report_item_t *new_report_item;
-	
-	if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
-		return NULL;
-	}					
-	memcpy(new_report_item,item, sizeof(usb_hid_report_item_t));
-	link_initialize(&(new_report_item->link));
-
-	return new_report_item;
-}
-
-
-usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 
-							usb_hid_report_field_t *field, 
-                            usb_hid_report_path_t *path, int flags, 
-                            usb_hid_report_type_t type)
-{
-	usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type);
-	link_t *field_it;
-	
-	if(report_des == NULL){
-		return NULL;
-	}
-
-	if(field == NULL){
-		// vezmu prvni co mathuje podle path!!
-		field_it = report_des->report_items.next;
-	}
-	else {
-		field_it = field->link.next;
-	}
-
-	while(field_it != &report_des->report_items) {
-		field = list_get_instance(field_it, usb_hid_report_field_t, link);
-
-		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
-			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
-			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){
-				usb_hid_report_remove_last_item (field->collection_path);
-				return field;
-			}
-			usb_hid_report_remove_last_item (field->collection_path);
-		}
-		field_it = field_it->next;
-	}
-
-	return NULL;
-}
-
-uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
-{
-	if(report == NULL){
-		return 0;
-	}
-
-	usb_hid_report_description_t *report_des;
-	link_t *report_it;
-	
-	if(report_id == 0) {
-		report_it = usb_hid_report_find_description (report, report_id, type)->link.next;		
-	}
-	else {
-		report_it = report->reports.next;
-	}
-
-	while(report_it != &report->reports) {
-		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
-		if(report_des->type == type){
-			return report_des->report_id;
-		}
-	}
-
-	return 0;
-}
-
-void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item)
-{
-	if(report_item == NULL)	{
-		return;
-	}
-	
-	report_item->usages_count = 0;
-	memset(report_item->usages, 0, USB_HID_MAX_USAGES);
-	
-	report_item->extended_usage_page = 0;
-	report_item->usage_minimum = 0;
-	report_item->usage_maximum = 0;
-	report_item->designator_index = 0;
-	report_item->designator_minimum = 0;
-	report_item->designator_maximum = 0;
-	report_item->string_index = 0;
-	report_item->string_minimum = 0;
-	report_item->string_maximum = 0;
-
-	return;
-}
-/**
- * @}
- */
Index: pace/lib/usb/src/hidpath.c
===================================================================
--- uspace/lib/usb/src/hidpath.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,414 +1,0 @@
-/*
- * Copyright (c) 2011 Matej Klonfar
- * 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 libusb
- * @{
- */
-/** @file
- * HID report descriptor and report data parser implementation.
- */
-#include <usb/classes/hidparser.h>
-#include <errno.h>
-#include <stdio.h>
-#include <malloc.h>
-#include <mem.h>
-#include <usb/debug.h>
-#include <assert.h>
-
-
-/**
- * Appends one item (couple of usage_path and usage) into the usage path
- * structure
- *
- * @param usage_path Usage path structure
- * @param usage_page Usage page constant
- * @param usage Usage constant
- * @return Error code
- */
-int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 
-                                    int32_t usage_page, int32_t usage)
-{	
-	usb_hid_report_usage_path_t *item;
-
-	if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {
-		return ENOMEM;
-	}
-	list_initialize(&item->link);
-
-	item->usage = usage;
-	item->usage_page = usage_page;
-	item->flags = 0;
-	
-	list_append (&item->link, &usage_path->head);
-	usage_path->depth++;
-	return EOK;
-}
-
-/**
- * Removes last item from the usage path structure
- * @param usage_path 
- * @return void
- */
-void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
-{
-	usb_hid_report_usage_path_t *item;
-	
-	if(!list_empty(&usage_path->head)){
-		item = list_get_instance(usage_path->head.prev, 
-		                         usb_hid_report_usage_path_t, link);		
-		list_remove(usage_path->head.prev);
-		usage_path->depth--;
-		free(item);
-	}
-}
-
-/**
- * Nulls last item of the usage path structure.
- *
- * @param usage_path
- * @return void
- */
-void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
-{
-	usb_hid_report_usage_path_t *item;
-	
-	if(!list_empty(&usage_path->head)){	
-		item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
-		memset(item, 0, sizeof(usb_hid_report_usage_path_t));
-	}
-}
-
-/**
- * Modifies last item of usage path structure by given usage page or usage
- *
- * @param usage_path Opaque usage path structure
- * @param tag Class of currently processed tag (Usage page tag falls into Global
- * class but Usage tag into the Local)
- * @param data Value of the processed tag
- * @return void
- */
-void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, 
-                                  int32_t tag, int32_t data)
-{
-	usb_hid_report_usage_path_t *item;
-	
-	if(!list_empty(&usage_path->head)){	
-		item = list_get_instance(usage_path->head.prev, 
-		                         usb_hid_report_usage_path_t, link);
-
-		switch(tag) {
-			case USB_HID_TAG_CLASS_GLOBAL:
-				item->usage_page = data;
-				break;
-			case USB_HID_TAG_CLASS_LOCAL:
-				item->usage = data;
-				break;
-		}
-	}
-	
-}
-
-
-void usb_hid_print_usage_path(usb_hid_report_path_t *path)
-{
-	usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id);
-	usb_log_debug("\tLENGTH: %d\n", path->depth);
-
-	link_t *item = path->head.next;
-	usb_hid_report_usage_path_t *path_item;
-	while(item != &path->head) {
-
-		path_item = list_get_instance(item, usb_hid_report_usage_path_t, link);
-		usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
-		usb_log_debug("\tUSAGE: %X\n", path_item->usage);
-		usb_log_debug("\tFLAGS: %d\n", path_item->flags);		
-		
-       		item = item->next;
-	}
-}
-
-/**
- * Compares two usage paths structures
- *
- *
- * @param report_path usage path structure to compare with @path 
- * @param path usage patrh structure to compare
- * @param flags Flags determining the mode of comparison
- * @return EOK if both paths are identical, non zero number otherwise
- */
-int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 
-                                      usb_hid_report_path_t *path,
-                                      int flags)
-{
-	usb_hid_report_usage_path_t *report_item;
-	usb_hid_report_usage_path_t *path_item;
-
-	link_t *report_link;
-	link_t *path_link;
-
-	int only_page;
-
-	if(report_path->report_id != path->report_id) {
-		return 1;
-	}
-
-	// Empty path match all others
-	if(path->depth == 0){
-		return EOK;
-	}
-
-
-	if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
-		flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;
-	}
-	
-	switch(flags){
-		/* path is somewhere in report_path */
-		case USB_HID_PATH_COMPARE_ANYWHERE:
-			if(path->depth != 1){
-				return 1;
-			}
-
-			// projit skrz cestu a kdyz nekde sedi tak vratim EOK
-			// dojduli az za konec tak nnesedi
-			report_link = report_path->head.next;
-			path_link = path->head.next;
-			path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
-
-			while(report_link != &report_path->head) {
-				report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
-				if(report_item->usage_page == path_item->usage_page){
-					if(only_page == 0){
-						if(report_item->usage == path_item->usage) {
-							return EOK;
-						}
-					}
-					else {
-						return EOK;
-					}
-				}
-
-				report_link = report_link->next;
-			}
-
-			return 1;
-			break;
-		/* the paths must be identical */
-		case USB_HID_PATH_COMPARE_STRICT:
-				if(report_path->depth != path->depth){
-					return 1;
-				}
-		
-		/* path is prefix of the report_path */
-		case USB_HID_PATH_COMPARE_BEGIN:
-	
-				report_link = report_path->head.next;
-				path_link = path->head.next;
-			
-				while((report_link != &report_path->head) && 
-				      (path_link != &path->head)) {
-						  
-					report_item = list_get_instance(report_link, 
-					                                usb_hid_report_usage_path_t, 
-					                                link);
-						  
-					path_item = list_get_instance(path_link, 
-					                              usb_hid_report_usage_path_t, 
-					                              link);		
-
-					if((report_item->usage_page != path_item->usage_page) || 
-					   ((only_page == 0) && 
-					    (report_item->usage != path_item->usage))) {
-							
-						   return 1;
-					} else {
-						report_link = report_link->next;
-						path_link = path_link->next;			
-					}
-			
-				}
-
-				if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && (path_link == &path->head)) || 
-				   ((report_link == &report_path->head) && (path_link == &path->head))) {
-					return EOK;
-				}
-				else {
-					return 1;
-				}						
-			break;
-
-		/* path is suffix of report_path */
-		case USB_HID_PATH_COMPARE_END:
-
-				report_link = report_path->head.prev;
-				path_link = path->head.prev;
-
-				if(list_empty(&path->head)){
-					return EOK;
-				}
-			
-				while((report_link != &report_path->head) && 
-				      (path_link != &path->head)) {
-						  
-					report_item = list_get_instance(report_link, 
-					                                usb_hid_report_usage_path_t, 
-					                                link);
-					path_item = list_get_instance(path_link, 
-					                              usb_hid_report_usage_path_t, 
-					                              link);		
-
-					if((report_item->usage_page != path_item->usage_page) || 
-					   ((only_page == 0) && 
-					    (report_item->usage != path_item->usage))) {
-						   return 1;
-					} else {
-						report_link = report_link->prev;
-						path_link = path_link->prev;			
-					}
-			
-				}
-
-				if(path_link == &path->head) {
-					return EOK;
-				}
-				else {
-					return 1;
-				}						
-			
-			break;
-
-		default:
-			return EINVAL;
-	}
-}
-
-/**
- * Allocates and initializes new usage path structure.
- *
- * @return Initialized usage path structure
- */
-usb_hid_report_path_t *usb_hid_report_path(void)
-{
-	usb_hid_report_path_t *path;
-	path = malloc(sizeof(usb_hid_report_path_t));
-	if(path == NULL){
-		return NULL;
-	}
-	else {
-		path->depth = 0;
-		path->report_id = 0;
-		list_initialize(&path->link);
-		list_initialize(&path->head);
-		return path;
-	}
-}
-
-/**
- * Releases given usage path structure.
- *
- * @param path usage path structure to release
- * @return void
- */
-void usb_hid_report_path_free(usb_hid_report_path_t *path)
-{
-	while(!list_empty(&path->head)){
-		usb_hid_report_remove_last_item(path);
-	}
-
-	list_remove(&path->link);
-	free(path);
-}
-
-
-/**
- * Clone content of given usage path to the new one
- *
- * @param usage_path Usage path structure to clone
- * @return New copy of given usage path structure
- */
-usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path)
-{
-	link_t *path_link;
-	usb_hid_report_usage_path_t *path_item;
-	usb_hid_report_usage_path_t *new_path_item;
-	usb_hid_report_path_t *new_usage_path = usb_hid_report_path ();
-
-	if(new_usage_path == NULL){
-		return NULL;
-	}
-
-	new_usage_path->report_id = usage_path->report_id;
-	
-	if(list_empty(&usage_path->head)){
-		return new_usage_path;
-	}
-
-	path_link = usage_path->head.next;
-	while(path_link != &usage_path->head) {
-		path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, 
-		                              link);
-		new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
-		if(new_path_item == NULL) {
-			return NULL;
-		}
-		
-		list_initialize (&new_path_item->link);		
-		new_path_item->usage_page = path_item->usage_page;
-		new_path_item->usage = path_item->usage;		
-		new_path_item->flags = path_item->flags;		
-		
-		list_append(&new_path_item->link, &new_usage_path->head);
-		new_usage_path->depth++;
-
-		path_link = path_link->next;
-	}
-
-	return new_usage_path;
-}
-
-
-/**
- * Sets report id in usage path structure
- *
- * @param path Usage path structure
- * @param report_id Report id to set
- * @return Error code
- */
-int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id)
-{
-	if(path == NULL){
-		return EINVAL;
-	}
-
-	path->report_id = report_id;
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/hidreport.c
===================================================================
--- uspace/lib/usb/src/hidreport.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,207 +1,0 @@
-/*
- * Copyright (c) 2011 Lubos Slovak
- * 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 libusb
- * @{
- */
-/**
- * @file
- * USB HID keyboard device structure and API.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb/debug.h>
-#include <usb/classes/hidparser.h>
-#include <usb/dp.h>
-#include <usb/devdrv.h>
-#include <usb/pipes.h>
-#include <usb/classes/hid.h>
-#include <usb/descriptor.h>
-#include <usb/request.h>
-
-#include <usb/classes/hidreport.h>
-
-static int usb_hid_get_report_descriptor(usb_device_t *dev, 
-    uint8_t **report_desc, size_t *size)
-{
-	assert(report_desc != NULL);
-	assert(size != NULL);
-	
-	usb_dp_parser_t parser =  {
-		.nesting = usb_dp_standard_descriptor_nesting
-	};
-	
-	usb_dp_parser_data_t parser_data = {
-		.data = dev->descriptors.configuration,
-		.size = dev->descriptors.configuration_size,
-		.arg = NULL
-	};
-	
-	/*
-	 * First nested descriptor of the configuration descriptor.
-	 */
-	uint8_t *d = 
-	    usb_dp_get_nested_descriptor(&parser, &parser_data, 
-	    dev->descriptors.configuration);
-	
-	/*
-	 * Find the interface descriptor corresponding to our interface number.
-	 */
-	int i = 0;
-	while (d != NULL && i < dev->interface_no) {
-		d = usb_dp_get_sibling_descriptor(&parser, &parser_data, 
-		    dev->descriptors.configuration, d);
-		++i;
-	}
-	
-	if (d == NULL) {
-		usb_log_error("The %d. interface descriptor not found!\n",
-		    dev->interface_no);
-		return ENOENT;
-	}
-	
-	/*
-	 * First nested descriptor of the interface descriptor.
-	 */
-	uint8_t *iface_desc = d;
-	d = usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
-	
-	/*
-	 * Search through siblings until the HID descriptor is found.
-	 */
-	while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {
-		d = usb_dp_get_sibling_descriptor(&parser, &parser_data, 
-		    iface_desc, d);
-	}
-	
-	if (d == NULL) {
-		usb_log_fatal("No HID descriptor found!\n");
-		return ENOENT;
-	}
-	
-	if (*d != sizeof(usb_standard_hid_descriptor_t)) {
-		usb_log_error("HID descriptor has wrong size (%u, expected %zu"
-		    ")\n", *d, sizeof(usb_standard_hid_descriptor_t));
-		return EINVAL;
-	}
-	
-	usb_standard_hid_descriptor_t *hid_desc = 
-	    (usb_standard_hid_descriptor_t *)d;
-	
-	uint16_t length =  hid_desc->report_desc_info.length;
-	size_t actual_size = 0;
-
-	/*
-	 * Allocate space for the report descriptor.
-	 */
-	*report_desc = (uint8_t *)malloc(length);
-	if (*report_desc == NULL) {
-		usb_log_error("Failed to allocate space for Report descriptor."
-		    "\n");
-		return ENOMEM;
-	}
-	
-	usb_log_debug("Getting Report descriptor, expected size: %u\n", length);
-	
-	/*
-	 * Get the descriptor from the device.
-	 */
-	int rc = usb_request_get_descriptor(&dev->ctrl_pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
-	    USB_DESCTYPE_HID_REPORT, 0, dev->interface_no,
-	    *report_desc, length, &actual_size);
-
-	if (rc != EOK) {
-		free(*report_desc);
-		*report_desc = NULL;
-		return rc;
-	}
-
-	if (actual_size != length) {
-		free(*report_desc);
-		*report_desc = NULL;
-		usb_log_error("Report descriptor has wrong size (%zu, expected "
-		    "%u)\n", actual_size, length);
-		return EINVAL;
-	}
-	
-	*size = length;
-	
-	usb_log_debug("Done.\n");
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
-int usb_hid_process_report_descriptor(usb_device_t *dev, 
-    usb_hid_report_t *report)
-{
-	if (dev == NULL || report == NULL) {
-		usb_log_error("Failed to process Report descriptor: wrong "
-		    "parameters given.\n");
-		return EINVAL;
-	}
-	
-	uint8_t *report_desc = NULL;
-	size_t report_size;
-	
-	int rc = usb_hid_get_report_descriptor(dev, &report_desc, 
-	    &report_size);
-	
-	if (rc != EOK) {
-		usb_log_error("Problem with getting Report descriptor: %s.\n",
-		    str_error(rc));
-		if (report_desc != NULL) {
-			free(report_desc);
-		}
-		return rc;
-	}
-	
-	assert(report_desc != NULL);
-	
-	rc = usb_hid_parse_report_descriptor(report, report_desc, report_size);
-	if (rc != EOK) {
-		usb_log_error("Problem parsing Report descriptor: %s.\n",
-		    str_error(rc));
-		free(report_desc);
-		return rc;
-	}
-	
-	usb_hid_descriptor_print(report);
-	free(report_desc);
-	
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/hidreq.c
===================================================================
--- uspace/lib/usb/src/hidreq.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,379 +1,0 @@
-/*
- * Copyright (c) 2011 Lubos Slovak
- * 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 drvusbhid
- * @{
- */
-/** @file
- * HID class-specific requests.
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb/classes/hid.h>
-#include <usb/debug.h>
-#include <usb/request.h>
-#include <usb/pipes.h>
-
-#include <usb/classes/hidreq.h>
-
-/*----------------------------------------------------------------------------*/
-/**
- * Send Set Report request to the HID device.
- *
- * @param hid_dev HID device to send the request to.
- * @param type Type of the report.
- * @param buffer Report data.
- * @param buf_size Report data size (in bytes).
- *
- * @retval EOK if successful.
- * @retval EINVAL if no HID device is given.
- * @return Other value inherited from function usb_control_request_set().
- */
-int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
-    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
-{
-	if (ctrl_pipe == NULL) {
-		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
-		return EINVAL;
-	}
-	
-	if (iface_no < 0) {
-		usb_log_warning("usbhid_req_set_report(): no interface given."
-		    "\n");
-		return EINVAL;
-	}
-	
-	/*
-	 * No need for checking other parameters, as they are checked in
-	 * the called function (usb_control_request_set()).
-	 */
-	
-	int rc;
-	
-	uint16_t value = 0;
-	value |= (type << 8);
-
-	usb_log_debug("Sending Set_Report request to the device.\n");
-	
-	rc = usb_control_request_set(ctrl_pipe, 
-	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size);
-
-	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
-		return rc;
-	}
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Send Set Protocol request to the HID device.
- *
- * @param hid_dev HID device to send the request to.
- * @param protocol Protocol to set.
- *
- * @retval EOK if successful.
- * @retval EINVAL if no HID device is given.
- * @return Other value inherited from function usb_control_request_set().
- */
-int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
-    usb_hid_protocol_t protocol)
-{
-	if (ctrl_pipe == NULL) {
-		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
-		return EINVAL;
-	}
-	
-	if (iface_no < 0) {
-		usb_log_warning("usbhid_req_set_report(): no interface given."
-		    "\n");
-		return EINVAL;
-	}
-	
-	/*
-	 * No need for checking other parameters, as they are checked in
-	 * the called function (usb_control_request_set()).
-	 */
-	
-	int rc;
-
-	usb_log_debug("Sending Set_Protocol request to the device ("
-	    "protocol: %d, iface: %d).\n", protocol, iface_no);
-	
-	rc = usb_control_request_set(ctrl_pipe, 
-	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0);
-
-	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
-		return rc;
-	}
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Send Set Idle request to the HID device.
- *
- * @param hid_dev HID device to send the request to.
- * @param duration Duration value (is multiplicated by 4 by the device to
- *                 get real duration in miliseconds).
- *
- * @retval EOK if successful.
- * @retval EINVAL if no HID device is given.
- * @return Other value inherited from function usb_control_request_set().
- */
-int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration)
-{
-	if (ctrl_pipe == NULL) {
-		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
-		return EINVAL;
-	}
-	
-	if (iface_no < 0) {
-		usb_log_warning("usbhid_req_set_report(): no interface given."
-		    "\n");
-		return EINVAL;
-	}
-	
-	/*
-	 * No need for checking other parameters, as they are checked in
-	 * the called function (usb_control_request_set()).
-	 */
-	
-	int rc;
-
-	usb_log_debug("Sending Set_Idle request to the device ("
-	    "duration: %u, iface: %d).\n", duration, iface_no);
-	
-	uint16_t value = duration << 8;
-	
-	rc = usb_control_request_set(ctrl_pipe, 
-	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0);
-
-	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
-		return rc;
-	}
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Send Get Report request to the HID device.
- *
- * @param[in] hid_dev HID device to send the request to.
- * @param[in] type Type of the report.
- * @param[in][out] buffer Buffer for the report data.
- * @param[in] buf_size Size of the buffer (in bytes).
- * @param[out] actual_size Actual size of report received from the device 
- *                         (in bytes).
- *
- * @retval EOK if successful.
- * @retval EINVAL if no HID device is given.
- * @return Other value inherited from function usb_control_request_set().
- */
-int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 
-    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 
-    size_t *actual_size)
-{
-	if (ctrl_pipe == NULL) {
-		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
-		return EINVAL;
-	}
-	
-	if (iface_no < 0) {
-		usb_log_warning("usbhid_req_set_report(): no interface given."
-		    "\n");
-		return EINVAL;
-	}
-	
-	/*
-	 * No need for checking other parameters, as they are checked in
-	 * the called function (usb_control_request_set()).
-	 */
-	
-	int rc;
-
-	uint16_t value = 0;
-	value |= (type << 8);
-	
-	usb_log_debug("Sending Get_Report request to the device.\n");
-	
-	rc = usb_control_request_get(ctrl_pipe, 
-	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size,
-	    actual_size);
-
-	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
-		return rc;
-	}
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Send Get Protocol request to the HID device.
- *
- * @param[in] hid_dev HID device to send the request to.
- * @param[out] protocol Current protocol of the device.
- *
- * @retval EOK if successful.
- * @retval EINVAL if no HID device is given.
- * @return Other value inherited from function usb_control_request_set().
- */
-int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 
-    usb_hid_protocol_t *protocol)
-{
-	if (ctrl_pipe == NULL) {
-		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
-		return EINVAL;
-	}
-	
-	if (iface_no < 0) {
-		usb_log_warning("usbhid_req_set_report(): no interface given."
-		    "\n");
-		return EINVAL;
-	}
-	
-	/*
-	 * No need for checking other parameters, as they are checked in
-	 * the called function (usb_control_request_set()).
-	 */
-	
-	int rc;	
-
-	usb_log_debug("Sending Get_Protocol request to the device ("
-	    "iface: %d).\n", iface_no);
-	
-	uint8_t buffer[1];
-	size_t actual_size = 0;
-	
-	rc = usb_control_request_get(ctrl_pipe, 
-	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size);
-
-	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
-		return rc;
-	}
-	
-	if (actual_size != 1) {
-		usb_log_warning("Wrong data size: %zu, expected: 1.\n",
-			actual_size);
-		return ELIMIT;
-	}
-	
-	*protocol = buffer[0];
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Send Get Idle request to the HID device.
- *
- * @param[in] hid_dev HID device to send the request to.
- * @param[out] duration Duration value (multiplicate by 4 to get real duration
- *                      in miliseconds).
- *
- * @retval EOK if successful.
- * @retval EINVAL if no HID device is given.
- * @return Other value inherited from one of functions 
- *         usb_pipe_start_session(), usb_pipe_end_session(),
- *         usb_control_request_set().
- */
-int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration)
-{
-	if (ctrl_pipe == NULL) {
-		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
-		return EINVAL;
-	}
-	
-	if (iface_no < 0) {
-		usb_log_warning("usbhid_req_set_report(): no interface given."
-		    "\n");
-		return EINVAL;
-	}
-	
-	/*
-	 * No need for checking other parameters, as they are checked in
-	 * the called function (usb_control_request_set()).
-	 */
-	
-	int rc;
-
-	usb_log_debug("Sending Get_Idle request to the device ("
-	    "iface: %d).\n", iface_no);
-	
-	uint16_t value = 0;
-	uint8_t buffer[1];
-	size_t actual_size = 0;
-	
-	rc = usb_control_request_get(ctrl_pipe, 
-	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
-	    USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1, 
-	    &actual_size);
-
-	if (rc != EOK) {
-		usb_log_warning("Error sending output report to the keyboard: "
-		    "%s.\n", str_error(rc));
-		return rc;
-	}
-	
-	if (actual_size != 1) {
-		usb_log_warning("Wrong data size: %zu, expected: 1.\n",
-			actual_size);
-		return ELIMIT;
-	}
-	
-	*duration = buffer[0];
-	
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
-/**
- * @}
- */
Index: pace/lib/usb/src/host/batch.c
===================================================================
--- uspace/lib/usb/src/host/batch.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,176 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libusb
- * @{
- */
-/** @file
- * USB transfer transaction structures (implementation).
- */
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb/usb.h>
-#include <usb/debug.h>
-#include <usb/host/batch.h>
-
-void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
-void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
-
-void usb_transfer_batch_init(
-    usb_transfer_batch_t *instance,
-    endpoint_t *ep,
-    char *buffer,
-    char *data_buffer,
-    size_t buffer_size,
-    char *setup_buffer,
-    size_t setup_size,
-    usbhc_iface_transfer_in_callback_t func_in,
-    usbhc_iface_transfer_out_callback_t func_out,
-    void *arg,
-    ddf_fun_t *fun,
-    void *private_data,
-    void (*private_data_dtor)(void *p_data)
-    )
-{
-	assert(instance);
-	link_initialize(&instance->link);
-	instance->ep = ep;
-	instance->callback_in = func_in;
-	instance->callback_out = func_out;
-	instance->arg = arg;
-	instance->buffer = buffer;
-	instance->data_buffer = data_buffer;
-	instance->buffer_size = buffer_size;
-	instance->setup_buffer = setup_buffer;
-	instance->setup_size = setup_size;
-	instance->fun = fun;
-	instance->private_data = private_data;
-	instance->private_data_dtor = private_data_dtor;
-	instance->transfered_size = 0;
-	instance->next_step = NULL;
-	instance->error = EOK;
-	endpoint_use(instance->ep);
-}
-/*----------------------------------------------------------------------------*/
-/** Helper function, calls callback and correctly destroys batch structure.
- *
- * @param[in] instance Batch structure to use.
- */
-void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	usb_transfer_batch_call_in(instance);
-	usb_transfer_batch_dispose(instance);
-}
-/*----------------------------------------------------------------------------*/
-/** Helper function calls callback and correctly destroys batch structure.
- *
- * @param[in] instance Batch structure to use.
- */
-void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	usb_transfer_batch_call_out(instance);
-	usb_transfer_batch_dispose(instance);
-}
-/*----------------------------------------------------------------------------*/
-/** Mark batch as finished and continue with next step.
- *
- * @param[in] instance Batch structure to use.
- *
- */
-void usb_transfer_batch_finish(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	assert(instance->ep);
-	endpoint_release(instance->ep);
-	instance->next_step(instance);
-}
-/*----------------------------------------------------------------------------*/
-/** Prepare data, get error status and call callback in.
- *
- * @param[in] instance Batch structure to use.
- * Copies data from transport buffer, and calls callback with appropriate
- * parameters.
- */
-void usb_transfer_batch_call_in(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	assert(instance->callback_in);
-	assert(instance->ep);
-
-	/* We are data in, we need data */
-	memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
-
-	usb_log_debug("Batch(%p) done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
-	    instance, instance->ep->address, instance->ep->endpoint,
-	    usb_str_speed(instance->ep->speed),
-	    usb_str_transfer_type_short(instance->ep->transfer_type),
-	    instance->transfered_size, str_error(instance->error),
-	    instance->error);
-
-	instance->callback_in(instance->fun, instance->error,
-	    instance->transfered_size, instance->arg);
-}
-/*----------------------------------------------------------------------------*/
-/** Get error status and call callback out.
- *
- * @param[in] instance Batch structure to use.
- */
-void usb_transfer_batch_call_out(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	assert(instance->callback_out);
-
-	usb_log_debug("Batch(%p) done (T%d.%d, %s %s out): %s (%d).\n",
-	    instance, instance->ep->address, instance->ep->endpoint,
-	    usb_str_speed(instance->ep->speed),
-	    usb_str_transfer_type_short(instance->ep->transfer_type),
-	    str_error(instance->error), instance->error);
-
-	instance->callback_out(instance->fun,
-	    instance->error, instance->arg);
-}
-/*----------------------------------------------------------------------------*/
-/** Correctly dispose all used data structures.
- *
- * @param[in] instance Batch structure to use.
- */
-void usb_transfer_batch_dispose(usb_transfer_batch_t *instance)
-{
-	assert(instance);
-	usb_log_debug("Batch(%p) disposing.\n", instance);
-	if (instance->private_data) {
-		assert(instance->private_data_dtor);
-		instance->private_data_dtor(instance->private_data);
-	}
-	free(instance);
-}
-/**
- * @}
- */
Index: pace/lib/usb/src/host/device_keeper.c
===================================================================
--- uspace/lib/usb/src/host/device_keeper.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,177 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 libusb
- * @{
- */
-/** @file
- * Device keeper structure and functions (implementation).
- */
-#include <assert.h>
-#include <errno.h>
-#include <usb/debug.h>
-#include <usb/host/device_keeper.h>
-
-/*----------------------------------------------------------------------------*/
-/** Initialize device keeper structure.
- *
- * @param[in] instance Memory place to initialize.
- *
- * Set all values to false/0.
- */
-void usb_device_keeper_init(usb_device_keeper_t *instance)
-{
-	assert(instance);
-	unsigned i = 0;
-	for (; i < USB_ADDRESS_COUNT; ++i) {
-		instance->devices[i].occupied = false;
-		instance->devices[i].handle = 0;
-		instance->devices[i].speed = USB_SPEED_MAX;
-	}
-	// TODO: is this hack enough?
-	// (it is needed to allow smooth registration at default address)
-	instance->devices[0].occupied = true;
-	instance->last_address = 0;
-	fibril_mutex_initialize(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Get a free USB address
- *
- * @param[in] instance Device keeper structure to use.
- * @param[in] speed Speed of the device requiring address.
- * @return Free address, or error code.
- */
-usb_address_t device_keeper_get_free_address(
-    usb_device_keeper_t *instance, usb_speed_t speed)
-{
-	assert(instance);
-	fibril_mutex_lock(&instance->guard);
-
-	usb_address_t new_address = instance->last_address;
-	do {
-		++new_address;
-		if (new_address > USB11_ADDRESS_MAX)
-			new_address = 1;
-		if (new_address == instance->last_address) {
-			fibril_mutex_unlock(&instance->guard);
-			return ENOSPC;
-		}
-	} while (instance->devices[new_address].occupied);
-
-	assert(new_address != USB_ADDRESS_DEFAULT);
-	assert(instance->devices[new_address].occupied == false);
-
-	instance->devices[new_address].occupied = true;
-	instance->devices[new_address].speed = speed;
-	instance->last_address = new_address;
-
-	fibril_mutex_unlock(&instance->guard);
-	return new_address;
-}
-/*----------------------------------------------------------------------------*/
-/** Bind USB address to devman handle.
- *
- * @param[in] instance Device keeper structure to use.
- * @param[in] address Device address
- * @param[in] handle Devman handle of the device.
- */
-void usb_device_keeper_bind(usb_device_keeper_t *instance,
-    usb_address_t address, devman_handle_t handle)
-{
-	assert(instance);
-	fibril_mutex_lock(&instance->guard);
-
-	assert(address > 0);
-	assert(address <= USB11_ADDRESS_MAX);
-	assert(instance->devices[address].occupied);
-
-	instance->devices[address].handle = handle;
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Release used USB address.
- *
- * @param[in] instance Device keeper structure to use.
- * @param[in] address Device address
- */
-void usb_device_keeper_release(
-    usb_device_keeper_t *instance, usb_address_t address)
-{
-	assert(instance);
-	assert(address > 0);
-	assert(address <= USB11_ADDRESS_MAX);
-
-	fibril_mutex_lock(&instance->guard);
-	assert(instance->devices[address].occupied);
-
-	instance->devices[address].occupied = false;
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-/** Find USB address associated with the device
- *
- * @param[in] instance Device keeper structure to use.
- * @param[in] handle Devman handle of the device seeking its address.
- * @return USB Address, or error code.
- */
-usb_address_t usb_device_keeper_find(
-    usb_device_keeper_t *instance, devman_handle_t handle)
-{
-	assert(instance);
-	fibril_mutex_lock(&instance->guard);
-	usb_address_t address = 1;
-	while (address <= USB11_ADDRESS_MAX) {
-		if (instance->devices[address].handle == handle) {
-			assert(instance->devices[address].occupied);
-			fibril_mutex_unlock(&instance->guard);
-			return address;
-		}
-		++address;
-	}
-	fibril_mutex_unlock(&instance->guard);
-	return ENOENT;
-}
-/*----------------------------------------------------------------------------*/
-/** Get speed associated with the address
- *
- * @param[in] instance Device keeper structure to use.
- * @param[in] address Address of the device.
- * @return USB speed.
- */
-usb_speed_t usb_device_keeper_get_speed(
-    usb_device_keeper_t *instance, usb_address_t address)
-{
-	assert(instance);
-	assert(address >= 0);
-	assert(address <= USB11_ADDRESS_MAX);
-
-	return instance->devices[address].speed;
-}
-/**
- * @}
- */
Index: pace/lib/usb/src/host/endpoint.c
===================================================================
--- uspace/lib/usb/src/host/endpoint.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,129 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * 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 drvusbuhcihc
- * @{
- */
-/** @file
- * @brief UHCI host controller driver structure
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <usb/host/endpoint.h>
-
-int endpoint_init(endpoint_t *instance, usb_address_t address,
-    usb_endpoint_t endpoint, usb_direction_t direction,
-    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size)
-{
-	assert(instance);
-	instance->address = address;
-	instance->endpoint = endpoint;
-	instance->direction = direction;
-	instance->transfer_type = type;
-	instance->speed = speed;
-	instance->max_packet_size = max_packet_size;
-	instance->toggle = 0;
-	instance->active = false;
-	fibril_mutex_initialize(&instance->guard);
-	fibril_condvar_initialize(&instance->avail);
-	endpoint_clear_hc_data(instance);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_destroy(endpoint_t *instance)
-{
-	assert(instance);
-	assert(!instance->active);
-	free(instance);
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_set_hc_data(endpoint_t *instance,
-    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int))
-{
-	assert(instance);
-	instance->hc_data.data = data;
-	instance->hc_data.toggle_get = toggle_get;
-	instance->hc_data.toggle_set = toggle_set;
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_clear_hc_data(endpoint_t *instance)
-{
-	assert(instance);
-	instance->hc_data.data = NULL;
-	instance->hc_data.toggle_get = NULL;
-	instance->hc_data.toggle_set = NULL;
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_use(endpoint_t *instance)
-{
-	assert(instance);
-	fibril_mutex_lock(&instance->guard);
-	while (instance->active)
-		fibril_condvar_wait(&instance->avail, &instance->guard);
-	instance->active = true;
-	fibril_mutex_unlock(&instance->guard);
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_release(endpoint_t *instance)
-{
-	assert(instance);
-	fibril_mutex_lock(&instance->guard);
-	instance->active = false;
-	fibril_mutex_unlock(&instance->guard);
-	fibril_condvar_signal(&instance->avail);
-}
-/*----------------------------------------------------------------------------*/
-int endpoint_toggle_get(endpoint_t *instance)
-{
-	assert(instance);
-	if (instance->hc_data.toggle_get)
-		instance->toggle =
-		    instance->hc_data.toggle_get(instance->hc_data.data);
-	return (int)instance->toggle;
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_toggle_set(endpoint_t *instance, int toggle)
-{
-	assert(instance);
-	assert(toggle == 0 || toggle == 1);
-	if (instance->hc_data.toggle_set)
-		instance->hc_data.toggle_set(instance->hc_data.data, toggle);
-	instance->toggle = toggle;
-}
-/*----------------------------------------------------------------------------*/
-void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target)
-{
-	assert(instance);
-	if (instance->address == target.address &&
-	    (instance->endpoint == target.endpoint || target.endpoint == 0))
-		endpoint_toggle_set(instance, 0);
-}
-/**
- * @}
- */
Index: pace/lib/usb/src/host/usb_endpoint_manager.c
===================================================================
--- uspace/lib/usb/src/host/usb_endpoint_manager.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,291 +1,0 @@
-/*
- * Copyright (c) 2011 Jan Vesely
- * All rights eps.
- *
- * 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.
- */
-
-#include <bool.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <usb/debug.h>
-#include <usb/host/usb_endpoint_manager.h>
-
-#define BUCKET_COUNT 7
-
-#define MAX_KEYS (3)
-typedef struct {
-	link_t link;
-	size_t bw;
-	endpoint_t *ep;
-} node_t;
-/*----------------------------------------------------------------------------*/
-static hash_index_t node_hash(unsigned long key[])
-{
-	hash_index_t hash = 0;
-	unsigned i = 0;
-	for (;i < MAX_KEYS; ++i) {
-		hash ^= key[i];
-	}
-	hash %= BUCKET_COUNT;
-	return hash;
-}
-/*----------------------------------------------------------------------------*/
-static int node_compare(unsigned long key[], hash_count_t keys, link_t *item)
-{
-	assert(item);
-	node_t *node = hash_table_get_instance(item, node_t, link);
-	assert(node);
-	assert(node->ep);
-	bool match = true;
-	switch (keys) {
-	case 3:
-		match = match && (key[2] == node->ep->direction);
-	case 2:
-		match = match && (key[1] == (unsigned long)node->ep->endpoint);
-	case 1:
-		match = match && (key[0] == (unsigned long)node->ep->address);
-		break;
-	default:
-		match = false;
-	}
-	return match;
-}
-/*----------------------------------------------------------------------------*/
-static void node_remove(link_t *item)
-{
-	assert(item);
-	node_t *node = hash_table_get_instance(item, node_t, link);
-	endpoint_destroy(node->ep);
-	free(node);
-}
-/*----------------------------------------------------------------------------*/
-static void node_toggle_reset_filtered(link_t *item, void *arg)
-{
-	assert(item);
-	node_t *node = hash_table_get_instance(item, node_t, link);
-	usb_target_t *target = arg;
-	endpoint_toggle_reset_filtered(node->ep, *target);
-}
-/*----------------------------------------------------------------------------*/
-static hash_table_operations_t op = {
-	.hash = node_hash,
-	.compare = node_compare,
-	.remove_callback = node_remove,
-};
-/*----------------------------------------------------------------------------*/
-size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
-    size_t size, size_t max_packet_size)
-{
-	/* We care about bandwidth only for interrupt and isochronous. */
-	if ((type != USB_TRANSFER_INTERRUPT)
-	    && (type != USB_TRANSFER_ISOCHRONOUS)) {
-		return 0;
-	}
-
-	const unsigned packet_count =
-	    (size + max_packet_size - 1) / max_packet_size;
-	/* TODO: It may be that ISO and INT transfers use only one data packet
-	 * per transaction, but I did not find text in UB spec that confirms
-	 * this */
-	/* NOTE: All data packets will be considered to be max_packet_size */
-	switch (speed)
-	{
-	case USB_SPEED_LOW:
-		assert(type == USB_TRANSFER_INTERRUPT);
-		/* Protocol overhead 13B
-		 * (3 SYNC bytes, 3 PID bytes, 2 Endpoint + CRC bytes, 2
-		 * CRC bytes, and a 3-byte interpacket delay)
-		 * see USB spec page 45-46. */
-		/* Speed penalty 8: low speed is 8-times slower*/
-		return packet_count * (13 + max_packet_size) * 8;
-	case USB_SPEED_FULL:
-		/* Interrupt transfer overhead see above
-		 * or page 45 of USB spec */
-		if (type == USB_TRANSFER_INTERRUPT)
-			return packet_count * (13 + max_packet_size);
-
-		assert(type == USB_TRANSFER_ISOCHRONOUS);
-		/* Protocol overhead 9B
-		 * (2 SYNC bytes, 2 PID bytes, 2 Endpoint + CRC bytes, 2 CRC
-		 * bytes, and a 1-byte interpacket delay)
-		 * see USB spec page 42 */
-		return packet_count * (9 + max_packet_size);
-	default:
-		return 0;
-	}
-}
-/*----------------------------------------------------------------------------*/
-int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
-    size_t available_bandwidth)
-{
-	assert(instance);
-	fibril_mutex_initialize(&instance->guard);
-	fibril_condvar_initialize(&instance->change);
-	instance->free_bw = available_bandwidth;
-	bool ht =
-	    hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op);
-	return ht ? EOK : ENOMEM;
-}
-/*----------------------------------------------------------------------------*/
-void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance)
-{
-	hash_table_destroy(&instance->ep_table);
-}
-/*----------------------------------------------------------------------------*/
-int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
-    endpoint_t *ep, size_t data_size)
-{
-	assert(ep);
-	size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
-	    data_size, ep->max_packet_size);
-	assert(instance);
-
-	unsigned long key[MAX_KEYS] =
-	    {ep->address, ep->endpoint, ep->direction};
-	fibril_mutex_lock(&instance->guard);
-
-	link_t *item =
-	    hash_table_find(&instance->ep_table, key);
-	if (item != NULL) {
-		fibril_mutex_unlock(&instance->guard);
-		return EEXISTS;
-	}
-
-	if (bw > instance->free_bw) {
-		fibril_mutex_unlock(&instance->guard);
-		return ENOSPC;
-	}
-
-	node_t *node = malloc(sizeof(node_t));
-	if (node == NULL) {
-		fibril_mutex_unlock(&instance->guard);
-		return ENOMEM;
-	}
-
-	node->bw = bw;
-	node->ep = ep;
-	link_initialize(&node->link);
-
-	hash_table_insert(&instance->ep_table, key, &node->link);
-	instance->free_bw -= bw;
-	fibril_mutex_unlock(&instance->guard);
-	fibril_condvar_broadcast(&instance->change);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
-{
-	assert(instance);
-	unsigned long key[MAX_KEYS] = {address, endpoint, direction};
-
-	fibril_mutex_lock(&instance->guard);
-	link_t *item = hash_table_find(&instance->ep_table, key);
-	if (item == NULL) {
-		fibril_mutex_unlock(&instance->guard);
-		return EINVAL;
-	}
-
-	node_t *node = hash_table_get_instance(item, node_t, link);
-	if (node->ep->active)
-		return EBUSY;
-
-	instance->free_bw += node->bw;
-	hash_table_remove(&instance->ep_table, key, MAX_KEYS);
-
-	fibril_mutex_unlock(&instance->guard);
-	fibril_condvar_broadcast(&instance->change);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
-    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
-    size_t *bw)
-{
-	assert(instance);
-	unsigned long key[MAX_KEYS] = {address, endpoint, direction};
-
-	fibril_mutex_lock(&instance->guard);
-	link_t *item = hash_table_find(&instance->ep_table, key);
-	if (item == NULL) {
-		fibril_mutex_unlock(&instance->guard);
-		return NULL;
-	}
-	node_t *node = hash_table_get_instance(item, node_t, link);
-	if (bw)
-		*bw = node->bw;
-
-	fibril_mutex_unlock(&instance->guard);
-	return node->ep;
-}
-/*----------------------------------------------------------------------------*/
-/** Check setup packet data for signs of toggle reset.
- *
- * @param[in] instance Device keeper structure to use.
- * @param[in] target Device to receive setup packet.
- * @param[in] data Setup packet data.
- *
- * Really ugly one.
- */
-void usb_endpoint_manager_reset_if_need(
-    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data)
-{
-	assert(instance);
-	if (target.endpoint > 15 || target.endpoint < 0
-	    || target.address >= USB11_ADDRESS_MAX || target.address < 0) {
-		usb_log_error("Invalid data when checking for toggle reset.\n");
-		return;
-	}
-
-	switch (data[1])
-	{
-	case 0x01: /*clear feature*/
-		/* recipient is endpoint, value is zero (ENDPOINT_STALL) */
-		if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
-			/* endpoint number is < 16, thus first byte is enough */
-			usb_target_t reset_target =
-			    { .address = target.address, data[4] };
-			fibril_mutex_lock(&instance->guard);
-			hash_table_apply(&instance->ep_table,
-			    node_toggle_reset_filtered, &reset_target);
-			fibril_mutex_unlock(&instance->guard);
-		}
-	break;
-
-	case 0x9: /* set configuration */
-	case 0x11: /* set interface */
-		/* target must be device */
-		if ((data[0] & 0xf) == 0) {
-			usb_target_t reset_target =
-			    { .address = target.address, 0 };
-			fibril_mutex_lock(&instance->guard);
-			hash_table_apply(&instance->ep_table,
-			    node_toggle_reset_filtered, &reset_target);
-			fibril_mutex_unlock(&instance->guard);
-		}
-	break;
-	}
-}
Index: pace/lib/usb/src/hub.c
===================================================================
--- uspace/lib/usb/src/hub.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,335 +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 libusb
- * @{
- */
-/** @file
- * Functions needed by hub drivers.
- */
-#include <usb/hub.h>
-#include <usb/pipes.h>
-#include <usb/request.h>
-#include <usb/recognise.h>
-#include <usbhc_iface.h>
-#include <errno.h>
-#include <assert.h>
-#include <usb/debug.h>
-
-/** How much time to wait between attempts to register endpoint 0:0.
- * The value is based on typical value for port reset + some overhead.
- */
-#define ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC (1000 * (10 + 2))
-
-/** Check that HC connection is alright.
- *
- * @param conn Connection to be checked.
- */
-#define CHECK_CONNECTION(conn) \
-	do { \
-		assert((conn)); \
-		if (!usb_hc_connection_is_opened((conn))) { \
-			return ENOENT; \
-		} \
-	} while (false)
-
-/** Ask host controller for free address assignment.
- *
- * @param connection Opened connection to host controller.
- * @param speed Speed of the new device (device that will be assigned
- *    the returned address).
- * @return Assigned USB address or negative error code.
- */
-usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
-    usb_speed_t speed)
-{
-	CHECK_CONNECTION(connection);
-
-	sysarg_t address;
-	int rc = async_req_2_1(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REQUEST_ADDRESS, speed,
-	    &address);
-	if (rc != EOK) {
-		return (usb_address_t) rc;
-	} else {
-		return (usb_address_t) address;
-	}
-}
-
-/** Inform host controller about new device.
- *
- * @param connection Opened connection to host controller.
- * @param attached_device Information about the new device.
- * @return Error code.
- */
-int usb_hc_register_device(usb_hc_connection_t * connection,
-    const usb_hc_attached_device_t *attached_device)
-{
-	CHECK_CONNECTION(connection);
-	if (attached_device == NULL) {
-		return EBADMEM;
-	}
-
-	return async_req_3_0(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_BIND_ADDRESS,
-	    attached_device->address, attached_device->handle);
-}
-
-/** Inform host controller about device removal.
- *
- * @param connection Opened connection to host controller.
- * @param address Address of the device that is being removed.
- * @return Error code.
- */
-int usb_hc_unregister_device(usb_hc_connection_t *connection,
-    usb_address_t address)
-{
-	CHECK_CONNECTION(connection);
-
-	return async_req_2_0(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RELEASE_ADDRESS, address);
-}
-
-static void unregister_control_endpoint_on_default_address(
-    usb_hc_connection_t *connection)
-{
-	usb_device_connection_t dev_conn;
-	int rc = usb_device_connection_initialize_on_default_address(&dev_conn,
-	    connection);
-	if (rc != EOK) {
-		return;
-	}
-
-	usb_pipe_t ctrl_pipe;
-	rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
-	if (rc != EOK) {
-		return;
-	}
-
-	usb_pipe_unregister(&ctrl_pipe, connection);
-}
-
-
-/** Wrapper for registering attached device to the hub.
- *
- * The @p enable_port function is expected to enable signaling on given
- * port.
- * The two arguments to it can have arbitrary meaning
- * (the @p port_no is only a suggestion)
- * and are not touched at all by this function
- * (they are passed as is to the @p enable_port function).
- *
- * If the @p enable_port fails (i.e. does not return EOK), the device
- * addition is canceled.
- * The return value is then returned (it is good idea to use different
- * error codes than those listed as return codes by this function itself).
- *
- * The @p connection representing connection with host controller does not
- * need to be started.
- * This function duplicates the connection to allow simultaneous calls of
- * this function (i.e. from different fibrils).
- *
- * @param[in] parent Parent device (i.e. the hub device).
- * @param[in] connection Connection to host controller.
- * @param[in] dev_speed New device speed.
- * @param[in] enable_port Function for enabling signaling through the port the
- *	device is attached to.
- * @param[in] port_no Port number (passed through to @p enable_port).
- * @param[in] arg Any data argument to @p enable_port.
- * @param[out] assigned_address USB address of the device.
- * @param[out] assigned_handle Devman handle of the new device.
- * @param[in] dev_ops Child device ops.
- * @param[in] new_dev_data Arbitrary pointer to be stored in the child
- *	as @c driver_data.
- * @param[out] new_fun Storage where pointer to allocated child function
- *	will be written.
- * @return Error code.
- * @retval ENOENT Connection to HC not opened.
- * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
- * @retval EBUSY Failed reserving default USB address.
- * @retval ENOTCONN Problem connecting to the host controller via USB pipe.
- * @retval ESTALL Problem communication with device (either SET_ADDRESS
- *	request or requests for descriptors when creating match ids).
- */
-int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection,
-    usb_speed_t dev_speed,
-    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
-    usb_address_t *assigned_address, devman_handle_t *assigned_handle,
-    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
-{
-	assert(connection != NULL);
-	// FIXME: this is awful, we are accessing directly the structure.
-	usb_hc_connection_t hc_conn = {
-		.hc_handle = connection->hc_handle,
-		.hc_phone = -1
-	};
-
-	int rc;
-
-	rc = usb_hc_connection_open(&hc_conn);
-	if (rc != EOK) {
-		return rc;
-	}
-
-
-	/*
-	 * Request new address.
-	 */
-	usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
-	if (dev_addr < 0) {
-		usb_hc_connection_close(&hc_conn);
-		return EADDRNOTAVAIL;
-	}
-
-	/*
-	 * We will not register control pipe on default address.
-	 * The registration might fail. That means that someone else already
-	 * registered that endpoint. We will simply wait and try again.
-	 * (Someone else already wants to add a new device.)
-	 */
-	usb_device_connection_t dev_conn;
-	rc = usb_device_connection_initialize_on_default_address(&dev_conn,
-	    &hc_conn);
-	if (rc != EOK) {
-		rc = ENOTCONN;
-		goto leave_release_free_address;
-	}
-
-	usb_pipe_t ctrl_pipe;
-	rc = usb_pipe_initialize_default_control(&ctrl_pipe,
-	    &dev_conn);
-	if (rc != EOK) {
-		rc = ENOTCONN;
-		goto leave_release_free_address;
-	}
-
-	do {
-		rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0,
-		    &hc_conn);
-		if (rc != EOK) {
-			/* Do not overheat the CPU ;-). */
-			async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
-		}
-	} while (rc != EOK);
-
-	/*
-	 * Endpoint is registered. We can enable the port and change
-	 * device address.
-	 */
-	rc = enable_port(port_no, arg);
-	if (rc != EOK) {
-		goto leave_release_default_address;
-	}
-
-	rc = usb_pipe_probe_default_control(&ctrl_pipe);
-	if (rc != EOK) {
-		rc = ESTALL;
-		goto leave_release_default_address;
-	}
-
-	rc = usb_request_set_address(&ctrl_pipe, dev_addr);
-	if (rc != EOK) {
-		rc = ESTALL;
-		goto leave_release_default_address;
-	}
-
-	/*
-	 * Address changed. We can release the original endpoint, thus
-	 * allowing other to access the default address.
-	 */
-	unregister_control_endpoint_on_default_address(&hc_conn);
-
-	/*
-	 * Time to register the new endpoint.
-	 */
-	rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
-	if (rc != EOK) {
-		goto leave_release_free_address;
-	}
-
-	/*
-	 * It is time to register the device with devman.
-	 */
-	/* FIXME: create device_register that will get opened ctrl pipe. */
-	devman_handle_t child_handle;
-	rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
-	    parent, &child_handle,
-	    dev_ops, new_dev_data, new_fun);
-	if (rc != EOK) {
-		rc = ESTALL;
-		goto leave_release_free_address;
-	}
-
-	/*
-	 * And now inform the host controller about the handle.
-	 */
-	usb_hc_attached_device_t new_device = {
-		.address = dev_addr,
-		.handle = child_handle
-	};
-	rc = usb_hc_register_device(&hc_conn, &new_device);
-	if (rc != EOK) {
-		rc = EDESTADDRREQ;
-		goto leave_release_free_address;
-	}
-
-	/*
-	 * And we are done.
-	 */
-	if (assigned_address != NULL) {
-		*assigned_address = dev_addr;
-	}
-	if (assigned_handle != NULL) {
-		*assigned_handle = child_handle;
-	}
-
-	return EOK;
-
-
-
-	/*
-	 * Error handling (like nested exceptions) starts here.
-	 * Completely ignoring errors here.
-	 */
-leave_release_default_address:
-	usb_pipe_unregister(&ctrl_pipe, &hc_conn);
-
-leave_release_free_address:
-	usb_hc_unregister_device(&hc_conn, dev_addr);
-
-	usb_hc_connection_close(&hc_conn);
-
-	return rc;
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/pipepriv.c
===================================================================
--- uspace/lib/usb/src/pipepriv.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,137 +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 libusb
- * @{
- */
-/** @file
- * Library internal functions on USB pipes (implementation).
- */
-#include "pipepriv.h"
-#include <devman.h>
-#include <errno.h>
-#include <assert.h>
-
-/** Ensure exclusive access to the IPC phone of given pipe.
- *
- * @param pipe Pipe to be exclusively accessed.
- */
-void pipe_start_transaction(usb_pipe_t *pipe)
-{
-	fibril_mutex_lock(&pipe->hc_phone_mutex);
-}
-
-/** Terminate exclusive access to the IPC phone of given pipe.
- *
- * @param pipe Pipe to be released from exclusive usage.
- */
-void pipe_end_transaction(usb_pipe_t *pipe)
-{
-	fibril_mutex_unlock(&pipe->hc_phone_mutex);
-}
-
-/** Ensure exclusive access to the pipe as a whole.
- *
- * @param pipe Pipe to be exclusively accessed.
- */
-void pipe_acquire(usb_pipe_t *pipe)
-{
-	fibril_mutex_lock(&pipe->guard);
-}
-
-/** Terminate exclusive access to the pipe as a whole.
- *
- * @param pipe Pipe to be released from exclusive usage.
- */
-void pipe_release(usb_pipe_t *pipe)
-{
-	fibril_mutex_unlock(&pipe->guard);
-}
-
-/** Add reference of active transfers over the pipe.
- *
- * @param pipe The USB pipe.
- * @param hide_failure Whether to hide failure when adding reference
- *	(use soft refcount).
- * @return Error code.
- * @retval EOK Currently always.
- */
-int pipe_add_ref(usb_pipe_t *pipe, bool hide_failure)
-{
-	pipe_acquire(pipe);
-
-	if (pipe->refcount == 0) {
-		/* Need to open the phone by ourselves. */
-		int phone = devman_device_connect(pipe->wire->hc_handle, 0);
-		if (phone < 0) {
-			if (hide_failure) {
-				pipe->refcount_soft++;
-				phone = EOK;
-			}
-			pipe_release(pipe);
-			return phone;
-		}
-		/*
-		 * No locking is needed, refcount is zero and whole pipe
-		 * mutex is locked.
-		 */
-		pipe->hc_phone = phone;
-	}
-	pipe->refcount++;
-
-	pipe_release(pipe);
-
-	return EOK;
-}
-
-/** Drop active transfer reference on the pipe.
- *
- * @param pipe The USB pipe.
- */
-void pipe_drop_ref(usb_pipe_t *pipe)
-{
-	pipe_acquire(pipe);
-	if (pipe->refcount_soft > 0) {
-		pipe->refcount_soft--;
-		pipe_release(pipe);
-		return;
-	}
-	assert(pipe->refcount > 0);
-	pipe->refcount--;
-	if (pipe->refcount == 0) {
-		/* We were the last users, let's hang-up. */
-		async_hangup(pipe->hc_phone);
-		pipe->hc_phone = -1;
-	}
-	pipe_release(pipe);
-}
-
-
-/**
- * @}
- */
Index: pace/lib/usb/src/pipepriv.h
===================================================================
--- uspace/lib/usb/src/pipepriv.h	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,54 +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 libusb
- * @{
- */
-/** @file
- * Library internal functions on USB pipes.
- */
-#ifndef LIBUSB_PIPEPRIV_H_
-#define LIBUSB_PIPEPRIV_H_
-
-#include <usb/pipes.h>
-#include <bool.h>
-
-void pipe_acquire(usb_pipe_t *);
-void pipe_release(usb_pipe_t *);
-
-void pipe_start_transaction(usb_pipe_t *);
-void pipe_end_transaction(usb_pipe_t *);
-
-int pipe_add_ref(usb_pipe_t *, bool);
-void pipe_drop_ref(usb_pipe_t *);
-
-
-#endif
-/**
- * @}
- */
Index: pace/lib/usb/src/pipes.c
===================================================================
--- uspace/lib/usb/src/pipes.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,259 +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 libusb
- * @{
- */
-/** @file
- * USB endpoint pipes miscellaneous functions.
- */
-#include <usb/usb.h>
-#include <usb/pipes.h>
-#include <usb/debug.h>
-#include <usbhc_iface.h>
-#include <usb_iface.h>
-#include <devman.h>
-#include <errno.h>
-#include <assert.h>
-#include "pipepriv.h"
-
-#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
-
-/** Tell USB address assigned to given device.
- *
- * @param phone Phone to parent device.
- * @param dev Device in question.
- * @return USB address or error code.
- */
-static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
-{
-	sysarg_t address;
-
-	/*
-	 * We are sending special value as a handle - zero - to get
-	 * handle of the parent function (that handle was used
-	 * when registering our device @p dev.
-	 */
-	int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_ADDRESS,
-	    0, &address);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	return (usb_address_t) address;
-}
-
-/** Tell USB interface assigned to given device.
- *
- * @param device Device in question.
- * @return Interface number (negative code means any).
- */
-int usb_device_get_assigned_interface(ddf_dev_t *device)
-{
-	int parent_phone = devman_parent_device_connect(device->handle,
-	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return -1;
-	}
-
-	sysarg_t iface_no;
-	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_INTERFACE,
-	    device->handle, &iface_no);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
-		return -1;
-	}
-
-	return (int) iface_no;
-}
-
-/** Tell USB address assigned to given device.
- *
- * @param dev_handle Devman handle of the USB device in question.
- * @return USB address or negative error code.
- */
-usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle)
-{
-	int parent_phone = devman_parent_device_connect(dev_handle,
-	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
-	sysarg_t address;
-
-	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_ADDRESS,
-	    dev_handle, &address);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	async_hangup(parent_phone);
-
-	return (usb_address_t) address;
-}
-
-/** Initialize connection to USB device.
- *
- * @param connection Connection structure to be initialized.
- * @param dev Generic device backing the USB device.
- * @return Error code.
- */
-int usb_device_connection_initialize_from_device(
-    usb_device_connection_t *connection, ddf_dev_t *dev)
-{
-	assert(connection);
-	assert(dev);
-
-	int rc;
-	devman_handle_t hc_handle;
-	usb_address_t my_address;
-
-	rc = usb_hc_find(dev->handle, &hc_handle);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	int parent_phone = devman_parent_device_connect(dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
-	/*
-	 * 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,
-	    hc_handle, my_address);
-
-leave:
-	async_hangup(parent_phone);
-	return rc;
-}
-
-/** Initialize connection to USB device.
- *
- * @param connection Connection structure to be initialized.
- * @param host_controller_handle Devman handle of host controller device is
- * 	connected to.
- * @param device_address Device USB address.
- * @return Error code.
- */
-int usb_device_connection_initialize(usb_device_connection_t *connection,
-    devman_handle_t host_controller_handle, usb_address_t device_address)
-{
-	assert(connection);
-
-	if ((device_address < 0) || (device_address >= USB11_ADDRESS_MAX)) {
-		return EINVAL;
-	}
-
-	connection->hc_handle = host_controller_handle;
-	connection->address = device_address;
-
-	return EOK;
-}
-
-/** Initialize connection to USB device on default address.
- *
- * @param dev_connection Device connection structure to be initialized.
- * @param hc_connection Initialized connection to host controller.
- * @return Error code.
- */
-int usb_device_connection_initialize_on_default_address(
-    usb_device_connection_t *dev_connection,
-    usb_hc_connection_t *hc_connection)
-{
-	assert(dev_connection);
-
-	if (hc_connection == NULL) {
-		return EBADMEM;
-	}
-
-	return usb_device_connection_initialize(dev_connection,
-	    hc_connection->hc_handle, (usb_address_t) 0);
-}
-
-/** Prepare pipe for a long transfer.
- *
- * By a long transfer is mean transfer consisting of several
- * requests to the HC.
- * Calling such function is optional and it has positive effect of
- * improved performance because IPC session is initiated only once.
- *
- * @param pipe Pipe over which the transfer will happen.
- * @return Error code.
- */
-void usb_pipe_start_long_transfer(usb_pipe_t *pipe)
-{
-	(void) pipe_add_ref(pipe, true);
-}
-
-/** Terminate a long transfer on a pipe.
- *
- * @see usb_pipe_start_long_transfer
- *
- * @param pipe Pipe where to end the long transfer.
- */
-void usb_pipe_end_long_transfer(usb_pipe_t *pipe)
-{
-	pipe_drop_ref(pipe);
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/pipesinit.c
===================================================================
--- uspace/lib/usb/src/pipesinit.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,525 +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 libusb
- * @{
- */
-/** @file
- * Initialization of endpoint pipes.
- *
- */
-#include <usb/usb.h>
-#include <usb/pipes.h>
-#include <usb/dp.h>
-#include <usb/request.h>
-#include <usbhc_iface.h>
-#include <errno.h>
-#include <assert.h>
-
-#define CTRL_PIPE_MIN_PACKET_SIZE 8
-#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
-
-
-#define NESTING(parentname, childname) \
-	{ \
-		.child = USB_DESCTYPE_##childname, \
-		.parent = USB_DESCTYPE_##parentname, \
-	}
-#define LAST_NESTING { -1, -1 }
-
-/** Nesting pairs of standard descriptors. */
-static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
-	NESTING(CONFIGURATION, INTERFACE),
-	NESTING(INTERFACE, ENDPOINT),
-	NESTING(INTERFACE, HUB),
-	NESTING(INTERFACE, HID),
-	NESTING(HID, HID_REPORT),
-	LAST_NESTING
-};
-
-/** Tells whether given descriptor is of endpoint type.
- *
- * @param descriptor Descriptor in question.
- * @return Whether the given descriptor is endpoint descriptor.
- */
-static inline bool is_endpoint_descriptor(uint8_t *descriptor)
-{
-	return descriptor[1] == USB_DESCTYPE_ENDPOINT;
-}
-
-/** Tells whether found endpoint corresponds to endpoint described by user.
- *
- * @param wanted Endpoint description as entered by driver author.
- * @param found Endpoint description obtained from endpoint descriptor.
- * @return Whether the @p found descriptor fits the @p wanted descriptor.
- */
-static bool endpoint_fits_description(const usb_endpoint_description_t *wanted,
-    usb_endpoint_description_t *found)
-{
-#define _SAME(fieldname) ((wanted->fieldname) == (found->fieldname))
-
-	if (!_SAME(direction)) {
-		return false;
-	}
-
-	if (!_SAME(transfer_type)) {
-		return false;
-	}
-
-	if ((wanted->interface_class >= 0) && !_SAME(interface_class)) {
-		return false;
-	}
-
-	if ((wanted->interface_subclass >= 0) && !_SAME(interface_subclass)) {
-		return false;
-	}
-
-	if ((wanted->interface_protocol >= 0) && !_SAME(interface_protocol)) {
-		return false;
-	}
-
-#undef _SAME
-
-	return true;
-}
-
-/** Find endpoint mapping for a found endpoint.
- *
- * @param mapping Endpoint mapping list.
- * @param mapping_count Number of endpoint mappings in @p mapping.
- * @param found_endpoint Description of found endpoint.
- * @param interface_number Number of currently processed interface.
- * @return Endpoint mapping corresponding to @p found_endpoint.
- * @retval NULL No corresponding endpoint found.
- */
-static usb_endpoint_mapping_t *find_endpoint_mapping(
-    usb_endpoint_mapping_t *mapping, size_t mapping_count,
-    usb_endpoint_description_t *found_endpoint,
-    int interface_number, int interface_setting)
-{
-	while (mapping_count > 0) {
-		bool interface_number_fits = (mapping->interface_no < 0)
-		    || (mapping->interface_no == interface_number);
-
-		bool interface_setting_fits = (mapping->interface_setting < 0)
-		    || (mapping->interface_setting == interface_setting);
-
-		bool endpoint_descriptions_fits = endpoint_fits_description(
-		    mapping->description, found_endpoint);
-
-		if (interface_number_fits
-		    && interface_setting_fits
-		    && endpoint_descriptions_fits) {
-			return mapping;
-		}
-
-		mapping++;
-		mapping_count--;
-	}
-	return NULL;
-}
-
-/** Process endpoint descriptor.
- *
- * @param mapping Endpoint mapping list.
- * @param mapping_count Number of endpoint mappings in @p mapping.
- * @param interface Interface descriptor under which belongs the @p endpoint.
- * @param endpoint Endpoint descriptor.
- * @param wire Connection backing the endpoint pipes.
- * @return Error code.
- */
-static int process_endpoint(
-    usb_endpoint_mapping_t *mapping, size_t mapping_count,
-    usb_standard_interface_descriptor_t *interface,
-    usb_standard_endpoint_descriptor_t *endpoint,
-    usb_device_connection_t *wire)
-{
-	usb_endpoint_description_t description;
-
-	/*
-	 * Get endpoint characteristics.
-	 */
-
-	/* Actual endpoint number is in bits 0..3 */
-	usb_endpoint_t ep_no = endpoint->endpoint_address & 0x0F;
-
-	/* Endpoint direction is set by bit 7 */
-	description.direction = (endpoint->endpoint_address & 128)
-	    ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
-	/* Transfer type is in bits 0..2 and the enum values corresponds 1:1 */
-	description.transfer_type = endpoint->attributes & 3;
-
-	/*
-	 * Get interface characteristics.
-	 */
-	description.interface_class = interface->interface_class;
-	description.interface_subclass = interface->interface_subclass;
-	description.interface_protocol = interface->interface_protocol;
-
-	/*
-	 * Find the most fitting mapping and initialize the pipe.
-	 */
-	usb_endpoint_mapping_t *ep_mapping = find_endpoint_mapping(mapping,
-	    mapping_count, &description,
-	    interface->interface_number, interface->alternate_setting);
-	if (ep_mapping == NULL) {
-		return ENOENT;
-	}
-
-	if (ep_mapping->pipe == NULL) {
-		return EBADMEM;
-	}
-	if (ep_mapping->present) {
-		return EEXISTS;
-	}
-
-	int rc = usb_pipe_initialize(ep_mapping->pipe, wire,
-	    ep_no, description.transfer_type, endpoint->max_packet_size,
-	    description.direction);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	ep_mapping->present = true;
-	ep_mapping->descriptor = endpoint;
-	ep_mapping->interface = interface;
-
-	return EOK;
-}
-
-/** Process whole USB interface.
- *
- * @param mapping Endpoint mapping list.
- * @param mapping_count Number of endpoint mappings in @p mapping.
- * @param parser Descriptor parser.
- * @param parser_data Descriptor parser data.
- * @param interface_descriptor Interface descriptor.
- * @return Error code.
- */
-static int process_interface(
-    usb_endpoint_mapping_t *mapping, size_t mapping_count,
-    usb_dp_parser_t *parser, usb_dp_parser_data_t *parser_data,
-    uint8_t *interface_descriptor)
-{
-	uint8_t *descriptor = usb_dp_get_nested_descriptor(parser,
-	    parser_data, interface_descriptor);
-
-	if (descriptor == NULL) {
-		return ENOENT;
-	}
-
-	do {
-		if (is_endpoint_descriptor(descriptor)) {
-			(void) process_endpoint(mapping, mapping_count,
-			    (usb_standard_interface_descriptor_t *)
-			        interface_descriptor,
-			    (usb_standard_endpoint_descriptor_t *)
-			        descriptor,
-			    (usb_device_connection_t *) parser_data->arg);
-		}
-
-		descriptor = usb_dp_get_sibling_descriptor(parser, parser_data,
-		    interface_descriptor, descriptor);
-	} while (descriptor != NULL);
-
-	return EOK;
-}
-
-/** Initialize endpoint pipes from configuration descriptor.
- *
- * The mapping array is expected to conform to following rules:
- * - @c pipe must point to already allocated structure with uninitialized pipe
- * - @c description must point to prepared endpoint description
- * - @c descriptor does not need to be initialized (will be overwritten)
- * - @c interface does not need to be initialized (will be overwritten)
- * - @c present does not need to be initialized (will be overwritten)
- *
- * After processing the configuration descriptor, the mapping is updated
- * in the following fashion:
- * - @c present will be set to @c true when the endpoint was found in the
- *   configuration
- * - @c descriptor will point inside the configuration descriptor to endpoint
- *   corresponding to given description (or NULL for not found descriptor)
- * - @c interface will point inside the configuration descriptor to interface
- *   descriptor the endpoint @c descriptor belongs to (or NULL for not found
- *   descriptor)
- * - @c pipe will be initialized when found, otherwise left untouched
- * - @c description will be untouched under all circumstances
- *
- * @param mapping Endpoint mapping list.
- * @param mapping_count Number of endpoint mappings in @p mapping.
- * @param configuration_descriptor Full configuration descriptor (is expected
- *	to be in USB endianness: i.e. as-is after being retrieved from
- *	the device).
- * @param configuration_descriptor_size Size of @p configuration_descriptor
- *	in bytes.
- * @param connection Connection backing the endpoint pipes.
- * @return Error code.
- */
-int usb_pipe_initialize_from_configuration(
-    usb_endpoint_mapping_t *mapping, size_t mapping_count,
-    uint8_t *configuration_descriptor, size_t configuration_descriptor_size,
-    usb_device_connection_t *connection)
-{
-	assert(connection);
-
-	if (configuration_descriptor == NULL) {
-		return EBADMEM;
-	}
-	if (configuration_descriptor_size
-	    < sizeof(usb_standard_configuration_descriptor_t)) {
-		return ERANGE;
-	}
-
-	/*
-	 * Go through the mapping and set all endpoints to not present.
-	 */
-	size_t i;
-	for (i = 0; i < mapping_count; i++) {
-		mapping[i].present = false;
-		mapping[i].descriptor = NULL;
-		mapping[i].interface = NULL;
-	}
-
-	/*
-	 * Prepare the descriptor parser.
-	 */
-	usb_dp_parser_t dp_parser = {
-		.nesting = descriptor_nesting
-	};
-	usb_dp_parser_data_t dp_data = {
-		.data = configuration_descriptor,
-		.size = configuration_descriptor_size,
-		.arg = connection
-	};
-
-	/*
-	 * Iterate through all interfaces.
-	 */
-	uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,
-	    &dp_data, configuration_descriptor);
-	if (interface == NULL) {
-		return ENOENT;
-	}
-	do {
-		(void) process_interface(mapping, mapping_count,
-		    &dp_parser, &dp_data,
-		    interface);
-		interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
-		    configuration_descriptor, interface);
-	} while (interface != NULL);
-
-	return EOK;
-}
-
-/** Initialize USB endpoint pipe.
- *
- * @param pipe Endpoint pipe to be initialized.
- * @param connection Connection to the USB device backing this pipe (the wire).
- * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
- * @param transfer_type Transfer type (e.g. interrupt or bulk).
- * @param max_packet_size Maximum packet size in bytes.
- * @param direction Endpoint direction (in/out).
- * @return Error code.
- */
-int usb_pipe_initialize(usb_pipe_t *pipe,
-    usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
-    usb_transfer_type_t transfer_type, size_t max_packet_size,
-    usb_direction_t direction)
-{
-	assert(pipe);
-	assert(connection);
-
-	fibril_mutex_initialize(&pipe->guard);
-	pipe->wire = connection;
-	pipe->hc_phone = -1;
-	fibril_mutex_initialize(&pipe->hc_phone_mutex);
-	pipe->endpoint_no = endpoint_no;
-	pipe->transfer_type = transfer_type;
-	pipe->max_packet_size = max_packet_size;
-	pipe->direction = direction;
-	pipe->refcount = 0;
-	pipe->refcount_soft = 0;
-	pipe->auto_reset_halt = false;
-
-	return EOK;
-}
-
-
-/** Initialize USB endpoint pipe as the default zero control pipe.
- *
- * @param pipe Endpoint pipe to be initialized.
- * @param connection Connection to the USB device backing this pipe (the wire).
- * @return Error code.
- */
-int usb_pipe_initialize_default_control(usb_pipe_t *pipe,
-    usb_device_connection_t *connection)
-{
-	assert(pipe);
-	assert(connection);
-
-	int rc = usb_pipe_initialize(pipe, connection,
-	    0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,
-	    USB_DIRECTION_BOTH);
-
-	pipe->auto_reset_halt = true;
-
-	return rc;
-}
-
-/** Probe default control pipe for max packet size.
- *
- * The function tries to get the correct value of max packet size several
- * time before giving up.
- *
- * The session on the pipe shall not be started.
- *
- * @param pipe Default control pipe.
- * @return Error code.
- */
-int usb_pipe_probe_default_control(usb_pipe_t *pipe)
-{
-	assert(pipe);
-	assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
-
-	if ((pipe->direction != USB_DIRECTION_BOTH) ||
-	    (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
-	    (pipe->endpoint_no != 0)) {
-		return EINVAL;
-	}
-
-#define TRY_LOOP(attempt_var) \
-	for (attempt_var = 0; attempt_var < 3; attempt_var++)
-
-	size_t failed_attempts;
-	int rc;
-
-	usb_pipe_start_long_transfer(pipe);
-
-	uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
-	size_t transferred_size;
-	TRY_LOOP(failed_attempts) {
-		rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
-		    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
-		    0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE,
-		    &transferred_size);
-		if (rc == EOK) {
-			if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) {
-				rc = ELIMIT;
-				continue;
-			}
-			break;
-		}
-	}
-	usb_pipe_end_long_transfer(pipe);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	pipe->max_packet_size
-	    = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
-
-	return EOK;
-}
-
-/** Register endpoint with the host controller.
- *
- * @param pipe Pipe to be registered.
- * @param interval Polling interval.
- * @param hc_connection Connection to the host controller (must be opened).
- * @return Error code.
- */
-int usb_pipe_register(usb_pipe_t *pipe,
-    unsigned int interval,
-    usb_hc_connection_t *hc_connection)
-{
-	return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1,
-	    interval, hc_connection);
-}
-
-/** Register endpoint with a speed at the host controller.
- *
- * You will rarely need to use this function because it is needed only
- * if the registered endpoint is of address 0 and there is no other way
- * to tell speed of the device at address 0.
- *
- * @param pipe Pipe to be registered.
- * @param speed Speed of the device
- *	(invalid speed means use previously specified one).
- * @param interval Polling interval.
- * @param hc_connection Connection to the host controller (must be opened).
- * @return Error code.
- */
-int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed,
-    unsigned int interval,
-    usb_hc_connection_t *hc_connection)
-{
-	assert(pipe);
-	assert(hc_connection);
-
-	if (!usb_hc_connection_is_opened(hc_connection)) {
-		return EBADF;
-	}
-
-#define _PACK2(high, low) (((high) << 16) + (low))
-#define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
-
-	return async_req_4_0(hc_connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
-	    _PACK2(pipe->wire->address, pipe->endpoint_no),
-	    _PACK3(speed, pipe->transfer_type, pipe->direction),
-	    _PACK2(pipe->max_packet_size, interval));
-
-#undef _PACK2
-#undef _PACK3
-}
-
-/** Revert endpoint registration with the host controller.
- *
- * @param pipe Pipe to be unregistered.
- * @param hc_connection Connection to the host controller (must be opened).
- * @return Error code.
- */
-int usb_pipe_unregister(usb_pipe_t *pipe,
-    usb_hc_connection_t *hc_connection)
-{
-	assert(pipe);
-	assert(hc_connection);
-
-	if (!usb_hc_connection_is_opened(hc_connection)) {
-		return EBADF;
-	}
-
-	return async_req_4_0(hc_connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT,
-	    pipe->wire->address, pipe->endpoint_no, pipe->direction);
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/pipesio.c
===================================================================
--- uspace/lib/usb/src/pipesio.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,601 +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 libusb
- * @{
- */
-/** @file
- * Input and output functions (reads and writes) on endpoint pipes.
- *
- * Note on synchronousness of the operations: there is ABSOLUTELY NO
- * guarantee that a call to particular function will not trigger a fibril
- * switch.
- *
- * Note about the implementation: the transfer requests are always divided
- * into two functions.
- * The outer one does checking of input parameters (e.g. that session was
- * already started, buffers are not NULL etc), while the inner one
- * (with _no_checks suffix) does the actual IPC (it checks for IPC errors,
- * obviously).
- */
-#include <usb/usb.h>
-#include <usb/pipes.h>
-#include <errno.h>
-#include <assert.h>
-#include <usbhc_iface.h>
-#include <usb/request.h>
-#include "pipepriv.h"
-
-/** Request an in transfer, no checking of input parameters.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[out] buffer Buffer where to store the data.
- * @param[in] size Size of the buffer (in bytes).
- * @param[out] size_transfered Number of bytes that were actually transfered.
- * @return Error code.
- */
-static int usb_pipe_read_no_checks(usb_pipe_t *pipe,
-    void *buffer, size_t size, size_t *size_transfered)
-{
-	/*
-	 * Get corresponding IPC method.
-	 * In future, replace with static array of mappings
-	 * transfer type -> method.
-	 */
-	usbhc_iface_funcs_t ipc_method;
-	switch (pipe->transfer_type) {
-		case USB_TRANSFER_INTERRUPT:
-			ipc_method = IPC_M_USBHC_INTERRUPT_IN;
-			break;
-		case USB_TRANSFER_BULK:
-			ipc_method = IPC_M_USBHC_BULK_IN;
-			break;
-		default:
-			return ENOTSUP;
-	}
-
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-
-	/*
-	 * Make call identifying target USB device and type of transfer.
-	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
-	    pipe->wire->address, pipe->endpoint_no,
-	    NULL);
-	if (opening_request == 0) {
-		pipe_end_transaction(pipe);
-		return ENOMEM;
-	}
-
-	/*
-	 * Retrieve the data.
-	 */
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(pipe->hc_phone, buffer, size,
-	    &data_request_call);
-
-	/*
-	 * Since now on, someone else might access the backing phone
-	 * without breaking the transfer IPC protocol.
-	 */
-	pipe_end_transaction(pipe);
-
-	if (data_request == 0) {
-		/*
-		 * FIXME:
-		 * How to let the other side know that we want to abort?
-		 */
-		async_wait_for(opening_request, NULL);
-		return ENOMEM;
-	}
-
-	/*
-	 * Wait for the answer.
-	 */
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-
-	if (data_request_rc != EOK) {
-		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK) {
-			return (int) opening_request_rc;
-		} else {
-			return (int) data_request_rc;
-		}
-	}
-	if (opening_request_rc != EOK) {
-		return (int) opening_request_rc;
-	}
-
-	*size_transfered = IPC_GET_ARG2(data_request_call);
-
-	return EOK;
-}
-
-
-/** Request a read (in) transfer on an endpoint pipe.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[out] buffer Buffer where to store the data.
- * @param[in] size Size of the buffer (in bytes).
- * @param[out] size_transfered Number of bytes that were actually transfered.
- * @return Error code.
- */
-int usb_pipe_read(usb_pipe_t *pipe,
-    void *buffer, size_t size, size_t *size_transfered)
-{
-	assert(pipe);
-
-	if (buffer == NULL) {
-		return EINVAL;
-	}
-
-	if (size == 0) {
-		return EINVAL;
-	}
-
-	if (pipe->direction != USB_DIRECTION_IN) {
-		return EBADF;
-	}
-
-	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
-		return EBADF;
-	}
-
-	int rc;
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-
-	size_t act_size = 0;
-
-	rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size);
-
-	pipe_drop_ref(pipe);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	if (size_transfered != NULL) {
-		*size_transfered = act_size;
-	}
-
-	return EOK;
-}
-
-
-
-
-/** Request an out transfer, no checking of input parameters.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] buffer Buffer with data to transfer.
- * @param[in] size Size of the buffer (in bytes).
- * @return Error code.
- */
-static int usb_pipe_write_no_check(usb_pipe_t *pipe,
-    void *buffer, size_t size)
-{
-	/*
-	 * Get corresponding IPC method.
-	 * In future, replace with static array of mappings
-	 * transfer type -> method.
-	 */
-	usbhc_iface_funcs_t ipc_method;
-	switch (pipe->transfer_type) {
-		case USB_TRANSFER_INTERRUPT:
-			ipc_method = IPC_M_USBHC_INTERRUPT_OUT;
-			break;
-		case USB_TRANSFER_BULK:
-			ipc_method = IPC_M_USBHC_BULK_OUT;
-			break;
-		default:
-			return ENOTSUP;
-	}
-
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-
-	/*
-	 * Make call identifying target USB device and type of transfer.
-	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
-	    pipe->wire->address, pipe->endpoint_no,
-	    NULL);
-	if (opening_request == 0) {
-		pipe_end_transaction(pipe);
-		return ENOMEM;
-	}
-
-	/*
-	 * Send the data.
-	 */
-	int rc = async_data_write_start(pipe->hc_phone, buffer, size);
-
-	/*
-	 * Since now on, someone else might access the backing phone
-	 * without breaking the transfer IPC protocol.
-	 */
-	pipe_end_transaction(pipe);
-
-	if (rc != EOK) {
-		async_wait_for(opening_request, NULL);
-		return rc;
-	}
-
-	/*
-	 * Wait for the answer.
-	 */
-	sysarg_t opening_request_rc;
-	async_wait_for(opening_request, &opening_request_rc);
-
-	return (int) opening_request_rc;
-}
-
-/** Request a write (out) transfer on an endpoint pipe.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] buffer Buffer with data to transfer.
- * @param[in] size Size of the buffer (in bytes).
- * @return Error code.
- */
-int usb_pipe_write(usb_pipe_t *pipe,
-    void *buffer, size_t size)
-{
-	assert(pipe);
-
-	if (buffer == NULL) {
-		return EINVAL;
-	}
-
-	if (size == 0) {
-		return EINVAL;
-	}
-
-	if (pipe->direction != USB_DIRECTION_OUT) {
-		return EBADF;
-	}
-
-	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
-		return EBADF;
-	}
-
-	int rc;
-
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	rc = usb_pipe_write_no_check(pipe, buffer, size);
-
-	pipe_drop_ref(pipe);
-
-	return rc;
-}
-
-/** Try to clear endpoint halt of default control pipe.
- *
- * @param pipe Pipe for control endpoint zero.
- */
-static void clear_self_endpoint_halt(usb_pipe_t *pipe)
-{
-	assert(pipe != NULL);
-
-	if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) {
-		return;
-	}
-
-
-	/* Prevent indefinite recursion. */
-	pipe->auto_reset_halt = false;
-	usb_request_clear_endpoint_halt(pipe, 0);
-	pipe->auto_reset_halt = true;
-}
-
-
-/** Request a control read transfer, no checking of input parameters.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] setup_buffer Buffer with the setup packet.
- * @param[in] setup_buffer_size Size of the setup packet (in bytes).
- * @param[out] data_buffer Buffer for incoming data.
- * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
- * @param[out] data_transfered_size Number of bytes that were actually
- *                                  transfered during the DATA stage.
- * @return Error code.
- */
-static int usb_pipe_control_read_no_check(usb_pipe_t *pipe,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
-{
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-
-	/*
-	 * Make call identifying target USB device and control transfer type.
-	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
-	    pipe->wire->address, pipe->endpoint_no,
-	    NULL);
-	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-	/*
-	 * Send the setup packet.
-	 */
-	int rc = async_data_write_start(pipe->hc_phone,
-	    setup_buffer, setup_buffer_size);
-	if (rc != EOK) {
-		pipe_end_transaction(pipe);
-		async_wait_for(opening_request, NULL);
-		return rc;
-	}
-
-	/*
-	 * Retrieve the data.
-	 */
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(pipe->hc_phone,
-	    data_buffer, data_buffer_size,
-	    &data_request_call);
-
-	/*
-	 * Since now on, someone else might access the backing phone
-	 * without breaking the transfer IPC protocol.
-	 */
-	pipe_end_transaction(pipe);
-
-
-	if (data_request == 0) {
-		async_wait_for(opening_request, NULL);
-		return ENOMEM;
-	}
-
-	/*
-	 * Wait for the answer.
-	 */
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-
-	if (data_request_rc != EOK) {
-		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK) {
-			return (int) opening_request_rc;
-		} else {
-			return (int) data_request_rc;
-		}
-	}
-	if (opening_request_rc != EOK) {
-		return (int) opening_request_rc;
-	}
-
-	*data_transfered_size = IPC_GET_ARG2(data_request_call);
-
-	return EOK;
-}
-
-/** Request a control read transfer on an endpoint pipe.
- *
- * This function encapsulates all three stages of a control transfer.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] setup_buffer Buffer with the setup packet.
- * @param[in] setup_buffer_size Size of the setup packet (in bytes).
- * @param[out] data_buffer Buffer for incoming data.
- * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
- * @param[out] data_transfered_size Number of bytes that were actually
- *                                  transfered during the DATA stage.
- * @return Error code.
- */
-int usb_pipe_control_read(usb_pipe_t *pipe,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
-{
-	assert(pipe);
-
-	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
-		return EINVAL;
-	}
-
-	if ((data_buffer == NULL) || (data_buffer_size == 0)) {
-		return EINVAL;
-	}
-
-	if ((pipe->direction != USB_DIRECTION_BOTH)
-	    || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
-		return EBADF;
-	}
-
-	int rc;
-
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	size_t act_size = 0;
-	rc = usb_pipe_control_read_no_check(pipe,
-	    setup_buffer, setup_buffer_size,
-	    data_buffer, data_buffer_size, &act_size);
-
-	if (rc == ESTALL) {
-		clear_self_endpoint_halt(pipe);
-	}
-
-	pipe_drop_ref(pipe);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	if (data_transfered_size != NULL) {
-		*data_transfered_size = act_size;
-	}
-
-	return EOK;
-}
-
-
-/** Request a control write transfer, no checking of input parameters.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] setup_buffer Buffer with the setup packet.
- * @param[in] setup_buffer_size Size of the setup packet (in bytes).
- * @param[in] data_buffer Buffer with data to be sent.
- * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
- * @return Error code.
- */
-static int usb_pipe_control_write_no_check(usb_pipe_t *pipe,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size)
-{
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-
-	/*
-	 * Make call identifying target USB device and control transfer type.
-	 */
-	aid_t opening_request = async_send_4(pipe->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
-	    pipe->wire->address, pipe->endpoint_no,
-	    data_buffer_size,
-	    NULL);
-	if (opening_request == 0) {
-		pipe_end_transaction(pipe);
-		return ENOMEM;
-	}
-
-	/*
-	 * Send the setup packet.
-	 */
-	int rc = async_data_write_start(pipe->hc_phone,
-	    setup_buffer, setup_buffer_size);
-	if (rc != EOK) {
-		pipe_end_transaction(pipe);
-		async_wait_for(opening_request, NULL);
-		return rc;
-	}
-
-	/*
-	 * Send the data (if any).
-	 */
-	if (data_buffer_size > 0) {
-		rc = async_data_write_start(pipe->hc_phone,
-		    data_buffer, data_buffer_size);
-
-		/* All data sent, pipe can be released. */
-		pipe_end_transaction(pipe);
-
-		if (rc != EOK) {
-			async_wait_for(opening_request, NULL);
-			return rc;
-		}
-	} else {
-		/* No data to send, we can release the pipe for others. */
-		pipe_end_transaction(pipe);
-	}
-
-	/*
-	 * Wait for the answer.
-	 */
-	sysarg_t opening_request_rc;
-	async_wait_for(opening_request, &opening_request_rc);
-
-	return (int) opening_request_rc;
-}
-
-/** Request a control write transfer on an endpoint pipe.
- *
- * This function encapsulates all three stages of a control transfer.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] setup_buffer Buffer with the setup packet.
- * @param[in] setup_buffer_size Size of the setup packet (in bytes).
- * @param[in] data_buffer Buffer with data to be sent.
- * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
- * @return Error code.
- */
-int usb_pipe_control_write(usb_pipe_t *pipe,
-    void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size)
-{
-	assert(pipe);
-
-	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
-		return EINVAL;
-	}
-
-	if ((data_buffer == NULL) && (data_buffer_size > 0)) {
-		return EINVAL;
-	}
-
-	if ((data_buffer != NULL) && (data_buffer_size == 0)) {
-		return EINVAL;
-	}
-
-	if ((pipe->direction != USB_DIRECTION_BOTH)
-	    || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
-		return EBADF;
-	}
-
-	int rc;
-
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	rc = usb_pipe_control_write_no_check(pipe,
-	    setup_buffer, setup_buffer_size, data_buffer, data_buffer_size);
-
-	if (rc == ESTALL) {
-		clear_self_endpoint_halt(pipe);
-	}
-
-	pipe_drop_ref(pipe);
-
-	return rc;
-}
-
-
-/**
- * @}
- */
Index: pace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,442 +1,0 @@
-/*
- * 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 libusb
- * @{
- */
-/** @file
- * Functions for recognition of attached devices.
- */
-#include <sys/types.h>
-#include <fibril_synch.h>
-#include <usb/pipes.h>
-#include <usb/recognise.h>
-#include <usb/ddfiface.h>
-#include <usb/request.h>
-#include <usb/classes/classes.h>
-#include <stdio.h>
-#include <errno.h>
-#include <assert.h>
-
-/** Index to append after device name for uniqueness. */
-static size_t device_name_index = 0;
-/** Mutex guard for device_name_index. */
-static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
-
-/** DDF operations of child devices. */
-ddf_dev_ops_t child_ops = {
-	.interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
-};
-
-/** Get integer part from BCD coded number. */
-#define BCD_INT(a) (((unsigned int)(a)) / 256)
-/** Get fraction part from BCD coded number (as an integer, no less). */
-#define BCD_FRAC(a) (((unsigned int)(a)) % 256)
-
-/** Format for BCD coded number to be used in printf. */
-#define BCD_FMT "%x.%x"
-/** Arguments to printf for BCD coded number. */
-#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
-
-/* FIXME: make this dynamic */
-#define MATCH_STRING_MAX 256
-
-/** Add formatted match id.
- *
- * @param matches List of match ids where to add to.
- * @param score Score of the match.
- * @param format Printf-like format
- * @return Error code.
- */
-static int usb_add_match_id(match_id_list_t *matches, int score,
-    const char *format, ...)
-{
-	char *match_str = NULL;
-	match_id_t *match_id = NULL;
-	int rc;
-	
-	match_str = malloc(MATCH_STRING_MAX + 1);
-	if (match_str == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-
-	/*
-	 * FIXME: replace with dynamic allocation of exact size
-	 */
-	va_list args;
-	va_start(args, format	);
-	vsnprintf(match_str, MATCH_STRING_MAX, format, args);
-	match_str[MATCH_STRING_MAX] = 0;
-	va_end(args);
-
-	match_id = create_match_id();
-	if (match_id == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-
-	match_id->id = match_str;
-	match_id->score = score;
-	add_match_id(matches, match_id);
-
-	return EOK;
-	
-failure:
-	if (match_str != NULL) {
-		free(match_str);
-	}
-	if (match_id != NULL) {
-		match_id->id = NULL;
-		delete_match_id(match_id);
-	}
-	
-	return rc;
-}
-
-/** Add match id to list or return with error code.
- *
- * @param match_ids List of match ids.
- * @param score Match id score.
- * @param format Format of the matching string
- * @param ... Arguments for the format.
- */
-#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
-	do { \
-		int __rc = usb_add_match_id((match_ids), (score), \
-		    format, ##__VA_ARGS__); \
-		if (__rc != EOK) { \
-			return __rc; \
-		} \
-	} while (0)
-
-/** Create device match ids based on its interface.
- *
- * @param[in] desc_device Device descriptor.
- * @param[in] desc_interface Interface descriptor.
- * @param[out] matches Initialized list of match ids.
- * @return Error code (the two mentioned are not the only ones).
- * @retval EINVAL Invalid input parameters (expects non NULL pointers).
- * @retval ENOENT Device class is not "use interface".
- */
-int usb_device_create_match_ids_from_interface(
-    const usb_standard_device_descriptor_t *desc_device,
-    const usb_standard_interface_descriptor_t *desc_interface,
-    match_id_list_t *matches)
-{
-	if (desc_interface == NULL) {
-		return EINVAL;
-	}
-	if (matches == NULL) {
-		return EINVAL;
-	}
-
-	if (desc_interface->interface_class == USB_CLASS_USE_INTERFACE) {
-		return ENOENT;
-	}
-
-	const char *classname = usb_str_class(desc_interface->interface_class);
-	assert(classname != NULL);
-
-#define IFACE_PROTOCOL_FMT "interface&class=%s&subclass=0x%02x&protocol=0x%02x"
-#define IFACE_PROTOCOL_ARGS classname, desc_interface->interface_subclass, \
-    desc_interface->interface_protocol
-
-#define IFACE_SUBCLASS_FMT "interface&class=%s&subclass=0x%02x"
-#define IFACE_SUBCLASS_ARGS classname, desc_interface->interface_subclass
-
-#define IFACE_CLASS_FMT "interface&class=%s"
-#define IFACE_CLASS_ARGS classname
-
-#define VENDOR_RELEASE_FMT "vendor=0x%04x&product=0x%04x&release=" BCD_FMT
-#define VENDOR_RELEASE_ARGS desc_device->vendor_id, desc_device->product_id, \
-    BCD_ARGS(desc_device->device_version)
-
-#define VENDOR_PRODUCT_FMT "vendor=0x%04x&product=0x%04x"
-#define VENDOR_PRODUCT_ARGS desc_device->vendor_id, desc_device->product_id
-
-#define VENDOR_ONLY_FMT "vendor=0x%04x"
-#define VENDOR_ONLY_ARGS desc_device->vendor_id
-
-	/*
-	 * If the vendor is specified, create match ids with vendor with
-	 * higher score.
-	 * Then the same ones without the vendor part.
-	 */
-	if ((desc_device != NULL) && (desc_device->vendor_id != 0)) {
-		/* First, interface matches with device release number. */
-		ADD_MATCHID_OR_RETURN(matches, 250,
-		    "usb&" VENDOR_RELEASE_FMT "&" IFACE_PROTOCOL_FMT,
-		    VENDOR_RELEASE_ARGS, IFACE_PROTOCOL_ARGS);
-		ADD_MATCHID_OR_RETURN(matches, 240,
-		    "usb&" VENDOR_RELEASE_FMT "&" IFACE_SUBCLASS_FMT,
-		    VENDOR_RELEASE_ARGS, IFACE_SUBCLASS_ARGS);
-		ADD_MATCHID_OR_RETURN(matches, 230,
-		    "usb&" VENDOR_RELEASE_FMT "&" IFACE_CLASS_FMT,
-		    VENDOR_RELEASE_ARGS, IFACE_CLASS_ARGS);
-
-		/* Next, interface matches without release number. */
-		ADD_MATCHID_OR_RETURN(matches, 220,
-		    "usb&" VENDOR_PRODUCT_FMT "&" IFACE_PROTOCOL_FMT,
-		    VENDOR_PRODUCT_ARGS, IFACE_PROTOCOL_ARGS);
-		ADD_MATCHID_OR_RETURN(matches, 210,
-		    "usb&" VENDOR_PRODUCT_FMT "&" IFACE_SUBCLASS_FMT,
-		    VENDOR_PRODUCT_ARGS, IFACE_SUBCLASS_ARGS);
-		ADD_MATCHID_OR_RETURN(matches, 200,
-		    "usb&" VENDOR_PRODUCT_FMT "&" IFACE_CLASS_FMT,
-		    VENDOR_PRODUCT_ARGS, IFACE_CLASS_ARGS);
-
-		/* Finally, interface matches with only vendor. */
-		ADD_MATCHID_OR_RETURN(matches, 190,
-		    "usb&" VENDOR_ONLY_FMT "&" IFACE_PROTOCOL_FMT,
-		    VENDOR_ONLY_ARGS, IFACE_PROTOCOL_ARGS);
-		ADD_MATCHID_OR_RETURN(matches, 180,
-		    "usb&" VENDOR_ONLY_FMT "&" IFACE_SUBCLASS_FMT,
-		    VENDOR_ONLY_ARGS, IFACE_SUBCLASS_ARGS);
-		ADD_MATCHID_OR_RETURN(matches, 170,
-		    "usb&" VENDOR_ONLY_FMT "&" IFACE_CLASS_FMT,
-		    VENDOR_ONLY_ARGS, IFACE_CLASS_ARGS);
-	}
-
-	/* Now, the same but without any vendor specification. */
-	ADD_MATCHID_OR_RETURN(matches, 160,
-	    "usb&" IFACE_PROTOCOL_FMT,
-	    IFACE_PROTOCOL_ARGS);
-	ADD_MATCHID_OR_RETURN(matches, 150,
-	    "usb&" IFACE_SUBCLASS_FMT,
-	    IFACE_SUBCLASS_ARGS);
-	ADD_MATCHID_OR_RETURN(matches, 140,
-	    "usb&" IFACE_CLASS_FMT,
-	    IFACE_CLASS_ARGS);
-
-#undef IFACE_PROTOCOL_FMT
-#undef IFACE_PROTOCOL_ARGS
-#undef IFACE_SUBCLASS_FMT
-#undef IFACE_SUBCLASS_ARGS
-#undef IFACE_CLASS_FMT
-#undef IFACE_CLASS_ARGS
-#undef VENDOR_RELEASE_FMT
-#undef VENDOR_RELEASE_ARGS
-#undef VENDOR_PRODUCT_FMT
-#undef VENDOR_PRODUCT_ARGS
-#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;
-}
-
-/** Create DDF match ids from USB device descriptor.
- *
- * @param matches List of match ids to extend.
- * @param device_descriptor Device descriptor returned by given device.
- * @return Error code.
- */
-int usb_device_create_match_ids_from_device_descriptor(
-    const usb_standard_device_descriptor_t *device_descriptor,
-    match_id_list_t *matches)
-{
-	/*
-	 * Unless the vendor id is 0, the pair idVendor-idProduct
-	 * quite uniquely describes the device.
-	 */
-	if (device_descriptor->vendor_id != 0) {
-		/* First, with release number. */
-		ADD_MATCHID_OR_RETURN(matches, 100,
-		    "usb&vendor=0x%04x&product=0x%04x&release=" BCD_FMT,
-		    (int) device_descriptor->vendor_id,
-		    (int) device_descriptor->product_id,
-		    BCD_ARGS(device_descriptor->device_version));
-		
-		/* Next, without release number. */
-		ADD_MATCHID_OR_RETURN(matches, 90,
-		    "usb&vendor=0x%04x&product=0x%04x",
-		    (int) device_descriptor->vendor_id,
-		    (int) device_descriptor->product_id);
-	}	
-
-	/*
-	 * If the device class points to interface we skip adding
-	 * class directly but we add a multi interface device.
-	 */
-	if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
-		ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
-		    usb_str_class(device_descriptor->device_class));
-	} else {
-		ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid");
-	}
-	
-	/* As a last resort, try fallback driver. */
-	ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback");
-
-	return EOK;
-}
-
-
-/** Create match ids describing attached device.
- *
- * @warning The list of match ids @p matches may change even when
- * function exits with error.
- *
- * @param ctrl_pipe Control pipe to given device (session must be already
- *	started).
- * @param matches Initialized list of match ids.
- * @return Error code.
- */
-int usb_device_create_match_ids(usb_pipe_t *ctrl_pipe,
-    match_id_list_t *matches)
-{
-	int rc;
-	/*
-	 * Retrieve device descriptor and add matches from it.
-	 */
-	usb_standard_device_descriptor_t device_descriptor;
-
-	rc = usb_request_get_device_descriptor(ctrl_pipe, &device_descriptor);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	rc = usb_device_create_match_ids_from_device_descriptor(
-	    &device_descriptor, matches);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	return EOK;
-}
-
-/** Probe for device kind and register it in devman.
- *
- * @param[in] address Address of the (unknown) attached device.
- * @param[in] hc_handle Handle of the host controller.
- * @param[in] parent Parent device.
- * @param[out] child_handle Handle of the child device.
- * @param[in] dev_ops Child device ops.
- * @param[in] dev_data Arbitrary pointer to be stored in the child
- *	as @c driver_data.
- * @param[out] child_fun Storage where pointer to allocated child function
- *	will be written.
- * @return Error code.
- */
-int usb_device_register_child_in_devman(usb_address_t address,
-    devman_handle_t hc_handle,
-    ddf_dev_t *parent, devman_handle_t *child_handle,
-    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
-{
-	size_t this_device_name_index;
-
-	fibril_mutex_lock(&device_name_index_mutex);
-	this_device_name_index = device_name_index;
-	device_name_index++;
-	fibril_mutex_unlock(&device_name_index_mutex);
-
-	ddf_fun_t *child = NULL;
-	char *child_name = NULL;
-	int rc;
-	usb_device_connection_t dev_connection;
-	usb_pipe_t ctrl_pipe;
-
-	rc = usb_device_connection_initialize(&dev_connection, hc_handle, address);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	rc = usb_pipe_initialize_default_control(&ctrl_pipe,
-	    &dev_connection);
-	if (rc != EOK) {
-		goto failure;
-	}
-	rc = usb_pipe_probe_default_control(&ctrl_pipe);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	/*
-	 * TODO: Once the device driver framework support persistent
-	 * naming etc., something more descriptive could be created.
-	 */
-	rc = asprintf(&child_name, "usb%02zu_a%d",
-	    this_device_name_index, address);
-	if (rc < 0) {
-		goto failure;
-	}
-
-	child = ddf_fun_create(parent, fun_inner, child_name);
-	if (child == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-
-	if (dev_ops != NULL) {
-		child->ops = dev_ops;
-	} else {
-		child->ops = &child_ops;
-	}
-
-	child->driver_data = dev_data;
-
-	rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	rc = ddf_fun_bind(child);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	if (child_handle != NULL) {
-		*child_handle = child->handle;
-	}
-
-	if (child_fun != NULL) {
-		*child_fun = child;
-	}
-
-	return EOK;
-
-failure:
-	if (child != NULL) {
-		child->name = NULL;
-		/* This takes care of match_id deallocation as well. */
-		ddf_fun_destroy(child);
-	}
-	if (child_name != NULL) {
-		free(child_name);
-	}
-
-	return rc;
-}
-
-
-/**
- * @}
- */
Index: pace/lib/usb/src/request.c
===================================================================
--- uspace/lib/usb/src/request.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,889 +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 libusb
- * @{
- */
-/** @file
- * Standard USB requests (implementation).
- */
-#include <usb/request.h>
-#include <errno.h>
-#include <assert.h>
-#include <usb/debug.h>
-
-#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
-
-/** Generic wrapper for SET requests using standard control request format.
- *
- * @see usb_pipe_control_write
- *
- * @param pipe Pipe used for the communication.
- * @param request_type Request type (standard/class/vendor).
- * @param recipient Request recipient (e.g. device or endpoint).
- * @param request Actual request (e.g. GET_DESCRIPTOR).
- * @param value Value of @c wValue field of setup packet
- * 	(must be in USB endianness).
- * @param index Value of @c wIndex field of setup packet
- * 	(must be in USB endianness).
- * @param data Data to be sent during DATA stage
- * 	(expected to be in USB endianness).
- * @param data_size Size of the @p data buffer (in native endianness).
- * @return Error code.
- * @retval EBADMEM @p pipe is NULL.
- * @retval EBADMEM @p data is NULL and @p data_size is not zero.
- * @retval ERANGE Data buffer too large.
- */
-int usb_control_request_set(usb_pipe_t *pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint8_t request,
-    uint16_t value, uint16_t index,
-    void *data, size_t data_size)
-{
-	if (pipe == NULL) {
-		return EBADMEM;
-	}
-
-	if (data_size > MAX_DATA_LENGTH) {
-		return ERANGE;
-	}
-
-	if ((data_size > 0) && (data == NULL)) {
-		return EBADMEM;
-	}
-
-	/*
-	 * TODO: check that @p request_type and @p recipient are
-	 * within ranges.
-	 */
-
-	usb_device_request_setup_packet_t setup_packet;
-	setup_packet.request_type = (request_type << 5) | recipient;
-	setup_packet.request = request;
-	setup_packet.value = value;
-	setup_packet.index = index;
-	setup_packet.length = (uint16_t) data_size;
-
-	int rc = usb_pipe_control_write(pipe,
-	    &setup_packet, sizeof(setup_packet),
-	    data, data_size);
-
-	return rc;
-}
-
- /** Generic wrapper for GET requests using standard control request format.
-  *
-  * @see usb_pipe_control_read
-  *
-  * @param pipe Pipe used for the communication.
-  * @param request_type Request type (standard/class/vendor).
-  * @param recipient Request recipient (e.g. device or endpoint).
-  * @param request Actual request (e.g. GET_DESCRIPTOR).
-  * @param value Value of @c wValue field of setup packet
-  * 	(must be in USB endianness).
-  * @param index Value of @c wIndex field of setup packet
-  *	(must be in USB endianness).
-  * @param data Buffer where to store data accepted during the DATA stage.
-  *	(they will come in USB endianness).
-  * @param data_size Size of the @p data buffer
-  * 	(in native endianness).
-  * @param actual_data_size Actual size of transfered data
-  * 	(in native endianness).
-  * @return Error code.
-  * @retval EBADMEM @p pipe is NULL.
-  * @retval EBADMEM @p data is NULL and @p data_size is not zero.
-  * @retval ERANGE Data buffer too large.
-  */
-int usb_control_request_get(usb_pipe_t *pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint8_t request,
-    uint16_t value, uint16_t index,
-    void *data, size_t data_size, size_t *actual_data_size)
-{
-	if (pipe == NULL) {
-		return EBADMEM;
-	}
-
-	if (data_size > MAX_DATA_LENGTH) {
-		return ERANGE;
-	}
-
-	if ((data_size > 0) && (data == NULL)) {
-		return EBADMEM;
-	}
-
-	/*
-	 * TODO: check that @p request_type and @p recipient are
-	 * within ranges.
-	 */
-
-	usb_device_request_setup_packet_t setup_packet;
-	setup_packet.request_type = 128 | (request_type << 5) | recipient;
-	setup_packet.request = request;
-	setup_packet.value = value;
-	setup_packet.index = index;
-	setup_packet.length = (uint16_t) data_size;
-
-	int rc = usb_pipe_control_read(pipe,
-	    &setup_packet, sizeof(setup_packet),
-	    data, data_size, actual_data_size);
-
-	return rc;
-}
-
-/** Retrieve status of a USB device.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] index Recipient index (in native endianness).
- * @param[in] recipient Recipient of the GET_STATUS request.
- * @param[out] status Recipient status (in native endianness).
- * @return Error code.
- */
-int usb_request_get_status(usb_pipe_t *pipe,
-    usb_request_recipient_t recipient, uint16_t index,
-    uint16_t *status)
-{
-	if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) {
-		return EINVAL;
-	}
-
-	if (status == NULL) {
-		return EBADMEM;
-	}
-
-	uint16_t status_usb_endianess;
-	size_t data_transfered_size;
-	int rc = usb_control_request_get(pipe, USB_REQUEST_TYPE_STANDARD,
-	    recipient, USB_DEVREQ_GET_STATUS, 0, uint16_host2usb(index),
-	    &status_usb_endianess, 2, &data_transfered_size);
-	if (rc != EOK) {
-		return rc;
-	}
-	if (data_transfered_size != 2) {
-		return ELIMIT;
-	}
-
-	*status = uint16_usb2host(status_usb_endianess);
-
-	return EOK;
-}
-
-/** Clear or disable specific device feature.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] request_type Request type (standard/class/vendor).
- * @param[in] recipient Recipient of the CLEAR_FEATURE request.
- * @param[in] feature_selector Feature selector (in native endianness).
- * @param[in] index Recipient index (in native endianness).
- * @return Error code.
- */
-int usb_request_clear_feature(usb_pipe_t *pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint16_t feature_selector, uint16_t index)
-{
-	if (request_type == USB_REQUEST_TYPE_STANDARD) {
-		if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
-		    && (index != 0)) {
-			return EINVAL;
-		}
-	}
-
-	int rc = usb_control_request_set(pipe, request_type, recipient,
-	    USB_DEVREQ_CLEAR_FEATURE,
-	    uint16_host2usb(feature_selector), uint16_host2usb(index),
-	    NULL, 0);
-
-	return rc;
-}
-
-/** Set or enable specific device feature.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] request_type Request type (standard/class/vendor).
- * @param[in] recipient Recipient of the SET_FEATURE request.
- * @param[in] feature_selector Feature selector (in native endianness).
- * @param[in] index Recipient index (in native endianness).
- * @return Error code.
- */
-int usb_request_set_feature(usb_pipe_t *pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint16_t feature_selector, uint16_t index)
-{
-	if (request_type == USB_REQUEST_TYPE_STANDARD) {
-		if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
-		    && (index != 0)) {
-			return EINVAL;
-		}
-	}
-
-	int rc = usb_control_request_set(pipe, request_type, recipient,
-	    USB_DEVREQ_SET_FEATURE,
-	    uint16_host2usb(feature_selector), uint16_host2usb(index),
-	    NULL, 0);
-
-	return rc;
-}
-
-/** Change address of connected device.
- * This function automatically updates the backing connection to point to
- * the new address.
- *
- * @param pipe Control endpoint pipe (session must be already started).
- * @param new_address New USB address to be set (in native endianness).
- * @return Error code.
- */
-int usb_request_set_address(usb_pipe_t *pipe,
-    usb_address_t new_address)
-{
-	if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
-		return EINVAL;
-	}
-
-	uint16_t addr = uint16_host2usb((uint16_t)new_address);
-
-	int rc = usb_control_request_set(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DEVREQ_SET_ADDRESS,
-	    addr, 0,
-	    NULL, 0);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	assert(pipe->wire != NULL);
-	/* TODO: prevent other from accessing wire now. */
-	pipe->wire->address = new_address;
-
-	return EOK;
-}
-
-/** Retrieve USB descriptor of a USB device.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] request_type Request type (standard/class/vendor).
- * @param[in] recipient Request recipient (device/interface/endpoint).
- * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
- * @param[in] descriptor_index Descriptor index.
- * @param[in] language Language index.
- * @param[out] buffer Buffer where to store the retrieved descriptor.
- * @param[in] size Size of the @p buffer.
- * @param[out] actual_size Number of bytes actually transferred.
- * @return Error code.
- */
-int usb_request_get_descriptor(usb_pipe_t *pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint8_t descriptor_type, uint8_t descriptor_index,
-    uint16_t language,
-    void *buffer, size_t size, size_t *actual_size)
-{
-	if (buffer == NULL) {
-		return EBADMEM;
-	}
-	if (size == 0) {
-		return EINVAL;
-	}
-
-	uint16_t wValue = descriptor_index | (descriptor_type << 8);
-
-	return usb_control_request_get(pipe,
-	    request_type, recipient,
-	    USB_DEVREQ_GET_DESCRIPTOR,
-	    wValue, language,
-	    buffer, size, actual_size);
-}
-
-/** Retrieve USB descriptor, allocate space for it.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] request_type Request type (standard/class/vendor).
- * @param[in] recipient Request recipient (device/interface/endpoint).
- * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
- * @param[in] descriptor_index Descriptor index.
- * @param[in] language Language index.
- * @param[out] buffer_ptr Where to store pointer to allocated buffer.
- * @param[out] buffer_size Where to store the size of the descriptor.
- * @return
- */
-int usb_request_get_descriptor_alloc(usb_pipe_t * pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint8_t descriptor_type, uint8_t descriptor_index,
-    uint16_t language,
-    void **buffer_ptr, size_t *buffer_size)
-{
-	if (buffer_ptr == NULL) {
-		return EBADMEM;
-	}
-
-	int rc;
-
-	/*
-	 * Get only first byte to retrieve descriptor length.
-	 */
-	uint8_t tmp_buffer[1];
-	size_t bytes_transfered;
-	rc = usb_request_get_descriptor(pipe, request_type, recipient,
-	    descriptor_type, descriptor_index, language,
-	    &tmp_buffer, 1, &bytes_transfered);
-	if (rc != EOK) {
-		return rc;
-	}
-	if (bytes_transfered != 1) {
-		/* FIXME: some better error code? */
-		return ESTALL;
-	}
-
-	size_t size = tmp_buffer[0];
-	if (size == 0) {
-		/* FIXME: some better error code? */
-		return ESTALL;
-	}
-
-	/*
-	 * Allocate buffer and get the descriptor again.
-	 */
-	void *buffer = malloc(size);
-	if (buffer == NULL) {
-		return ENOMEM;
-	}
-
-	rc = usb_request_get_descriptor(pipe, request_type, recipient,
-	    descriptor_type, descriptor_index, language,
-	    buffer, size, &bytes_transfered);
-	if (rc != EOK) {
-		free(buffer);
-		return rc;
-	}
-	if (bytes_transfered != size) {
-		free(buffer);
-		/* FIXME: some better error code? */
-		return ESTALL;
-	}
-
-	*buffer_ptr = buffer;
-	if (buffer_size != NULL) {
-		*buffer_size = size;
-	}
-
-	return EOK;
-}
-
-/** Retrieve standard device descriptor of a USB device.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[out] descriptor Storage for the device descriptor.
- * @return Error code.
- */
-int usb_request_get_device_descriptor(usb_pipe_t *pipe,
-    usb_standard_device_descriptor_t *descriptor)
-{
-	if (descriptor == NULL) {
-		return EBADMEM;
-	}
-
-	size_t actually_transferred = 0;
-	usb_standard_device_descriptor_t descriptor_tmp;
-	int rc = usb_request_get_descriptor(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 
-	    USB_DESCTYPE_DEVICE, 0, 0,
-	    &descriptor_tmp, sizeof(descriptor_tmp),
-	    &actually_transferred);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/* Verify that all data has been transferred. */
-	if (actually_transferred < sizeof(descriptor_tmp)) {
-		return ELIMIT;
-	}
-
-	/* Everything is okay, copy the descriptor. */
-	memcpy(descriptor, &descriptor_tmp,
-	    sizeof(descriptor_tmp));
-
-	return EOK;
-}
-
-/** Retrieve configuration descriptor of a USB device.
- *
- * The function does not retrieve additional data binded with configuration
- * descriptor (such as its interface and endpoint descriptors) - use
- * usb_request_get_full_configuration_descriptor() instead.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] index Descriptor index.
- * @param[out] descriptor Storage for the device descriptor.
- * @return Error code.
- */
-int usb_request_get_bare_configuration_descriptor(usb_pipe_t *pipe,
-    int index, usb_standard_configuration_descriptor_t *descriptor)
-{
-	if (descriptor == NULL) {
-		return EBADMEM;
-	}
-
-	if ((index < 0) || (index > 0xFF)) {
-		return ERANGE;
-	}
-
-	size_t actually_transferred = 0;
-	usb_standard_configuration_descriptor_t descriptor_tmp;
-	int rc = usb_request_get_descriptor(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DESCTYPE_CONFIGURATION, index, 0,
-	    &descriptor_tmp, sizeof(descriptor_tmp),
-	    &actually_transferred);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/* Verify that all data has been transferred. */
-	if (actually_transferred < sizeof(descriptor_tmp)) {
-		return ELIMIT;
-	}
-
-	/* Everything is okay, copy the descriptor. */
-	memcpy(descriptor, &descriptor_tmp,
-	    sizeof(descriptor_tmp));
-
-	return EOK;
-}
-
-/** Retrieve full configuration descriptor of a USB device.
- *
- * @warning The @p buffer might be touched (i.e. its contents changed)
- * even when error occurs.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] index Descriptor index.
- * @param[out] descriptor Storage for the device descriptor.
- * @param[in] descriptor_size Size of @p descriptor buffer.
- * @param[out] actual_size Number of bytes actually transferred.
- * @return Error code.
- */
-int usb_request_get_full_configuration_descriptor(usb_pipe_t *pipe,
-    int index, void *descriptor, size_t descriptor_size, size_t *actual_size)
-{
-	if ((index < 0) || (index > 0xFF)) {
-		return ERANGE;
-	}
-
-	return usb_request_get_descriptor(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DESCTYPE_CONFIGURATION, index, 0,
-	    descriptor, descriptor_size, actual_size);
-}
-
-/** Retrieve full configuration descriptor, allocate space for it.
- *
- * The function takes care that full configuration descriptor is returned
- * (i.e. the function will fail when less data then descriptor.totalLength
- * is returned).
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] index Configuration index.
- * @param[out] descriptor_ptr Where to store pointer to allocated buffer.
- * @param[out] descriptor_size Where to store the size of the descriptor.
- * @return Error code.
- */
-int usb_request_get_full_configuration_descriptor_alloc(
-    usb_pipe_t *pipe, int index,
-    void **descriptor_ptr, size_t *descriptor_size)
-{
-	int rc;
-
-	if (descriptor_ptr == NULL) {
-		return EBADMEM;
-	}
-
-	usb_standard_configuration_descriptor_t bare_config;
-	rc = usb_request_get_bare_configuration_descriptor(pipe, index,
-	    &bare_config);
-	if (rc != EOK) {
-		return rc;
-	}
-	if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {
-		return ENOENT;
-	}
-	if (bare_config.total_length < sizeof(bare_config)) {
-		return ELIMIT;
-	}
-
-	void *buffer = malloc(bare_config.total_length);
-	if (buffer == NULL) {
-		return ENOMEM;
-	}
-
-	size_t transferred = 0;
-	rc = usb_request_get_full_configuration_descriptor(pipe, index,
-	    buffer, bare_config.total_length, &transferred);
-	if (rc != EOK) {
-		free(buffer);
-		return rc;
-	}
-
-	if (transferred != bare_config.total_length) {
-		free(buffer);
-		return ELIMIT;
-	}
-
-	/* Everything looks okay, copy the pointers. */
-
-	*descriptor_ptr = buffer;
-
-	if (descriptor_size != NULL) {
-		*descriptor_size = bare_config.total_length;
-	}
-
-	return EOK;
-}
-
-/** Update existing or add new USB descriptor to a USB device.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] request_type Request type (standard/class/vendor).
- * @param[in] recipient Request recipient (device/interface/endpoint).
- * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
- * @param[in] descriptor_index Descriptor index.
- * @param[in] language Language index (in native endianness).
- * @param[in] buffer Buffer with the new descriptor (in USB endianness).
- * @param[in] size Size of the @p buffer in bytes (in native endianness).
- * @return Error code.
- */
-int usb_request_set_descriptor(usb_pipe_t *pipe,
-    usb_request_type_t request_type, usb_request_recipient_t recipient,
-    uint8_t descriptor_type, uint8_t descriptor_index,
-    uint16_t language,
-    void *buffer, size_t size)
-{
-	if (buffer == NULL) {
-		return EBADMEM;
-	}
-	if (size == 0) {
-		return EINVAL;
-	}
-
-	/* FIXME: proper endianness. */
-	uint16_t wValue = descriptor_index | (descriptor_type << 8);
-
-	return usb_control_request_set(pipe,
-	    request_type, recipient,
-	    USB_DEVREQ_SET_DESCRIPTOR,
-	    wValue, language,
-	    buffer, size);
-}
-
-/** Get current configuration value of USB device.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[out] configuration_value Current configuration value.
- * @return Error code.
- */
-int usb_request_get_configuration(usb_pipe_t *pipe,
-    uint8_t *configuration_value)
-{
-	uint8_t value;
-	size_t actual_size;
-
-	int rc = usb_control_request_get(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DEVREQ_GET_CONFIGURATION,
-	    0, 0,
-	    &value, 1, &actual_size);
-
-	if (rc != EOK) {
-		return rc;
-	}
-	if (actual_size != 1) {
-		return ELIMIT;
-	}
-
-	if (configuration_value != NULL) {
-		*configuration_value = value;
-	}
-
-	return EOK;
-}
-
-/** Set configuration of USB device.
- *
- * @param pipe Control endpoint pipe (session must be already started).
- * @param configuration_value New configuration value.
- * @return Error code.
- */
-int usb_request_set_configuration(usb_pipe_t *pipe,
-    uint8_t configuration_value)
-{
-	uint16_t config_value
-	    = uint16_host2usb((uint16_t) configuration_value);
-
-	return usb_control_request_set(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DEVREQ_SET_CONFIGURATION, config_value, 0,
-	    NULL, 0);
-}
-
-/** Get selected alternate setting for USB interface.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] interface_index Interface index.
- * @param[out] alternate_setting Alternate setting for the interface.
- * @return Error code.
- */
-int usb_request_get_interface(usb_pipe_t *pipe,
-    uint8_t interface_index, uint8_t *alternate_setting)
-{
-	uint8_t value;
-	size_t actual_size;
-
-	int rc = usb_control_request_get(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
-	    USB_DEVREQ_GET_INTERFACE,
-	    0, uint16_host2usb((uint16_t) interface_index),
-	    &value, 1, &actual_size);
-
-	if (rc != EOK) {
-		return rc;
-	}
-	if (actual_size != 1) {
-		return ELIMIT;
-	}
-
-	if (alternate_setting != NULL) {
-		*alternate_setting = value;
-	}
-
-	return EOK;
-}
-
-/** Select alternate setting for USB interface.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] interface_index Interface index.
- * @param[in] alternate_setting Alternate setting to select.
- * @return Error code.
- */
-int usb_request_set_interface(usb_pipe_t *pipe,
-    uint8_t interface_index, uint8_t alternate_setting)
-{
-	return usb_control_request_set(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
-	    USB_DEVREQ_SET_INTERFACE,
-	    uint16_host2usb((uint16_t) alternate_setting),
-	    uint16_host2usb((uint16_t) interface_index),
-	    NULL, 0);
-}
-
-/** Get list of supported languages by USB device.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[out] languages_ptr Where to store pointer to allocated array of
- *	supported languages.
- * @param[out] languages_count Number of supported languages.
- * @return Error code.
- */
-int usb_request_get_supported_languages(usb_pipe_t *pipe,
-    l18_win_locales_t **languages_ptr, size_t *languages_count)
-{
-	int rc;
-
-	if (languages_ptr == NULL) {
-		return EBADMEM;
-	}
-	if (languages_count == NULL) {
-		return EBADMEM;
-	}
-
-	uint8_t *string_descriptor = NULL;
-	size_t string_descriptor_size = 0;
-	rc = usb_request_get_descriptor_alloc(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DESCTYPE_STRING, 0, 0,
-	    (void **) &string_descriptor, &string_descriptor_size);
-	if (rc != EOK) {
-		return rc;
-	}
-	if (string_descriptor_size <= 2) {
-		free(string_descriptor);
-		return EEMPTY;
-	}
-	/* Subtract first 2 bytes (length and descriptor type). */
-	string_descriptor_size -= 2;
-
-	/* Odd number of bytes - descriptor is broken? */
-	if ((string_descriptor_size % 2) != 0) {
-		/* FIXME: shall we return with error or silently ignore? */
-		free(string_descriptor);
-		return ESTALL;
-	}
-
-	size_t langs_count = string_descriptor_size / 2;
-	l18_win_locales_t *langs
-	    = malloc(sizeof(l18_win_locales_t) * langs_count);
-	if (langs == NULL) {
-		free(string_descriptor);
-		return ENOMEM;
-	}
-
-	size_t i;
-	for (i = 0; i < langs_count; i++) {
-		/* Language code from the descriptor is in USB endianness. */
-		/* FIXME: is this really correct? */
-		uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
-		    + string_descriptor[2 + 2 * i];
-		langs[i] = uint16_usb2host(lang_code);
-	}
-
-	free(string_descriptor);
-
-	*languages_ptr = langs;
-	*languages_count =langs_count;
-
-	return EOK;
-}
-
-/** Get string (descriptor) from USB device.
- *
- * The string is returned in native encoding of the operating system.
- * For HelenOS, that is UTF-8.
- *
- * @param[in] pipe Control endpoint pipe (session must be already started).
- * @param[in] index String index (in native endianness),
- *	first index has number 1 (index from descriptors can be used directly).
- * @param[in] lang String language (in native endianness).
- * @param[out] string_ptr Where to store allocated string in native encoding.
- * @return Error code.
- */
-int usb_request_get_string(usb_pipe_t *pipe,
-    size_t index, l18_win_locales_t lang, char **string_ptr)
-{
-	if (string_ptr == NULL) {
-		return EBADMEM;
-	}
-	/*
-	 * Index is actually one byte value and zero index is used
-	 * to retrieve list of supported languages.
-	 */
-	if ((index < 1) || (index > 0xFF)) {
-		return ERANGE;
-	}
-	/* Language is actually two byte value. */
-	if (lang > 0xFFFF) {
-		return ERANGE;
-	}
-
-	int rc;
-
-	/* Prepare dynamically allocated variables. */
-	uint8_t *string = NULL;
-	wchar_t *string_chars = NULL;
-
-	/* Get the actual descriptor. */
-	size_t string_size;
-	rc = usb_request_get_descriptor_alloc(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
-	    USB_DESCTYPE_STRING, index, uint16_host2usb(lang),
-	    (void **) &string, &string_size);
-	if (rc != EOK) {
-		goto leave;
-	}
-
-	if (string_size <= 2) {
-		rc =  EEMPTY;
-		goto leave;
-	}
-	/* Subtract first 2 bytes (length and descriptor type). */
-	string_size -= 2;
-
-	/* Odd number of bytes - descriptor is broken? */
-	if ((string_size % 2) != 0) {
-		/* FIXME: shall we return with error or silently ignore? */
-		rc = ESTALL;
-		goto leave;
-	}
-
-	size_t string_char_count = string_size / 2;
-	string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
-	if (string_chars == NULL) {
-		rc = ENOMEM;
-		goto leave;
-	}
-
-	/*
-	 * Build a wide string.
-	 * And do not forget to set NULL terminator (string descriptors
-	 * do not have them).
-	 */
-	size_t i;
-	for (i = 0; i < string_char_count; i++) {
-		uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
-		    + string[2 + 2 * i];
-		string_chars[i] = uni_char;
-	}
-	string_chars[string_char_count] = 0;
-
-
-	/* Convert to normal string. */
-	char *str = wstr_to_astr(string_chars);
-	if (str == NULL) {
-		rc = ENOMEM;
-		goto leave;
-	}
-
-	*string_ptr = str;
-	rc = EOK;
-
-leave:
-	if (string != NULL) {
-		free(string);
-	}
-	if (string_chars != NULL) {
-		free(string_chars);
-	}
-
-	return rc;
-}
-
-/** Clear halt bit of an endpoint pipe (after pipe stall).
- *
- * @param pipe Control pipe.
- * @param ep_index Endpoint index (in native endianness).
- * @return Error code.
- */
-int usb_request_clear_endpoint_halt(usb_pipe_t *pipe, uint16_t ep_index)
-{
-	return usb_request_clear_feature(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
-	    uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
-	    uint16_host2usb(ep_index));
-}
-
-/**
- * @}
- */
Index: pace/lib/usb/src/usbdevice.c
===================================================================
--- uspace/lib/usb/src/usbdevice.c	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ 	(revision )
@@ -1,179 +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 libusb
- * @{
- */
-/** @file
- * General communication between device drivers and host controller driver.
- */
-#include <devman.h>
-#include <async.h>
-#include <usb_iface.h>
-#include <usb/usbdevice.h>
-#include <usb/debug.h>
-#include <errno.h>
-#include <assert.h>
-
-/** Find host controller handle that is ancestor of given device.
- *
- * @param[in] device_handle Device devman handle.
- * @param[out] hc_handle Where to store handle of host controller
- *	controlling device with @p device_handle handle.
- * @return Error code.
- */
-int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle)
-{
-	int parent_phone = devman_parent_device_connect(device_handle,
-	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
-	devman_handle_t h;
-	usb_log_debug("asking for HC handle (my handle is %zu).\n", device_handle);
-	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	if (hc_handle != NULL) {
-		*hc_handle = h;
-	}
-
-	return EOK;
-}
-
-/** Initialize connection to USB host controller.
- *
- * @param connection Connection to be initialized.
- * @param device Device connecting to the host controller.
- * @return Error code.
- */
-int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
-    ddf_dev_t *device)
-{
-	assert(connection);
-
-	if (device == NULL) {
-		return EBADMEM;
-	}
-
-	devman_handle_t hc_handle;
-	int rc = usb_hc_find(device->handle, &hc_handle);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	rc = usb_hc_connection_initialize(connection, hc_handle);
-
-	return rc;
-}
-
-/** Manually initialize connection to USB host controller.
- *
- * @param connection Connection to be initialized.
- * @param hc_handle Devman handle of the host controller.
- * @return Error code.
- */
-int usb_hc_connection_initialize(usb_hc_connection_t *connection,
-    devman_handle_t hc_handle)
-{
-	assert(connection);
-
-	connection->hc_handle = hc_handle;
-	connection->hc_phone = -1;
-
-	return EOK;
-}
-
-/** Open connection to host controller.
- *
- * @param connection Connection to the host controller.
- * @return Error code.
- */
-int usb_hc_connection_open(usb_hc_connection_t *connection)
-{
-	assert(connection);
-
-	if (usb_hc_connection_is_opened(connection)) {
-		return EBUSY;
-	}
-
-	int phone = devman_device_connect(connection->hc_handle, 0);
-	if (phone < 0) {
-		return phone;
-	}
-
-	connection->hc_phone = phone;
-
-	return EOK;
-}
-
-/** Tells whether connection to host controller is opened.
- *
- * @param connection Connection to the host controller.
- * @return Whether connection is opened.
- */
-bool usb_hc_connection_is_opened(const usb_hc_connection_t *connection)
-{
-	assert(connection);
-
-	return (connection->hc_phone >= 0);
-}
-
-/** Close connection to the host controller.
- *
- * @param connection Connection to the host controller.
- * @return Error code.
- */
-int usb_hc_connection_close(usb_hc_connection_t *connection)
-{
-	assert(connection);
-
-	if (!usb_hc_connection_is_opened(connection)) {
-		return ENOENT;
-	}
-
-	int rc = async_hangup(connection->hc_phone);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	connection->hc_phone = -1;
-
-	return EOK;
-}
-
-/**
- * @}
- */
Index: uspace/lib/usbdev/Makefile
===================================================================
--- uspace/lib/usbdev/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,51 @@
+#
+# 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 = ../..
+LIBRARY = libusbdev
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include \
+	-Iinclude
+
+SOURCES = \
+	src/altiface.c \
+	src/devdrv.c \
+	src/devpoll.c \
+	src/dp.c \
+	src/hub.c \
+	src/pipepriv.c \
+	src/pipepriv.h \
+	src/pipes.c \
+	src/pipesinit.c \
+	src/pipesio.c \
+	src/recognise.c \
+	src/request.c \
+	src/usbdevice.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usbdev/include/usb/devdrv.h
===================================================================
--- uspace/lib/usbdev/include/usb/devdrv.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/devdrv.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,178 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB device driver framework.
+ */
+#ifndef LIBUSB_DEVDRV_H_
+#define LIBUSB_DEVDRV_H_
+
+#include <usb/pipes.h>
+
+/** Descriptors for USB device. */
+typedef struct {
+	/** Standard device descriptor. */
+	usb_standard_device_descriptor_t device;
+	/** Full configuration descriptor of current configuration. */
+	uint8_t *configuration;
+	size_t configuration_size;
+} usb_device_descriptors_t;
+
+/** Wrapper for data related to alternate interface setting.
+ * The pointers will typically point inside configuration descriptor and
+ * thus you shall not deallocate them.
+ */
+typedef struct {
+	/** Interface descriptor. */
+	usb_standard_interface_descriptor_t *interface;
+	/** Pointer to start of descriptor tree bound with this interface. */
+	uint8_t *nested_descriptors;
+	/** Size of data pointed by nested_descriptors in bytes. */
+	size_t nested_descriptors_size;
+} usb_alternate_interface_descriptors_t;
+
+/** Alternate interface settings. */
+typedef struct {
+	/** Array of alternate interfaces descriptions. */
+	usb_alternate_interface_descriptors_t *alternatives;
+	/** Size of @c alternatives array. */
+	size_t alternative_count;
+	/** Index of currently selected one. */
+	size_t current;
+} usb_alternate_interfaces_t;
+
+/** USB device structure. */
+typedef struct {
+	/** The default control pipe. */
+	usb_pipe_t ctrl_pipe;
+	/** Other endpoint pipes.
+	 * This is an array of other endpoint pipes in the same order as
+	 * in usb_driver_t.
+	 */
+	usb_endpoint_mapping_t *pipes;
+	/** Number of other endpoint pipes. */
+	size_t pipes_count;
+	/** Current interface.
+	 * Usually, drivers operate on single interface only.
+	 * This item contains the value of the interface or -1 for any.
+	 */
+	int interface_no;
+
+	/** Alternative interfaces.
+	 * Set to NULL when the driver controls whole device
+	 * (i.e. more (or any) interfaces).
+	 */
+	usb_alternate_interfaces_t *alternate_interfaces;
+
+	/** Some useful descriptors. */
+	usb_device_descriptors_t descriptors;
+
+	/** Generic DDF device backing this one. */
+	ddf_dev_t *ddf_dev;
+	/** Custom driver data.
+	 * Do not use the entry in generic device, that is already used
+	 * by the framework.
+	 */
+	void *driver_data;
+
+	/** Connection backing the pipes.
+	 * Typically, you will not need to use this attribute at all.
+	 */
+	usb_device_connection_t wire;
+} usb_device_t;
+
+/** USB driver ops. */
+typedef struct {
+	/** Callback when new device is about to be controlled by the driver. */
+	int (*add_device)(usb_device_t *);
+} usb_driver_ops_t;
+
+/** USB driver structure. */
+typedef struct {
+	/** Driver name.
+	 * This name is copied to the generic driver name and must be exactly
+	 * the same as the directory name where the driver executable resides.
+	 */
+	const char *name;
+	/** Expected endpoints description.
+	 * This description shall exclude default control endpoint (pipe zero)
+	 * and must be NULL terminated.
+	 * When only control endpoint is expected, you may set NULL directly
+	 * without creating one item array containing NULL.
+	 *
+	 * When the driver expect single interrupt in endpoint,
+	 * the initialization may look like this:
+\code
+static usb_endpoint_description_t poll_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 usb_endpoint_description_t *hub_endpoints[] = {
+	&poll_endpoint_description,
+	NULL
+};
+
+static usb_driver_t hub_driver = {
+	.endpoints = hub_endpoints,
+	...
+};
+\endcode
+	 */
+	usb_endpoint_description_t **endpoints;
+	/** Driver ops. */
+	usb_driver_ops_t *ops;
+} usb_driver_t;
+
+int usb_driver_main(usb_driver_t *);
+
+int usb_device_select_interface(usb_device_t *, uint8_t,
+    usb_endpoint_description_t **);
+
+int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
+int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
+    usb_endpoint_description_t **, uint8_t *, size_t, int, int,
+    usb_endpoint_mapping_t **, size_t *);
+int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
+int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);
+
+size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
+int usb_alternate_interfaces_create(uint8_t *, size_t, int,
+    usb_alternate_interfaces_t **);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/devpoll.h
===================================================================
--- uspace/lib/usbdev/include/usb/devpoll.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/devpoll.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,99 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB device polling functions.
+ */
+#ifndef LIBUSB_DEVPOLL_H_
+#define LIBUSB_DEVPOLL_H_
+
+#include <usb/devdrv.h>
+#include <time.h>
+
+typedef struct {
+	/** Level of debugging messages from auto polling.
+	 * 0 - nothing
+	 * 1 - inform about errors and polling start/end
+	 * 2 - also dump every retrieved buffer
+	 */
+	int debug;
+	/** Maximum number of consecutive errors before polling termination. */
+	size_t max_failures;
+	/** Delay between poll requests in milliseconds.
+	 * Set to negative value to use value from endpoint descriptor.
+	 */
+	int delay;
+	/** Whether to automatically try to clear the HALT feature after
+	 * the endpoint stalls.
+	 */
+	bool auto_clear_halt;
+	/** Callback when data arrives.
+	 *
+	 * @param dev Device that was polled.
+	 * @param data Data buffer (in USB endianness).
+	 * @param data_size Size of the @p data buffer in bytes.
+	 * @param arg Custom argument.
+	 * @return Whether to continue in polling.
+	 */
+	bool (*on_data)(usb_device_t *dev, uint8_t *data, size_t data_size,
+	    void *arg);
+	/** Callback when polling is terminated.
+	 *
+	 * @param dev Device where the polling was terminated.
+	 * @param due_to_errors Whether polling stopped due to several failures.
+	 * @param arg Custom argument.
+	 */
+	void (*on_polling_end)(usb_device_t *dev, bool due_to_errors,
+	    void *arg);
+	/** Callback when error occurs.
+	 *
+	 * @param dev Device where error occurred.
+	 * @param err_code Error code (as returned from usb_pipe_read).
+	 * @param arg Custom argument.
+	 * @return Whether to continue in polling.
+	 */
+	bool (*on_error)(usb_device_t *dev, int err_code, void *arg);
+} usb_device_auto_polling_t;
+
+int usb_device_auto_polling(usb_device_t *, size_t, usb_device_auto_polling_t *,
+    size_t, void *);
+
+typedef bool (*usb_polling_callback_t)(usb_device_t *,
+    uint8_t *, size_t, void *);
+typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
+
+int usb_device_auto_poll(usb_device_t *, size_t,
+    usb_polling_callback_t, size_t, usb_polling_terminted_callback_t, void *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/dp.h
===================================================================
--- uspace/lib/usbdev/include/usb/dp.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/dp.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,85 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB descriptor parser.
+ */
+#ifndef LIBUSB_DP_H_
+#define LIBUSB_DP_H_
+
+#include <sys/types.h>
+#include <usb/usb.h>
+#include <usb/descriptor.h>
+
+/** USB descriptors nesting.
+ * The nesting describes the logical tree USB descriptors form
+ * (e.g. that endpoint descriptor belongs to interface or that
+ * interface belongs to configuration).
+ *
+ * See usb_descriptor_type_t for descriptor constants.
+ */
+typedef struct {
+	/** Child descriptor id. */
+	int child;
+	/** Parent descriptor id. */
+	int parent;
+} usb_dp_descriptor_nesting_t;
+
+extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
+
+/** Descriptor parser structure. */
+typedef struct {
+	/** Used descriptor nesting. */
+	usb_dp_descriptor_nesting_t *nesting;
+} usb_dp_parser_t;
+
+/** Descriptor parser data. */
+typedef struct {
+	/** Data to be parsed. */
+	uint8_t *data;
+	/** Size of input data in bytes. */
+	size_t size;
+	/** Custom argument. */
+	void *arg;
+} usb_dp_parser_data_t;
+
+uint8_t *usb_dp_get_nested_descriptor(usb_dp_parser_t *,
+    usb_dp_parser_data_t *, uint8_t *);
+uint8_t *usb_dp_get_sibling_descriptor(usb_dp_parser_t *,
+    usb_dp_parser_data_t *, uint8_t *, uint8_t *);
+
+void usb_dp_walk_simple(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
+    void (*)(uint8_t *, size_t, void *), void *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/hub.h
===================================================================
--- uspace/lib/usbdev/include/usb/hub.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/hub.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,71 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Functions needed by hub drivers.
+ *
+ * For class specific requests, see usb/classes/hub.h.
+ */
+#ifndef LIBUSB_HUB_H_
+#define LIBUSB_HUB_H_
+
+#include <sys/types.h>
+#include <usb/usbdevice.h>
+
+int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
+    int (*)(int, void *), int, void *,
+    usb_address_t *, devman_handle_t *,
+    ddf_dev_ops_t *, void *, ddf_fun_t **);
+
+/** Info about device attached to host controller.
+ *
+ * This structure exists only to keep the same signature of
+ * usb_hc_register_device() when more properties of the device
+ * would have to be passed to the host controller.
+ */
+typedef struct {
+	/** Device address. */
+	usb_address_t address;
+	/** Devman handle of the device. */
+	devman_handle_t handle;
+} usb_hc_attached_device_t;
+
+usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
+int usb_hc_register_device(usb_hc_connection_t *,
+    const usb_hc_attached_device_t *);
+int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t);
+int usb_hc_get_handle_by_address(usb_hc_connection_t *, usb_address_t,
+    devman_handle_t *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/pipes.h
===================================================================
--- uspace/lib/usbdev/include/usb/pipes.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/pipes.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,193 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB pipes representation.
+ */
+#ifndef LIBUSB_PIPES_H_
+#define LIBUSB_PIPES_H_
+
+#include <sys/types.h>
+#include <usb/usb.h>
+#include <usb/usbdevice.h>
+#include <usb/descriptor.h>
+#include <ipc/devman.h>
+#include <ddf/driver.h>
+#include <fibril_synch.h>
+
+/** Abstraction of a physical connection to the device.
+ * This type is an abstraction of the USB wire that connects the host and
+ * the function (device).
+ */
+typedef struct {
+	/** Handle of the host controller device is connected to. */
+	devman_handle_t hc_handle;
+	/** Address of the device. */
+	usb_address_t address;
+} usb_device_connection_t;
+
+/** Abstraction of a logical connection to USB device endpoint.
+ * It encapsulates endpoint attributes (transfer type etc.) as well
+ * as information about currently running sessions.
+ * This endpoint must be bound with existing usb_device_connection_t
+ * (i.e. the wire to send data over).
+ *
+ * Locking order: if you want to lock both mutexes
+ * (@c guard and @c hc_phone_mutex), lock @c guard first.
+ * It is not necessary to lock @c guard if you want to lock @c hc_phone_mutex
+ * only.
+ */
+typedef struct {
+	/** Guard of the whole pipe. */
+	fibril_mutex_t guard;
+
+	/** The connection used for sending the data. */
+	usb_device_connection_t *wire;
+
+	/** Endpoint number. */
+	usb_endpoint_t endpoint_no;
+
+	/** Endpoint transfer type. */
+	usb_transfer_type_t transfer_type;
+
+	/** Endpoint direction. */
+	usb_direction_t direction;
+
+	/** Maximum packet size for the endpoint. */
+	size_t max_packet_size;
+
+	/** Phone to the host controller.
+	 * Negative when no session is active.
+	 * It is an error to access this member without @c hc_phone_mutex
+	 * being locked.
+	 * If call over the phone is to be made, it must be preceeded by
+	 * call to pipe_add_ref() [internal libusb function].
+	 */
+	int hc_phone;
+
+	/** Guard for serialization of requests over the phone. */
+	fibril_mutex_t hc_phone_mutex;
+
+	/** Number of active transfers over the pipe. */
+	int refcount;
+	/** Number of failed attempts to open the HC phone.
+	 * When user requests usb_pipe_start_long_transfer() and the operation
+	 * fails, there is no way to report this to the user.
+	 * That the soft reference counter is increased to record the attempt.
+	 * When the user then request e.g. usb_pipe_read(), it will try to
+	 * add reference as well.
+	 * If that fails, it is reported to the user. If it is okay, the
+	 * real reference counter is incremented.
+	 * The problem might arise when ending the long transfer (since
+	 * the number of references would be only 1, but logically it shall be
+	 * two).
+	 * Decrementing the soft counter first shall solve this.
+	 */
+	int refcount_soft;
+
+	/** Whether to automatically reset halt on the endpoint.
+	 * Valid only for control endpoint zero.
+	 */
+	bool auto_reset_halt;
+} usb_pipe_t;
+
+
+/** Description of endpoint characteristics. */
+typedef struct {
+	/** Transfer type (e.g. control or interrupt). */
+	usb_transfer_type_t transfer_type;
+	/** Transfer direction (to or from a device). */
+	usb_direction_t direction;
+	/** Interface class this endpoint belongs to (-1 for any). */
+	int interface_class;
+	/** Interface subclass this endpoint belongs to (-1 for any). */
+	int interface_subclass;
+	/** Interface protocol this endpoint belongs to (-1 for any). */
+	int interface_protocol;
+	/** Extra endpoint flags. */
+	unsigned int flags;
+} usb_endpoint_description_t;
+
+/** Mapping of endpoint pipes and endpoint descriptions. */
+typedef struct {
+	/** Endpoint pipe. */
+	usb_pipe_t *pipe;
+	/** Endpoint description. */
+	const usb_endpoint_description_t *description;
+	/** Interface number the endpoint must belong to (-1 for any). */
+	int interface_no;
+	/** Alternate interface setting to choose. */
+	int interface_setting;
+	/** Found descriptor fitting the description. */
+	usb_standard_endpoint_descriptor_t *descriptor;
+	/** Interface descriptor the endpoint belongs to. */
+	usb_standard_interface_descriptor_t *interface;
+	/** Whether the endpoint was actually found. */
+	bool present;
+} usb_endpoint_mapping_t;
+
+int usb_device_connection_initialize_on_default_address(
+    usb_device_connection_t *, usb_hc_connection_t *);
+int usb_device_connection_initialize_from_device(usb_device_connection_t *,
+    ddf_dev_t *);
+int usb_device_connection_initialize(usb_device_connection_t *,
+    devman_handle_t, usb_address_t);
+
+int usb_device_get_assigned_interface(ddf_dev_t *);
+usb_address_t usb_device_get_assigned_address(devman_handle_t);
+
+int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *,
+    usb_endpoint_t, usb_transfer_type_t, size_t, usb_direction_t);
+int usb_pipe_initialize_default_control(usb_pipe_t *,
+    usb_device_connection_t *);
+int usb_pipe_probe_default_control(usb_pipe_t *);
+int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
+    size_t, uint8_t *, size_t, usb_device_connection_t *);
+int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
+    unsigned int, usb_hc_connection_t *);
+int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);
+int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);
+
+void usb_pipe_start_long_transfer(usb_pipe_t *);
+void usb_pipe_end_long_transfer(usb_pipe_t *);
+
+int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *);
+int usb_pipe_write(usb_pipe_t *, void *, size_t);
+
+int usb_pipe_control_read(usb_pipe_t *, void *, size_t,
+    void *, size_t, size_t *);
+int usb_pipe_control_write(usb_pipe_t *, void *, size_t,
+    void *, size_t);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/recognise.h
===================================================================
--- uspace/lib/usbdev/include/usb/recognise.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/recognise.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,58 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB device recognition.
+ */
+#ifndef LIBUSB_RECOGNISE_H_
+#define LIBUSB_RECOGNISE_H_
+
+#include <sys/types.h>
+#include <usb/usb.h>
+#include <usb/pipes.h>
+#include <ipc/devman.h>
+
+int usb_device_create_match_ids_from_device_descriptor(
+    const usb_standard_device_descriptor_t *, match_id_list_t *);
+
+int usb_device_create_match_ids_from_interface(
+    const usb_standard_device_descriptor_t *,
+    const usb_standard_interface_descriptor_t *, match_id_list_t *);
+
+int usb_device_create_match_ids(usb_pipe_t *, match_id_list_t *);
+
+int usb_device_register_child_in_devman(usb_address_t, devman_handle_t,
+    ddf_dev_t *, devman_handle_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/request.h
===================================================================
--- uspace/lib/usbdev/include/usb/request.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/request.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,150 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Standard USB requests.
+ */
+#ifndef LIBUSB_REQUEST_H_
+#define LIBUSB_REQUEST_H_
+
+#include <sys/types.h>
+#include <l18n/langs.h>
+#include <usb/usb.h>
+#include <usb/pipes.h>
+#include <usb/descriptor.h>
+
+/** USB device status - device is self powered (opposed to bus powered). */
+#define USB_DEVICE_STATUS_SELF_POWERED ((uint16_t)(1 << 0))
+
+/** USB device status - remote wake-up signaling is enabled. */
+#define USB_DEVICE_STATUS_REMOTE_WAKEUP ((uint16_t)(1 << 1))
+
+/** USB endpoint status - endpoint is halted (stalled). */
+#define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0))
+
+/** USB feature selector - endpoint halt (stall). */
+#define USB_FEATURE_SELECTOR_ENDPOINT_HALT (0)
+
+/** USB feature selector - device remote wake-up. */
+#define USB_FEATURE_SELECTOR_REMOTE_WAKEUP (1)
+
+/** Standard device request. */
+typedef enum {
+	USB_DEVREQ_GET_STATUS = 0,
+	USB_DEVREQ_CLEAR_FEATURE = 1,
+	USB_DEVREQ_SET_FEATURE = 3,
+	USB_DEVREQ_SET_ADDRESS = 5,
+	USB_DEVREQ_GET_DESCRIPTOR = 6,
+	USB_DEVREQ_SET_DESCRIPTOR = 7,
+	USB_DEVREQ_GET_CONFIGURATION = 8,
+	USB_DEVREQ_SET_CONFIGURATION = 9,
+	USB_DEVREQ_GET_INTERFACE = 10,
+	USB_DEVREQ_SET_INTERFACE = 11,
+	USB_DEVREQ_SYNCH_FRAME = 12,
+	USB_DEVREQ_LAST_STD
+} usb_stddevreq_t;
+
+/** Device request setup packet.
+ * The setup packet describes the request.
+ */
+typedef struct {
+	/** Request type.
+	 * The type combines transfer direction, request type and
+	 * intended recipient.
+	 */
+	uint8_t request_type;
+	/** Request identification. */
+	uint8_t request;
+	/** Main parameter to the request. */
+	union {
+		uint16_t value;
+		/* FIXME: add #ifdefs according to host endianness */
+		struct {
+			uint8_t value_low;
+			uint8_t value_high;
+		};
+	};
+	/** Auxiliary parameter to the request.
+	 * Typically, it is offset to something.
+	 */
+	uint16_t index;
+	/** Length of extra data. */
+	uint16_t length;
+} __attribute__ ((packed)) usb_device_request_setup_packet_t;
+
+int usb_control_request_set(usb_pipe_t *,
+    usb_request_type_t, usb_request_recipient_t, uint8_t,
+    uint16_t, uint16_t, void *, size_t);
+
+int usb_control_request_get(usb_pipe_t *,
+    usb_request_type_t, usb_request_recipient_t, uint8_t,
+    uint16_t, uint16_t, void *, size_t, size_t *);
+
+int usb_request_get_status(usb_pipe_t *, usb_request_recipient_t,
+    uint16_t, uint16_t *);
+int usb_request_clear_feature(usb_pipe_t *, usb_request_type_t,
+    usb_request_recipient_t, uint16_t, uint16_t);
+int usb_request_set_feature(usb_pipe_t *, usb_request_type_t,
+    usb_request_recipient_t, uint16_t, uint16_t);
+int usb_request_set_address(usb_pipe_t *, usb_address_t);
+int usb_request_get_descriptor(usb_pipe_t *, usb_request_type_t,
+    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 
+    size_t *);
+int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t,
+    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void **, size_t *);
+int usb_request_get_device_descriptor(usb_pipe_t *,
+    usb_standard_device_descriptor_t *);
+int usb_request_get_bare_configuration_descriptor(usb_pipe_t *, int,
+    usb_standard_configuration_descriptor_t *);
+int usb_request_get_full_configuration_descriptor(usb_pipe_t *, int,
+    void *, size_t, size_t *);
+int usb_request_get_full_configuration_descriptor_alloc(usb_pipe_t *,
+    int, void **, size_t *);
+int usb_request_set_descriptor(usb_pipe_t *, usb_request_type_t,
+    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t);
+int usb_request_get_configuration(usb_pipe_t *, uint8_t *);
+int usb_request_set_configuration(usb_pipe_t *, uint8_t);
+int usb_request_get_interface(usb_pipe_t *, uint8_t, uint8_t *);
+int usb_request_set_interface(usb_pipe_t *, uint8_t, uint8_t);
+
+int usb_request_get_supported_languages(usb_pipe_t *,
+    l18_win_locales_t **, size_t *);
+int usb_request_get_string(usb_pipe_t *, size_t, l18_win_locales_t,
+    char **);
+
+int usb_request_clear_endpoint_halt(usb_pipe_t *, uint16_t);
+int usb_pipe_clear_halt(usb_pipe_t *, usb_pipe_t *);
+int usb_request_get_endpoint_status(usb_pipe_t *, usb_pipe_t *, uint16_t *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/include/usb/usbdevice.h
===================================================================
--- uspace/lib/usbdev/include/usb/usbdevice.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/include/usb/usbdevice.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,65 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * General communication between device drivers and host controller driver.
+ */
+#ifndef LIBUSB_USBDEVICE_H_
+#define LIBUSB_USBDEVICE_H_
+
+#include <sys/types.h>
+#include <ipc/devman.h>
+#include <ddf/driver.h>
+#include <bool.h>
+#include <usb/usb.h>
+
+/** Connection to the host controller driver. */
+typedef struct {
+	/** Devman handle of the host controller. */
+	devman_handle_t hc_handle;
+	/** Phone to the host controller. */
+	int hc_phone;
+} usb_hc_connection_t;
+
+int usb_hc_connection_initialize_from_device(usb_hc_connection_t *,
+    ddf_dev_t *);
+int usb_hc_connection_initialize(usb_hc_connection_t *, devman_handle_t);
+
+int usb_hc_connection_open(usb_hc_connection_t *);
+bool usb_hc_connection_is_opened(const usb_hc_connection_t *);
+int usb_hc_connection_close(usb_hc_connection_t *);
+
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/altiface.c
===================================================================
--- uspace/lib/usbdev/src/altiface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/altiface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,181 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Handling alternate interface settings.
+ */
+#include <usb/devdrv.h>
+#include <usb/request.h>
+#include <usb/debug.h>
+#include <usb/dp.h>
+#include <errno.h>
+#include <str_error.h>
+#include <assert.h>
+
+/** Count number of alternate settings of a interface.
+ *
+ * @param config_descr Full configuration descriptor.
+ * @param config_descr_size Size of @p config_descr in bytes.
+ * @param interface_no Interface number.
+ * @return Number of alternate interfaces for @p interface_no interface.
+ */
+size_t usb_interface_count_alternates(uint8_t *config_descr,
+    size_t config_descr_size, uint8_t interface_no)
+{
+	assert(config_descr != NULL);
+	assert(config_descr_size > 0);
+
+	usb_dp_parser_t dp_parser = {
+		.nesting = usb_dp_standard_descriptor_nesting
+	};
+	usb_dp_parser_data_t dp_data = {
+		.data = config_descr,
+		.size = config_descr_size,
+		.arg = NULL
+	};
+
+	size_t alternate_count = 0;
+
+	uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
+	    &dp_data, config_descr);
+	while (iface_ptr != NULL) {
+		usb_standard_interface_descriptor_t *iface
+		    = (usb_standard_interface_descriptor_t *) iface_ptr;
+		if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) {
+			if (iface->interface_number == interface_no) {
+				alternate_count++;
+			}
+		}
+		iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
+		    config_descr, iface_ptr);
+	}
+
+	return alternate_count;
+}
+
+/** Create alternate interface representation structure.
+ *
+ * @param[in] config_descr Configuration descriptor.
+ * @param[in] config_descr_size Size of configuration descriptor.
+ * @param[in] interface_number Interface number.
+ * @param[out] alternates_ptr Where to store pointer to allocated structure.
+ * @return Error code.
+ */
+int usb_alternate_interfaces_create(uint8_t *config_descr,
+    size_t config_descr_size, int interface_number,
+    usb_alternate_interfaces_t **alternates_ptr)
+{
+	assert(alternates_ptr != NULL);
+	assert(config_descr != NULL);
+	assert(config_descr_size > 0);
+
+	if (interface_number < 0) {
+		alternates_ptr = NULL;
+		return EOK;
+	}
+
+	usb_alternate_interfaces_t *alternates
+	    = malloc(sizeof(usb_alternate_interfaces_t));
+
+	if (alternates == NULL) {
+		return ENOMEM;
+	}
+
+	alternates->alternative_count
+	    = usb_interface_count_alternates(config_descr, config_descr_size,
+	    interface_number);
+
+	if (alternates->alternative_count == 0) {
+		free(alternates);
+		return ENOENT;
+	}
+
+	alternates->alternatives = malloc(alternates->alternative_count
+	    * sizeof(usb_alternate_interface_descriptors_t));
+	if (alternates->alternatives == NULL) {
+		free(alternates);
+		return ENOMEM;
+	}
+
+	alternates->current = 0;
+
+	usb_dp_parser_t dp_parser = {
+		.nesting = usb_dp_standard_descriptor_nesting
+	};
+	usb_dp_parser_data_t dp_data = {
+		.data = config_descr,
+		.size = config_descr_size,
+		.arg = NULL
+	};
+
+	usb_alternate_interface_descriptors_t *cur_alt_iface
+	    = &alternates->alternatives[0];
+
+	uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
+	    &dp_data, dp_data.data);
+	while (iface_ptr != NULL) {
+		usb_standard_interface_descriptor_t *iface
+		    = (usb_standard_interface_descriptor_t *) iface_ptr;
+		if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE)
+		    || (iface->interface_number != interface_number)) {
+			iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser,
+			    &dp_data,
+			    dp_data.data, iface_ptr);
+			continue;
+		}
+
+		cur_alt_iface->interface = iface;
+		cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface);
+
+		/* Find next interface to count size of nested descriptors. */
+		iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
+		    dp_data.data, iface_ptr);
+		if (iface_ptr == NULL) {
+			uint8_t *next = dp_data.data + dp_data.size;
+			cur_alt_iface->nested_descriptors_size
+			    = next - cur_alt_iface->nested_descriptors;
+		} else {
+			cur_alt_iface->nested_descriptors_size
+			    = iface_ptr - cur_alt_iface->nested_descriptors;
+		}
+
+		cur_alt_iface++;
+	}
+
+	*alternates_ptr = alternates;
+
+	return EOK;
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/devdrv.c
===================================================================
--- uspace/lib/usbdev/src/devdrv.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/devdrv.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,537 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB device driver framework.
+ */
+#include <usb/devdrv.h>
+#include <usb/request.h>
+#include <usb/debug.h>
+#include <usb/dp.h>
+#include <errno.h>
+#include <str_error.h>
+#include <assert.h>
+
+static int generic_add_device(ddf_dev_t *);
+
+static driver_ops_t generic_driver_ops = {
+	.add_device = generic_add_device
+};
+static driver_t generic_driver = {
+	.driver_ops = &generic_driver_ops
+};
+
+static usb_driver_t *driver = NULL;
+
+
+/** Main routine of USB device driver.
+ *
+ * Under normal conditions, this function never returns.
+ *
+ * @param drv USB device driver structure.
+ * @return Task exit status.
+ */
+int usb_driver_main(usb_driver_t *drv)
+{
+	assert(drv != NULL);
+
+	/* Prepare the generic driver. */
+	generic_driver.name = drv->name;
+
+	driver = drv;
+
+	return ddf_driver_main(&generic_driver);
+}
+
+/** Count number of pipes the driver expects.
+ *
+ * @param drv USB driver.
+ * @return Number of pipes (excluding default control pipe).
+ */
+static size_t count_other_pipes(usb_endpoint_description_t **endpoints)
+{
+	size_t count = 0;
+	if (endpoints == NULL) {
+		return 0;
+	}
+
+	while (endpoints[count] != NULL) {
+		count++;
+	}
+
+	return count;
+}
+
+/** Initialize endpoint pipes, excluding default control one.
+ *
+ * @param drv The device driver.
+ * @param dev Device to be initialized.
+ * @return Error code.
+ */
+static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
+    usb_device_t *dev, int alternate_setting)
+{
+	if (endpoints == NULL) {
+		dev->pipes = NULL;
+		dev->pipes_count = 0;
+		return EOK;
+	}
+
+	usb_endpoint_mapping_t *pipes;
+	size_t pipes_count;
+
+	int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,
+	    dev->descriptors.configuration, dev->descriptors.configuration_size,
+	    dev->interface_no, alternate_setting,
+	    &pipes, &pipes_count);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	dev->pipes = pipes;
+	dev->pipes_count = pipes_count;
+
+	return EOK;
+}
+
+/** Callback when new device is supposed to be controlled by this driver.
+ *
+ * This callback is a wrapper for USB specific version of @c add_device.
+ *
+ * @param gen_dev Device structure as prepared by DDF.
+ * @return Error code.
+ */
+int generic_add_device(ddf_dev_t *gen_dev)
+{
+	assert(driver);
+	assert(driver->ops);
+	assert(driver->ops->add_device);
+
+	int rc;
+
+	usb_device_t *dev = NULL;
+	const char *err_msg = NULL;
+	rc = usb_device_create(gen_dev, driver->endpoints, &dev, &err_msg);
+	if (rc != EOK) {
+		usb_log_error("USB device `%s' creation failed (%s): %s.\n",
+		    gen_dev->name, err_msg, str_error(rc));
+		return rc;
+	}
+
+	return driver->ops->add_device(dev);
+}
+
+/** Destroy existing pipes of a USB device.
+ *
+ * @param dev Device where to destroy the pipes.
+ * @return Error code.
+ */
+static int destroy_current_pipes(usb_device_t *dev)
+{
+	int rc = usb_device_destroy_pipes(dev->ddf_dev,
+	    dev->pipes, dev->pipes_count);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	dev->pipes = NULL;
+	dev->pipes_count = 0;
+
+	return EOK;
+}
+
+/** Change interface setting of a device.
+ * This function selects new alternate setting of an interface by issuing
+ * proper USB command to the device and also creates new USB pipes
+ * under @c dev->pipes.
+ *
+ * @warning This function is intended for drivers working at interface level.
+ * For drivers controlling the whole device, you need to change interface
+ * manually using usb_request_set_interface() and creating new pipes
+ * with usb_pipe_initialize_from_configuration().
+ *
+ * @warning This is a wrapper function that does several operations that
+ * can fail and that cannot be rollbacked easily. That means that a failure
+ * during the SET_INTERFACE request would result in having a device with
+ * no pipes at all (except the default control one). That is because the old
+ * pipes needs to be unregistered at HC first and the new ones could not
+ * be created.
+ *
+ * @param dev USB device.
+ * @param alternate_setting Alternate setting to choose.
+ * @param endpoints New endpoint descriptions.
+ * @return Error code.
+ */
+int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
+    usb_endpoint_description_t **endpoints)
+{
+	if (dev->interface_no < 0) {
+		return EINVAL;
+	}
+
+	int rc;
+
+	/* Destroy existing pipes. */
+	rc = destroy_current_pipes(dev);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Change the interface itself. */
+	rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
+	    alternate_setting);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Create new pipes. */
+	rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting);
+
+	return rc;
+}
+
+/** Retrieve basic descriptors from the device.
+ *
+ * @param[in] ctrl_pipe Control endpoint pipe.
+ * @param[out] descriptors Where to store the descriptors.
+ * @return Error code.
+ */
+int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe,
+    usb_device_descriptors_t *descriptors)
+{
+	assert(descriptors != NULL);
+
+	descriptors->configuration = NULL;
+
+	int rc;
+
+	/* It is worth to start a long transfer. */
+	usb_pipe_start_long_transfer(ctrl_pipe);
+
+	/* Get the device descriptor. */
+	rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
+	if (rc != EOK) {
+		goto leave;
+	}
+
+	/* Get the full configuration descriptor. */
+	rc = usb_request_get_full_configuration_descriptor_alloc(
+	    ctrl_pipe, 0, (void **) &descriptors->configuration,
+	    &descriptors->configuration_size);
+
+leave:
+	usb_pipe_end_long_transfer(ctrl_pipe);
+
+	return rc;
+}
+
+/** Create pipes for a device.
+ *
+ * This is more or less a wrapper that does following actions:
+ * - allocate and initialize pipes
+ * - map endpoints to the pipes based on the descriptions
+ * - registers endpoints with the host controller
+ *
+ * @param[in] dev Generic DDF device backing the USB one.
+ * @param[in] wire Initialized backing connection to the host controller.
+ * @param[in] endpoints Endpoints description, NULL terminated.
+ * @param[in] config_descr Configuration descriptor of active configuration.
+ * @param[in] config_descr_size Size of @p config_descr in bytes.
+ * @param[in] interface_no Interface to map from.
+ * @param[in] interface_setting Interface setting (default is usually 0).
+ * @param[out] pipes_ptr Where to store array of created pipes
+ *	(not NULL terminated).
+ * @param[out] pipes_count_ptr Where to store number of pipes
+ *	(set to if you wish to ignore the count).
+ * @return Error code.
+ */
+int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire,
+    usb_endpoint_description_t **endpoints,
+    uint8_t *config_descr, size_t config_descr_size,
+    int interface_no, int interface_setting,
+    usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
+{
+	assert(dev != NULL);
+	assert(wire != NULL);
+	assert(endpoints != NULL);
+	assert(config_descr != NULL);
+	assert(config_descr_size > 0);
+	assert(pipes_ptr != NULL);
+
+	size_t i;
+	int rc;
+
+	size_t pipe_count = count_other_pipes(endpoints);
+	if (pipe_count == 0) {
+		*pipes_ptr = NULL;
+		return EOK;
+	}
+
+	usb_endpoint_mapping_t *pipes
+	    = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
+	if (pipes == NULL) {
+		return ENOMEM;
+	}
+
+	/* Initialize to NULL to allow smooth rollback. */
+	for (i = 0; i < pipe_count; i++) {
+		pipes[i].pipe = NULL;
+	}
+
+	/* Now allocate and fully initialize. */
+	for (i = 0; i < pipe_count; i++) {
+		pipes[i].pipe = malloc(sizeof(usb_pipe_t));
+		if (pipes[i].pipe == NULL) {
+			rc = ENOMEM;
+			goto rollback_free_only;
+		}
+		pipes[i].description = endpoints[i];
+		pipes[i].interface_no = interface_no;
+		pipes[i].interface_setting = interface_setting;
+	}
+
+	/* Find the mapping from configuration descriptor. */
+	rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
+	    config_descr, config_descr_size, wire);
+	if (rc != EOK) {
+		goto rollback_free_only;
+	}
+
+	/* Register the endpoints with HC. */
+	usb_hc_connection_t hc_conn;
+	rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
+	if (rc != EOK) {
+		goto rollback_free_only;
+	}
+
+	rc = usb_hc_connection_open(&hc_conn);
+	if (rc != EOK) {
+		goto rollback_free_only;
+	}
+
+	for (i = 0; i < pipe_count; i++) {
+		if (pipes[i].present) {
+			rc = usb_pipe_register(pipes[i].pipe,
+			    pipes[i].descriptor->poll_interval, &hc_conn);
+			if (rc != EOK) {
+				goto rollback_unregister_endpoints;
+			}
+		}
+	}
+
+	usb_hc_connection_close(&hc_conn);
+
+	*pipes_ptr = pipes;
+	if (pipes_count_ptr != NULL) {
+		*pipes_count_ptr = pipe_count;
+	}
+
+	return EOK;
+
+	/*
+	 * Jump here if something went wrong after endpoints have
+	 * been registered.
+	 * This is also the target when the registration of
+	 * endpoints fails.
+	 */
+rollback_unregister_endpoints:
+	for (i = 0; i < pipe_count; i++) {
+		if (pipes[i].present) {
+			usb_pipe_unregister(pipes[i].pipe, &hc_conn);
+		}
+	}
+
+	usb_hc_connection_close(&hc_conn);
+
+	/*
+	 * Jump here if something went wrong before some actual communication
+	 * with HC. Then the only thing that needs to be done is to free
+	 * allocated memory.
+	 */
+rollback_free_only:
+	for (i = 0; i < pipe_count; i++) {
+		if (pipes[i].pipe != NULL) {
+			free(pipes[i].pipe);
+		}
+	}
+	free(pipes);
+
+	return rc;
+}
+
+/** Destroy pipes previously created by usb_device_create_pipes.
+ *
+ * @param[in] dev Generic DDF device backing the USB one.
+ * @param[in] pipes Endpoint mapping to be destroyed.
+ * @param[in] pipes_count Number of endpoints.
+ */
+int usb_device_destroy_pipes(ddf_dev_t *dev,
+    usb_endpoint_mapping_t *pipes, size_t pipes_count)
+{
+	assert(dev != NULL);
+	assert(((pipes != NULL) && (pipes_count > 0))
+	    || ((pipes == NULL) && (pipes_count == 0)));
+
+	if (pipes_count == 0) {
+		return EOK;
+	}
+
+	int rc;
+
+	/* Prepare connection to HC to allow endpoint unregistering. */
+	usb_hc_connection_t hc_conn;
+	rc = usb_hc_connection_initialize_from_device(&hc_conn, dev);
+	if (rc != EOK) {
+		return rc;
+	}
+	rc = usb_hc_connection_open(&hc_conn);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Destroy the pipes. */
+	size_t i;
+	for (i = 0; i < pipes_count; i++) {
+		usb_pipe_unregister(pipes[i].pipe, &hc_conn);
+		free(pipes[i].pipe);
+	}
+
+	usb_hc_connection_close(&hc_conn);
+
+	free(pipes);
+
+	return EOK;
+}
+
+/** Initialize control pipe in a device.
+ *
+ * @param dev USB device in question.
+ * @param errmsg Where to store error context.
+ * @return
+ */
+static int init_wire_and_ctrl_pipe(usb_device_t *dev, const char **errmsg)
+{
+	int rc;
+
+	rc = usb_device_connection_initialize_from_device(&dev->wire,
+	    dev->ddf_dev);
+	if (rc != EOK) {
+		*errmsg = "device connection initialization";
+		return rc;
+	}
+
+	rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
+	    &dev->wire);
+	if (rc != EOK) {
+		*errmsg = "default control pipe initialization";
+		return rc;
+	}
+
+	return EOK;
+}
+
+
+/** Create new instance of USB device.
+ *
+ * @param[in] ddf_dev Generic DDF device backing the USB one.
+ * @param[in] endpoints NULL terminated array of endpoints (NULL for none).
+ * @param[out] dev_ptr Where to store pointer to the new device.
+ * @param[out] errstr_ptr Where to store description of context
+ *	(in case error occurs).
+ * @return Error code.
+ */
+int usb_device_create(ddf_dev_t *ddf_dev,
+    usb_endpoint_description_t **endpoints,
+    usb_device_t **dev_ptr, const char **errstr_ptr)
+{
+	assert(dev_ptr != NULL);
+	assert(ddf_dev != NULL);
+
+	int rc;
+
+	usb_device_t *dev = malloc(sizeof(usb_device_t));
+	if (dev == NULL) {
+		*errstr_ptr = "structure allocation";
+		return ENOMEM;
+	}
+
+	// FIXME: proper deallocation in case of errors
+
+	dev->ddf_dev = ddf_dev;
+	dev->driver_data = NULL;
+	dev->descriptors.configuration = NULL;
+	dev->alternate_interfaces = NULL;
+
+	dev->pipes_count = 0;
+	dev->pipes = NULL;
+
+	/* Initialize backing wire and control pipe. */
+	rc = init_wire_and_ctrl_pipe(dev, errstr_ptr);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Get our interface. */
+	dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
+
+	/* Retrieve standard descriptors. */
+	rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
+	    &dev->descriptors);
+	if (rc != EOK) {
+		*errstr_ptr = "descriptor retrieval";
+		return rc;
+	}
+
+	/* Create alternate interfaces. */
+	rc = usb_alternate_interfaces_create(dev->descriptors.configuration,
+	    dev->descriptors.configuration_size, dev->interface_no,
+	    &dev->alternate_interfaces);
+	if (rc != EOK) {
+		/* We will try to silently ignore this. */
+		dev->alternate_interfaces = NULL;
+	}
+
+	rc = initialize_other_pipes(endpoints, dev, 0);
+	if (rc != EOK) {
+		*errstr_ptr = "pipes initialization";
+		return rc;
+	}
+
+	*errstr_ptr = NULL;
+	*dev_ptr = dev;
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/devpoll.c
===================================================================
--- uspace/lib/usbdev/src/devpoll.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/devpoll.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,317 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB device driver framework - automatic interrupt polling.
+ */
+#include <usb/devpoll.h>
+#include <usb/request.h>
+#include <usb/debug.h>
+#include <usb/classes/classes.h>
+#include <errno.h>
+#include <str_error.h>
+#include <assert.h>
+
+/** Maximum number of failed consecutive requests before announcing failure. */
+#define MAX_FAILED_ATTEMPTS 3
+
+/** Data needed for polling. */
+typedef struct {
+	int debug;
+	size_t max_failures;
+	useconds_t delay;
+	bool auto_clear_halt;
+	bool (*on_data)(usb_device_t *, uint8_t *, size_t, void *);
+	void (*on_polling_end)(usb_device_t *, bool, void *);
+	bool (*on_error)(usb_device_t *, int, void *);
+
+	usb_device_t *dev;
+	size_t pipe_index;
+	size_t request_size;
+	uint8_t *buffer;
+	void *custom_arg;
+} polling_data_t;
+
+
+/** Polling fibril.
+ *
+ * @param arg Pointer to polling_data_t.
+ * @return Always EOK.
+ */
+static int polling_fibril(void *arg)
+{
+	polling_data_t *polling_data = (polling_data_t *) arg;
+	assert(polling_data);
+
+	usb_pipe_t *pipe
+	    = polling_data->dev->pipes[polling_data->pipe_index].pipe;
+	
+	if (polling_data->debug > 0) {
+		usb_endpoint_mapping_t *mapping
+		    = &polling_data->dev->pipes[polling_data->pipe_index];
+		usb_log_debug("Poll%p: started polling of `%s' - " \
+		    "interface %d (%s,%d,%d), %zuB/%zu.\n",
+		    polling_data,
+		    polling_data->dev->ddf_dev->name,
+		    (int) mapping->interface->interface_number,
+		    usb_str_class(mapping->interface->interface_class),
+		    (int) mapping->interface->interface_subclass,
+		    (int) mapping->interface->interface_protocol,
+		    polling_data->request_size, pipe->max_packet_size);
+	}
+
+	size_t failed_attempts = 0;
+	while (failed_attempts <= polling_data->max_failures) {
+		int rc;
+
+		size_t actual_size;
+		rc = usb_pipe_read(pipe, polling_data->buffer,
+		    polling_data->request_size, &actual_size);
+
+		if (polling_data->debug > 1) {
+			if (rc == EOK) {
+				usb_log_debug(
+				    "Poll%p: received: '%s' (%zuB).\n",
+				    polling_data,
+				    usb_debug_str_buffer(polling_data->buffer,
+				        actual_size, 16),
+				    actual_size);
+			} else {
+				usb_log_debug(
+				    "Poll%p: polling failed: %s.\n",
+				    polling_data, str_error(rc));
+			}
+		}
+
+		/* If the pipe stalled, we can try to reset the stall. */
+		if ((rc == ESTALL) && (polling_data->auto_clear_halt)) {
+			/*
+			 * We ignore error here as this is usually a futile
+			 * attempt anyway.
+			 */
+			usb_request_clear_endpoint_halt(
+			    &polling_data->dev->ctrl_pipe,
+			    pipe->endpoint_no);
+		}
+
+		if (rc != EOK) {
+			if (polling_data->on_error != NULL) {
+				bool cont = polling_data->on_error(
+				    polling_data->dev, rc,
+				    polling_data->custom_arg);
+				if (!cont) {
+					failed_attempts
+					    = polling_data->max_failures;
+				}
+			}
+			failed_attempts++;
+			continue;
+		}
+
+		/* We have the data, execute the callback now. */
+		bool carry_on = polling_data->on_data(polling_data->dev,
+		    polling_data->buffer, actual_size,
+		    polling_data->custom_arg);
+
+		if (!carry_on) {
+			failed_attempts = 0;
+			break;
+		}
+
+		/* Reset as something might be only a temporary problem. */
+		failed_attempts = 0;
+
+		/* Take a rest before next request. */
+		async_usleep(polling_data->delay);
+	}
+
+	if (polling_data->on_polling_end != NULL) {
+		polling_data->on_polling_end(polling_data->dev,
+		    failed_attempts > 0, polling_data->custom_arg);
+	}
+
+	if (polling_data->debug > 0) {
+		if (failed_attempts > 0) {
+			usb_log_error(
+			    "Polling of device `%s' terminated: %s.\n",
+			    polling_data->dev->ddf_dev->name,
+			    "recurring failures");
+		} else {
+			usb_log_debug(
+			    "Polling of device `%s' terminated by user.\n",
+			    polling_data->dev->ddf_dev->name
+			);
+		}
+	}
+
+	/* Free the allocated memory. */
+	free(polling_data->buffer);
+	free(polling_data);
+
+	return EOK;
+}
+
+/** Start automatic device polling over interrupt in pipe.
+ *
+ * @warning It is up to the callback to produce delays between individual
+ * requests.
+ *
+ * @warning There is no guarantee when the request to the device
+ * will be sent for the first time (it is possible that this
+ * first request would be executed prior to return from this function).
+ *
+ * @param dev Device to be periodically polled.
+ * @param pipe_index Index of the endpoint pipe used for polling.
+ * @param callback Callback when data are available.
+ * @param request_size How many bytes to ask for in each request.
+ * @param terminated_callback Callback when polling is terminated.
+ * @param arg Custom argument (passed as is to the callbacks).
+ * @return Error code.
+ * @retval EOK New fibril polling the device was already started.
+ */
+int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
+    usb_polling_callback_t callback, size_t request_size,
+    usb_polling_terminted_callback_t terminated_callback, void *arg)
+{
+	if ((dev == NULL) || (callback == NULL)) {
+		return EBADMEM;
+	}
+	if (request_size == 0) {
+		return EINVAL;
+	}
+	if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
+	    || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
+		return EINVAL;
+	}
+
+	usb_device_auto_polling_t *auto_polling
+	    = malloc(sizeof(usb_device_auto_polling_t));
+	if (auto_polling == NULL) {
+		return ENOMEM;
+	}
+
+	auto_polling->debug = 1;
+	auto_polling->auto_clear_halt = true;
+	auto_polling->delay = 0;
+	auto_polling->max_failures = MAX_FAILED_ATTEMPTS;
+	auto_polling->on_data = callback;
+	auto_polling->on_polling_end = terminated_callback;
+	auto_polling->on_error = NULL;
+
+	int rc = usb_device_auto_polling(dev, pipe_index, auto_polling,
+	   request_size, arg);
+
+	free(auto_polling);
+
+	return rc;
+}
+
+/** Start automatic device polling over interrupt in pipe.
+ *
+ * The polling settings is copied thus it is okay to destroy the structure
+ * after this function returns.
+ *
+ * @warning There is no guarantee when the request to the device
+ * will be sent for the first time (it is possible that this
+ * first request would be executed prior to return from this function).
+ *
+ * @param dev Device to be periodically polled.
+ * @param pipe_index Index of the endpoint pipe used for polling.
+ * @param polling Polling settings.
+ * @param request_size How many bytes to ask for in each request.
+ * @param arg Custom argument (passed as is to the callbacks).
+ * @return Error code.
+ * @retval EOK New fibril polling the device was already started.
+ */
+int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
+    usb_device_auto_polling_t *polling,
+    size_t request_size, void *arg)
+{
+	if (dev == NULL) {
+		return EBADMEM;
+	}
+	if (pipe_index >= dev->pipes_count) {
+		return EINVAL;
+	}
+	if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
+	    || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
+		return EINVAL;
+	}
+	if ((polling == NULL) || (polling->on_data == NULL)) {
+		return EBADMEM;
+	}
+
+	polling_data_t *polling_data = malloc(sizeof(polling_data_t));
+	if (polling_data == NULL) {
+		return ENOMEM;
+	}
+
+	/* Fill-in the data. */
+	polling_data->buffer = malloc(sizeof(request_size));
+	if (polling_data->buffer == NULL) {
+		free(polling_data);
+		return ENOMEM;
+	}
+	polling_data->request_size = request_size;
+	polling_data->dev = dev;
+	polling_data->pipe_index = pipe_index;
+	polling_data->custom_arg = arg;
+
+	polling_data->debug = polling->debug;
+	polling_data->max_failures = polling->max_failures;
+	if (polling->delay >= 0) {
+		polling_data->delay = (useconds_t) polling->delay;
+	} else {
+		polling_data->delay = (useconds_t) dev->pipes[pipe_index]
+		    .descriptor->poll_interval;
+	}
+	polling_data->auto_clear_halt = polling->auto_clear_halt;
+
+	polling_data->on_data = polling->on_data;
+	polling_data->on_polling_end = polling->on_polling_end;
+	polling_data->on_error = polling->on_error;
+
+	fid_t fibril = fibril_create(polling_fibril, polling_data);
+	if (fibril == 0) {
+		free(polling_data->buffer);
+		free(polling_data);
+		return ENOMEM;
+	}
+	fibril_add_ready(fibril);
+
+	/* Fibril launched. That fibril will free the allocated data. */
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/dp.c
===================================================================
--- uspace/lib/usbdev/src/dp.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/dp.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,326 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/**
+ * @file
+ * USB descriptor parser (implementation).
+ *
+ * The descriptor parser is a generic parser for structure, where individual
+ * items are stored in single buffer and each item begins with length followed
+ * by type. These types are organized into tree hierarchy.
+ *
+ * The parser is able of only two actions: find first child and find next
+ * sibling.
+ */
+#include <stdio.h>
+#include <str_error.h>
+#include <errno.h>
+#include <assert.h>
+#include <bool.h>
+#include <usb/dp.h>
+#include <usb/descriptor.h>
+
+#define NESTING(parentname, childname) \
+	{ \
+		.child = USB_DESCTYPE_##childname, \
+		.parent = USB_DESCTYPE_##parentname, \
+	}
+#define LAST_NESTING { -1, -1 }
+
+/** Nesting of standard USB descriptors. */
+usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = {
+	NESTING(CONFIGURATION, INTERFACE),
+	NESTING(INTERFACE, ENDPOINT),
+	NESTING(INTERFACE, HUB),
+	NESTING(INTERFACE, HID),
+	NESTING(HID, HID_REPORT),
+	LAST_NESTING
+};
+
+#undef NESTING
+#undef LAST_NESTING
+
+/** Tells whether pointer points inside descriptor data.
+ *
+ * @param data Parser data.
+ * @param ptr Pointer to be verified.
+ * @return Whether @p ptr points inside <code>data->data</code> field.
+ */
+static bool is_valid_descriptor_pointer(usb_dp_parser_data_t *data,
+    uint8_t *ptr)
+{
+	if (ptr == NULL) {
+		return false;
+	}
+
+	if (ptr < data->data) {
+		return false;
+	}
+
+	if ((size_t)(ptr - data->data) >= data->size) {
+		return false;
+	}
+
+	return true;
+}
+
+/** Get next descriptor regardless of the nesting.
+ *
+ * @param data Parser data.
+ * @param current Pointer to current descriptor.
+ * @return Pointer to start of next descriptor.
+ * @retval NULL Invalid input or no next descriptor.
+ */
+static uint8_t *get_next_descriptor(usb_dp_parser_data_t *data,
+    uint8_t *current)
+{
+	assert(is_valid_descriptor_pointer(data, current));
+
+	uint8_t current_length = *current;
+	uint8_t *next = current + current_length;
+
+	if (!is_valid_descriptor_pointer(data, next)) {
+		return NULL;
+	}
+
+	return next;
+}
+
+/** Get descriptor type.
+ *
+ * @see usb_descriptor_type_t
+ *
+ * @param data Parser data.
+ * @param start Pointer to start of the descriptor.
+ * @return Descriptor type.
+ * @retval -1 Invalid input.
+ */
+static int get_descriptor_type(usb_dp_parser_data_t *data, uint8_t *start)
+{
+	if (start == NULL) {
+		return -1;
+	}
+
+	start++;
+	if (!is_valid_descriptor_pointer(data, start)) {
+		return -1;
+	} else {
+		return (int) (*start);
+	}
+}
+
+/** Tells whether descriptors could be nested.
+ *
+ * @param parser Parser.
+ * @param child Child descriptor type.
+ * @param parent Parent descriptor type.
+ * @return Whether @p child could be child of @p parent.
+ */
+static bool is_nested_descriptor_type(usb_dp_parser_t *parser,
+    int child, int parent)
+{
+	usb_dp_descriptor_nesting_t *nesting = parser->nesting;
+	while ((nesting->child > 0) && (nesting->parent > 0)) {
+		if ((nesting->child == child) && (nesting->parent == parent)) {
+			return true;
+		}
+		nesting++;
+	}
+	return false;
+}
+
+/** Tells whether descriptors could be nested.
+ *
+ * @param parser Parser.
+ * @param data Parser data.
+ * @param child Pointer to child descriptor.
+ * @param parent Pointer to parent descriptor.
+ * @return Whether @p child could be child of @p parent.
+ */
+static bool is_nested_descriptor(usb_dp_parser_t *parser,
+    usb_dp_parser_data_t *data, uint8_t *child, uint8_t *parent)
+{
+	return is_nested_descriptor_type(parser,
+	    get_descriptor_type(data, child),
+	    get_descriptor_type(data, parent));
+}
+
+/** Find first nested descriptor of given parent.
+ *
+ * @param parser Parser.
+ * @param data Parser data.
+ * @param parent Pointer to the beginning of parent descriptor.
+ * @return Pointer to the beginning of the first nested (child) descriptor.
+ * @retval NULL No child descriptor found.
+ * @retval NULL Invalid input.
+ */
+uint8_t *usb_dp_get_nested_descriptor(usb_dp_parser_t *parser,
+    usb_dp_parser_data_t *data, uint8_t *parent)
+{
+	if (!is_valid_descriptor_pointer(data, parent)) {
+		return NULL;
+	}
+
+	uint8_t *next = get_next_descriptor(data, parent);
+	if (next == NULL) {
+		return NULL;
+	}
+
+	if (is_nested_descriptor(parser, data, next, parent)) {
+		return next;
+	} else {
+		return NULL;
+	}
+}
+
+/** Skip all nested descriptors.
+ *
+ * @param parser Parser.
+ * @param data Parser data.
+ * @param parent Pointer to the beginning of parent descriptor.
+ * @return Pointer to first non-child descriptor.
+ * @retval NULL No next descriptor.
+ * @retval NULL Invalid input.
+ */
+static uint8_t *skip_nested_descriptors(usb_dp_parser_t *parser,
+    usb_dp_parser_data_t *data, uint8_t *parent)
+{
+	uint8_t *child = usb_dp_get_nested_descriptor(parser, data, parent);
+	if (child == NULL) {
+		return get_next_descriptor(data, parent);
+	}
+	uint8_t *next_child = skip_nested_descriptors(parser, data, child);
+	while (is_nested_descriptor(parser, data, next_child, parent)) {
+		next_child = skip_nested_descriptors(parser, data, next_child);
+	}
+
+	return next_child;
+}
+
+/** Get sibling descriptor.
+ *
+ * @param parser Parser.
+ * @param data Parser data.
+ * @param parent Pointer to common parent descriptor.
+ * @param sibling Left sibling.
+ * @return Pointer to first right sibling of @p sibling.
+ * @retval NULL No sibling exist.
+ * @retval NULL Invalid input.
+ */
+uint8_t *usb_dp_get_sibling_descriptor(usb_dp_parser_t *parser,
+    usb_dp_parser_data_t *data, uint8_t *parent, uint8_t *sibling)
+{
+	if (!is_valid_descriptor_pointer(data, parent)
+	    || !is_valid_descriptor_pointer(data, sibling)) {
+		return NULL;
+	}
+
+	uint8_t *possible_sibling = skip_nested_descriptors(parser, data, sibling);
+	if (possible_sibling == NULL) {
+		return NULL;
+	}
+
+	int parent_type = get_descriptor_type(data, parent);
+	int possible_sibling_type = get_descriptor_type(data, possible_sibling);
+	if (is_nested_descriptor_type(parser, possible_sibling_type, parent_type)) {
+		return possible_sibling;
+	} else {
+		return NULL;
+	}
+}
+
+/** Browser of the descriptor tree.
+ *
+ * @see usb_dp_walk_simple
+ *
+ * @param parser Descriptor parser.
+ * @param data Data for descriptor parser.
+ * @param root Pointer to current root of the tree.
+ * @param depth Current nesting depth.
+ * @param callback Callback for each found descriptor.
+ * @param arg Custom (user) argument.
+ */
+static void usb_dp_browse_simple_internal(usb_dp_parser_t *parser,
+    usb_dp_parser_data_t *data, uint8_t *root, size_t depth,
+    void (*callback)(uint8_t *, size_t, void *), void *arg)
+{
+	if (root == NULL) {
+		return;
+	}
+	callback(root, depth, arg);
+	uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
+	do {
+		usb_dp_browse_simple_internal(parser, data, child, depth + 1,
+		    callback, arg);
+		child = usb_dp_get_sibling_descriptor(parser, data,
+		    root, child);
+	} while (child != NULL);
+}
+
+/** Browse flatten descriptor tree.
+ *
+ * The callback is called with following arguments: pointer to the start
+ * of the descriptor (somewhere inside @p descriptors), depth of the nesting
+ * (starting from 0 for the first descriptor) and the custom argument.
+ * Note that the size of the descriptor is not passed because it can
+ * be read from the first byte of the descriptor.
+ *
+ * @param descriptors Descriptor data.
+ * @param descriptors_size Size of descriptor data (in bytes).
+ * @param descriptor_nesting Possible descriptor nesting.
+ * @param callback Callback for each found descriptor.
+ * @param arg Custom (user) argument.
+ */
+void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size,
+    usb_dp_descriptor_nesting_t *descriptor_nesting,
+    void (*callback)(uint8_t *, size_t, void *), void *arg)
+{
+	if ((descriptors == NULL) || (descriptors_size == 0)
+	    || (descriptor_nesting == NULL) || (callback == NULL)) {
+		return;
+	}
+
+	usb_dp_parser_data_t data = {
+		.data = descriptors,
+		.size = descriptors_size,
+		.arg = NULL
+	};
+
+	usb_dp_parser_t parser = {
+		.nesting = descriptor_nesting
+	};
+
+	usb_dp_browse_simple_internal(&parser, &data, descriptors,
+	    0, callback, arg);
+}
+
+/** @}
+ */
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/hub.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,359 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Functions needed by hub drivers.
+ */
+#include <usb/hub.h>
+#include <usb/pipes.h>
+#include <usb/request.h>
+#include <usb/recognise.h>
+#include <usbhc_iface.h>
+#include <errno.h>
+#include <assert.h>
+#include <usb/debug.h>
+
+/** How much time to wait between attempts to register endpoint 0:0.
+ * The value is based on typical value for port reset + some overhead.
+ */
+#define ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC (1000 * (10 + 2))
+
+/** Check that HC connection is alright.
+ *
+ * @param conn Connection to be checked.
+ */
+#define CHECK_CONNECTION(conn) \
+	do { \
+		assert((conn)); \
+		if (!usb_hc_connection_is_opened((conn))) { \
+			return ENOENT; \
+		} \
+	} while (false)
+
+/** Ask host controller for free address assignment.
+ *
+ * @param connection Opened connection to host controller.
+ * @param speed Speed of the new device (device that will be assigned
+ *    the returned address).
+ * @return Assigned USB address or negative error code.
+ */
+usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
+    usb_speed_t speed)
+{
+	CHECK_CONNECTION(connection);
+
+	sysarg_t address;
+	int rc = async_req_2_1(connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_REQUEST_ADDRESS, speed,
+	    &address);
+	if (rc != EOK) {
+		return (usb_address_t) rc;
+	} else {
+		return (usb_address_t) address;
+	}
+}
+
+/** Inform host controller about new device.
+ *
+ * @param connection Opened connection to host controller.
+ * @param attached_device Information about the new device.
+ * @return Error code.
+ */
+int usb_hc_register_device(usb_hc_connection_t * connection,
+    const usb_hc_attached_device_t *attached_device)
+{
+	CHECK_CONNECTION(connection);
+	if (attached_device == NULL) {
+		return EBADMEM;
+	}
+
+	return async_req_3_0(connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_BIND_ADDRESS,
+	    attached_device->address, attached_device->handle);
+}
+
+/** Inform host controller about device removal.
+ *
+ * @param connection Opened connection to host controller.
+ * @param address Address of the device that is being removed.
+ * @return Error code.
+ */
+int usb_hc_unregister_device(usb_hc_connection_t *connection,
+    usb_address_t address)
+{
+	CHECK_CONNECTION(connection);
+
+	return async_req_2_0(connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_RELEASE_ADDRESS, address);
+}
+
+/** Get handle of USB device with given address.
+ *
+ * @param[in] connection Opened connection to host controller.
+ * @param[in] address Address of device in question.
+ * @param[out] handle Where to write the device handle.
+ * @return Error code.
+ */
+int usb_hc_get_handle_by_address(usb_hc_connection_t *connection,
+    usb_address_t address, devman_handle_t *handle)
+{
+	CHECK_CONNECTION(connection);
+
+	sysarg_t tmp;
+	int rc = async_req_2_1(connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_GET_HANDLE_BY_ADDRESS,
+	    address, &tmp);
+	if ((rc == EOK) && (handle != NULL)) {
+		*handle = tmp;
+	}
+
+	return rc;
+}
+
+static void unregister_control_endpoint_on_default_address(
+    usb_hc_connection_t *connection)
+{
+	usb_device_connection_t dev_conn;
+	int rc = usb_device_connection_initialize_on_default_address(&dev_conn,
+	    connection);
+	if (rc != EOK) {
+		return;
+	}
+
+	usb_pipe_t ctrl_pipe;
+	rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
+	if (rc != EOK) {
+		return;
+	}
+
+	usb_pipe_unregister(&ctrl_pipe, connection);
+}
+
+
+/** Wrapper for registering attached device to the hub.
+ *
+ * The @p enable_port function is expected to enable signaling on given
+ * port.
+ * The two arguments to it can have arbitrary meaning
+ * (the @p port_no is only a suggestion)
+ * and are not touched at all by this function
+ * (they are passed as is to the @p enable_port function).
+ *
+ * If the @p enable_port fails (i.e. does not return EOK), the device
+ * addition is canceled.
+ * The return value is then returned (it is good idea to use different
+ * error codes than those listed as return codes by this function itself).
+ *
+ * The @p connection representing connection with host controller does not
+ * need to be started.
+ * This function duplicates the connection to allow simultaneous calls of
+ * this function (i.e. from different fibrils).
+ *
+ * @param[in] parent Parent device (i.e. the hub device).
+ * @param[in] connection Connection to host controller.
+ * @param[in] dev_speed New device speed.
+ * @param[in] enable_port Function for enabling signaling through the port the
+ *	device is attached to.
+ * @param[in] port_no Port number (passed through to @p enable_port).
+ * @param[in] arg Any data argument to @p enable_port.
+ * @param[out] assigned_address USB address of the device.
+ * @param[out] assigned_handle Devman handle of the new device.
+ * @param[in] dev_ops Child device ops.
+ * @param[in] new_dev_data Arbitrary pointer to be stored in the child
+ *	as @c driver_data.
+ * @param[out] new_fun Storage where pointer to allocated child function
+ *	will be written.
+ * @return Error code.
+ * @retval ENOENT Connection to HC not opened.
+ * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
+ * @retval EBUSY Failed reserving default USB address.
+ * @retval ENOTCONN Problem connecting to the host controller via USB pipe.
+ * @retval ESTALL Problem communication with device (either SET_ADDRESS
+ *	request or requests for descriptors when creating match ids).
+ */
+int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection,
+    usb_speed_t dev_speed,
+    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
+    usb_address_t *assigned_address, devman_handle_t *assigned_handle,
+    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
+{
+	assert(connection != NULL);
+	// FIXME: this is awful, we are accessing directly the structure.
+	usb_hc_connection_t hc_conn = {
+		.hc_handle = connection->hc_handle,
+		.hc_phone = -1
+	};
+
+	int rc;
+
+	rc = usb_hc_connection_open(&hc_conn);
+	if (rc != EOK) {
+		return rc;
+	}
+
+
+	/*
+	 * Request new address.
+	 */
+	usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
+	if (dev_addr < 0) {
+		usb_hc_connection_close(&hc_conn);
+		return EADDRNOTAVAIL;
+	}
+
+	/*
+	 * We will not register control pipe on default address.
+	 * The registration might fail. That means that someone else already
+	 * registered that endpoint. We will simply wait and try again.
+	 * (Someone else already wants to add a new device.)
+	 */
+	usb_device_connection_t dev_conn;
+	rc = usb_device_connection_initialize_on_default_address(&dev_conn,
+	    &hc_conn);
+	if (rc != EOK) {
+		rc = ENOTCONN;
+		goto leave_release_free_address;
+	}
+
+	usb_pipe_t ctrl_pipe;
+	rc = usb_pipe_initialize_default_control(&ctrl_pipe,
+	    &dev_conn);
+	if (rc != EOK) {
+		rc = ENOTCONN;
+		goto leave_release_free_address;
+	}
+
+	do {
+		rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0,
+		    &hc_conn);
+		if (rc != EOK) {
+			/* Do not overheat the CPU ;-). */
+			async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
+		}
+	} while (rc != EOK);
+
+	/*
+	 * Endpoint is registered. We can enable the port and change
+	 * device address.
+	 */
+	rc = enable_port(port_no, arg);
+	if (rc != EOK) {
+		goto leave_release_default_address;
+	}
+
+	rc = usb_pipe_probe_default_control(&ctrl_pipe);
+	if (rc != EOK) {
+		rc = ESTALL;
+		goto leave_release_default_address;
+	}
+
+	rc = usb_request_set_address(&ctrl_pipe, dev_addr);
+	if (rc != EOK) {
+		rc = ESTALL;
+		goto leave_release_default_address;
+	}
+
+	/*
+	 * Address changed. We can release the original endpoint, thus
+	 * allowing other to access the default address.
+	 */
+	unregister_control_endpoint_on_default_address(&hc_conn);
+
+	/*
+	 * Time to register the new endpoint.
+	 */
+	rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
+	if (rc != EOK) {
+		goto leave_release_free_address;
+	}
+
+	/*
+	 * It is time to register the device with devman.
+	 */
+	/* FIXME: create device_register that will get opened ctrl pipe. */
+	devman_handle_t child_handle;
+	rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
+	    parent, &child_handle,
+	    dev_ops, new_dev_data, new_fun);
+	if (rc != EOK) {
+		rc = ESTALL;
+		goto leave_release_free_address;
+	}
+
+	/*
+	 * And now inform the host controller about the handle.
+	 */
+	usb_hc_attached_device_t new_device = {
+		.address = dev_addr,
+		.handle = child_handle
+	};
+	rc = usb_hc_register_device(&hc_conn, &new_device);
+	if (rc != EOK) {
+		rc = EDESTADDRREQ;
+		goto leave_release_free_address;
+	}
+
+	/*
+	 * And we are done.
+	 */
+	if (assigned_address != NULL) {
+		*assigned_address = dev_addr;
+	}
+	if (assigned_handle != NULL) {
+		*assigned_handle = child_handle;
+	}
+
+	return EOK;
+
+
+
+	/*
+	 * Error handling (like nested exceptions) starts here.
+	 * Completely ignoring errors here.
+	 */
+leave_release_default_address:
+	usb_pipe_unregister(&ctrl_pipe, &hc_conn);
+
+leave_release_free_address:
+	usb_hc_unregister_device(&hc_conn, dev_addr);
+
+	usb_hc_connection_close(&hc_conn);
+
+	return rc;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/pipepriv.c
===================================================================
--- uspace/lib/usbdev/src/pipepriv.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/pipepriv.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,137 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Library internal functions on USB pipes (implementation).
+ */
+#include "pipepriv.h"
+#include <devman.h>
+#include <errno.h>
+#include <assert.h>
+
+/** Ensure exclusive access to the IPC phone of given pipe.
+ *
+ * @param pipe Pipe to be exclusively accessed.
+ */
+void pipe_start_transaction(usb_pipe_t *pipe)
+{
+	fibril_mutex_lock(&pipe->hc_phone_mutex);
+}
+
+/** Terminate exclusive access to the IPC phone of given pipe.
+ *
+ * @param pipe Pipe to be released from exclusive usage.
+ */
+void pipe_end_transaction(usb_pipe_t *pipe)
+{
+	fibril_mutex_unlock(&pipe->hc_phone_mutex);
+}
+
+/** Ensure exclusive access to the pipe as a whole.
+ *
+ * @param pipe Pipe to be exclusively accessed.
+ */
+void pipe_acquire(usb_pipe_t *pipe)
+{
+	fibril_mutex_lock(&pipe->guard);
+}
+
+/** Terminate exclusive access to the pipe as a whole.
+ *
+ * @param pipe Pipe to be released from exclusive usage.
+ */
+void pipe_release(usb_pipe_t *pipe)
+{
+	fibril_mutex_unlock(&pipe->guard);
+}
+
+/** Add reference of active transfers over the pipe.
+ *
+ * @param pipe The USB pipe.
+ * @param hide_failure Whether to hide failure when adding reference
+ *	(use soft refcount).
+ * @return Error code.
+ * @retval EOK Currently always.
+ */
+int pipe_add_ref(usb_pipe_t *pipe, bool hide_failure)
+{
+	pipe_acquire(pipe);
+
+	if (pipe->refcount == 0) {
+		/* Need to open the phone by ourselves. */
+		int phone = devman_device_connect(pipe->wire->hc_handle, 0);
+		if (phone < 0) {
+			if (hide_failure) {
+				pipe->refcount_soft++;
+				phone = EOK;
+			}
+			pipe_release(pipe);
+			return phone;
+		}
+		/*
+		 * No locking is needed, refcount is zero and whole pipe
+		 * mutex is locked.
+		 */
+		pipe->hc_phone = phone;
+	}
+	pipe->refcount++;
+
+	pipe_release(pipe);
+
+	return EOK;
+}
+
+/** Drop active transfer reference on the pipe.
+ *
+ * @param pipe The USB pipe.
+ */
+void pipe_drop_ref(usb_pipe_t *pipe)
+{
+	pipe_acquire(pipe);
+	if (pipe->refcount_soft > 0) {
+		pipe->refcount_soft--;
+		pipe_release(pipe);
+		return;
+	}
+	assert(pipe->refcount > 0);
+	pipe->refcount--;
+	if (pipe->refcount == 0) {
+		/* We were the last users, let's hang-up. */
+		async_hangup(pipe->hc_phone);
+		pipe->hc_phone = -1;
+	}
+	pipe_release(pipe);
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/pipepriv.h
===================================================================
--- uspace/lib/usbdev/src/pipepriv.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/pipepriv.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,54 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Library internal functions on USB pipes.
+ */
+#ifndef LIBUSB_PIPEPRIV_H_
+#define LIBUSB_PIPEPRIV_H_
+
+#include <usb/pipes.h>
+#include <bool.h>
+
+void pipe_acquire(usb_pipe_t *);
+void pipe_release(usb_pipe_t *);
+
+void pipe_start_transaction(usb_pipe_t *);
+void pipe_end_transaction(usb_pipe_t *);
+
+int pipe_add_ref(usb_pipe_t *, bool);
+void pipe_drop_ref(usb_pipe_t *);
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/pipes.c
===================================================================
--- uspace/lib/usbdev/src/pipes.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/pipes.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,260 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB endpoint pipes miscellaneous functions.
+ */
+#include <usb/usb.h>
+#include <usb/pipes.h>
+#include <usb/debug.h>
+#include <usb/driver.h>
+#include <usbhc_iface.h>
+#include <usb_iface.h>
+#include <devman.h>
+#include <errno.h>
+#include <assert.h>
+#include "pipepriv.h"
+
+#define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */
+
+/** Tell USB address assigned to given device.
+ *
+ * @param phone Phone to parent device.
+ * @param dev Device in question.
+ * @return USB address or error code.
+ */
+static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
+{
+	sysarg_t address;
+
+	/*
+	 * We are sending special value as a handle - zero - to get
+	 * handle of the parent function (that handle was used
+	 * when registering our device @p dev.
+	 */
+	int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_ADDRESS,
+	    0, &address);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return (usb_address_t) address;
+}
+
+/** Tell USB interface assigned to given device.
+ *
+ * @param device Device in question.
+ * @return Interface number (negative code means any).
+ */
+int usb_device_get_assigned_interface(ddf_dev_t *device)
+{
+	int parent_phone = devman_parent_device_connect(device->handle,
+	    IPC_FLAG_BLOCKING);
+	if (parent_phone < 0) {
+		return -1;
+	}
+
+	sysarg_t iface_no;
+	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_INTERFACE,
+	    device->handle, &iface_no);
+
+	async_hangup(parent_phone);
+
+	if (rc != EOK) {
+		return -1;
+	}
+
+	return (int) iface_no;
+}
+
+/** Tell USB address assigned to given device.
+ *
+ * @param dev_handle Devman handle of the USB device in question.
+ * @return USB address or negative error code.
+ */
+usb_address_t usb_device_get_assigned_address(devman_handle_t dev_handle)
+{
+	int parent_phone = devman_parent_device_connect(dev_handle,
+	    IPC_FLAG_BLOCKING);
+	if (parent_phone < 0) {
+		return parent_phone;
+	}
+
+	sysarg_t address;
+
+	int rc = async_req_2_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_ADDRESS,
+	    dev_handle, &address);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	async_hangup(parent_phone);
+
+	return (usb_address_t) address;
+}
+
+/** Initialize connection to USB device.
+ *
+ * @param connection Connection structure to be initialized.
+ * @param dev Generic device backing the USB device.
+ * @return Error code.
+ */
+int usb_device_connection_initialize_from_device(
+    usb_device_connection_t *connection, ddf_dev_t *dev)
+{
+	assert(connection);
+	assert(dev);
+
+	int rc;
+	devman_handle_t hc_handle;
+	usb_address_t my_address;
+
+	rc = usb_hc_find(dev->handle, &hc_handle);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	int parent_phone = devman_parent_device_connect(dev->handle,
+	    IPC_FLAG_BLOCKING);
+	if (parent_phone < 0) {
+		return parent_phone;
+	}
+
+	/*
+	 * 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,
+	    hc_handle, my_address);
+
+leave:
+	async_hangup(parent_phone);
+	return rc;
+}
+
+/** Initialize connection to USB device.
+ *
+ * @param connection Connection structure to be initialized.
+ * @param host_controller_handle Devman handle of host controller device is
+ * 	connected to.
+ * @param device_address Device USB address.
+ * @return Error code.
+ */
+int usb_device_connection_initialize(usb_device_connection_t *connection,
+    devman_handle_t host_controller_handle, usb_address_t device_address)
+{
+	assert(connection);
+
+	if ((device_address < 0) || (device_address >= USB11_ADDRESS_MAX)) {
+		return EINVAL;
+	}
+
+	connection->hc_handle = host_controller_handle;
+	connection->address = device_address;
+
+	return EOK;
+}
+
+/** Initialize connection to USB device on default address.
+ *
+ * @param dev_connection Device connection structure to be initialized.
+ * @param hc_connection Initialized connection to host controller.
+ * @return Error code.
+ */
+int usb_device_connection_initialize_on_default_address(
+    usb_device_connection_t *dev_connection,
+    usb_hc_connection_t *hc_connection)
+{
+	assert(dev_connection);
+
+	if (hc_connection == NULL) {
+		return EBADMEM;
+	}
+
+	return usb_device_connection_initialize(dev_connection,
+	    hc_connection->hc_handle, (usb_address_t) 0);
+}
+
+/** Prepare pipe for a long transfer.
+ *
+ * By a long transfer is mean transfer consisting of several
+ * requests to the HC.
+ * Calling such function is optional and it has positive effect of
+ * improved performance because IPC session is initiated only once.
+ *
+ * @param pipe Pipe over which the transfer will happen.
+ * @return Error code.
+ */
+void usb_pipe_start_long_transfer(usb_pipe_t *pipe)
+{
+	(void) pipe_add_ref(pipe, true);
+}
+
+/** Terminate a long transfer on a pipe.
+ *
+ * @see usb_pipe_start_long_transfer
+ *
+ * @param pipe Pipe where to end the long transfer.
+ */
+void usb_pipe_end_long_transfer(usb_pipe_t *pipe)
+{
+	pipe_drop_ref(pipe);
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,525 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Initialization of endpoint pipes.
+ *
+ */
+#include <usb/usb.h>
+#include <usb/pipes.h>
+#include <usb/dp.h>
+#include <usb/request.h>
+#include <usbhc_iface.h>
+#include <errno.h>
+#include <assert.h>
+
+#define CTRL_PIPE_MIN_PACKET_SIZE 8
+#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
+
+
+#define NESTING(parentname, childname) \
+	{ \
+		.child = USB_DESCTYPE_##childname, \
+		.parent = USB_DESCTYPE_##parentname, \
+	}
+#define LAST_NESTING { -1, -1 }
+
+/** Nesting pairs of standard descriptors. */
+static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
+	NESTING(CONFIGURATION, INTERFACE),
+	NESTING(INTERFACE, ENDPOINT),
+	NESTING(INTERFACE, HUB),
+	NESTING(INTERFACE, HID),
+	NESTING(HID, HID_REPORT),
+	LAST_NESTING
+};
+
+/** Tells whether given descriptor is of endpoint type.
+ *
+ * @param descriptor Descriptor in question.
+ * @return Whether the given descriptor is endpoint descriptor.
+ */
+static inline bool is_endpoint_descriptor(uint8_t *descriptor)
+{
+	return descriptor[1] == USB_DESCTYPE_ENDPOINT;
+}
+
+/** Tells whether found endpoint corresponds to endpoint described by user.
+ *
+ * @param wanted Endpoint description as entered by driver author.
+ * @param found Endpoint description obtained from endpoint descriptor.
+ * @return Whether the @p found descriptor fits the @p wanted descriptor.
+ */
+static bool endpoint_fits_description(const usb_endpoint_description_t *wanted,
+    usb_endpoint_description_t *found)
+{
+#define _SAME(fieldname) ((wanted->fieldname) == (found->fieldname))
+
+	if (!_SAME(direction)) {
+		return false;
+	}
+
+	if (!_SAME(transfer_type)) {
+		return false;
+	}
+
+	if ((wanted->interface_class >= 0) && !_SAME(interface_class)) {
+		return false;
+	}
+
+	if ((wanted->interface_subclass >= 0) && !_SAME(interface_subclass)) {
+		return false;
+	}
+
+	if ((wanted->interface_protocol >= 0) && !_SAME(interface_protocol)) {
+		return false;
+	}
+
+#undef _SAME
+
+	return true;
+}
+
+/** Find endpoint mapping for a found endpoint.
+ *
+ * @param mapping Endpoint mapping list.
+ * @param mapping_count Number of endpoint mappings in @p mapping.
+ * @param found_endpoint Description of found endpoint.
+ * @param interface_number Number of currently processed interface.
+ * @return Endpoint mapping corresponding to @p found_endpoint.
+ * @retval NULL No corresponding endpoint found.
+ */
+static usb_endpoint_mapping_t *find_endpoint_mapping(
+    usb_endpoint_mapping_t *mapping, size_t mapping_count,
+    usb_endpoint_description_t *found_endpoint,
+    int interface_number, int interface_setting)
+{
+	while (mapping_count > 0) {
+		bool interface_number_fits = (mapping->interface_no < 0)
+		    || (mapping->interface_no == interface_number);
+
+		bool interface_setting_fits = (mapping->interface_setting < 0)
+		    || (mapping->interface_setting == interface_setting);
+
+		bool endpoint_descriptions_fits = endpoint_fits_description(
+		    mapping->description, found_endpoint);
+
+		if (interface_number_fits
+		    && interface_setting_fits
+		    && endpoint_descriptions_fits) {
+			return mapping;
+		}
+
+		mapping++;
+		mapping_count--;
+	}
+	return NULL;
+}
+
+/** Process endpoint descriptor.
+ *
+ * @param mapping Endpoint mapping list.
+ * @param mapping_count Number of endpoint mappings in @p mapping.
+ * @param interface Interface descriptor under which belongs the @p endpoint.
+ * @param endpoint Endpoint descriptor.
+ * @param wire Connection backing the endpoint pipes.
+ * @return Error code.
+ */
+static int process_endpoint(
+    usb_endpoint_mapping_t *mapping, size_t mapping_count,
+    usb_standard_interface_descriptor_t *interface,
+    usb_standard_endpoint_descriptor_t *endpoint,
+    usb_device_connection_t *wire)
+{
+	usb_endpoint_description_t description;
+
+	/*
+	 * Get endpoint characteristics.
+	 */
+
+	/* Actual endpoint number is in bits 0..3 */
+	usb_endpoint_t ep_no = endpoint->endpoint_address & 0x0F;
+
+	/* Endpoint direction is set by bit 7 */
+	description.direction = (endpoint->endpoint_address & 128)
+	    ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
+	/* Transfer type is in bits 0..2 and the enum values corresponds 1:1 */
+	description.transfer_type = endpoint->attributes & 3;
+
+	/*
+	 * Get interface characteristics.
+	 */
+	description.interface_class = interface->interface_class;
+	description.interface_subclass = interface->interface_subclass;
+	description.interface_protocol = interface->interface_protocol;
+
+	/*
+	 * Find the most fitting mapping and initialize the pipe.
+	 */
+	usb_endpoint_mapping_t *ep_mapping = find_endpoint_mapping(mapping,
+	    mapping_count, &description,
+	    interface->interface_number, interface->alternate_setting);
+	if (ep_mapping == NULL) {
+		return ENOENT;
+	}
+
+	if (ep_mapping->pipe == NULL) {
+		return EBADMEM;
+	}
+	if (ep_mapping->present) {
+		return EEXISTS;
+	}
+
+	int rc = usb_pipe_initialize(ep_mapping->pipe, wire,
+	    ep_no, description.transfer_type, endpoint->max_packet_size,
+	    description.direction);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	ep_mapping->present = true;
+	ep_mapping->descriptor = endpoint;
+	ep_mapping->interface = interface;
+
+	return EOK;
+}
+
+/** Process whole USB interface.
+ *
+ * @param mapping Endpoint mapping list.
+ * @param mapping_count Number of endpoint mappings in @p mapping.
+ * @param parser Descriptor parser.
+ * @param parser_data Descriptor parser data.
+ * @param interface_descriptor Interface descriptor.
+ * @return Error code.
+ */
+static int process_interface(
+    usb_endpoint_mapping_t *mapping, size_t mapping_count,
+    usb_dp_parser_t *parser, usb_dp_parser_data_t *parser_data,
+    uint8_t *interface_descriptor)
+{
+	uint8_t *descriptor = usb_dp_get_nested_descriptor(parser,
+	    parser_data, interface_descriptor);
+
+	if (descriptor == NULL) {
+		return ENOENT;
+	}
+
+	do {
+		if (is_endpoint_descriptor(descriptor)) {
+			(void) process_endpoint(mapping, mapping_count,
+			    (usb_standard_interface_descriptor_t *)
+			        interface_descriptor,
+			    (usb_standard_endpoint_descriptor_t *)
+			        descriptor,
+			    (usb_device_connection_t *) parser_data->arg);
+		}
+
+		descriptor = usb_dp_get_sibling_descriptor(parser, parser_data,
+		    interface_descriptor, descriptor);
+	} while (descriptor != NULL);
+
+	return EOK;
+}
+
+/** Initialize endpoint pipes from configuration descriptor.
+ *
+ * The mapping array is expected to conform to following rules:
+ * - @c pipe must point to already allocated structure with uninitialized pipe
+ * - @c description must point to prepared endpoint description
+ * - @c descriptor does not need to be initialized (will be overwritten)
+ * - @c interface does not need to be initialized (will be overwritten)
+ * - @c present does not need to be initialized (will be overwritten)
+ *
+ * After processing the configuration descriptor, the mapping is updated
+ * in the following fashion:
+ * - @c present will be set to @c true when the endpoint was found in the
+ *   configuration
+ * - @c descriptor will point inside the configuration descriptor to endpoint
+ *   corresponding to given description (or NULL for not found descriptor)
+ * - @c interface will point inside the configuration descriptor to interface
+ *   descriptor the endpoint @c descriptor belongs to (or NULL for not found
+ *   descriptor)
+ * - @c pipe will be initialized when found, otherwise left untouched
+ * - @c description will be untouched under all circumstances
+ *
+ * @param mapping Endpoint mapping list.
+ * @param mapping_count Number of endpoint mappings in @p mapping.
+ * @param configuration_descriptor Full configuration descriptor (is expected
+ *	to be in USB endianness: i.e. as-is after being retrieved from
+ *	the device).
+ * @param configuration_descriptor_size Size of @p configuration_descriptor
+ *	in bytes.
+ * @param connection Connection backing the endpoint pipes.
+ * @return Error code.
+ */
+int usb_pipe_initialize_from_configuration(
+    usb_endpoint_mapping_t *mapping, size_t mapping_count,
+    uint8_t *configuration_descriptor, size_t configuration_descriptor_size,
+    usb_device_connection_t *connection)
+{
+	assert(connection);
+
+	if (configuration_descriptor == NULL) {
+		return EBADMEM;
+	}
+	if (configuration_descriptor_size
+	    < sizeof(usb_standard_configuration_descriptor_t)) {
+		return ERANGE;
+	}
+
+	/*
+	 * Go through the mapping and set all endpoints to not present.
+	 */
+	size_t i;
+	for (i = 0; i < mapping_count; i++) {
+		mapping[i].present = false;
+		mapping[i].descriptor = NULL;
+		mapping[i].interface = NULL;
+	}
+
+	/*
+	 * Prepare the descriptor parser.
+	 */
+	usb_dp_parser_t dp_parser = {
+		.nesting = descriptor_nesting
+	};
+	usb_dp_parser_data_t dp_data = {
+		.data = configuration_descriptor,
+		.size = configuration_descriptor_size,
+		.arg = connection
+	};
+
+	/*
+	 * Iterate through all interfaces.
+	 */
+	uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,
+	    &dp_data, configuration_descriptor);
+	if (interface == NULL) {
+		return ENOENT;
+	}
+	do {
+		(void) process_interface(mapping, mapping_count,
+		    &dp_parser, &dp_data,
+		    interface);
+		interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
+		    configuration_descriptor, interface);
+	} while (interface != NULL);
+
+	return EOK;
+}
+
+/** Initialize USB endpoint pipe.
+ *
+ * @param pipe Endpoint pipe to be initialized.
+ * @param connection Connection to the USB device backing this pipe (the wire).
+ * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
+ * @param transfer_type Transfer type (e.g. interrupt or bulk).
+ * @param max_packet_size Maximum packet size in bytes.
+ * @param direction Endpoint direction (in/out).
+ * @return Error code.
+ */
+int usb_pipe_initialize(usb_pipe_t *pipe,
+    usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
+    usb_transfer_type_t transfer_type, size_t max_packet_size,
+    usb_direction_t direction)
+{
+	assert(pipe);
+	assert(connection);
+
+	fibril_mutex_initialize(&pipe->guard);
+	pipe->wire = connection;
+	pipe->hc_phone = -1;
+	fibril_mutex_initialize(&pipe->hc_phone_mutex);
+	pipe->endpoint_no = endpoint_no;
+	pipe->transfer_type = transfer_type;
+	pipe->max_packet_size = max_packet_size;
+	pipe->direction = direction;
+	pipe->refcount = 0;
+	pipe->refcount_soft = 0;
+	pipe->auto_reset_halt = false;
+
+	return EOK;
+}
+
+
+/** Initialize USB endpoint pipe as the default zero control pipe.
+ *
+ * @param pipe Endpoint pipe to be initialized.
+ * @param connection Connection to the USB device backing this pipe (the wire).
+ * @return Error code.
+ */
+int usb_pipe_initialize_default_control(usb_pipe_t *pipe,
+    usb_device_connection_t *connection)
+{
+	assert(pipe);
+	assert(connection);
+
+	int rc = usb_pipe_initialize(pipe, connection,
+	    0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,
+	    USB_DIRECTION_BOTH);
+
+	pipe->auto_reset_halt = true;
+
+	return rc;
+}
+
+/** Probe default control pipe for max packet size.
+ *
+ * The function tries to get the correct value of max packet size several
+ * time before giving up.
+ *
+ * The session on the pipe shall not be started.
+ *
+ * @param pipe Default control pipe.
+ * @return Error code.
+ */
+int usb_pipe_probe_default_control(usb_pipe_t *pipe)
+{
+	assert(pipe);
+	assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
+
+	if ((pipe->direction != USB_DIRECTION_BOTH) ||
+	    (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
+	    (pipe->endpoint_no != 0)) {
+		return EINVAL;
+	}
+
+#define TRY_LOOP(attempt_var) \
+	for (attempt_var = 0; attempt_var < 3; attempt_var++)
+
+	size_t failed_attempts;
+	int rc;
+
+	usb_pipe_start_long_transfer(pipe);
+
+	uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
+	size_t transferred_size;
+	TRY_LOOP(failed_attempts) {
+		rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
+		    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
+		    0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE,
+		    &transferred_size);
+		if (rc == EOK) {
+			if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) {
+				rc = ELIMIT;
+				continue;
+			}
+			break;
+		}
+	}
+	usb_pipe_end_long_transfer(pipe);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	pipe->max_packet_size
+	    = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
+
+	return EOK;
+}
+
+/** Register endpoint with the host controller.
+ *
+ * @param pipe Pipe to be registered.
+ * @param interval Polling interval.
+ * @param hc_connection Connection to the host controller (must be opened).
+ * @return Error code.
+ */
+int usb_pipe_register(usb_pipe_t *pipe,
+    unsigned int interval,
+    usb_hc_connection_t *hc_connection)
+{
+	return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1,
+	    interval, hc_connection);
+}
+
+/** Register endpoint with a speed at the host controller.
+ *
+ * You will rarely need to use this function because it is needed only
+ * if the registered endpoint is of address 0 and there is no other way
+ * to tell speed of the device at address 0.
+ *
+ * @param pipe Pipe to be registered.
+ * @param speed Speed of the device
+ *	(invalid speed means use previously specified one).
+ * @param interval Polling interval.
+ * @param hc_connection Connection to the host controller (must be opened).
+ * @return Error code.
+ */
+int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed,
+    unsigned int interval,
+    usb_hc_connection_t *hc_connection)
+{
+	assert(pipe);
+	assert(hc_connection);
+
+	if (!usb_hc_connection_is_opened(hc_connection)) {
+		return EBADF;
+	}
+
+#define _PACK2(high, low) (((high) << 16) + (low))
+#define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
+
+	return async_req_4_0(hc_connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
+	    _PACK2(pipe->wire->address, pipe->endpoint_no),
+	    _PACK3(speed, pipe->transfer_type, pipe->direction),
+	    _PACK2(pipe->max_packet_size, interval));
+
+#undef _PACK2
+#undef _PACK3
+}
+
+/** Revert endpoint registration with the host controller.
+ *
+ * @param pipe Pipe to be unregistered.
+ * @param hc_connection Connection to the host controller (must be opened).
+ * @return Error code.
+ */
+int usb_pipe_unregister(usb_pipe_t *pipe,
+    usb_hc_connection_t *hc_connection)
+{
+	assert(pipe);
+	assert(hc_connection);
+
+	if (!usb_hc_connection_is_opened(hc_connection)) {
+		return EBADF;
+	}
+
+	return async_req_4_0(hc_connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT,
+	    pipe->wire->address, pipe->endpoint_no, pipe->direction);
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/pipesio.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,601 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Input and output functions (reads and writes) on endpoint pipes.
+ *
+ * Note on synchronousness of the operations: there is ABSOLUTELY NO
+ * guarantee that a call to particular function will not trigger a fibril
+ * switch.
+ *
+ * Note about the implementation: the transfer requests are always divided
+ * into two functions.
+ * The outer one does checking of input parameters (e.g. that session was
+ * already started, buffers are not NULL etc), while the inner one
+ * (with _no_checks suffix) does the actual IPC (it checks for IPC errors,
+ * obviously).
+ */
+#include <usb/usb.h>
+#include <usb/pipes.h>
+#include <errno.h>
+#include <assert.h>
+#include <usbhc_iface.h>
+#include <usb/request.h>
+#include "pipepriv.h"
+
+/** Request an in transfer, no checking of input parameters.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[out] buffer Buffer where to store the data.
+ * @param[in] size Size of the buffer (in bytes).
+ * @param[out] size_transfered Number of bytes that were actually transfered.
+ * @return Error code.
+ */
+static int usb_pipe_read_no_checks(usb_pipe_t *pipe,
+    void *buffer, size_t size, size_t *size_transfered)
+{
+	/*
+	 * Get corresponding IPC method.
+	 * In future, replace with static array of mappings
+	 * transfer type -> method.
+	 */
+	usbhc_iface_funcs_t ipc_method;
+	switch (pipe->transfer_type) {
+		case USB_TRANSFER_INTERRUPT:
+			ipc_method = IPC_M_USBHC_INTERRUPT_IN;
+			break;
+		case USB_TRANSFER_BULK:
+			ipc_method = IPC_M_USBHC_BULK_IN;
+			break;
+		default:
+			return ENOTSUP;
+	}
+
+	/* Ensure serialization over the phone. */
+	pipe_start_transaction(pipe);
+
+	/*
+	 * Make call identifying target USB device and type of transfer.
+	 */
+	aid_t opening_request = async_send_3(pipe->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
+	    pipe->wire->address, pipe->endpoint_no,
+	    NULL);
+	if (opening_request == 0) {
+		pipe_end_transaction(pipe);
+		return ENOMEM;
+	}
+
+	/*
+	 * Retrieve the data.
+	 */
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(pipe->hc_phone, buffer, size,
+	    &data_request_call);
+
+	/*
+	 * Since now on, someone else might access the backing phone
+	 * without breaking the transfer IPC protocol.
+	 */
+	pipe_end_transaction(pipe);
+
+	if (data_request == 0) {
+		/*
+		 * FIXME:
+		 * How to let the other side know that we want to abort?
+		 */
+		async_wait_for(opening_request, NULL);
+		return ENOMEM;
+	}
+
+	/*
+	 * Wait for the answer.
+	 */
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+
+	if (data_request_rc != EOK) {
+		/* Prefer the return code of the opening request. */
+		if (opening_request_rc != EOK) {
+			return (int) opening_request_rc;
+		} else {
+			return (int) data_request_rc;
+		}
+	}
+	if (opening_request_rc != EOK) {
+		return (int) opening_request_rc;
+	}
+
+	*size_transfered = IPC_GET_ARG2(data_request_call);
+
+	return EOK;
+}
+
+
+/** Request a read (in) transfer on an endpoint pipe.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[out] buffer Buffer where to store the data.
+ * @param[in] size Size of the buffer (in bytes).
+ * @param[out] size_transfered Number of bytes that were actually transfered.
+ * @return Error code.
+ */
+int usb_pipe_read(usb_pipe_t *pipe,
+    void *buffer, size_t size, size_t *size_transfered)
+{
+	assert(pipe);
+
+	if (buffer == NULL) {
+		return EINVAL;
+	}
+
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	if (pipe->direction != USB_DIRECTION_IN) {
+		return EBADF;
+	}
+
+	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
+		return EBADF;
+	}
+
+	int rc;
+	rc = pipe_add_ref(pipe, false);
+	if (rc != EOK) {
+		return rc;
+	}
+
+
+	size_t act_size = 0;
+
+	rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size);
+
+	pipe_drop_ref(pipe);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (size_transfered != NULL) {
+		*size_transfered = act_size;
+	}
+
+	return EOK;
+}
+
+
+
+
+/** Request an out transfer, no checking of input parameters.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] buffer Buffer with data to transfer.
+ * @param[in] size Size of the buffer (in bytes).
+ * @return Error code.
+ */
+static int usb_pipe_write_no_check(usb_pipe_t *pipe,
+    void *buffer, size_t size)
+{
+	/*
+	 * Get corresponding IPC method.
+	 * In future, replace with static array of mappings
+	 * transfer type -> method.
+	 */
+	usbhc_iface_funcs_t ipc_method;
+	switch (pipe->transfer_type) {
+		case USB_TRANSFER_INTERRUPT:
+			ipc_method = IPC_M_USBHC_INTERRUPT_OUT;
+			break;
+		case USB_TRANSFER_BULK:
+			ipc_method = IPC_M_USBHC_BULK_OUT;
+			break;
+		default:
+			return ENOTSUP;
+	}
+
+	/* Ensure serialization over the phone. */
+	pipe_start_transaction(pipe);
+
+	/*
+	 * Make call identifying target USB device and type of transfer.
+	 */
+	aid_t opening_request = async_send_3(pipe->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
+	    pipe->wire->address, pipe->endpoint_no,
+	    NULL);
+	if (opening_request == 0) {
+		pipe_end_transaction(pipe);
+		return ENOMEM;
+	}
+
+	/*
+	 * Send the data.
+	 */
+	int rc = async_data_write_start(pipe->hc_phone, buffer, size);
+
+	/*
+	 * Since now on, someone else might access the backing phone
+	 * without breaking the transfer IPC protocol.
+	 */
+	pipe_end_transaction(pipe);
+
+	if (rc != EOK) {
+		async_wait_for(opening_request, NULL);
+		return rc;
+	}
+
+	/*
+	 * Wait for the answer.
+	 */
+	sysarg_t opening_request_rc;
+	async_wait_for(opening_request, &opening_request_rc);
+
+	return (int) opening_request_rc;
+}
+
+/** Request a write (out) transfer on an endpoint pipe.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] buffer Buffer with data to transfer.
+ * @param[in] size Size of the buffer (in bytes).
+ * @return Error code.
+ */
+int usb_pipe_write(usb_pipe_t *pipe,
+    void *buffer, size_t size)
+{
+	assert(pipe);
+
+	if (buffer == NULL) {
+		return EINVAL;
+	}
+
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	if (pipe->direction != USB_DIRECTION_OUT) {
+		return EBADF;
+	}
+
+	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
+		return EBADF;
+	}
+
+	int rc;
+
+	rc = pipe_add_ref(pipe, false);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	rc = usb_pipe_write_no_check(pipe, buffer, size);
+
+	pipe_drop_ref(pipe);
+
+	return rc;
+}
+
+/** Try to clear endpoint halt of default control pipe.
+ *
+ * @param pipe Pipe for control endpoint zero.
+ */
+static void clear_self_endpoint_halt(usb_pipe_t *pipe)
+{
+	assert(pipe != NULL);
+
+	if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) {
+		return;
+	}
+
+
+	/* Prevent indefinite recursion. */
+	pipe->auto_reset_halt = false;
+	usb_request_clear_endpoint_halt(pipe, 0);
+	pipe->auto_reset_halt = true;
+}
+
+
+/** Request a control read transfer, no checking of input parameters.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] setup_buffer Buffer with the setup packet.
+ * @param[in] setup_buffer_size Size of the setup packet (in bytes).
+ * @param[out] data_buffer Buffer for incoming data.
+ * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
+ * @param[out] data_transfered_size Number of bytes that were actually
+ *                                  transfered during the DATA stage.
+ * @return Error code.
+ */
+static int usb_pipe_control_read_no_check(usb_pipe_t *pipe,
+    void *setup_buffer, size_t setup_buffer_size,
+    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
+{
+	/* Ensure serialization over the phone. */
+	pipe_start_transaction(pipe);
+
+	/*
+	 * Make call identifying target USB device and control transfer type.
+	 */
+	aid_t opening_request = async_send_3(pipe->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
+	    pipe->wire->address, pipe->endpoint_no,
+	    NULL);
+	if (opening_request == 0) {
+		return ENOMEM;
+	}
+
+	/*
+	 * Send the setup packet.
+	 */
+	int rc = async_data_write_start(pipe->hc_phone,
+	    setup_buffer, setup_buffer_size);
+	if (rc != EOK) {
+		pipe_end_transaction(pipe);
+		async_wait_for(opening_request, NULL);
+		return rc;
+	}
+
+	/*
+	 * Retrieve the data.
+	 */
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(pipe->hc_phone,
+	    data_buffer, data_buffer_size,
+	    &data_request_call);
+
+	/*
+	 * Since now on, someone else might access the backing phone
+	 * without breaking the transfer IPC protocol.
+	 */
+	pipe_end_transaction(pipe);
+
+
+	if (data_request == 0) {
+		async_wait_for(opening_request, NULL);
+		return ENOMEM;
+	}
+
+	/*
+	 * Wait for the answer.
+	 */
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+
+	if (data_request_rc != EOK) {
+		/* Prefer the return code of the opening request. */
+		if (opening_request_rc != EOK) {
+			return (int) opening_request_rc;
+		} else {
+			return (int) data_request_rc;
+		}
+	}
+	if (opening_request_rc != EOK) {
+		return (int) opening_request_rc;
+	}
+
+	*data_transfered_size = IPC_GET_ARG2(data_request_call);
+
+	return EOK;
+}
+
+/** Request a control read transfer on an endpoint pipe.
+ *
+ * This function encapsulates all three stages of a control transfer.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] setup_buffer Buffer with the setup packet.
+ * @param[in] setup_buffer_size Size of the setup packet (in bytes).
+ * @param[out] data_buffer Buffer for incoming data.
+ * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
+ * @param[out] data_transfered_size Number of bytes that were actually
+ *                                  transfered during the DATA stage.
+ * @return Error code.
+ */
+int usb_pipe_control_read(usb_pipe_t *pipe,
+    void *setup_buffer, size_t setup_buffer_size,
+    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
+{
+	assert(pipe);
+
+	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
+		return EINVAL;
+	}
+
+	if ((data_buffer == NULL) || (data_buffer_size == 0)) {
+		return EINVAL;
+	}
+
+	if ((pipe->direction != USB_DIRECTION_BOTH)
+	    || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
+		return EBADF;
+	}
+
+	int rc;
+
+	rc = pipe_add_ref(pipe, false);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	size_t act_size = 0;
+	rc = usb_pipe_control_read_no_check(pipe,
+	    setup_buffer, setup_buffer_size,
+	    data_buffer, data_buffer_size, &act_size);
+
+	if (rc == ESTALL) {
+		clear_self_endpoint_halt(pipe);
+	}
+
+	pipe_drop_ref(pipe);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (data_transfered_size != NULL) {
+		*data_transfered_size = act_size;
+	}
+
+	return EOK;
+}
+
+
+/** Request a control write transfer, no checking of input parameters.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] setup_buffer Buffer with the setup packet.
+ * @param[in] setup_buffer_size Size of the setup packet (in bytes).
+ * @param[in] data_buffer Buffer with data to be sent.
+ * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
+ * @return Error code.
+ */
+static int usb_pipe_control_write_no_check(usb_pipe_t *pipe,
+    void *setup_buffer, size_t setup_buffer_size,
+    void *data_buffer, size_t data_buffer_size)
+{
+	/* Ensure serialization over the phone. */
+	pipe_start_transaction(pipe);
+
+	/*
+	 * Make call identifying target USB device and control transfer type.
+	 */
+	aid_t opening_request = async_send_4(pipe->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
+	    pipe->wire->address, pipe->endpoint_no,
+	    data_buffer_size,
+	    NULL);
+	if (opening_request == 0) {
+		pipe_end_transaction(pipe);
+		return ENOMEM;
+	}
+
+	/*
+	 * Send the setup packet.
+	 */
+	int rc = async_data_write_start(pipe->hc_phone,
+	    setup_buffer, setup_buffer_size);
+	if (rc != EOK) {
+		pipe_end_transaction(pipe);
+		async_wait_for(opening_request, NULL);
+		return rc;
+	}
+
+	/*
+	 * Send the data (if any).
+	 */
+	if (data_buffer_size > 0) {
+		rc = async_data_write_start(pipe->hc_phone,
+		    data_buffer, data_buffer_size);
+
+		/* All data sent, pipe can be released. */
+		pipe_end_transaction(pipe);
+
+		if (rc != EOK) {
+			async_wait_for(opening_request, NULL);
+			return rc;
+		}
+	} else {
+		/* No data to send, we can release the pipe for others. */
+		pipe_end_transaction(pipe);
+	}
+
+	/*
+	 * Wait for the answer.
+	 */
+	sysarg_t opening_request_rc;
+	async_wait_for(opening_request, &opening_request_rc);
+
+	return (int) opening_request_rc;
+}
+
+/** Request a control write transfer on an endpoint pipe.
+ *
+ * This function encapsulates all three stages of a control transfer.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] setup_buffer Buffer with the setup packet.
+ * @param[in] setup_buffer_size Size of the setup packet (in bytes).
+ * @param[in] data_buffer Buffer with data to be sent.
+ * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
+ * @return Error code.
+ */
+int usb_pipe_control_write(usb_pipe_t *pipe,
+    void *setup_buffer, size_t setup_buffer_size,
+    void *data_buffer, size_t data_buffer_size)
+{
+	assert(pipe);
+
+	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
+		return EINVAL;
+	}
+
+	if ((data_buffer == NULL) && (data_buffer_size > 0)) {
+		return EINVAL;
+	}
+
+	if ((data_buffer != NULL) && (data_buffer_size == 0)) {
+		return EINVAL;
+	}
+
+	if ((pipe->direction != USB_DIRECTION_BOTH)
+	    || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
+		return EBADF;
+	}
+
+	int rc;
+
+	rc = pipe_add_ref(pipe, false);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	rc = usb_pipe_control_write_no_check(pipe,
+	    setup_buffer, setup_buffer_size, data_buffer, data_buffer_size);
+
+	if (rc == ESTALL) {
+		clear_self_endpoint_halt(pipe);
+	}
+
+	pipe_drop_ref(pipe);
+
+	return rc;
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/recognise.c
===================================================================
--- uspace/lib/usbdev/src/recognise.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/recognise.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,442 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Functions for recognition of attached devices.
+ */
+#include <sys/types.h>
+#include <fibril_synch.h>
+#include <usb/pipes.h>
+#include <usb/recognise.h>
+#include <usb/ddfiface.h>
+#include <usb/request.h>
+#include <usb/classes/classes.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+
+/** Index to append after device name for uniqueness. */
+static size_t device_name_index = 0;
+/** Mutex guard for device_name_index. */
+static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
+
+/** DDF operations of child devices. */
+ddf_dev_ops_t child_ops = {
+	.interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
+};
+
+/** Get integer part from BCD coded number. */
+#define BCD_INT(a) (((unsigned int)(a)) / 256)
+/** Get fraction part from BCD coded number (as an integer, no less). */
+#define BCD_FRAC(a) (((unsigned int)(a)) % 256)
+
+/** Format for BCD coded number to be used in printf. */
+#define BCD_FMT "%x.%x"
+/** Arguments to printf for BCD coded number. */
+#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
+
+/* FIXME: make this dynamic */
+#define MATCH_STRING_MAX 256
+
+/** Add formatted match id.
+ *
+ * @param matches List of match ids where to add to.
+ * @param score Score of the match.
+ * @param format Printf-like format
+ * @return Error code.
+ */
+static int usb_add_match_id(match_id_list_t *matches, int score,
+    const char *format, ...)
+{
+	char *match_str = NULL;
+	match_id_t *match_id = NULL;
+	int rc;
+	
+	match_str = malloc(MATCH_STRING_MAX + 1);
+	if (match_str == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	/*
+	 * FIXME: replace with dynamic allocation of exact size
+	 */
+	va_list args;
+	va_start(args, format	);
+	vsnprintf(match_str, MATCH_STRING_MAX, format, args);
+	match_str[MATCH_STRING_MAX] = 0;
+	va_end(args);
+
+	match_id = create_match_id();
+	if (match_id == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	match_id->id = match_str;
+	match_id->score = score;
+	add_match_id(matches, match_id);
+
+	return EOK;
+	
+failure:
+	if (match_str != NULL) {
+		free(match_str);
+	}
+	if (match_id != NULL) {
+		match_id->id = NULL;
+		delete_match_id(match_id);
+	}
+	
+	return rc;
+}
+
+/** Add match id to list or return with error code.
+ *
+ * @param match_ids List of match ids.
+ * @param score Match id score.
+ * @param format Format of the matching string
+ * @param ... Arguments for the format.
+ */
+#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
+	do { \
+		int __rc = usb_add_match_id((match_ids), (score), \
+		    format, ##__VA_ARGS__); \
+		if (__rc != EOK) { \
+			return __rc; \
+		} \
+	} while (0)
+
+/** Create device match ids based on its interface.
+ *
+ * @param[in] desc_device Device descriptor.
+ * @param[in] desc_interface Interface descriptor.
+ * @param[out] matches Initialized list of match ids.
+ * @return Error code (the two mentioned are not the only ones).
+ * @retval EINVAL Invalid input parameters (expects non NULL pointers).
+ * @retval ENOENT Device class is not "use interface".
+ */
+int usb_device_create_match_ids_from_interface(
+    const usb_standard_device_descriptor_t *desc_device,
+    const usb_standard_interface_descriptor_t *desc_interface,
+    match_id_list_t *matches)
+{
+	if (desc_interface == NULL) {
+		return EINVAL;
+	}
+	if (matches == NULL) {
+		return EINVAL;
+	}
+
+	if (desc_interface->interface_class == USB_CLASS_USE_INTERFACE) {
+		return ENOENT;
+	}
+
+	const char *classname = usb_str_class(desc_interface->interface_class);
+	assert(classname != NULL);
+
+#define IFACE_PROTOCOL_FMT "interface&class=%s&subclass=0x%02x&protocol=0x%02x"
+#define IFACE_PROTOCOL_ARGS classname, desc_interface->interface_subclass, \
+    desc_interface->interface_protocol
+
+#define IFACE_SUBCLASS_FMT "interface&class=%s&subclass=0x%02x"
+#define IFACE_SUBCLASS_ARGS classname, desc_interface->interface_subclass
+
+#define IFACE_CLASS_FMT "interface&class=%s"
+#define IFACE_CLASS_ARGS classname
+
+#define VENDOR_RELEASE_FMT "vendor=0x%04x&product=0x%04x&release=" BCD_FMT
+#define VENDOR_RELEASE_ARGS desc_device->vendor_id, desc_device->product_id, \
+    BCD_ARGS(desc_device->device_version)
+
+#define VENDOR_PRODUCT_FMT "vendor=0x%04x&product=0x%04x"
+#define VENDOR_PRODUCT_ARGS desc_device->vendor_id, desc_device->product_id
+
+#define VENDOR_ONLY_FMT "vendor=0x%04x"
+#define VENDOR_ONLY_ARGS desc_device->vendor_id
+
+	/*
+	 * If the vendor is specified, create match ids with vendor with
+	 * higher score.
+	 * Then the same ones without the vendor part.
+	 */
+	if ((desc_device != NULL) && (desc_device->vendor_id != 0)) {
+		/* First, interface matches with device release number. */
+		ADD_MATCHID_OR_RETURN(matches, 250,
+		    "usb&" VENDOR_RELEASE_FMT "&" IFACE_PROTOCOL_FMT,
+		    VENDOR_RELEASE_ARGS, IFACE_PROTOCOL_ARGS);
+		ADD_MATCHID_OR_RETURN(matches, 240,
+		    "usb&" VENDOR_RELEASE_FMT "&" IFACE_SUBCLASS_FMT,
+		    VENDOR_RELEASE_ARGS, IFACE_SUBCLASS_ARGS);
+		ADD_MATCHID_OR_RETURN(matches, 230,
+		    "usb&" VENDOR_RELEASE_FMT "&" IFACE_CLASS_FMT,
+		    VENDOR_RELEASE_ARGS, IFACE_CLASS_ARGS);
+
+		/* Next, interface matches without release number. */
+		ADD_MATCHID_OR_RETURN(matches, 220,
+		    "usb&" VENDOR_PRODUCT_FMT "&" IFACE_PROTOCOL_FMT,
+		    VENDOR_PRODUCT_ARGS, IFACE_PROTOCOL_ARGS);
+		ADD_MATCHID_OR_RETURN(matches, 210,
+		    "usb&" VENDOR_PRODUCT_FMT "&" IFACE_SUBCLASS_FMT,
+		    VENDOR_PRODUCT_ARGS, IFACE_SUBCLASS_ARGS);
+		ADD_MATCHID_OR_RETURN(matches, 200,
+		    "usb&" VENDOR_PRODUCT_FMT "&" IFACE_CLASS_FMT,
+		    VENDOR_PRODUCT_ARGS, IFACE_CLASS_ARGS);
+
+		/* Finally, interface matches with only vendor. */
+		ADD_MATCHID_OR_RETURN(matches, 190,
+		    "usb&" VENDOR_ONLY_FMT "&" IFACE_PROTOCOL_FMT,
+		    VENDOR_ONLY_ARGS, IFACE_PROTOCOL_ARGS);
+		ADD_MATCHID_OR_RETURN(matches, 180,
+		    "usb&" VENDOR_ONLY_FMT "&" IFACE_SUBCLASS_FMT,
+		    VENDOR_ONLY_ARGS, IFACE_SUBCLASS_ARGS);
+		ADD_MATCHID_OR_RETURN(matches, 170,
+		    "usb&" VENDOR_ONLY_FMT "&" IFACE_CLASS_FMT,
+		    VENDOR_ONLY_ARGS, IFACE_CLASS_ARGS);
+	}
+
+	/* Now, the same but without any vendor specification. */
+	ADD_MATCHID_OR_RETURN(matches, 160,
+	    "usb&" IFACE_PROTOCOL_FMT,
+	    IFACE_PROTOCOL_ARGS);
+	ADD_MATCHID_OR_RETURN(matches, 150,
+	    "usb&" IFACE_SUBCLASS_FMT,
+	    IFACE_SUBCLASS_ARGS);
+	ADD_MATCHID_OR_RETURN(matches, 140,
+	    "usb&" IFACE_CLASS_FMT,
+	    IFACE_CLASS_ARGS);
+
+#undef IFACE_PROTOCOL_FMT
+#undef IFACE_PROTOCOL_ARGS
+#undef IFACE_SUBCLASS_FMT
+#undef IFACE_SUBCLASS_ARGS
+#undef IFACE_CLASS_FMT
+#undef IFACE_CLASS_ARGS
+#undef VENDOR_RELEASE_FMT
+#undef VENDOR_RELEASE_ARGS
+#undef VENDOR_PRODUCT_FMT
+#undef VENDOR_PRODUCT_ARGS
+#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;
+}
+
+/** Create DDF match ids from USB device descriptor.
+ *
+ * @param matches List of match ids to extend.
+ * @param device_descriptor Device descriptor returned by given device.
+ * @return Error code.
+ */
+int usb_device_create_match_ids_from_device_descriptor(
+    const usb_standard_device_descriptor_t *device_descriptor,
+    match_id_list_t *matches)
+{
+	/*
+	 * Unless the vendor id is 0, the pair idVendor-idProduct
+	 * quite uniquely describes the device.
+	 */
+	if (device_descriptor->vendor_id != 0) {
+		/* First, with release number. */
+		ADD_MATCHID_OR_RETURN(matches, 100,
+		    "usb&vendor=0x%04x&product=0x%04x&release=" BCD_FMT,
+		    (int) device_descriptor->vendor_id,
+		    (int) device_descriptor->product_id,
+		    BCD_ARGS(device_descriptor->device_version));
+		
+		/* Next, without release number. */
+		ADD_MATCHID_OR_RETURN(matches, 90,
+		    "usb&vendor=0x%04x&product=0x%04x",
+		    (int) device_descriptor->vendor_id,
+		    (int) device_descriptor->product_id);
+	}	
+
+	/*
+	 * If the device class points to interface we skip adding
+	 * class directly but we add a multi interface device.
+	 */
+	if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
+		ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
+		    usb_str_class(device_descriptor->device_class));
+	} else {
+		ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid");
+	}
+	
+	/* As a last resort, try fallback driver. */
+	ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback");
+
+	return EOK;
+}
+
+
+/** Create match ids describing attached device.
+ *
+ * @warning The list of match ids @p matches may change even when
+ * function exits with error.
+ *
+ * @param ctrl_pipe Control pipe to given device (session must be already
+ *	started).
+ * @param matches Initialized list of match ids.
+ * @return Error code.
+ */
+int usb_device_create_match_ids(usb_pipe_t *ctrl_pipe,
+    match_id_list_t *matches)
+{
+	int rc;
+	/*
+	 * Retrieve device descriptor and add matches from it.
+	 */
+	usb_standard_device_descriptor_t device_descriptor;
+
+	rc = usb_request_get_device_descriptor(ctrl_pipe, &device_descriptor);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	rc = usb_device_create_match_ids_from_device_descriptor(
+	    &device_descriptor, matches);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return EOK;
+}
+
+/** Probe for device kind and register it in devman.
+ *
+ * @param[in] address Address of the (unknown) attached device.
+ * @param[in] hc_handle Handle of the host controller.
+ * @param[in] parent Parent device.
+ * @param[out] child_handle Handle of the child device.
+ * @param[in] dev_ops Child device ops.
+ * @param[in] dev_data Arbitrary pointer to be stored in the child
+ *	as @c driver_data.
+ * @param[out] child_fun Storage where pointer to allocated child function
+ *	will be written.
+ * @return Error code.
+ */
+int usb_device_register_child_in_devman(usb_address_t address,
+    devman_handle_t hc_handle,
+    ddf_dev_t *parent, devman_handle_t *child_handle,
+    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
+{
+	size_t this_device_name_index;
+
+	fibril_mutex_lock(&device_name_index_mutex);
+	this_device_name_index = device_name_index;
+	device_name_index++;
+	fibril_mutex_unlock(&device_name_index_mutex);
+
+	ddf_fun_t *child = NULL;
+	char *child_name = NULL;
+	int rc;
+	usb_device_connection_t dev_connection;
+	usb_pipe_t ctrl_pipe;
+
+	rc = usb_device_connection_initialize(&dev_connection, hc_handle, address);
+	if (rc != EOK) {
+		goto failure;
+	}
+
+	rc = usb_pipe_initialize_default_control(&ctrl_pipe,
+	    &dev_connection);
+	if (rc != EOK) {
+		goto failure;
+	}
+	rc = usb_pipe_probe_default_control(&ctrl_pipe);
+	if (rc != EOK) {
+		goto failure;
+	}
+
+	/*
+	 * TODO: Once the device driver framework support persistent
+	 * naming etc., something more descriptive could be created.
+	 */
+	rc = asprintf(&child_name, "usb%02zu_a%d",
+	    this_device_name_index, address);
+	if (rc < 0) {
+		goto failure;
+	}
+
+	child = ddf_fun_create(parent, fun_inner, child_name);
+	if (child == NULL) {
+		rc = ENOMEM;
+		goto failure;
+	}
+
+	if (dev_ops != NULL) {
+		child->ops = dev_ops;
+	} else {
+		child->ops = &child_ops;
+	}
+
+	child->driver_data = dev_data;
+
+	rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
+	if (rc != EOK) {
+		goto failure;
+	}
+
+	rc = ddf_fun_bind(child);
+	if (rc != EOK) {
+		goto failure;
+	}
+
+	if (child_handle != NULL) {
+		*child_handle = child->handle;
+	}
+
+	if (child_fun != NULL) {
+		*child_fun = child;
+	}
+
+	return EOK;
+
+failure:
+	if (child != NULL) {
+		child->name = NULL;
+		/* This takes care of match_id deallocation as well. */
+		ddf_fun_destroy(child);
+	}
+	if (child_name != NULL) {
+		free(child_name);
+	}
+
+	return rc;
+}
+
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/request.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,930 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Standard USB requests (implementation).
+ */
+#include <usb/request.h>
+#include <errno.h>
+#include <assert.h>
+#include <usb/debug.h>
+
+#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
+
+/** Generic wrapper for SET requests using standard control request format.
+ *
+ * @see usb_pipe_control_write
+ *
+ * @param pipe Pipe used for the communication.
+ * @param request_type Request type (standard/class/vendor).
+ * @param recipient Request recipient (e.g. device or endpoint).
+ * @param request Actual request (e.g. GET_DESCRIPTOR).
+ * @param value Value of @c wValue field of setup packet
+ * 	(must be in USB endianness).
+ * @param index Value of @c wIndex field of setup packet
+ * 	(must be in USB endianness).
+ * @param data Data to be sent during DATA stage
+ * 	(expected to be in USB endianness).
+ * @param data_size Size of the @p data buffer (in native endianness).
+ * @return Error code.
+ * @retval EBADMEM @p pipe is NULL.
+ * @retval EBADMEM @p data is NULL and @p data_size is not zero.
+ * @retval ERANGE Data buffer too large.
+ */
+int usb_control_request_set(usb_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint8_t request,
+    uint16_t value, uint16_t index,
+    void *data, size_t data_size)
+{
+	if (pipe == NULL) {
+		return EBADMEM;
+	}
+
+	if (data_size > MAX_DATA_LENGTH) {
+		return ERANGE;
+	}
+
+	if ((data_size > 0) && (data == NULL)) {
+		return EBADMEM;
+	}
+
+	/*
+	 * TODO: check that @p request_type and @p recipient are
+	 * within ranges.
+	 */
+
+	usb_device_request_setup_packet_t setup_packet;
+	setup_packet.request_type = (request_type << 5) | recipient;
+	setup_packet.request = request;
+	setup_packet.value = value;
+	setup_packet.index = index;
+	setup_packet.length = (uint16_t) data_size;
+
+	int rc = usb_pipe_control_write(pipe,
+	    &setup_packet, sizeof(setup_packet),
+	    data, data_size);
+
+	return rc;
+}
+
+ /** Generic wrapper for GET requests using standard control request format.
+  *
+  * @see usb_pipe_control_read
+  *
+  * @param pipe Pipe used for the communication.
+  * @param request_type Request type (standard/class/vendor).
+  * @param recipient Request recipient (e.g. device or endpoint).
+  * @param request Actual request (e.g. GET_DESCRIPTOR).
+  * @param value Value of @c wValue field of setup packet
+  * 	(must be in USB endianness).
+  * @param index Value of @c wIndex field of setup packet
+  *	(must be in USB endianness).
+  * @param data Buffer where to store data accepted during the DATA stage.
+  *	(they will come in USB endianness).
+  * @param data_size Size of the @p data buffer
+  * 	(in native endianness).
+  * @param actual_data_size Actual size of transfered data
+  * 	(in native endianness).
+  * @return Error code.
+  * @retval EBADMEM @p pipe is NULL.
+  * @retval EBADMEM @p data is NULL and @p data_size is not zero.
+  * @retval ERANGE Data buffer too large.
+  */
+int usb_control_request_get(usb_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint8_t request,
+    uint16_t value, uint16_t index,
+    void *data, size_t data_size, size_t *actual_data_size)
+{
+	if (pipe == NULL) {
+		return EBADMEM;
+	}
+
+	if (data_size > MAX_DATA_LENGTH) {
+		return ERANGE;
+	}
+
+	if ((data_size > 0) && (data == NULL)) {
+		return EBADMEM;
+	}
+
+	/*
+	 * TODO: check that @p request_type and @p recipient are
+	 * within ranges.
+	 */
+
+	usb_device_request_setup_packet_t setup_packet;
+	setup_packet.request_type = 128 | (request_type << 5) | recipient;
+	setup_packet.request = request;
+	setup_packet.value = value;
+	setup_packet.index = index;
+	setup_packet.length = (uint16_t) data_size;
+
+	int rc = usb_pipe_control_read(pipe,
+	    &setup_packet, sizeof(setup_packet),
+	    data, data_size, actual_data_size);
+
+	return rc;
+}
+
+/** Retrieve status of a USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index Recipient index (in native endianness).
+ * @param[in] recipient Recipient of the GET_STATUS request.
+ * @param[out] status Recipient status (in native endianness).
+ * @return Error code.
+ */
+int usb_request_get_status(usb_pipe_t *pipe,
+    usb_request_recipient_t recipient, uint16_t index,
+    uint16_t *status)
+{
+	if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) {
+		return EINVAL;
+	}
+
+	if (status == NULL) {
+		return EBADMEM;
+	}
+
+	uint16_t status_usb_endianess;
+	size_t data_transfered_size;
+	int rc = usb_control_request_get(pipe, USB_REQUEST_TYPE_STANDARD,
+	    recipient, USB_DEVREQ_GET_STATUS, 0, uint16_host2usb(index),
+	    &status_usb_endianess, 2, &data_transfered_size);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (data_transfered_size != 2) {
+		return ELIMIT;
+	}
+
+	*status = uint16_usb2host(status_usb_endianess);
+
+	return EOK;
+}
+
+/** Clear or disable specific device feature.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Recipient of the CLEAR_FEATURE request.
+ * @param[in] feature_selector Feature selector (in native endianness).
+ * @param[in] index Recipient index (in native endianness).
+ * @return Error code.
+ */
+int usb_request_clear_feature(usb_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint16_t feature_selector, uint16_t index)
+{
+	if (request_type == USB_REQUEST_TYPE_STANDARD) {
+		if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
+		    && (index != 0)) {
+			return EINVAL;
+		}
+	}
+
+	int rc = usb_control_request_set(pipe, request_type, recipient,
+	    USB_DEVREQ_CLEAR_FEATURE,
+	    uint16_host2usb(feature_selector), uint16_host2usb(index),
+	    NULL, 0);
+
+	return rc;
+}
+
+/** Set or enable specific device feature.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Recipient of the SET_FEATURE request.
+ * @param[in] feature_selector Feature selector (in native endianness).
+ * @param[in] index Recipient index (in native endianness).
+ * @return Error code.
+ */
+int usb_request_set_feature(usb_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint16_t feature_selector, uint16_t index)
+{
+	if (request_type == USB_REQUEST_TYPE_STANDARD) {
+		if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
+		    && (index != 0)) {
+			return EINVAL;
+		}
+	}
+
+	int rc = usb_control_request_set(pipe, request_type, recipient,
+	    USB_DEVREQ_SET_FEATURE,
+	    uint16_host2usb(feature_selector), uint16_host2usb(index),
+	    NULL, 0);
+
+	return rc;
+}
+
+/** Change address of connected device.
+ * This function automatically updates the backing connection to point to
+ * the new address.
+ *
+ * @param pipe Control endpoint pipe (session must be already started).
+ * @param new_address New USB address to be set (in native endianness).
+ * @return Error code.
+ */
+int usb_request_set_address(usb_pipe_t *pipe,
+    usb_address_t new_address)
+{
+	if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
+		return EINVAL;
+	}
+
+	uint16_t addr = uint16_host2usb((uint16_t)new_address);
+
+	int rc = usb_control_request_set(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_SET_ADDRESS,
+	    addr, 0,
+	    NULL, 0);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	assert(pipe->wire != NULL);
+	/* TODO: prevent other from accessing wire now. */
+	pipe->wire->address = new_address;
+
+	return EOK;
+}
+
+/** Retrieve USB descriptor of a USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Request recipient (device/interface/endpoint).
+ * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
+ * @param[in] descriptor_index Descriptor index.
+ * @param[in] language Language index.
+ * @param[out] buffer Buffer where to store the retrieved descriptor.
+ * @param[in] size Size of the @p buffer.
+ * @param[out] actual_size Number of bytes actually transferred.
+ * @return Error code.
+ */
+int usb_request_get_descriptor(usb_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint8_t descriptor_type, uint8_t descriptor_index,
+    uint16_t language,
+    void *buffer, size_t size, size_t *actual_size)
+{
+	if (buffer == NULL) {
+		return EBADMEM;
+	}
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	uint16_t wValue = descriptor_index | (descriptor_type << 8);
+
+	return usb_control_request_get(pipe,
+	    request_type, recipient,
+	    USB_DEVREQ_GET_DESCRIPTOR,
+	    wValue, language,
+	    buffer, size, actual_size);
+}
+
+/** Retrieve USB descriptor, allocate space for it.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Request recipient (device/interface/endpoint).
+ * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
+ * @param[in] descriptor_index Descriptor index.
+ * @param[in] language Language index.
+ * @param[out] buffer_ptr Where to store pointer to allocated buffer.
+ * @param[out] buffer_size Where to store the size of the descriptor.
+ * @return
+ */
+int usb_request_get_descriptor_alloc(usb_pipe_t * pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint8_t descriptor_type, uint8_t descriptor_index,
+    uint16_t language,
+    void **buffer_ptr, size_t *buffer_size)
+{
+	if (buffer_ptr == NULL) {
+		return EBADMEM;
+	}
+
+	int rc;
+
+	/*
+	 * Get only first byte to retrieve descriptor length.
+	 */
+	uint8_t tmp_buffer[1];
+	size_t bytes_transfered;
+	rc = usb_request_get_descriptor(pipe, request_type, recipient,
+	    descriptor_type, descriptor_index, language,
+	    &tmp_buffer, 1, &bytes_transfered);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (bytes_transfered != 1) {
+		/* FIXME: some better error code? */
+		return ESTALL;
+	}
+
+	size_t size = tmp_buffer[0];
+	if (size == 0) {
+		/* FIXME: some better error code? */
+		return ESTALL;
+	}
+
+	/*
+	 * Allocate buffer and get the descriptor again.
+	 */
+	void *buffer = malloc(size);
+	if (buffer == NULL) {
+		return ENOMEM;
+	}
+
+	rc = usb_request_get_descriptor(pipe, request_type, recipient,
+	    descriptor_type, descriptor_index, language,
+	    buffer, size, &bytes_transfered);
+	if (rc != EOK) {
+		free(buffer);
+		return rc;
+	}
+	if (bytes_transfered != size) {
+		free(buffer);
+		/* FIXME: some better error code? */
+		return ESTALL;
+	}
+
+	*buffer_ptr = buffer;
+	if (buffer_size != NULL) {
+		*buffer_size = size;
+	}
+
+	return EOK;
+}
+
+/** Retrieve standard device descriptor of a USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[out] descriptor Storage for the device descriptor.
+ * @return Error code.
+ */
+int usb_request_get_device_descriptor(usb_pipe_t *pipe,
+    usb_standard_device_descriptor_t *descriptor)
+{
+	if (descriptor == NULL) {
+		return EBADMEM;
+	}
+
+	size_t actually_transferred = 0;
+	usb_standard_device_descriptor_t descriptor_tmp;
+	int rc = usb_request_get_descriptor(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 
+	    USB_DESCTYPE_DEVICE, 0, 0,
+	    &descriptor_tmp, sizeof(descriptor_tmp),
+	    &actually_transferred);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Verify that all data has been transferred. */
+	if (actually_transferred < sizeof(descriptor_tmp)) {
+		return ELIMIT;
+	}
+
+	/* Everything is okay, copy the descriptor. */
+	memcpy(descriptor, &descriptor_tmp,
+	    sizeof(descriptor_tmp));
+
+	return EOK;
+}
+
+/** Retrieve configuration descriptor of a USB device.
+ *
+ * The function does not retrieve additional data binded with configuration
+ * descriptor (such as its interface and endpoint descriptors) - use
+ * usb_request_get_full_configuration_descriptor() instead.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index Descriptor index.
+ * @param[out] descriptor Storage for the device descriptor.
+ * @return Error code.
+ */
+int usb_request_get_bare_configuration_descriptor(usb_pipe_t *pipe,
+    int index, usb_standard_configuration_descriptor_t *descriptor)
+{
+	if (descriptor == NULL) {
+		return EBADMEM;
+	}
+
+	if ((index < 0) || (index > 0xFF)) {
+		return ERANGE;
+	}
+
+	size_t actually_transferred = 0;
+	usb_standard_configuration_descriptor_t descriptor_tmp;
+	int rc = usb_request_get_descriptor(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_CONFIGURATION, index, 0,
+	    &descriptor_tmp, sizeof(descriptor_tmp),
+	    &actually_transferred);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Verify that all data has been transferred. */
+	if (actually_transferred < sizeof(descriptor_tmp)) {
+		return ELIMIT;
+	}
+
+	/* Everything is okay, copy the descriptor. */
+	memcpy(descriptor, &descriptor_tmp,
+	    sizeof(descriptor_tmp));
+
+	return EOK;
+}
+
+/** Retrieve full configuration descriptor of a USB device.
+ *
+ * @warning The @p buffer might be touched (i.e. its contents changed)
+ * even when error occurs.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index Descriptor index.
+ * @param[out] descriptor Storage for the device descriptor.
+ * @param[in] descriptor_size Size of @p descriptor buffer.
+ * @param[out] actual_size Number of bytes actually transferred.
+ * @return Error code.
+ */
+int usb_request_get_full_configuration_descriptor(usb_pipe_t *pipe,
+    int index, void *descriptor, size_t descriptor_size, size_t *actual_size)
+{
+	if ((index < 0) || (index > 0xFF)) {
+		return ERANGE;
+	}
+
+	return usb_request_get_descriptor(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_CONFIGURATION, index, 0,
+	    descriptor, descriptor_size, actual_size);
+}
+
+/** Retrieve full configuration descriptor, allocate space for it.
+ *
+ * The function takes care that full configuration descriptor is returned
+ * (i.e. the function will fail when less data then descriptor.totalLength
+ * is returned).
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index Configuration index.
+ * @param[out] descriptor_ptr Where to store pointer to allocated buffer.
+ * @param[out] descriptor_size Where to store the size of the descriptor.
+ * @return Error code.
+ */
+int usb_request_get_full_configuration_descriptor_alloc(
+    usb_pipe_t *pipe, int index,
+    void **descriptor_ptr, size_t *descriptor_size)
+{
+	int rc;
+
+	if (descriptor_ptr == NULL) {
+		return EBADMEM;
+	}
+
+	usb_standard_configuration_descriptor_t bare_config;
+	rc = usb_request_get_bare_configuration_descriptor(pipe, index,
+	    &bare_config);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {
+		return ENOENT;
+	}
+	if (bare_config.total_length < sizeof(bare_config)) {
+		return ELIMIT;
+	}
+
+	void *buffer = malloc(bare_config.total_length);
+	if (buffer == NULL) {
+		return ENOMEM;
+	}
+
+	size_t transferred = 0;
+	rc = usb_request_get_full_configuration_descriptor(pipe, index,
+	    buffer, bare_config.total_length, &transferred);
+	if (rc != EOK) {
+		free(buffer);
+		return rc;
+	}
+
+	if (transferred != bare_config.total_length) {
+		free(buffer);
+		return ELIMIT;
+	}
+
+	/* Everything looks okay, copy the pointers. */
+
+	*descriptor_ptr = buffer;
+
+	if (descriptor_size != NULL) {
+		*descriptor_size = bare_config.total_length;
+	}
+
+	return EOK;
+}
+
+/** Update existing or add new USB descriptor to a USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Request recipient (device/interface/endpoint).
+ * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
+ * @param[in] descriptor_index Descriptor index.
+ * @param[in] language Language index (in native endianness).
+ * @param[in] buffer Buffer with the new descriptor (in USB endianness).
+ * @param[in] size Size of the @p buffer in bytes (in native endianness).
+ * @return Error code.
+ */
+int usb_request_set_descriptor(usb_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint8_t descriptor_type, uint8_t descriptor_index,
+    uint16_t language,
+    void *buffer, size_t size)
+{
+	if (buffer == NULL) {
+		return EBADMEM;
+	}
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	/* FIXME: proper endianness. */
+	uint16_t wValue = descriptor_index | (descriptor_type << 8);
+
+	return usb_control_request_set(pipe,
+	    request_type, recipient,
+	    USB_DEVREQ_SET_DESCRIPTOR,
+	    wValue, language,
+	    buffer, size);
+}
+
+/** Get current configuration value of USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[out] configuration_value Current configuration value.
+ * @return Error code.
+ */
+int usb_request_get_configuration(usb_pipe_t *pipe,
+    uint8_t *configuration_value)
+{
+	uint8_t value;
+	size_t actual_size;
+
+	int rc = usb_control_request_get(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_GET_CONFIGURATION,
+	    0, 0,
+	    &value, 1, &actual_size);
+
+	if (rc != EOK) {
+		return rc;
+	}
+	if (actual_size != 1) {
+		return ELIMIT;
+	}
+
+	if (configuration_value != NULL) {
+		*configuration_value = value;
+	}
+
+	return EOK;
+}
+
+/** Set configuration of USB device.
+ *
+ * @param pipe Control endpoint pipe (session must be already started).
+ * @param configuration_value New configuration value.
+ * @return Error code.
+ */
+int usb_request_set_configuration(usb_pipe_t *pipe,
+    uint8_t configuration_value)
+{
+	uint16_t config_value
+	    = uint16_host2usb((uint16_t) configuration_value);
+
+	return usb_control_request_set(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_SET_CONFIGURATION, config_value, 0,
+	    NULL, 0);
+}
+
+/** Get selected alternate setting for USB interface.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] interface_index Interface index.
+ * @param[out] alternate_setting Alternate setting for the interface.
+ * @return Error code.
+ */
+int usb_request_get_interface(usb_pipe_t *pipe,
+    uint8_t interface_index, uint8_t *alternate_setting)
+{
+	uint8_t value;
+	size_t actual_size;
+
+	int rc = usb_control_request_get(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DEVREQ_GET_INTERFACE,
+	    0, uint16_host2usb((uint16_t) interface_index),
+	    &value, 1, &actual_size);
+
+	if (rc != EOK) {
+		return rc;
+	}
+	if (actual_size != 1) {
+		return ELIMIT;
+	}
+
+	if (alternate_setting != NULL) {
+		*alternate_setting = value;
+	}
+
+	return EOK;
+}
+
+/** Select alternate setting for USB interface.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] interface_index Interface index.
+ * @param[in] alternate_setting Alternate setting to select.
+ * @return Error code.
+ */
+int usb_request_set_interface(usb_pipe_t *pipe,
+    uint8_t interface_index, uint8_t alternate_setting)
+{
+	return usb_control_request_set(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DEVREQ_SET_INTERFACE,
+	    uint16_host2usb((uint16_t) alternate_setting),
+	    uint16_host2usb((uint16_t) interface_index),
+	    NULL, 0);
+}
+
+/** Get list of supported languages by USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[out] languages_ptr Where to store pointer to allocated array of
+ *	supported languages.
+ * @param[out] languages_count Number of supported languages.
+ * @return Error code.
+ */
+int usb_request_get_supported_languages(usb_pipe_t *pipe,
+    l18_win_locales_t **languages_ptr, size_t *languages_count)
+{
+	int rc;
+
+	if (languages_ptr == NULL) {
+		return EBADMEM;
+	}
+	if (languages_count == NULL) {
+		return EBADMEM;
+	}
+
+	uint8_t *string_descriptor = NULL;
+	size_t string_descriptor_size = 0;
+	rc = usb_request_get_descriptor_alloc(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_STRING, 0, 0,
+	    (void **) &string_descriptor, &string_descriptor_size);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (string_descriptor_size <= 2) {
+		free(string_descriptor);
+		return EEMPTY;
+	}
+	/* Subtract first 2 bytes (length and descriptor type). */
+	string_descriptor_size -= 2;
+
+	/* Odd number of bytes - descriptor is broken? */
+	if ((string_descriptor_size % 2) != 0) {
+		/* FIXME: shall we return with error or silently ignore? */
+		free(string_descriptor);
+		return ESTALL;
+	}
+
+	size_t langs_count = string_descriptor_size / 2;
+	l18_win_locales_t *langs
+	    = malloc(sizeof(l18_win_locales_t) * langs_count);
+	if (langs == NULL) {
+		free(string_descriptor);
+		return ENOMEM;
+	}
+
+	size_t i;
+	for (i = 0; i < langs_count; i++) {
+		/* Language code from the descriptor is in USB endianness. */
+		/* FIXME: is this really correct? */
+		uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
+		    + string_descriptor[2 + 2 * i];
+		langs[i] = uint16_usb2host(lang_code);
+	}
+
+	free(string_descriptor);
+
+	*languages_ptr = langs;
+	*languages_count =langs_count;
+
+	return EOK;
+}
+
+/** Get string (descriptor) from USB device.
+ *
+ * The string is returned in native encoding of the operating system.
+ * For HelenOS, that is UTF-8.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index String index (in native endianness),
+ *	first index has number 1 (index from descriptors can be used directly).
+ * @param[in] lang String language (in native endianness).
+ * @param[out] string_ptr Where to store allocated string in native encoding.
+ * @return Error code.
+ */
+int usb_request_get_string(usb_pipe_t *pipe,
+    size_t index, l18_win_locales_t lang, char **string_ptr)
+{
+	if (string_ptr == NULL) {
+		return EBADMEM;
+	}
+	/*
+	 * Index is actually one byte value and zero index is used
+	 * to retrieve list of supported languages.
+	 */
+	if ((index < 1) || (index > 0xFF)) {
+		return ERANGE;
+	}
+	/* Language is actually two byte value. */
+	if (lang > 0xFFFF) {
+		return ERANGE;
+	}
+
+	int rc;
+
+	/* Prepare dynamically allocated variables. */
+	uint8_t *string = NULL;
+	wchar_t *string_chars = NULL;
+
+	/* Get the actual descriptor. */
+	size_t string_size;
+	rc = usb_request_get_descriptor_alloc(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_STRING, index, uint16_host2usb(lang),
+	    (void **) &string, &string_size);
+	if (rc != EOK) {
+		goto leave;
+	}
+
+	if (string_size <= 2) {
+		rc =  EEMPTY;
+		goto leave;
+	}
+	/* Subtract first 2 bytes (length and descriptor type). */
+	string_size -= 2;
+
+	/* Odd number of bytes - descriptor is broken? */
+	if ((string_size % 2) != 0) {
+		/* FIXME: shall we return with error or silently ignore? */
+		rc = ESTALL;
+		goto leave;
+	}
+
+	size_t string_char_count = string_size / 2;
+	string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
+	if (string_chars == NULL) {
+		rc = ENOMEM;
+		goto leave;
+	}
+
+	/*
+	 * Build a wide string.
+	 * And do not forget to set NULL terminator (string descriptors
+	 * do not have them).
+	 */
+	size_t i;
+	for (i = 0; i < string_char_count; i++) {
+		uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
+		    + string[2 + 2 * i];
+		string_chars[i] = uni_char;
+	}
+	string_chars[string_char_count] = 0;
+
+
+	/* Convert to normal string. */
+	char *str = wstr_to_astr(string_chars);
+	if (str == NULL) {
+		rc = ENOMEM;
+		goto leave;
+	}
+
+	*string_ptr = str;
+	rc = EOK;
+
+leave:
+	if (string != NULL) {
+		free(string);
+	}
+	if (string_chars != NULL) {
+		free(string_chars);
+	}
+
+	return rc;
+}
+
+/** Clear halt bit of an endpoint pipe (after pipe stall).
+ *
+ * @param pipe Control pipe.
+ * @param ep_index Endpoint index (in native endianness).
+ * @return Error code.
+ */
+int usb_request_clear_endpoint_halt(usb_pipe_t *pipe, uint16_t ep_index)
+{
+	return usb_request_clear_feature(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
+	    uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
+	    uint16_host2usb(ep_index));
+}
+
+/** Clear halt bit of an endpoint pipe (after pipe stall).
+ *
+ * @param ctrl_pipe Control pipe.
+ * @param target_pipe Which pipe is halted and shall be cleared.
+ * @return Error code.
+ */
+int usb_pipe_clear_halt(usb_pipe_t *ctrl_pipe, usb_pipe_t *target_pipe)
+{
+	if ((ctrl_pipe == NULL) || (target_pipe == NULL)) {
+		return EINVAL;
+	}
+	return usb_request_clear_endpoint_halt(ctrl_pipe,
+	    target_pipe->endpoint_no);
+}
+
+/** Get endpoint status.
+ *
+ * @param[in] ctrl_pipe Control pipe.
+ * @param[in] pipe Of which pipe the status shall be received.
+ * @param[out] status Where to store pipe status (in native endianness).
+ * @return Error code.
+ */
+int usb_request_get_endpoint_status(usb_pipe_t *ctrl_pipe, usb_pipe_t *pipe,
+    uint16_t *status)
+{
+	uint16_t status_tmp;
+	uint16_t pipe_index = (uint16_t) pipe->endpoint_no;
+	int rc = usb_request_get_status(ctrl_pipe,
+	    USB_REQUEST_RECIPIENT_ENDPOINT, uint16_host2usb(pipe_index),
+	    &status_tmp);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (status != NULL) {
+		*status = uint16_usb2host(status_tmp);
+	}
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbdev/src/usbdevice.c
===================================================================
--- uspace/lib/usbdev/src/usbdevice.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbdev/src/usbdevice.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,147 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * General communication between device drivers and host controller driver.
+ */
+#include <devman.h>
+#include <async.h>
+#include <usb_iface.h>
+#include <usb/usbdevice.h>
+#include <usb/driver.h>
+#include <usb/debug.h>
+#include <errno.h>
+#include <assert.h>
+
+/** Initialize connection to USB host controller.
+ *
+ * @param connection Connection to be initialized.
+ * @param device Device connecting to the host controller.
+ * @return Error code.
+ */
+int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
+    ddf_dev_t *device)
+{
+	assert(connection);
+
+	if (device == NULL) {
+		return EBADMEM;
+	}
+
+	devman_handle_t hc_handle;
+	int rc = usb_hc_find(device->handle, &hc_handle);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	rc = usb_hc_connection_initialize(connection, hc_handle);
+
+	return rc;
+}
+
+/** Manually initialize connection to USB host controller.
+ *
+ * @param connection Connection to be initialized.
+ * @param hc_handle Devman handle of the host controller.
+ * @return Error code.
+ */
+int usb_hc_connection_initialize(usb_hc_connection_t *connection,
+    devman_handle_t hc_handle)
+{
+	assert(connection);
+
+	connection->hc_handle = hc_handle;
+	connection->hc_phone = -1;
+
+	return EOK;
+}
+
+/** Open connection to host controller.
+ *
+ * @param connection Connection to the host controller.
+ * @return Error code.
+ */
+int usb_hc_connection_open(usb_hc_connection_t *connection)
+{
+	assert(connection);
+
+	if (usb_hc_connection_is_opened(connection)) {
+		return EBUSY;
+	}
+
+	int phone = devman_device_connect(connection->hc_handle, 0);
+	if (phone < 0) {
+		return phone;
+	}
+
+	connection->hc_phone = phone;
+
+	return EOK;
+}
+
+/** Tells whether connection to host controller is opened.
+ *
+ * @param connection Connection to the host controller.
+ * @return Whether connection is opened.
+ */
+bool usb_hc_connection_is_opened(const usb_hc_connection_t *connection)
+{
+	assert(connection);
+
+	return (connection->hc_phone >= 0);
+}
+
+/** Close connection to the host controller.
+ *
+ * @param connection Connection to the host controller.
+ * @return Error code.
+ */
+int usb_hc_connection_close(usb_hc_connection_t *connection)
+{
+	assert(connection);
+
+	if (!usb_hc_connection_is_opened(connection)) {
+		return ENOENT;
+	}
+
+	int rc = async_hangup(connection->hc_phone);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	connection->hc_phone = -1;
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/Makefile
===================================================================
--- uspace/lib/usbhid/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,45 @@
+#
+# 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 = ../..
+LIBRARY = libusbhid
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include \
+	-Iinclude
+
+SOURCES = \
+	src/hiddescriptor.c \
+	src/hidiface.c \
+	src/hidparser.c \
+	src/hidpath.c \
+	src/hidreport.c \
+	src/hidreq.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usbhid/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hid.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hid.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,75 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * @brief USB HID device related types.
+ */
+#ifndef LIBUSB_HID_H_
+#define LIBUSB_HID_H_
+
+#include <usb/usb.h>
+#include <usb/classes/hidparser.h>
+#include <usb/descriptor.h>
+
+/** USB/HID device requests. */
+typedef enum {
+	USB_HIDREQ_GET_REPORT = 1,
+	USB_HIDREQ_GET_IDLE = 2,
+	USB_HIDREQ_GET_PROTOCOL = 3,
+	/* Values 4 to 8 are reserved. */
+	USB_HIDREQ_SET_REPORT = 9,
+	USB_HIDREQ_SET_IDLE = 10,
+	USB_HIDREQ_SET_PROTOCOL = 11
+} usb_hid_request_t;
+
+typedef enum {
+	USB_HID_PROTOCOL_BOOT = 0,
+	USB_HID_PROTOCOL_REPORT = 1
+} usb_hid_protocol_t;
+
+/** USB/HID subclass constants. */
+typedef enum {
+	USB_HID_SUBCLASS_NONE = 0,
+	USB_HID_SUBCLASS_BOOT = 1
+} usb_hid_subclass_t;
+
+/** USB/HID interface protocols. */
+typedef enum {
+	USB_HID_PROTOCOL_NONE = 0,
+	USB_HID_PROTOCOL_KEYBOARD = 1,
+	USB_HID_PROTOCOL_MOUSE = 2
+} usb_hid_iface_protocol_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hid/iface.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hid/iface.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hid/iface.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,47 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Client functions for accessing USB HID interface.
+ */
+#ifndef LIBUSB_CLASSES_HID_IFACE_H_
+#define LIBUSB_CLASSES_HID_IFACE_H_
+
+#include <sys/types.h>
+
+int usbhid_dev_get_event_length(int);
+int usbhid_dev_get_event(int, uint16_t *, uint16_t *, size_t, size_t *,
+    unsigned int);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hid/utled.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hid/utled.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hid/utled.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2010 Lubos Slovak
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * @brief USB HID Usage Tables - LED page.
+ */
+#ifndef LIBUSB_UTLED_H_
+#define LIBUSB_UTLED_H_
+
+typedef enum {
+	USB_HID_LED_UNDEFINED = 0,
+	USB_HID_LED_NUM_LOCK,
+	USB_HID_LED_CAPS_LOCK,
+	USB_HID_LED_SCROLL_LOCK,
+	USB_HID_LED_COMPOSE,
+	USB_HID_LED_KANA,
+	USB_HID_LED_POWER,
+	USB_HID_LED_SHIFT,
+	USB_HID_LED_DND,
+	USB_HID_LED_MUTE,
+	USB_HID_LED_TONE_ENABLE,
+	USB_HID_LED_HIGH_CUT_FILTER,
+	USB_HID_LED_LOW_CUT_FILTER,
+	USB_HID_LED_EQ_ENABLE,
+	USB_HID_LED_SOUND_FIELD_ON,
+	USB_HID_LED_SURROUND_ON,
+	USB_HID_LED_REPEAT,
+	USB_HID_LED_STEREO,
+	USB_HID_LED_SAMPLING_RATE_DETECT,
+	USB_HID_LED_SPINNING,
+	USB_HID_LED_CAV,
+	USB_HID_LED_CLV,
+	USB_HID_LED_RECORDING_FORMAT_DETECT,
+	USB_HID_LED_OFF_HOOK,
+	USB_HID_LED_RING,
+	USB_HID_LED_MESSAGE_WAITING,
+	USB_HID_LED_DATA_MODE,
+	USB_HID_LED_BATTERY_OPERATION,
+	USB_HID_LED_BATTERY_OK,
+	USB_HID_LED_BATTERY_LOW,
+	USB_HID_LED_SPEAKER,
+	USB_HID_LED_HEAD_SET,
+	USB_HID_LED_HOLD,
+	USB_HID_LED_MICRO,
+	USB_HID_LED_COVERAGE,
+	USB_HID_LED_NIGHT_MODE,
+	USB_HID_LED_SEND_CALLS,
+	USB_HID_LED_CALL_PICKUP,
+	USB_HID_LED_CONFERENCE,
+	USB_HID_LED_STAND_BY,
+	USB_HID_LED_CAMERA_ON,
+	USB_HID_LED_CAMERA_OFF,
+	USB_HID_LED_ON_LINE,
+	USB_HID_LED_OFF_LINE,
+	USB_HID_LED_BUSY,
+	USB_HID_LED_READY,
+	USB_HID_LED_PAPER_OUT,
+	USB_HID_LED_PAPER_JAM,
+	USB_HID_LED_REMOTE,
+	USB_HID_LED_FORWARD,
+	USB_HID_LED_REVERSE,
+	USB_HID_LED_STOP,
+	USB_HID_LED_REWIND,
+	USB_HID_LED_FAST_FORWARD,
+	USB_HID_LED_PLAY,
+	USB_HID_LED_PAUSE,
+	USB_HID_LED_RECORD,
+	USB_HID_LED_ERROR,
+	USB_HID_LED_USAGE_SELECTED_IND,
+	USB_HID_LED_USAGE_IN_USE_IND,
+	USB_HID_LED_USAGE_MULTI_MODE_IND,
+	USB_HID_LED_IND_ON,
+	USB_HID_LED_IND_FLASH,
+	USB_HID_LED_IND_SLOW_BLINK,
+	USB_HID_LED_IND_FAST_BLINK,
+	USB_HID_LED_IND_OFF,
+	USB_HID_LED_FLASH_ON_TIME,
+	USB_HID_LED_SLOW_BLINK_ON_TIME,
+	USB_HID_LED_SLOW_BLINK_OFF_TIME,
+	USB_HID_LED_FAST_BLINK_ON_TIME,
+	USB_HID_LED_FAST_BLINK_OFF_TIME,
+	USB_HID_LED_USAGE_IND_COLOR,
+	USB_HID_LED_IND_RED,
+	USB_HID_LED_IND_GREEN,
+	USB_HID_LED_IND_AMBER,
+	USB_HID_LED_GENERIC_IND,
+	USB_HID_LED_SYSTEM_SUSPEND,
+	USB_HID_LED_EXTERNAL_POWER
+} usb_hid_usage_led_t;
+
+#endif /* LIBUSB_UTLED_H_ */
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hid_report_items.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hid_report_items.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hid_report_items.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * @brief USB HID parser.
+ */
+#ifndef LIBUSB_HID_REPORT_ITEMS_H_
+#define LIBUSB_HID_REPORT_ITEMS_H_
+
+#include <stdint.h>
+
+/**
+ * Item prefix
+ */
+#define USB_HID_ITEM_SIZE(data) 	((uint8_t)(data & 0x3))
+#define USB_HID_ITEM_TAG(data) 		((uint8_t)((data & 0xF0) >> 4))
+#define USB_HID_ITEM_TAG_CLASS(data)	((uint8_t)((data & 0xC) >> 2))
+#define USB_HID_ITEM_IS_LONG(data)	(data == 0xFE)
+
+
+/**
+ * Input/Output/Feature Item flags
+ */
+/** Constant (1) / Variable (0) */
+#define USB_HID_ITEM_FLAG_CONSTANT(flags) 	((flags & 0x1) == 0x1)
+/** Variable (1) / Array (0) */
+#define USB_HID_ITEM_FLAG_VARIABLE(flags) 	((flags & 0x2) == 0x2)
+/** Absolute / Relative*/
+#define USB_HID_ITEM_FLAG_RELATIVE(flags) 	((flags & 0x4) == 0x4)
+/** Wrap / No Wrap */
+#define USB_HID_ITEM_FLAG_WRAP(flags)		((flags & 0x8) == 0x8)
+#define USB_HID_ITEM_FLAG_LINEAR(flags)		((flags & 0x10) == 0x10)
+#define USB_HID_ITEM_FLAG_PREFERRED(flags)	((flags & 0x20) == 0x20)
+#define USB_HID_ITEM_FLAG_POSITION(flags)	((flags & 0x40) == 0x40)
+#define USB_HID_ITEM_FLAG_VOLATILE(flags)	((flags & 0x80) == 0x80)
+#define USB_HID_ITEM_FLAG_BUFFERED(flags)	((flags & 0x100) == 0x100)
+
+/* MAIN ITEMS */
+#define USB_HID_TAG_CLASS_MAIN				0x0
+#define USB_HID_REPORT_TAG_INPUT			0x8
+#define USB_HID_REPORT_TAG_OUTPUT			0x9
+#define USB_HID_REPORT_TAG_FEATURE			0xB
+#define USB_HID_REPORT_TAG_COLLECTION		0xA
+#define USB_HID_REPORT_TAG_END_COLLECTION	0xC
+
+/* GLOBAL ITEMS */
+#define USB_HID_TAG_CLASS_GLOBAL			0x1
+#define USB_HID_REPORT_TAG_USAGE_PAGE		0x0
+#define USB_HID_REPORT_TAG_LOGICAL_MINIMUM	0x1
+#define USB_HID_REPORT_TAG_LOGICAL_MAXIMUM	0x2
+#define USB_HID_REPORT_TAG_PHYSICAL_MINIMUM 0x3
+#define USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM 0x4
+#define USB_HID_REPORT_TAG_UNIT_EXPONENT	0x5
+#define USB_HID_REPORT_TAG_UNIT				0x6
+#define USB_HID_REPORT_TAG_REPORT_SIZE		0x7
+#define USB_HID_REPORT_TAG_REPORT_ID		0x8
+#define USB_HID_REPORT_TAG_REPORT_COUNT		0x9
+#define USB_HID_REPORT_TAG_PUSH				0xA
+#define USB_HID_REPORT_TAG_POP				0xB
+
+
+/* LOCAL ITEMS */
+#define USB_HID_TAG_CLASS_LOCAL					0x2
+#define USB_HID_REPORT_TAG_USAGE				0x0
+#define USB_HID_REPORT_TAG_USAGE_MINIMUM		0x1
+#define USB_HID_REPORT_TAG_USAGE_MAXIMUM		0x2
+#define USB_HID_REPORT_TAG_DESIGNATOR_INDEX		0x3
+#define USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM	0x4
+#define USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM	0x5
+#define USB_HID_REPORT_TAG_STRING_INDEX			0x7
+#define USB_HID_REPORT_TAG_STRING_MINIMUM		0x8
+#define USB_HID_REPORT_TAG_STRING_MAXIMUM		0x9
+#define USB_HID_REPORT_TAG_DELIMITER			0xA
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hiddescriptor.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hiddescriptor.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hiddescriptor.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB HID report descriptor and report data parser
+ */
+#ifndef LIBUSB_HIDDESCRIPTOR_H_
+#define LIBUSB_HIDDESCRIPTOR_H_
+
+#include <stdint.h>
+#include <adt/list.h>
+#include <usb/classes/hid_report_items.h>
+#include <usb/classes/hidpath.h>
+#include <usb/classes/hidtypes.h>
+
+
+/*
+ * Descriptor parser functions
+ */
+
+/** */
+int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 
+                                    const uint8_t *data, size_t size);
+
+/** */
+void usb_hid_free_report(usb_hid_report_t *report);
+
+/** */
+void usb_hid_descriptor_print(usb_hid_report_t *report);
+
+
+int usb_hid_report_init(usb_hid_report_t *report);
+int usb_hid_report_append_fields(usb_hid_report_t *report, 
+                                 usb_hid_report_item_t *report_item);
+
+usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type);
+int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
+int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
+int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
+int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
+
+void usb_hid_descriptor_print_list(link_t *head);
+void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
+void usb_hid_free_report_list(link_t *head);
+usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
+uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
+
+usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path);
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidparser.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidparser.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB HID report descriptor and report data parser
+ */
+#ifndef LIBUSB_HIDPARSER_H_
+#define LIBUSB_HIDPARSER_H_
+
+#include <stdint.h>
+#include <adt/list.h>
+#include <usb/classes/hid_report_items.h>
+#include <usb/classes/hidpath.h>
+#include <usb/classes/hidtypes.h>
+#include <usb/classes/hiddescriptor.h>
+
+
+/*
+ * Input report parser functions
+ */
+/** */
+int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data, 
+                         size_t size, uint8_t *report_id);
+
+/** */
+size_t usb_hid_report_input_length(const usb_hid_report_t *report,
+	usb_hid_report_path_t *path, int flags);
+
+/*
+ * Output report parser functions
+ */
+/** Allocates output report buffer*/
+uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, 
+                               uint8_t report_id);
+
+/** Frees output report buffer*/
+void usb_hid_report_output_free(uint8_t *output);
+
+/** Returns size of output for given usage path */
+size_t usb_hid_report_output_size(usb_hid_report_t *report,
+                                  usb_hid_report_path_t *path, int flags);
+
+/** Makes the output report buffer by translated given data */
+int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id, 
+                                    uint8_t *buffer, size_t size);
+
+/** */
+usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 
+                                                   usb_hid_report_field_t *field, 
+                                                   usb_hid_report_path_t *path, 
+                                                   int flags, 
+                                                   usb_hid_report_type_t type);
+
+/** */
+uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, 
+                                     uint8_t report_id, 
+                                     usb_hid_report_type_t type);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidpath.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidpath.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidpath.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB HID report descriptor and report data parser
+ */
+#ifndef LIBUSB_HIDPATH_H_
+#define LIBUSB_HIDPATH_H_
+
+#include <usb/classes/hidparser.h>
+#include <stdint.h>
+#include <adt/list.h>
+
+/**
+ * Description of path of usage pages and usages in report descriptor
+ */
+/** Wanted usage path must be exactly the same as the searched one */
+#define USB_HID_PATH_COMPARE_STRICT		0
+/** Wanted usage path must be the suffix in the searched one */
+#define USB_HID_PATH_COMPARE_END		1
+/** */
+#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY	2
+/** Searched usage page must be prefix of the other one */
+#define USB_HID_PATH_COMPARE_BEGIN		4
+/** Searched couple of usage page and usage can be anywhere in usage path */
+#define USB_HID_PATH_COMPARE_ANYWHERE		8
+
+
+/** Collection usage path structure */
+typedef struct {
+	/** */
+	uint32_t usage_page;
+	/** */	
+	uint32_t usage;
+
+	uint8_t flags;
+	/** */
+	link_t link;
+} usb_hid_report_usage_path_t;
+
+/** */
+typedef struct {
+	/** */	
+	int depth;	
+	uint8_t report_id;
+	
+	/** */	
+	link_t link; /* list */
+
+	link_t head; /* head of list of usage paths */
+
+} usb_hid_report_path_t;
+
+/** */
+usb_hid_report_path_t *usb_hid_report_path(void);
+
+/** */
+void usb_hid_report_path_free(usb_hid_report_path_t *path);
+
+/** */
+int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, 
+                                      uint8_t report_id);
+
+/** */
+int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 
+                                    int32_t usage_page, int32_t usage);
+
+/** */
+void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);
+
+/** */
+void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);
+
+/** */
+void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, 
+                                  int32_t tag, int32_t data);
+
+/** */
+int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 
+                                      usb_hid_report_path_t *path, int flags);
+
+/** */
+usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path);
+
+void usb_hid_print_usage_path(usb_hid_report_path_t *path);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidreport.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidreport.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidreport.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011 Lubos Slovak
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB HID report parser initialization from descriptors.
+ */
+
+#ifndef LIBUSB_HIDREPORT_H_
+#define LIBUSB_HIDREPORT_H_
+
+#include <usb/devdrv.h>
+#include <usb/classes/hidparser.h>
+
+/**
+ * Retrieves the Report descriptor from the USB device and initializes the
+ * report parser.
+ *
+ * \param dev USB device representing a HID device.
+ * \param parser HID Report parser.
+ *
+ * \retval EOK if successful.
+ * \retval EINVAL if one of the parameters is not given (is NULL).
+ * \retval ENOENT if there are some descriptors missing.
+ * \retval ENOMEM if an error with allocation occured.
+ * \retval EINVAL if the Report descriptor's size does not match the size 
+ *         from the interface descriptor.
+ * \return Other value inherited from function usb_pipe_start_session(),
+ *         usb_pipe_end_session() or usb_request_get_descriptor().
+ */
+int usb_hid_process_report_descriptor(usb_device_t *dev, 
+    usb_hid_report_t *report);
+
+#endif /* LIBUSB_HIDREPORT_H_ */
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidreq.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidreq.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidreq.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011 Lubos Slovak
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * HID class-specific requests.
+ */
+
+#ifndef USB_KBD_HIDREQ_H_
+#define USB_KBD_HIDREQ_H_
+
+#include <stdint.h>
+
+#include <usb/classes/hid.h>
+#include <usb/pipes.h>
+
+/*----------------------------------------------------------------------------*/
+
+int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
+    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size);
+
+int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 
+    usb_hid_protocol_t protocol);
+
+int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration);
+
+int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 
+    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 
+    size_t *actual_size);
+
+int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 
+    usb_hid_protocol_t *protocol);
+
+int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration);
+
+/*----------------------------------------------------------------------------*/
+
+#endif /* USB_KBD_HIDREQ_H_ */
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidtypes.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidtypes.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidtypes.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB HID report descriptor and report data parser
+ */
+#ifndef LIBUSB_HIDTYPES_H_
+#define LIBUSB_HIDTYPES_H_
+
+#include <stdint.h>
+#include <adt/list.h>
+
+#define USB_HID_MAX_USAGES	20
+
+#define USB_HID_UINT32_TO_INT32(x, size)	((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
+#define USB_HID_INT32_TO_UINT32(x, size)	(((x) < 0 ) ? ((1 << (size)) + (x)) : (x))
+
+
+typedef enum {
+	USB_HID_REPORT_TYPE_INPUT = 1,
+	USB_HID_REPORT_TYPE_OUTPUT = 2,
+	USB_HID_REPORT_TYPE_FEATURE = 3
+} usb_hid_report_type_t;
+
+
+typedef struct {
+	/** */
+	int report_count;
+	link_t reports;		/** list of usb_hid_report_description_t */
+
+	link_t collection_paths;
+	int collection_paths_count;
+
+	int use_report_ids;
+	uint8_t last_report_id;
+	
+} usb_hid_report_t;
+
+typedef struct {
+	uint8_t report_id;
+	usb_hid_report_type_t type;
+
+	size_t bit_length;
+	size_t item_length;
+	
+	link_t report_items;	/** list of report items (fields) */
+
+	link_t link;
+} usb_hid_report_description_t;
+
+typedef struct {
+
+	int offset;
+	size_t size;
+
+	uint16_t usage_page;
+	uint16_t usage;
+
+	uint8_t item_flags;
+	usb_hid_report_path_t *collection_path;
+
+	int32_t logical_minimum;
+	int32_t logical_maximum;
+	int32_t physical_minimum;
+	int32_t physical_maximum;
+	uint32_t usage_minimum;
+	uint32_t usage_maximum;
+	uint32_t unit;
+	uint32_t unit_exponent;
+	
+
+	int32_t value;
+
+	link_t link;
+} usb_hid_report_field_t;
+
+
+
+/**
+ * state table
+ */
+typedef struct {
+	/** report id */	
+	int32_t id;
+	
+	/** */
+	uint16_t extended_usage_page;
+	uint32_t usages[USB_HID_MAX_USAGES];
+	int usages_count;
+
+	/** */
+	uint32_t usage_page;
+
+	/** */	
+	uint32_t usage_minimum;
+	/** */	
+	uint32_t usage_maximum;
+	/** */	
+	int32_t logical_minimum;
+	/** */	
+	int32_t logical_maximum;
+	/** */	
+	int32_t size;
+	/** */	
+	int32_t count;
+	/** */	
+	size_t offset;
+	/** */	
+	int32_t unit_exponent;
+	/** */	
+	int32_t unit;
+
+	/** */
+	uint32_t string_index;
+	/** */	
+	uint32_t string_minimum;
+	/** */	
+	uint32_t string_maximum;
+	/** */	
+	uint32_t designator_index;
+	/** */	
+	uint32_t designator_minimum;
+	/** */	
+	uint32_t designator_maximum;
+	/** */	
+	int32_t physical_minimum;
+	/** */	
+	int32_t physical_maximum;
+
+	/** */	
+	uint8_t item_flags;
+
+	usb_hid_report_type_t type;
+
+	/** current collection path*/	
+	usb_hid_report_path_t *usage_path;
+	/** */	
+	link_t link;
+
+	int in_delimiter;
+} usb_hid_report_item_t;
+
+/** HID parser callbacks for IN items. */
+typedef struct {
+	/** Callback for keyboard.
+	 *
+	 * @param key_codes Array of pressed key (including modifiers).
+	 * @param count Length of @p key_codes.
+	 * @param arg Custom argument.
+	 */
+	void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t report_id, void *arg);
+} usb_hid_report_in_callbacks_t;
+
+
+typedef enum {
+	USB_HID_MOD_LCTRL = 0x01,
+	USB_HID_MOD_LSHIFT = 0x02,
+	USB_HID_MOD_LALT = 0x04,
+	USB_HID_MOD_LGUI = 0x08,
+	USB_HID_MOD_RCTRL = 0x10,
+	USB_HID_MOD_RSHIFT = 0x20,
+	USB_HID_MOD_RALT = 0x40,
+	USB_HID_MOD_RGUI = 0x80,
+	USB_HID_MOD_COUNT = 8
+} usb_hid_modifiers_t;
+
+static const usb_hid_modifiers_t 
+    usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = {
+	USB_HID_MOD_LCTRL,
+	USB_HID_MOD_LSHIFT,
+	USB_HID_MOD_LALT,
+	USB_HID_MOD_LGUI,
+	USB_HID_MOD_RCTRL,
+	USB_HID_MOD_RSHIFT,
+	USB_HID_MOD_RALT,
+	USB_HID_MOD_RGUI
+};
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidut.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidut.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidut.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,73 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * @brief USB HID Usage Tables.
+ */
+#ifndef LIBUSB_HIDUT_H_
+#define LIBUSB_HIDUT_H_
+
+/** USB/HID Usage Pages. */
+typedef enum {
+	USB_HIDUT_PAGE_GENERIC_DESKTOP = 1,
+	USB_HIDUT_PAGE_SIMULATION = 2,
+	USB_HIDUT_PAGE_VR = 3,
+	USB_HIDUT_PAGE_SPORT = 4,
+	USB_HIDUT_PAGE_GAME = 5,
+	USB_HIDUT_PAGE_GENERIC_DEVICE = 6,
+	USB_HIDUT_PAGE_KEYBOARD = 7,
+	USB_HIDUT_PAGE_LED = 8,
+	USB_HIDUT_PAGE_BUTTON = 9,
+	USB_HIDUT_PAGE_ORDINAL = 0x0a,
+	USB_HIDUT_PAGE_TELEPHONY_DEVICE = 0x0b,
+	USB_HIDUT_PAGE_CONSUMER = 0x0c
+} usb_hidut_usage_page_t;
+
+/** Usages for Generic Desktop Page. */
+typedef enum {
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_POINTER = 1,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE = 2,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_JOYSTICK = 4,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_GAMEPAD = 5,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD = 6,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_X = 0x30,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_Y = 0x31,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL = 0x38
+	/* USB_HIDUT_USAGE_GENERIC_DESKTOP_ = , */
+	
+} usb_hidut_usage_generic_desktop_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/include/usb/classes/hidutkbd.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidutkbd.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/include/usb/classes/hidutkbd.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,175 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * @brief USB HID key codes.
+ * @details
+ * This is not a typical header as by default it is equal to empty file.
+ * However, by cleverly defining the USB_HIDUT_KBD_KEY you can use it
+ * to generate conversion tables etc.
+ *
+ * For example, this creates enum for known keys:
+ * @code
+#define USB_HIDUT_KBD_KEY(name, usage_id, l, lc, l1, l2) \
+	USB_KBD_KEY_##name = usage_id,
+typedef enum {
+	#include <usb/hidutkbd.h>
+} usb_key_code_t;
+ @endcode
+ *
+ * Maybe, it might be better that you would place such enums into separate
+ * files and create them as separate step before compiling to allow tools
+ * such as Doxygen get the definitions right.
+ *
+ * @warning This file does not include guard to prevent multiple inclusions
+ * into a single file.
+ */
+
+
+#ifndef USB_HIDUT_KBD_KEY
+/** Declare keyboard key.
+ * @param name Key name (identifier).
+ * @param usage_id Key code (see Keyboard/Keypad Page (0x07) in HUT1.12.
+ * @param letter Corresponding character (0 if not applicable).
+ * @param letter_caps Corresponding character with Caps on.
+ * @param letter_mod1 Corresponding character with modifier #1 on.
+ * @param letter_mod2 Corresponding character with modifier #2 on.
+ */
+#define USB_HIDUT_KBD_KEY(name, usage_id, letter, letter_caps, letter_mod1, letter_mod2)
+
+#endif
+
+#define __NONPRINT(name, usage_id) \
+	USB_HIDUT_KBD_KEY(name, usage_id, 0, 0, 0, 0)
+
+/* US alphabet letters */
+USB_HIDUT_KBD_KEY(A, 0x04, 'a', 'A', 0, 0)
+USB_HIDUT_KBD_KEY(B, 0x05, 'b', 'B', 0, 0)
+USB_HIDUT_KBD_KEY(C, 0x06, 'c', 'C', 0, 0)
+USB_HIDUT_KBD_KEY(D, 0x07, 'd', 'D', 0, 0)
+USB_HIDUT_KBD_KEY(E, 0x08, 'e', 'E', 0, 0)
+USB_HIDUT_KBD_KEY(F, 0x09, 'f', 'F', 0, 0)
+USB_HIDUT_KBD_KEY(G, 0x0A, 'g', 'G', 0, 0)
+USB_HIDUT_KBD_KEY(H, 0x0B, 'h', 'H', 0, 0)
+USB_HIDUT_KBD_KEY(I, 0x0C, 'i', 'I', 0, 0)
+USB_HIDUT_KBD_KEY(J, 0x0D, 'j', 'J', 0, 0)
+USB_HIDUT_KBD_KEY(K, 0x0E, 'k', 'K', 0, 0)
+USB_HIDUT_KBD_KEY(L, 0x0F, 'l', 'L', 0, 0)
+USB_HIDUT_KBD_KEY(M, 0x10, 'm', 'M', 0, 0)
+USB_HIDUT_KBD_KEY(N, 0x11, 'n', 'N', 0, 0)
+USB_HIDUT_KBD_KEY(O, 0x12, 'o', 'O', 0, 0)
+USB_HIDUT_KBD_KEY(P, 0x13, 'p', 'P', 0, 0)
+USB_HIDUT_KBD_KEY(Q, 0x14, 'q', 'Q', 0, 0)
+USB_HIDUT_KBD_KEY(R, 0x15, 'r', 'R', 0, 0)
+USB_HIDUT_KBD_KEY(S, 0x16, 's', 'S', 0, 0)
+USB_HIDUT_KBD_KEY(T, 0x17, 't', 'T', 0, 0)
+USB_HIDUT_KBD_KEY(U, 0x18, 'u', 'U', 0, 0)
+USB_HIDUT_KBD_KEY(V, 0x19, 'v', 'V', 0, 0)
+USB_HIDUT_KBD_KEY(W, 0x1A, 'w', 'W', 0, 0)
+USB_HIDUT_KBD_KEY(X, 0x1B, 'x', 'X', 0, 0)
+USB_HIDUT_KBD_KEY(Y, 0x1C, 'y', 'Y', 0, 0)
+USB_HIDUT_KBD_KEY(Z, 0x1D, 'z', 'Z', 0, 0)
+
+/* Keyboard digits */
+USB_HIDUT_KBD_KEY(1, 0x1E, '1', '!', 0, 0)
+USB_HIDUT_KBD_KEY(2, 0x1F, '2', '@', 0, 0)
+USB_HIDUT_KBD_KEY(3, 0x20, '3', '#', 0, 0)
+USB_HIDUT_KBD_KEY(4, 0x21, '4', '$', 0, 0)
+USB_HIDUT_KBD_KEY(5, 0x22, '5', '%', 0, 0)
+USB_HIDUT_KBD_KEY(6, 0x23, '6', '^', 0, 0)
+USB_HIDUT_KBD_KEY(7, 0x24, '7', '&', 0, 0)
+USB_HIDUT_KBD_KEY(8, 0x25, '8', '*', 0, 0)
+USB_HIDUT_KBD_KEY(9, 0x26, '9', '(', 0, 0)
+USB_HIDUT_KBD_KEY(0, 0x27, '0', ')', 0, 0)
+
+/* More-or-less typewriter command keys */
+USB_HIDUT_KBD_KEY(ENTER, 0x28, '\n', 0, 0, 0)
+USB_HIDUT_KBD_KEY(ESCAPE, 0x29, 0, 0, 0, 0)
+USB_HIDUT_KBD_KEY(BACKSPACE, 0x2A, '\b', 0, 0, 0)
+USB_HIDUT_KBD_KEY(TAB, 0x2B, '\t', 0, 0, 0)
+USB_HIDUT_KBD_KEY(SPACE, 0x2C, ' ', 0, 0, 0)
+
+/* Special (printable) characters */
+USB_HIDUT_KBD_KEY(DASH, 0x2D, '-', '_', 0, 0)
+USB_HIDUT_KBD_KEY(EQUALS, 0x2E, '=', '+', 0, 0)
+USB_HIDUT_KBD_KEY(LEFT_BRACKET, 0x2F, '[', '{', 0, 0)
+USB_HIDUT_KBD_KEY(RIGHT_BRACKET, 0x30, ']', '}', 0, 0)
+USB_HIDUT_KBD_KEY(BACKSLASH, 0x31, '\\', '|', 0, 0)
+USB_HIDUT_KBD_KEY(HASH, 0x32, '#', '~', 0, 0)
+USB_HIDUT_KBD_KEY(SEMICOLON, 0x33, ';', ':', 0, 0)
+USB_HIDUT_KBD_KEY(APOSTROPHE, 0x34, '\'', '"', 0, 0)
+USB_HIDUT_KBD_KEY(GRAVE_ACCENT, 0x35, '`', '~', 0, 0)
+USB_HIDUT_KBD_KEY(COMMA, 0x36, ',', '<', 0, 0)
+USB_HIDUT_KBD_KEY(PERIOD, 0x37, '.', '>', 0, 0)
+USB_HIDUT_KBD_KEY(SLASH, 0x38, '/', '?', 0, 0)
+
+USB_HIDUT_KBD_KEY(CAPS_LOCK, 0x39, 0, 0, 0, 0)
+
+/* Function keys */
+__NONPRINT( F1, 0x3A)
+__NONPRINT( F2, 0x3B)
+__NONPRINT( F3, 0x3C)
+__NONPRINT( F4, 0x3D)
+__NONPRINT( F5, 0x3E)
+__NONPRINT( F6, 0x3F)
+__NONPRINT( F7, 0x40)
+__NONPRINT( F8, 0x41)
+__NONPRINT( F9, 0x42)
+__NONPRINT(F10, 0x43)
+__NONPRINT(F11, 0x44)
+__NONPRINT(F12, 0x45)
+
+/* Cursor movement keys & co. */
+__NONPRINT(PRINT_SCREEN, 0x46)
+__NONPRINT(SCROLL_LOCK, 0x47)
+__NONPRINT(PAUSE, 0x48)
+__NONPRINT(INSERT, 0x49)
+__NONPRINT(HOME, 0x4A)
+__NONPRINT(PAGE_UP, 0x4B)
+__NONPRINT(DELETE, 0x4C)
+__NONPRINT(END, 0x4D)
+__NONPRINT(PAGE_DOWN, 0x4E)
+__NONPRINT(RIGHT_ARROW, 0x4F)
+__NONPRINT(LEFT_ARROW, 0x50)
+__NONPRINT(DOWN_ARROW, 0x51)
+__NONPRINT(UP_ARROW, 0x52)
+
+
+
+
+/* USB_HIDUT_KBD_KEY(, 0x, '', '', 0, 0) */
+
+#undef __NONPRINT
+
+/**
+ * @}
+ */
+
Index: uspace/lib/usbhid/src/hiddescriptor.c
===================================================================
--- uspace/lib/usbhid/src/hiddescriptor.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/src/hiddescriptor.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,789 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * HID report descriptor and report data parser implementation.
+ */
+#include <usb/classes/hidparser.h>
+#include <errno.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <mem.h>
+#include <usb/debug.h>
+#include <assert.h>
+
+
+#define OUTSIDE_DELIMITER_SET	0
+#define START_DELIMITER_SET	1
+#define INSIDE_DELIMITER_SET	2
+	
+/** The new report item flag. Used to determine when the item is completly
+ * configured and should be added to the report structure
+ */
+#define USB_HID_NEW_REPORT_ITEM 1
+
+/** No special action after the report descriptor tag is processed should be
+ * done
+ */
+#define USB_HID_NO_ACTION	2
+
+#define USB_HID_RESET_OFFSET	3
+
+/** Unknown tag was founded in report descriptor data*/
+#define USB_HID_UNKNOWN_TAG		-99
+
+usb_hid_report_path_t *usb_hid_report_path_try_insert(usb_hid_report_t *report, usb_hid_report_path_t *cmp_path)
+{
+	/* find or append current collection path to the list */
+	link_t *path_it = report->collection_paths.next;
+	usb_hid_report_path_t *path = NULL;
+	while(path_it != &report->collection_paths) {
+		path = list_get_instance(path_it, usb_hid_report_path_t, link);
+		
+		if(usb_hid_report_compare_usage_path(path, cmp_path, USB_HID_PATH_COMPARE_STRICT) == EOK){
+			break;
+		}			
+		path_it = path_it->next;
+	}
+	if(path_it == &report->collection_paths) {
+		path = usb_hid_report_path_clone(cmp_path);			
+		list_append(&path->link, &report->collection_paths);					
+		report->collection_paths_count++;
+
+		return path;
+	}
+	else {
+		return list_get_instance(path_it, usb_hid_report_path_t, link);
+	}
+}
+
+/**
+ * Initialize the report descriptor parser structure
+ *
+ * @param parser Report descriptor parser structure
+ * @return Error code
+ */
+int usb_hid_report_init(usb_hid_report_t *report)
+{
+	if(report == NULL) {
+		return EINVAL;
+	}
+
+	memset(report, 0, sizeof(usb_hid_report_t));
+	list_initialize(&report->reports);
+	list_initialize(&report->collection_paths);
+
+	report->use_report_ids = 0;
+    return EOK;   
+}
+
+
+/*
+ *
+ *
+ */
+int usb_hid_report_append_fields(usb_hid_report_t *report, usb_hid_report_item_t *report_item)
+{
+	usb_hid_report_field_t *field;
+	int i;
+
+	for(i=0; i<report_item->usages_count; i++){
+		usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
+	}
+
+	usb_hid_report_path_t *path = report_item->usage_path;	
+	for(i=0; i<report_item->count; i++){
+
+		field = malloc(sizeof(usb_hid_report_field_t));
+		memset(field, 0, sizeof(usb_hid_report_field_t));
+		list_initialize(&field->link);
+
+		/* fill the attributes */		
+		field->logical_minimum = report_item->logical_minimum;
+		field->logical_maximum = report_item->logical_maximum;
+		field->physical_minimum = report_item->physical_minimum;
+		field->physical_maximum = report_item->physical_maximum;
+
+		field->usage_minimum = report_item->usage_minimum;
+		field->usage_maximum = report_item->usage_maximum;
+		if(report_item->extended_usage_page != 0){
+			field->usage_page = report_item->extended_usage_page;
+		}
+		else {
+			field->usage_page = report_item->usage_page;
+		}
+
+		if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
+			uint32_t usage;
+			if(i < report_item->usages_count){
+				usage = report_item->usages[i];
+			}
+			else {
+				usage = report_item->usages[report_item->usages_count - 1];
+			}
+
+						
+			if((usage & 0xFFFF0000) != 0){
+				field->usage_page = (usage >> 16);					
+				field->usage = (usage & 0xFFFF);
+			}
+			else {
+				field->usage = usage;
+			}
+
+			
+		}	
+
+		if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
+			field->usage = report_item->usage_minimum + i;					
+		}
+		
+		usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_GLOBAL, field->usage_page);
+		usb_hid_report_set_last_item(path, USB_HID_TAG_CLASS_LOCAL, field->usage);
+
+		field->collection_path = usb_hid_report_path_try_insert(report, path);
+
+		field->size = report_item->size;
+		
+		size_t offset_byte = (report_item->offset + (i * report_item->size)) / 8;
+		size_t offset_bit = 8 - ((report_item->offset + (i * report_item->size)) % 8) - report_item->size;
+
+		field->offset = 8 * offset_byte + offset_bit;
+		if(report_item->id != 0) {
+			field->offset += 8;
+			report->use_report_ids = 1;
+		}
+		field->item_flags = report_item->item_flags;
+
+		/* find the right report list*/
+		usb_hid_report_description_t *report_des;
+		report_des = usb_hid_report_find_description(report, report_item->id, report_item->type);
+		if(report_des == NULL){
+			report_des = malloc(sizeof(usb_hid_report_description_t));
+			memset(report_des, 0, sizeof(usb_hid_report_description_t));
+
+			report_des->type = report_item->type;
+			report_des->report_id = report_item->id;
+			list_initialize (&report_des->link);
+			list_initialize (&report_des->report_items);
+
+			list_append(&report_des->link, &report->reports);
+			report->report_count++;
+		}
+
+		/* append this field to the end of founded report list */
+		list_append (&field->link, &report_des->report_items);
+		
+		/* update the sizes */
+		report_des->bit_length += field->size;
+		report_des->item_length++;
+
+	}
+
+
+	return EOK;
+}
+
+usb_hid_report_description_t * usb_hid_report_find_description(const usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
+{
+	link_t *report_it = report->reports.next;
+	usb_hid_report_description_t *report_des = NULL;
+	
+	while(report_it != &report->reports) {
+		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
+
+		if((report_des->report_id == report_id) && (report_des->type == type)){
+			return report_des;
+		}
+		
+		report_it = report_it->next;
+	}
+
+	return NULL;
+}
+
+/** Parse HID report descriptor.
+ *
+ * @param parser Opaque HID report parser structure.
+ * @param data Data describing the report.
+ * @return Error code.
+ */
+int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 
+    const uint8_t *data, size_t size)
+{
+	size_t i=0;
+	uint8_t tag=0;
+	uint8_t item_size=0;
+	int class=0;
+	int ret;
+	usb_hid_report_item_t *report_item=0;
+	usb_hid_report_item_t *new_report_item;	
+	usb_hid_report_path_t *usage_path;
+
+	size_t offset_input=0;
+	size_t offset_output=0;
+	size_t offset_feature=0;
+
+	link_t stack;
+	list_initialize(&stack);	
+
+	/* parser structure initialization*/
+	if(usb_hid_report_init(report) != EOK) {
+		return EINVAL;
+	}
+	
+	/*report item initialization*/
+	if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
+		return ENOMEM;
+	}
+	memset(report_item, 0, sizeof(usb_hid_report_item_t));
+	list_initialize(&(report_item->link));	
+
+	/* usage path context initialization */
+	if(!(usage_path=usb_hid_report_path())){
+		return ENOMEM;
+	}
+	usb_hid_report_path_append_item(usage_path, 0, 0);	
+	
+	while(i<size){	
+		if(!USB_HID_ITEM_IS_LONG(data[i])){
+
+			if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
+				return EINVAL;
+			}
+			
+			tag = USB_HID_ITEM_TAG(data[i]);
+			item_size = USB_HID_ITEM_SIZE(data[i]);
+			class = USB_HID_ITEM_TAG_CLASS(data[i]);
+			
+			ret = usb_hid_report_parse_tag(tag,class,data+i+1,
+			                               item_size,report_item, usage_path);
+			switch(ret){
+				case USB_HID_NEW_REPORT_ITEM:
+					// store report item to report and create the new one
+					// store current collection path
+					report_item->usage_path = usage_path;
+					
+					usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);	
+					if(report_item->id != 0){
+						report->use_report_ids = 1;
+					}
+					
+					switch(tag) {
+						case USB_HID_REPORT_TAG_INPUT:
+							report_item->type = USB_HID_REPORT_TYPE_INPUT;
+							report_item->offset = offset_input;
+							offset_input += report_item->count * report_item->size;
+							break;
+						case USB_HID_REPORT_TAG_OUTPUT:
+							report_item->type = USB_HID_REPORT_TYPE_OUTPUT;
+							report_item->offset = offset_output;
+							offset_output += report_item->count * report_item->size;
+
+							break;
+						case USB_HID_REPORT_TAG_FEATURE:
+							report_item->type = USB_HID_REPORT_TYPE_FEATURE;
+							report_item->offset = offset_feature;
+							offset_feature += report_item->count * report_item->size;
+							break;
+						default:
+						    usb_log_debug("\tjump over - tag %X\n", tag);
+						    break;
+					}
+					
+					/* 
+					 * append new fields to the report
+					 * structure 					 
+					 */
+					usb_hid_report_append_fields(report, report_item);
+
+					/* reset local items */
+					usb_hid_report_reset_local_items (report_item);
+
+					break;
+
+				case USB_HID_RESET_OFFSET:
+					offset_input = 0;
+					offset_output = 0;
+					offset_feature = 0;
+					usb_hid_report_path_set_report_id (usage_path, report_item->id);
+					break;
+
+				case USB_HID_REPORT_TAG_PUSH:
+					// push current state to stack
+					new_report_item = usb_hid_report_item_clone(report_item);
+					usb_hid_report_path_t *tmp_path = usb_hid_report_path_clone(usage_path);
+					new_report_item->usage_path = tmp_path; 
+
+					list_prepend (&new_report_item->link, &stack);
+					break;
+				case USB_HID_REPORT_TAG_POP:
+					// restore current state from stack
+					if(list_empty (&stack)) {
+						return EINVAL;
+					}
+					free(report_item);
+						
+					report_item = list_get_instance(stack.next, usb_hid_report_item_t, link);
+					
+					usb_hid_report_usage_path_t *tmp_usage_path;
+					tmp_usage_path = list_get_instance(report_item->usage_path->link.prev, usb_hid_report_usage_path_t, link);
+					
+					usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, tmp_usage_path->usage_page);
+					usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, tmp_usage_path->usage);
+
+					usb_hid_report_path_free(report_item->usage_path);
+					list_initialize(&report_item->usage_path->link);
+					list_remove (stack.next);
+					
+					break;
+					
+				default:
+					// nothing special to do					
+					break;
+			}
+
+			/* jump over the processed block */
+			i += 1 + USB_HID_ITEM_SIZE(data[i]);
+		}
+		else{
+			// TBD
+			i += 3 + USB_HID_ITEM_SIZE(data[i+1]);
+		}
+		
+
+	}
+	
+	return EOK;
+}
+
+
+/**
+ * Parse one tag of the report descriptor
+ *
+ * @param Tag to parse
+ * @param Report descriptor buffer
+ * @param Size of data belongs to this tag
+ * @param Current report item structe
+ * @return Code of action to be done next
+ */
+int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
+{	
+	int ret;
+	
+	switch(class){
+		case USB_HID_TAG_CLASS_MAIN:
+
+			if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
+				return USB_HID_NEW_REPORT_ITEM;
+			}
+			else {
+				/*TODO process the error */
+				return ret;
+			   }
+			break;
+
+		case USB_HID_TAG_CLASS_GLOBAL:	
+			return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
+			break;
+
+		case USB_HID_TAG_CLASS_LOCAL:			
+			return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
+			break;
+		default:
+			return USB_HID_NO_ACTION;
+	}
+}
+
+/**
+ * Parse main tags of report descriptor
+ *
+ * @param Tag identifier
+ * @param Data buffer
+ * @param Length of data buffer
+ * @param Current state table
+ * @return Error code
+ */
+
+int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
+{
+	usb_hid_report_usage_path_t *path_item;
+	
+	switch(tag)
+	{
+		case USB_HID_REPORT_TAG_INPUT:
+		case USB_HID_REPORT_TAG_OUTPUT:
+		case USB_HID_REPORT_TAG_FEATURE:
+			report_item->item_flags = *data;			
+			return EOK;			
+			break;
+			
+		case USB_HID_REPORT_TAG_COLLECTION:
+			// store collection atributes
+			path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
+			path_item->flags = *data;	
+			
+			// set last item
+			usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page);
+			usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]);
+			
+			// append the new one which will be set by common
+			// usage/usage page
+			usb_hid_report_path_append_item(usage_path, report_item->usage_page, report_item->usages[report_item->usages_count-1]);	
+			usb_hid_report_reset_local_items (report_item);
+			return USB_HID_NO_ACTION;
+			break;
+			
+		case USB_HID_REPORT_TAG_END_COLLECTION:
+			usb_hid_report_remove_last_item(usage_path);
+			return USB_HID_NO_ACTION;
+			break;
+		default:
+			return USB_HID_NO_ACTION;
+	}
+
+	return EOK;
+}
+
+/**
+ * Parse global tags of report descriptor
+ *
+ * @param Tag identifier
+ * @param Data buffer
+ * @param Length of data buffer
+ * @param Current state table
+ * @return Error code
+ */
+int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
+{
+	// TODO take care about the bit length of data
+	switch(tag)
+	{
+		case USB_HID_REPORT_TAG_USAGE_PAGE:
+			report_item->usage_page = usb_hid_report_tag_data_uint32(data, item_size);
+			break;
+		case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
+			report_item->logical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
+			break;
+		case USB_HID_REPORT_TAG_LOGICAL_MAXIMUM:
+			report_item->logical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
+			break;
+		case USB_HID_REPORT_TAG_PHYSICAL_MINIMUM:
+			report_item->physical_minimum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
+			break;			
+		case USB_HID_REPORT_TAG_PHYSICAL_MAXIMUM:
+			report_item->physical_maximum = USB_HID_UINT32_TO_INT32(usb_hid_report_tag_data_uint32(data,item_size), item_size * 8);
+
+			break;
+		case USB_HID_REPORT_TAG_UNIT_EXPONENT:
+			report_item->unit_exponent = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_UNIT:
+			report_item->unit = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_REPORT_SIZE:
+			report_item->size = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_REPORT_COUNT:
+			report_item->count = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_REPORT_ID:
+			report_item->id = usb_hid_report_tag_data_uint32(data,item_size);
+			return USB_HID_RESET_OFFSET;
+			break;
+		case USB_HID_REPORT_TAG_PUSH:
+		case USB_HID_REPORT_TAG_POP:
+			/* 
+			 * stack operations are done in top level parsing
+			 * function
+			 */
+			return tag;
+			break;
+			
+		default:
+			return USB_HID_NO_ACTION;
+	}
+
+	return EOK;
+}
+
+/**
+ * Parse local tags of report descriptor
+ *
+ * @param Tag identifier
+ * @param Data buffer
+ * @param Length of data buffer
+ * @param Current state table
+ * @return Error code
+ */
+int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
+                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
+{
+	switch(tag) {
+		case USB_HID_REPORT_TAG_USAGE:
+			switch(report_item->in_delimiter) {
+				case INSIDE_DELIMITER_SET:
+					// nothing to do
+					break;
+				case START_DELIMITER_SET:
+					report_item->in_delimiter = INSIDE_DELIMITER_SET;
+				case OUTSIDE_DELIMITER_SET:
+					report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
+					report_item->usages_count++;
+					break;
+			}
+			break;
+		case USB_HID_REPORT_TAG_USAGE_MINIMUM:
+			if (item_size == 3) {
+				// usage extended usages
+				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
+				report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
+			}
+			else {
+				report_item->usage_minimum = usb_hid_report_tag_data_uint32(data,item_size);
+			}
+			break;
+		case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
+			if (item_size == 3) {
+				// usage extended usages
+				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
+				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size) & 0xFF;
+			}
+			else {
+				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
+			}
+			break;
+		case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
+			report_item->designator_index = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_DESIGNATOR_MINIMUM:
+			report_item->designator_minimum = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_DESIGNATOR_MAXIMUM:
+			report_item->designator_maximum = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_STRING_INDEX:
+			report_item->string_index = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_STRING_MINIMUM:
+			report_item->string_minimum = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+		case USB_HID_REPORT_TAG_STRING_MAXIMUM:
+			report_item->string_maximum = usb_hid_report_tag_data_uint32(data,item_size);
+			break;			
+		case USB_HID_REPORT_TAG_DELIMITER:
+			report_item->in_delimiter = usb_hid_report_tag_data_uint32(data,item_size);
+			break;
+
+		default:
+			return USB_HID_NO_ACTION;
+	}
+
+	return EOK;
+}
+
+/**
+ * Converts raw data to uint32 (thats the maximum length of short item data)
+ *
+ * @param Data buffer
+ * @param Size of buffer
+ * @return Converted int32 number
+ */
+uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size)
+{
+	unsigned int i;
+	uint32_t result;
+
+	result = 0;
+	for(i=0; i<size; i++) {
+		result = (result | (data[i]) << (i*8));
+	}
+
+	return result;
+}
+
+/**
+ * Prints content of given list of report items.
+ *
+ * @param List of report items (usb_hid_report_item_t)
+ * @return void
+ */
+void usb_hid_descriptor_print_list(link_t *head)
+{
+	usb_hid_report_field_t *report_item;
+	link_t *item;
+
+
+	if(head == NULL || list_empty(head)) {
+	    usb_log_debug("\tempty\n");
+	    return;
+	}
+        
+	for(item = head->next; item != head; item = item->next) {
+                
+		report_item = list_get_instance(item, usb_hid_report_field_t, link);
+
+		usb_log_debug("\t\tOFFSET: %X\n", report_item->offset);
+		usb_log_debug("\t\tSIZE: %zu\n", report_item->size);				
+		usb_log_debug("\t\tLOGMIN: %d\n", report_item->logical_minimum);
+		usb_log_debug("\t\tLOGMAX: %d\n", report_item->logical_maximum);		
+		usb_log_debug("\t\tPHYMIN: %d\n", report_item->physical_minimum);		
+		usb_log_debug("\t\tPHYMAX: %d\n", report_item->physical_maximum);				
+		usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
+		usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
+
+		usb_log_debug("\t\tVALUE: %X\n", report_item->value);
+		usb_log_debug("\t\ttUSAGE: %X\n", report_item->usage);
+		usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
+		
+		//usb_hid_print_usage_path(report_item->collection_path);
+
+		usb_log_debug("\n");		
+
+	}
+
+
+}
+/**
+ * Prints content of given report descriptor in human readable format.
+ *
+ * @param parser Parsed descriptor to print
+ * @return void
+ */
+void usb_hid_descriptor_print(usb_hid_report_t *report)
+{
+	if(report == NULL) {
+		return;
+	}
+
+	link_t *report_it = report->reports.next;
+	usb_hid_report_description_t *report_des;
+
+	while(report_it != &report->reports) {
+		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
+		usb_log_debug("Report ID: %d\n", report_des->report_id);
+		usb_log_debug("\tType: %d\n", report_des->type);
+		usb_log_debug("\tLength: %zu\n", report_des->bit_length);		
+		usb_log_debug("\tItems: %zu\n", report_des->item_length);		
+
+		usb_hid_descriptor_print_list(&report_des->report_items);
+
+
+		link_t *path_it = report->collection_paths.next;
+		while(path_it != &report->collection_paths) {
+			usb_hid_print_usage_path (list_get_instance(path_it, usb_hid_report_path_t, link));
+			path_it = path_it->next;
+		}
+		
+		report_it = report_it->next;
+	}
+}
+
+/**
+ * Releases whole linked list of report items
+ *
+ * @param head Head of list of report descriptor items (usb_hid_report_item_t)
+ * @return void
+ */
+void usb_hid_free_report_list(link_t *head)
+{
+	return; 
+	
+	usb_hid_report_item_t *report_item;
+	link_t *next;
+	
+	if(head == NULL || list_empty(head)) {		
+	    return;
+	}
+	
+	next = head->next;
+	while(next != head) {
+	
+	    report_item = list_get_instance(next, usb_hid_report_item_t, link);
+
+		while(!list_empty(&report_item->usage_path->link)) {
+			usb_hid_report_remove_last_item(report_item->usage_path);
+		}
+
+		
+	    next = next->next;
+	    
+	    free(report_item);
+	}
+	
+	return;
+	
+}
+
+/** Frees the HID report descriptor parser structure 
+ *
+ * @param parser Opaque HID report parser structure
+ * @return void
+ */
+void usb_hid_free_report(usb_hid_report_t *report)
+{
+	if(report == NULL){
+		return;
+	}
+
+	// free collection paths
+	usb_hid_report_path_t *path;
+	while(!list_empty(&report->collection_paths)) {
+		path = list_get_instance(report->collection_paths.next, usb_hid_report_path_t, link);
+		usb_hid_report_path_free(path);		
+	}
+	
+	// free report items
+	usb_hid_report_description_t *report_des;
+	usb_hid_report_field_t *field;
+	while(!list_empty(&report->reports)) {
+		report_des = list_get_instance(report->reports.next, usb_hid_report_description_t, link);
+		list_remove(&report_des->link);
+		
+		while(!list_empty(&report_des->report_items)) {
+			field = list_get_instance(report_des->report_items.next, usb_hid_report_field_t, link);
+			list_remove(&field->link);
+
+			free(field);
+		}
+		
+		free(report_des);
+	}
+	
+	return;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/src/hidiface.c
===================================================================
--- uspace/lib/usbhid/src/hidiface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/src/hidiface.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,146 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Client functions for accessing USB HID interface (implementation).
+ */
+#include <dev_iface.h>
+#include <usbhid_iface.h>
+#include <usb/classes/hid/iface.h>
+#include <errno.h>
+#include <str_error.h>
+#include <async.h>
+#include <assert.h>
+
+/** Ask for event array length.
+ *
+ * @param dev_phone Opened phone to DDF device providing USB HID interface.
+ * @return Number of usages returned or negative error code.
+ */
+int usbhid_dev_get_event_length(int dev_phone)
+{
+	if (dev_phone < 0) {
+		return EINVAL;
+	}
+
+	sysarg_t len;
+	int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(USBHID_DEV_IFACE),
+	    IPC_M_USBHID_GET_EVENT_LENGTH, &len);
+	if (rc == EOK) {
+		return (int) len;
+	} else {
+		return rc;
+	}
+}
+
+/** Request for next event from HID device.
+ *
+ * @param[in] dev_phone Opened phone to DDF device providing USB HID interface.
+ * @param[out] usage_pages Where to store usage pages.
+ * @param[out] usages Where to store usages (actual data).
+ * @param[in] usage_count Length of @p usage_pages and @p usages buffer
+ *	(in items, not bytes).
+ * @param[out] actual_usage_count Number of usages actually returned by the
+ *	device driver.
+ * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
+ * @return Error code.
+ */
+int usbhid_dev_get_event(int dev_phone, uint16_t *usage_pages, uint16_t *usages,
+    size_t usage_count, size_t *actual_usage_count, unsigned int flags)
+{
+	if (dev_phone < 0) {
+		return EINVAL;
+	}
+	if ((usage_pages == NULL) || (usages == NULL)) {
+		return ENOMEM;
+	}
+	if (usage_count == 0) {
+		return EINVAL;
+	}
+
+	size_t buffer_size = sizeof(uint16_t) * usage_count * 2;
+	uint16_t *buffer = malloc(buffer_size);
+	if (buffer == NULL) {
+		return ENOMEM;
+	}
+
+	aid_t opening_request = async_send_2(dev_phone,
+	    DEV_IFACE_ID(USBHID_DEV_IFACE), IPC_M_USBHID_GET_EVENT,
+	    flags, NULL);
+	if (opening_request == 0) {
+		free(buffer);
+		return ENOMEM;
+	}
+
+	ipc_call_t data_request_call;
+	aid_t data_request = async_data_read(dev_phone, buffer, buffer_size,
+	    &data_request_call);
+	if (data_request == 0) {
+		async_wait_for(opening_request, NULL);
+		free(buffer);
+		return ENOMEM;
+	}
+
+	sysarg_t data_request_rc;
+	sysarg_t opening_request_rc;
+	async_wait_for(data_request, &data_request_rc);
+	async_wait_for(opening_request, &opening_request_rc);
+
+	if (data_request_rc != EOK) {
+		/* Prefer return code of the opening request. */
+		if (opening_request_rc != EOK) {
+			return (int) opening_request_rc;
+		} else {
+			return (int) data_request_rc;
+		}
+	}
+
+	if (opening_request_rc != EOK) {
+		return (int) opening_request_rc;
+	}
+
+	size_t actual_size = IPC_GET_ARG2(data_request_call);
+	size_t items = actual_size / 2;
+
+	/* Copy the individual items. */
+	memcpy(usage_pages, buffer, items * sizeof(uint16_t));
+	memcpy(usages, buffer + items, items * sizeof(uint16_t));
+
+	if (actual_usage_count != NULL) {
+		*actual_usage_count = items;
+	}
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/src/hidparser.c
===================================================================
--- uspace/lib/usbhid/src/hidparser.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/src/hidparser.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * HID report descriptor and report data parser implementation.
+ */
+#include <usb/classes/hidparser.h>
+#include <errno.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <mem.h>
+#include <usb/debug.h>
+#include <assert.h>
+
+
+/*
+ * Data translation private functions
+ */
+uint32_t usb_hid_report_tag_data_uint32(const uint8_t *data, size_t size);
+inline size_t usb_hid_count_item_offset(usb_hid_report_item_t * report_item, size_t offset);
+int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data);
+uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int32_t value);
+int usb_pow(int a, int b);
+
+
+// TODO: tohle ma bejt asi jinde
+int usb_pow(int a, int b)
+{
+	switch(b) {
+		case 0:
+			return 1;
+			break;
+		case 1:
+			return a;
+			break;
+		default:
+			return a * usb_pow(a, b-1);
+			break;
+	}
+}
+
+
+
+
+/** Parse and act upon a HID report.
+ *
+ * @see usb_hid_parse_report_descriptor
+ *
+ * @param parser Opaque HID report parser structure.
+ * @param data Data for the report.
+ * @return Error code.
+ */ 
+int usb_hid_parse_report(const usb_hid_report_t *report,  
+    const uint8_t *data, size_t size, uint8_t *report_id)
+{
+	link_t *list_item;
+	usb_hid_report_field_t *item;
+
+	usb_hid_report_description_t *report_des;
+	usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
+
+	if(report == NULL) {
+		return EINVAL;
+	}
+
+	if(report->use_report_ids != 0) {
+		*report_id = data[0];
+	}	
+	else {
+		*report_id = 0;
+	}
+
+
+	report_des = usb_hid_report_find_description(report, *report_id, type);
+
+	/* read data */
+	list_item = report_des->report_items.next;	   
+	while(list_item != &(report_des->report_items)) {
+
+		item = list_get_instance(list_item, usb_hid_report_field_t, link);
+
+		if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
+			
+			if(USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) {
+
+				// array
+				item->value = usb_hid_translate_data(item, data);
+			    item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
+			}
+			else {
+				// variable item
+				item->value = usb_hid_translate_data(item, data);				
+			}				
+		}
+		list_item = list_item->next;
+	}
+	   
+	return EOK;
+	
+}
+
+/**
+ * Translate data from the report as specified in report descriptor item
+ *
+ * @param item Report descriptor item with definition of translation
+ * @param data Data to translate
+ * @param j Index of processed field in report descriptor item
+ * @return Translated data
+ */
+int usb_hid_translate_data(usb_hid_report_field_t *item, const uint8_t *data)
+{
+	int resolution;
+	int offset;
+	int part_size;
+	
+	int32_t value=0;
+	int32_t mask;
+	const uint8_t *foo;
+
+	// now only shot tags are allowed
+	if(item->size > 32) {
+		return 0;
+	}
+
+	if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
+		item->physical_minimum = item->logical_minimum;
+		item->physical_maximum = item->logical_maximum;			
+	}
+	
+
+	if(item->physical_maximum == item->physical_minimum){
+	    resolution = 1;
+	}
+	else {
+	    resolution = (item->logical_maximum - item->logical_minimum) / 
+		((item->physical_maximum - item->physical_minimum) * 
+		(usb_pow(10,(item->unit_exponent))));
+	}
+
+	offset = item->offset;
+	// FIXME
+	if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) {
+		
+		part_size = ((offset+item->size)%8);
+
+		size_t i=0;
+		for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){
+			if(i == (size_t)(offset/8)) {
+				// the higher one
+				foo = data + i;
+				mask =  ((1 << (item->size-part_size))-1);
+				value = (*foo & mask) << part_size;
+			}
+			else if(i == ((offset+item->size-1)/8)){
+				// the lower one
+				foo = data + i;
+				mask =  ((1 << part_size)-1) << (8-part_size);
+				value += ((*foo & mask) >> (8-part_size));
+			}
+			else {
+				value = value << 8;
+				value += *(data + 1);
+			}
+		}
+	}
+	else {		
+		foo = data+(offset/8);
+		mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
+		value = (*foo & mask) >> (8-((offset%8)+item->size));
+	}
+
+	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
+		value = USB_HID_UINT32_TO_INT32(value, item->size);
+	}
+
+	return (int)(((value - item->logical_minimum) / resolution) + item->physical_minimum);
+	
+}
+
+/**
+ * Returns number of items in input report which are accessible by given usage path
+ *
+ * @param parser Opaque report descriptor structure
+ * @param path Usage path specification
+ * @param flags Usage path comparison flags
+ * @return Number of items in input report
+ */
+size_t usb_hid_report_input_length(const usb_hid_report_t *report,
+	usb_hid_report_path_t *path, int flags)
+{	
+	
+	size_t ret = 0;
+
+	if(report == NULL) {
+		return 0;
+	}
+
+	usb_hid_report_description_t *report_des;
+	report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
+	if(report_des == NULL) {
+		return 0;
+	}
+
+	link_t *field_it = report_des->report_items.next;
+	usb_hid_report_field_t *field;
+	while(field_it != &report_des->report_items) {
+
+		field = list_get_instance(field_it, usb_hid_report_field_t, link);
+		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
+			
+			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
+			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
+				ret++;
+			}
+			usb_hid_report_remove_last_item (field->collection_path);
+		}
+		
+		field_it = field_it->next;
+	}
+
+	return ret;
+	}
+
+/*** OUTPUT API **/
+
+/** 
+ * Allocates output report buffer for output report
+ *
+ * @param parser Report parsed structure
+ * @param size Size of returned buffer
+ * @param report_id Report id of created output report
+ * @return Returns allocated output buffer for specified output
+ */
+uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size, uint8_t report_id)
+{
+	if(report == NULL) {
+		*size = 0;
+		return NULL;
+	}
+
+	link_t *report_it = report->reports.next;
+	usb_hid_report_description_t *report_des = NULL;
+	while(report_it != &report->reports) {
+		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
+		if((report_des->report_id == report_id) && (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
+			break;
+		}
+
+		report_it = report_it->next;
+	}
+
+	if(report_des == NULL){
+		*size = 0;
+		return NULL;
+	}
+	else {
+		*size = (report_des->bit_length + (8 - 1))/8;
+		uint8_t *ret = malloc((*size) * sizeof(uint8_t));
+		memset(ret, 0, (*size) * sizeof(uint8_t));
+		return ret;
+	}
+}
+
+
+/** Frees output report buffer
+ *
+ * @param output Output report buffer
+ * @return void
+ */
+void usb_hid_report_output_free(uint8_t *output)
+
+{
+	if(output != NULL) {
+		free (output);
+	}
+}
+
+/** Returns size of output for given usage path 
+ *
+ * @param parser Opaque report parser structure
+ * @param path Usage path specified which items will be thought for the output
+ * @param flags Flags of usage path structure comparison
+ * @return Number of items matching the given usage path
+ */
+size_t usb_hid_report_output_size(usb_hid_report_t *report,
+                                  usb_hid_report_path_t *path, int flags)
+{
+	size_t ret = 0;	
+	usb_hid_report_description_t *report_des;
+
+	if(report == NULL) {
+		return 0;
+	}
+
+	report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
+	if(report_des == NULL){
+		return 0;
+	}
+	
+	link_t *field_it = report_des->report_items.next;
+	usb_hid_report_field_t *field;
+	while(field_it != &report_des->report_items) {
+
+		field = list_get_instance(field_it, usb_hid_report_field_t, link);
+		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){
+			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
+			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
+				ret++;
+			}
+			usb_hid_report_remove_last_item (field->collection_path);
+		}
+		
+		field_it = field_it->next;
+	}
+
+	return ret;
+	
+}
+
+/** Makes the output report buffer for data given in the report structure
+ *
+ * @param parser Opaque report parser structure
+ * @param path Usage path specifing which parts of output will be set
+ * @param flags Usage path structure comparison flags
+ * @param buffer Output buffer
+ * @param size Size of output buffer
+ * @return Error code
+ */
+int usb_hid_report_output_translate(usb_hid_report_t *report, uint8_t report_id,
+                                    uint8_t *buffer, size_t size)
+{
+	link_t *item;	
+	int32_t value=0;
+	int offset;
+	int length;
+	int32_t tmp_value;
+	
+	if(report == NULL) {
+		return EINVAL;
+	}
+
+	if(report->use_report_ids != 0) {
+		buffer[0] = report_id;		
+	}
+
+	usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
+	
+	usb_hid_report_description_t *report_des;
+	report_des = usb_hid_report_find_description (report, report_id, USB_HID_REPORT_TYPE_OUTPUT);
+	if(report_des == NULL){
+		return EINVAL;
+	}
+
+	usb_hid_report_field_t *report_item;	
+	item = report_des->report_items.next;	
+	while(item != &report_des->report_items) {
+		report_item = list_get_instance(item, usb_hid_report_field_t, link);
+
+			if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
+					
+				// array
+				value = usb_hid_translate_data_reverse(report_item, report_item->value);
+				offset = report_item->offset;
+				length = report_item->size;
+			}
+			else {
+				// variable item
+				value  = usb_hid_translate_data_reverse(report_item, report_item->value);
+				offset = report_item->offset;
+				length = report_item->size;
+			}
+
+			if((offset/8) == ((offset+length-1)/8)) {
+				// je to v jednom bytu
+				if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
+					break; // TODO ErrorCode
+				}
+
+				size_t shift = 8 - offset%8 - length;
+
+				value = value << shift;							
+				value = value & (((1 << length)-1) << shift);
+				
+				uint8_t mask = 0;
+				mask = 0xff - (((1 << length) - 1) << shift);
+				buffer[offset/8] = (buffer[offset/8] & mask) | value;
+			}
+			else {
+				int i = 0;
+				uint8_t mask = 0;
+				for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
+					if(i == (offset/8)) {
+						tmp_value = value;
+						tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);				
+						tmp_value = tmp_value << (offset%8);
+	
+						mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
+						buffer[i] = (buffer[i] & mask) | tmp_value;			
+					}
+					else if (i == ((offset + length -1)/8)) {
+						
+						value = value >> (length - ((offset + length) % 8));
+						value = value & ((1 << (length - ((offset + length) % 8))) - 1);
+				
+						mask = (1 << (length - ((offset + length) % 8))) - 1;
+						buffer[i] = (buffer[i] & mask) | value;
+					}
+					else {
+						buffer[i] = value & (0xFF << i);
+					}
+				}
+			}
+
+
+		// reset value
+		report_item->value = 0;
+		
+		item = item->next;
+	}
+	
+	usb_log_debug("OUTPUT BUFFER: %s\n", usb_debug_str_buffer(buffer,size, 0));
+
+	return EOK;
+}
+
+/**
+ * Translate given data for putting them into the outoput report
+ * @param item Report item structure
+ * @param value Value to translate
+ * @return ranslated value
+ */
+uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item, int value)
+{
+	int ret=0;
+	int resolution;
+
+	if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) {
+		ret = item->logical_minimum;
+	}
+
+	if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
+		item->physical_minimum = item->logical_minimum;
+		item->physical_maximum = item->logical_maximum;			
+	}
+	
+
+	if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) {
+
+		// variable item
+		if(item->physical_maximum == item->physical_minimum){
+		    resolution = 1;
+		}
+		else {
+		    resolution = (item->logical_maximum - item->logical_minimum) /
+			((item->physical_maximum - item->physical_minimum) *
+			(usb_pow(10,(item->unit_exponent))));
+		}
+
+		ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
+	}
+	else {
+		// bitmapa
+		if(value == 0) {
+			ret = 0;
+		}
+		else {
+			size_t bitmap_idx = (value - item->usage_minimum);
+			ret = 1 << bitmap_idx;
+		}
+	}
+
+	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
+		return USB_HID_INT32_TO_UINT32(ret, item->size);
+	}
+	return (int32_t)ret;
+}
+
+usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item)
+{
+	usb_hid_report_item_t *new_report_item;
+	
+	if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
+		return NULL;
+	}					
+	memcpy(new_report_item,item, sizeof(usb_hid_report_item_t));
+	link_initialize(&(new_report_item->link));
+
+	return new_report_item;
+}
+
+
+usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report, 
+							usb_hid_report_field_t *field, 
+                            usb_hid_report_path_t *path, int flags, 
+                            usb_hid_report_type_t type)
+{
+	usb_hid_report_description_t *report_des = usb_hid_report_find_description (report, path->report_id, type);
+	link_t *field_it;
+	
+	if(report_des == NULL){
+		return NULL;
+	}
+
+	if(field == NULL){
+		// vezmu prvni co mathuje podle path!!
+		field_it = report_des->report_items.next;
+	}
+	else {
+		field_it = field->link.next;
+	}
+
+	while(field_it != &report_des->report_items) {
+		field = list_get_instance(field_it, usb_hid_report_field_t, link);
+
+		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
+			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
+			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK){
+				usb_hid_report_remove_last_item (field->collection_path);
+				return field;
+			}
+			usb_hid_report_remove_last_item (field->collection_path);
+		}
+		field_it = field_it->next;
+	}
+
+	return NULL;
+}
+
+uint8_t usb_hid_report_get_report_id(usb_hid_report_t *report, uint8_t report_id, usb_hid_report_type_t type)
+{
+	if(report == NULL){
+		return 0;
+	}
+
+	usb_hid_report_description_t *report_des;
+	link_t *report_it;
+	
+	if(report_id == 0) {
+		report_it = usb_hid_report_find_description (report, report_id, type)->link.next;		
+	}
+	else {
+		report_it = report->reports.next;
+	}
+
+	while(report_it != &report->reports) {
+		report_des = list_get_instance(report_it, usb_hid_report_description_t, link);
+		if(report_des->type == type){
+			return report_des->report_id;
+		}
+	}
+
+	return 0;
+}
+
+void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item)
+{
+	if(report_item == NULL)	{
+		return;
+	}
+	
+	report_item->usages_count = 0;
+	memset(report_item->usages, 0, USB_HID_MAX_USAGES);
+	
+	report_item->extended_usage_page = 0;
+	report_item->usage_minimum = 0;
+	report_item->usage_maximum = 0;
+	report_item->designator_index = 0;
+	report_item->designator_minimum = 0;
+	report_item->designator_maximum = 0;
+	report_item->string_index = 0;
+	report_item->string_minimum = 0;
+	report_item->string_maximum = 0;
+
+	return;
+}
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/src/hidpath.c
===================================================================
--- uspace/lib/usbhid/src/hidpath.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/src/hidpath.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2011 Matej Klonfar
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * HID report descriptor and report data parser implementation.
+ */
+#include <usb/classes/hidparser.h>
+#include <errno.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <mem.h>
+#include <usb/debug.h>
+#include <assert.h>
+
+
+/**
+ * Appends one item (couple of usage_path and usage) into the usage path
+ * structure
+ *
+ * @param usage_path Usage path structure
+ * @param usage_page Usage page constant
+ * @param usage Usage constant
+ * @return Error code
+ */
+int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 
+                                    int32_t usage_page, int32_t usage)
+{	
+	usb_hid_report_usage_path_t *item;
+
+	if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {
+		return ENOMEM;
+	}
+	list_initialize(&item->link);
+
+	item->usage = usage;
+	item->usage_page = usage_page;
+	item->flags = 0;
+	
+	list_append (&item->link, &usage_path->head);
+	usage_path->depth++;
+	return EOK;
+}
+
+/**
+ * Removes last item from the usage path structure
+ * @param usage_path 
+ * @return void
+ */
+void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
+{
+	usb_hid_report_usage_path_t *item;
+	
+	if(!list_empty(&usage_path->head)){
+		item = list_get_instance(usage_path->head.prev, 
+		                         usb_hid_report_usage_path_t, link);		
+		list_remove(usage_path->head.prev);
+		usage_path->depth--;
+		free(item);
+	}
+}
+
+/**
+ * Nulls last item of the usage path structure.
+ *
+ * @param usage_path
+ * @return void
+ */
+void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
+{
+	usb_hid_report_usage_path_t *item;
+	
+	if(!list_empty(&usage_path->head)){	
+		item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
+		memset(item, 0, sizeof(usb_hid_report_usage_path_t));
+	}
+}
+
+/**
+ * Modifies last item of usage path structure by given usage page or usage
+ *
+ * @param usage_path Opaque usage path structure
+ * @param tag Class of currently processed tag (Usage page tag falls into Global
+ * class but Usage tag into the Local)
+ * @param data Value of the processed tag
+ * @return void
+ */
+void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, 
+                                  int32_t tag, int32_t data)
+{
+	usb_hid_report_usage_path_t *item;
+	
+	if(!list_empty(&usage_path->head)){	
+		item = list_get_instance(usage_path->head.prev, 
+		                         usb_hid_report_usage_path_t, link);
+
+		switch(tag) {
+			case USB_HID_TAG_CLASS_GLOBAL:
+				item->usage_page = data;
+				break;
+			case USB_HID_TAG_CLASS_LOCAL:
+				item->usage = data;
+				break;
+		}
+	}
+	
+}
+
+
+void usb_hid_print_usage_path(usb_hid_report_path_t *path)
+{
+	usb_log_debug("USAGE_PATH FOR RId(%d):\n", path->report_id);
+	usb_log_debug("\tLENGTH: %d\n", path->depth);
+
+	link_t *item = path->head.next;
+	usb_hid_report_usage_path_t *path_item;
+	while(item != &path->head) {
+
+		path_item = list_get_instance(item, usb_hid_report_usage_path_t, link);
+		usb_log_debug("\tUSAGE_PAGE: %X\n", path_item->usage_page);
+		usb_log_debug("\tUSAGE: %X\n", path_item->usage);
+		usb_log_debug("\tFLAGS: %d\n", path_item->flags);		
+		
+       		item = item->next;
+	}
+}
+
+/**
+ * Compares two usage paths structures
+ *
+ *
+ * @param report_path usage path structure to compare with @path 
+ * @param path usage patrh structure to compare
+ * @param flags Flags determining the mode of comparison
+ * @return EOK if both paths are identical, non zero number otherwise
+ */
+int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 
+                                      usb_hid_report_path_t *path,
+                                      int flags)
+{
+	usb_hid_report_usage_path_t *report_item;
+	usb_hid_report_usage_path_t *path_item;
+
+	link_t *report_link;
+	link_t *path_link;
+
+	int only_page;
+
+	if(report_path->report_id != path->report_id) {
+		return 1;
+	}
+
+	// Empty path match all others
+	if(path->depth == 0){
+		return EOK;
+	}
+
+
+	if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
+		flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;
+	}
+	
+	switch(flags){
+		/* path is somewhere in report_path */
+		case USB_HID_PATH_COMPARE_ANYWHERE:
+			if(path->depth != 1){
+				return 1;
+			}
+
+			// projit skrz cestu a kdyz nekde sedi tak vratim EOK
+			// dojduli az za konec tak nnesedi
+			report_link = report_path->head.next;
+			path_link = path->head.next;
+			path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
+
+			while(report_link != &report_path->head) {
+				report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
+				if(report_item->usage_page == path_item->usage_page){
+					if(only_page == 0){
+						if(report_item->usage == path_item->usage) {
+							return EOK;
+						}
+					}
+					else {
+						return EOK;
+					}
+				}
+
+				report_link = report_link->next;
+			}
+
+			return 1;
+			break;
+		/* the paths must be identical */
+		case USB_HID_PATH_COMPARE_STRICT:
+				if(report_path->depth != path->depth){
+					return 1;
+				}
+		
+		/* path is prefix of the report_path */
+		case USB_HID_PATH_COMPARE_BEGIN:
+	
+				report_link = report_path->head.next;
+				path_link = path->head.next;
+			
+				while((report_link != &report_path->head) && 
+				      (path_link != &path->head)) {
+						  
+					report_item = list_get_instance(report_link, 
+					                                usb_hid_report_usage_path_t, 
+					                                link);
+						  
+					path_item = list_get_instance(path_link, 
+					                              usb_hid_report_usage_path_t, 
+					                              link);		
+
+					if((report_item->usage_page != path_item->usage_page) || 
+					   ((only_page == 0) && 
+					    (report_item->usage != path_item->usage))) {
+							
+						   return 1;
+					} else {
+						report_link = report_link->next;
+						path_link = path_link->next;			
+					}
+			
+				}
+
+				if((((flags & USB_HID_PATH_COMPARE_BEGIN) != 0) && (path_link == &path->head)) || 
+				   ((report_link == &report_path->head) && (path_link == &path->head))) {
+					return EOK;
+				}
+				else {
+					return 1;
+				}						
+			break;
+
+		/* path is suffix of report_path */
+		case USB_HID_PATH_COMPARE_END:
+
+				report_link = report_path->head.prev;
+				path_link = path->head.prev;
+
+				if(list_empty(&path->head)){
+					return EOK;
+				}
+			
+				while((report_link != &report_path->head) && 
+				      (path_link != &path->head)) {
+						  
+					report_item = list_get_instance(report_link, 
+					                                usb_hid_report_usage_path_t, 
+					                                link);
+					path_item = list_get_instance(path_link, 
+					                              usb_hid_report_usage_path_t, 
+					                              link);		
+
+					if((report_item->usage_page != path_item->usage_page) || 
+					   ((only_page == 0) && 
+					    (report_item->usage != path_item->usage))) {
+						   return 1;
+					} else {
+						report_link = report_link->prev;
+						path_link = path_link->prev;			
+					}
+			
+				}
+
+				if(path_link == &path->head) {
+					return EOK;
+				}
+				else {
+					return 1;
+				}						
+			
+			break;
+
+		default:
+			return EINVAL;
+	}
+}
+
+/**
+ * Allocates and initializes new usage path structure.
+ *
+ * @return Initialized usage path structure
+ */
+usb_hid_report_path_t *usb_hid_report_path(void)
+{
+	usb_hid_report_path_t *path;
+	path = malloc(sizeof(usb_hid_report_path_t));
+	if(path == NULL){
+		return NULL;
+	}
+	else {
+		path->depth = 0;
+		path->report_id = 0;
+		list_initialize(&path->link);
+		list_initialize(&path->head);
+		return path;
+	}
+}
+
+/**
+ * Releases given usage path structure.
+ *
+ * @param path usage path structure to release
+ * @return void
+ */
+void usb_hid_report_path_free(usb_hid_report_path_t *path)
+{
+	while(!list_empty(&path->head)){
+		usb_hid_report_remove_last_item(path);
+	}
+
+	list_remove(&path->link);
+	free(path);
+}
+
+
+/**
+ * Clone content of given usage path to the new one
+ *
+ * @param usage_path Usage path structure to clone
+ * @return New copy of given usage path structure
+ */
+usb_hid_report_path_t *usb_hid_report_path_clone(usb_hid_report_path_t *usage_path)
+{
+	link_t *path_link;
+	usb_hid_report_usage_path_t *path_item;
+	usb_hid_report_usage_path_t *new_path_item;
+	usb_hid_report_path_t *new_usage_path = usb_hid_report_path ();
+
+	if(new_usage_path == NULL){
+		return NULL;
+	}
+
+	new_usage_path->report_id = usage_path->report_id;
+	
+	if(list_empty(&usage_path->head)){
+		return new_usage_path;
+	}
+
+	path_link = usage_path->head.next;
+	while(path_link != &usage_path->head) {
+		path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, 
+		                              link);
+		new_path_item = malloc(sizeof(usb_hid_report_usage_path_t));
+		if(new_path_item == NULL) {
+			return NULL;
+		}
+		
+		list_initialize (&new_path_item->link);		
+		new_path_item->usage_page = path_item->usage_page;
+		new_path_item->usage = path_item->usage;		
+		new_path_item->flags = path_item->flags;		
+		
+		list_append(&new_path_item->link, &new_usage_path->head);
+		new_usage_path->depth++;
+
+		path_link = path_link->next;
+	}
+
+	return new_usage_path;
+}
+
+
+/**
+ * Sets report id in usage path structure
+ *
+ * @param path Usage path structure
+ * @param report_id Report id to set
+ * @return Error code
+ */
+int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id)
+{
+	if(path == NULL){
+		return EINVAL;
+	}
+
+	path->report_id = report_id;
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/src/hidreport.c
===================================================================
--- uspace/lib/usbhid/src/hidreport.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/src/hidreport.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2011 Lubos Slovak
+ * 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 libusb
+ * @{
+ */
+/**
+ * @file
+ * USB HID keyboard device structure and API.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb/debug.h>
+#include <usb/classes/hidparser.h>
+#include <usb/dp.h>
+#include <usb/devdrv.h>
+#include <usb/pipes.h>
+#include <usb/classes/hid.h>
+#include <usb/descriptor.h>
+#include <usb/request.h>
+
+#include <usb/classes/hidreport.h>
+
+static int usb_hid_get_report_descriptor(usb_device_t *dev, 
+    uint8_t **report_desc, size_t *size)
+{
+	assert(report_desc != NULL);
+	assert(size != NULL);
+	
+	usb_dp_parser_t parser =  {
+		.nesting = usb_dp_standard_descriptor_nesting
+	};
+	
+	usb_dp_parser_data_t parser_data = {
+		.data = dev->descriptors.configuration,
+		.size = dev->descriptors.configuration_size,
+		.arg = NULL
+	};
+	
+	/*
+	 * First nested descriptor of the configuration descriptor.
+	 */
+	uint8_t *d = 
+	    usb_dp_get_nested_descriptor(&parser, &parser_data, 
+	    dev->descriptors.configuration);
+	
+	/*
+	 * Find the interface descriptor corresponding to our interface number.
+	 */
+	int i = 0;
+	while (d != NULL && i < dev->interface_no) {
+		d = usb_dp_get_sibling_descriptor(&parser, &parser_data, 
+		    dev->descriptors.configuration, d);
+		++i;
+	}
+	
+	if (d == NULL) {
+		usb_log_error("The %d. interface descriptor not found!\n",
+		    dev->interface_no);
+		return ENOENT;
+	}
+	
+	/*
+	 * First nested descriptor of the interface descriptor.
+	 */
+	uint8_t *iface_desc = d;
+	d = usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
+	
+	/*
+	 * Search through siblings until the HID descriptor is found.
+	 */
+	while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {
+		d = usb_dp_get_sibling_descriptor(&parser, &parser_data, 
+		    iface_desc, d);
+	}
+	
+	if (d == NULL) {
+		usb_log_fatal("No HID descriptor found!\n");
+		return ENOENT;
+	}
+	
+	if (*d != sizeof(usb_standard_hid_descriptor_t)) {
+		usb_log_error("HID descriptor has wrong size (%u, expected %zu"
+		    ")\n", *d, sizeof(usb_standard_hid_descriptor_t));
+		return EINVAL;
+	}
+	
+	usb_standard_hid_descriptor_t *hid_desc = 
+	    (usb_standard_hid_descriptor_t *)d;
+	
+	uint16_t length =  hid_desc->report_desc_info.length;
+	size_t actual_size = 0;
+
+	/*
+	 * Allocate space for the report descriptor.
+	 */
+	*report_desc = (uint8_t *)malloc(length);
+	if (*report_desc == NULL) {
+		usb_log_error("Failed to allocate space for Report descriptor."
+		    "\n");
+		return ENOMEM;
+	}
+	
+	usb_log_debug("Getting Report descriptor, expected size: %u\n", length);
+	
+	/*
+	 * Get the descriptor from the device.
+	 */
+	int rc = usb_request_get_descriptor(&dev->ctrl_pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DESCTYPE_HID_REPORT, 0, dev->interface_no,
+	    *report_desc, length, &actual_size);
+
+	if (rc != EOK) {
+		free(*report_desc);
+		*report_desc = NULL;
+		return rc;
+	}
+
+	if (actual_size != length) {
+		free(*report_desc);
+		*report_desc = NULL;
+		usb_log_error("Report descriptor has wrong size (%zu, expected "
+		    "%u)\n", actual_size, length);
+		return EINVAL;
+	}
+	
+	*size = length;
+	
+	usb_log_debug("Done.\n");
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
+int usb_hid_process_report_descriptor(usb_device_t *dev, 
+    usb_hid_report_t *report)
+{
+	if (dev == NULL || report == NULL) {
+		usb_log_error("Failed to process Report descriptor: wrong "
+		    "parameters given.\n");
+		return EINVAL;
+	}
+	
+	uint8_t *report_desc = NULL;
+	size_t report_size;
+	
+	int rc = usb_hid_get_report_descriptor(dev, &report_desc, 
+	    &report_size);
+	
+	if (rc != EOK) {
+		usb_log_error("Problem with getting Report descriptor: %s.\n",
+		    str_error(rc));
+		if (report_desc != NULL) {
+			free(report_desc);
+		}
+		return rc;
+	}
+	
+	assert(report_desc != NULL);
+	
+	rc = usb_hid_parse_report_descriptor(report, report_desc, report_size);
+	if (rc != EOK) {
+		usb_log_error("Problem parsing Report descriptor: %s.\n",
+		    str_error(rc));
+		free(report_desc);
+		return rc;
+	}
+	
+	usb_hid_descriptor_print(report);
+	free(report_desc);
+	
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhid/src/hidreq.c
===================================================================
--- uspace/lib/usbhid/src/hidreq.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhid/src/hidreq.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2011 Lubos Slovak
+ * 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 drvusbhid
+ * @{
+ */
+/** @file
+ * HID class-specific requests.
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb/classes/hid.h>
+#include <usb/debug.h>
+#include <usb/request.h>
+#include <usb/pipes.h>
+
+#include <usb/classes/hidreq.h>
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Set Report request to the HID device.
+ *
+ * @param hid_dev HID device to send the request to.
+ * @param type Type of the report.
+ * @param buffer Report data.
+ * @param buf_size Report data size (in bytes).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from function usb_control_request_set().
+ */
+int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
+    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
+{
+	if (ctrl_pipe == NULL) {
+		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
+		return EINVAL;
+	}
+	
+	if (iface_no < 0) {
+		usb_log_warning("usbhid_req_set_report(): no interface given."
+		    "\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc;
+	
+	uint16_t value = 0;
+	value |= (type << 8);
+
+	usb_log_debug("Sending Set_Report request to the device.\n");
+	
+	rc = usb_control_request_set(ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Set Protocol request to the HID device.
+ *
+ * @param hid_dev HID device to send the request to.
+ * @param protocol Protocol to set.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from function usb_control_request_set().
+ */
+int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
+    usb_hid_protocol_t protocol)
+{
+	if (ctrl_pipe == NULL) {
+		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
+		return EINVAL;
+	}
+	
+	if (iface_no < 0) {
+		usb_log_warning("usbhid_req_set_report(): no interface given."
+		    "\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc;
+
+	usb_log_debug("Sending Set_Protocol request to the device ("
+	    "protocol: %d, iface: %d).\n", protocol, iface_no);
+	
+	rc = usb_control_request_set(ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Set Idle request to the HID device.
+ *
+ * @param hid_dev HID device to send the request to.
+ * @param duration Duration value (is multiplicated by 4 by the device to
+ *                 get real duration in miliseconds).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from function usb_control_request_set().
+ */
+int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration)
+{
+	if (ctrl_pipe == NULL) {
+		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
+		return EINVAL;
+	}
+	
+	if (iface_no < 0) {
+		usb_log_warning("usbhid_req_set_report(): no interface given."
+		    "\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc;
+
+	usb_log_debug("Sending Set_Idle request to the device ("
+	    "duration: %u, iface: %d).\n", duration, iface_no);
+	
+	uint16_t value = duration << 8;
+	
+	rc = usb_control_request_set(ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Get Report request to the HID device.
+ *
+ * @param[in] hid_dev HID device to send the request to.
+ * @param[in] type Type of the report.
+ * @param[in][out] buffer Buffer for the report data.
+ * @param[in] buf_size Size of the buffer (in bytes).
+ * @param[out] actual_size Actual size of report received from the device 
+ *                         (in bytes).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from function usb_control_request_set().
+ */
+int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 
+    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 
+    size_t *actual_size)
+{
+	if (ctrl_pipe == NULL) {
+		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
+		return EINVAL;
+	}
+	
+	if (iface_no < 0) {
+		usb_log_warning("usbhid_req_set_report(): no interface given."
+		    "\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc;
+
+	uint16_t value = 0;
+	value |= (type << 8);
+	
+	usb_log_debug("Sending Get_Report request to the device.\n");
+	
+	rc = usb_control_request_get(ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size,
+	    actual_size);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Get Protocol request to the HID device.
+ *
+ * @param[in] hid_dev HID device to send the request to.
+ * @param[out] protocol Current protocol of the device.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from function usb_control_request_set().
+ */
+int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 
+    usb_hid_protocol_t *protocol)
+{
+	if (ctrl_pipe == NULL) {
+		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
+		return EINVAL;
+	}
+	
+	if (iface_no < 0) {
+		usb_log_warning("usbhid_req_set_report(): no interface given."
+		    "\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc;	
+
+	usb_log_debug("Sending Get_Protocol request to the device ("
+	    "iface: %d).\n", iface_no);
+	
+	uint8_t buffer[1];
+	size_t actual_size = 0;
+	
+	rc = usb_control_request_get(ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
+	if (actual_size != 1) {
+		usb_log_warning("Wrong data size: %zu, expected: 1.\n",
+			actual_size);
+		return ELIMIT;
+	}
+	
+	*protocol = buffer[0];
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Get Idle request to the HID device.
+ *
+ * @param[in] hid_dev HID device to send the request to.
+ * @param[out] duration Duration value (multiplicate by 4 to get real duration
+ *                      in miliseconds).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_pipe_start_session(), usb_pipe_end_session(),
+ *         usb_control_request_set().
+ */
+int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration)
+{
+	if (ctrl_pipe == NULL) {
+		usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
+		return EINVAL;
+	}
+	
+	if (iface_no < 0) {
+		usb_log_warning("usbhid_req_set_report(): no interface given."
+		    "\n");
+		return EINVAL;
+	}
+	
+	/*
+	 * No need for checking other parameters, as they are checked in
+	 * the called function (usb_control_request_set()).
+	 */
+	
+	int rc;
+
+	usb_log_debug("Sending Get_Idle request to the device ("
+	    "iface: %d).\n", iface_no);
+	
+	uint16_t value = 0;
+	uint8_t buffer[1];
+	size_t actual_size = 0;
+	
+	rc = usb_control_request_get(ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1, 
+	    &actual_size);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
+	if (actual_size != 1) {
+		usb_log_warning("Wrong data size: %zu, expected: 1.\n",
+			actual_size);
+		return ELIMIT;
+	}
+	
+	*duration = buffer[0];
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/Makefile
===================================================================
--- uspace/lib/usbhost/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,43 @@
+#
+# 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 = ../..
+LIBRARY = libusbhost
+EXTRA_CFLAGS += \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBDRV_PREFIX)/include \
+	-Iinclude
+
+SOURCES = \
+	src/addrkeep.c \
+	src/batch.c \
+	src/device_keeper.c \
+	src/endpoint.c \
+	src/usb_endpoint_manager.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/usbhost/include/usb/addrkeep.h
===================================================================
--- uspace/lib/usbhost/include/usb/addrkeep.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/include/usb/addrkeep.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,86 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB address keeping for host controller drivers.
+ */
+#ifndef LIBUSB_ADDRKEEP_H_
+#define LIBUSB_ADDRKEEP_H_
+
+#include <usb/usb.h>
+#include <fibril_synch.h>
+#include <devman.h>
+
+/** Info about used address. */
+typedef struct {
+	/** Linked list member. */
+	link_t link;
+	/** Address. */
+	usb_address_t address;
+	/** Corresponding devman handle. */
+	devman_handle_t devman_handle;
+} usb_address_keeping_used_t;
+
+/** Structure for keeping track of free and used USB addresses. */
+typedef struct {
+	/** Head of list of used addresses. */
+	link_t used_addresses;
+	/** Upper bound for USB addresses. */
+	usb_address_t max_address;
+	/** Mutex protecting used address. */
+	fibril_mutex_t used_addresses_guard;
+	/** Condition variable for used addresses. */
+	fibril_condvar_t used_addresses_condvar;
+
+	/** Condition variable mutex for default address. */
+	fibril_mutex_t default_condvar_guard;
+	/** Condition variable for default address. */
+	fibril_condvar_t default_condvar;
+	/** Whether is default address available. */
+	bool default_available;
+} usb_address_keeping_t;
+
+void usb_address_keeping_init(usb_address_keeping_t *, usb_address_t);
+
+void usb_address_keeping_reserve_default(usb_address_keeping_t *);
+void usb_address_keeping_release_default(usb_address_keeping_t *);
+
+usb_address_t usb_address_keeping_request(usb_address_keeping_t *);
+int usb_address_keeping_release(usb_address_keeping_t *, usb_address_t);
+void usb_address_keeping_devman_bind(usb_address_keeping_t *, usb_address_t,
+    devman_handle_t);
+usb_address_t usb_address_keeping_find(usb_address_keeping_t *,
+    devman_handle_t);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/include/usb/host/batch.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/batch.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/include/usb/host/batch.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB transfer transaction structures.
+ */
+#ifndef LIBUSB_HOST_BATCH_H
+#define LIBUSB_HOST_BATCH_H
+
+#include <adt/list.h>
+
+#include <usbhc_iface.h>
+#include <usb/usb.h>
+#include <usb/host/endpoint.h>
+
+typedef struct usb_transfer_batch usb_transfer_batch_t;
+struct usb_transfer_batch {
+	endpoint_t *ep;
+	link_t link;
+	usbhc_iface_transfer_in_callback_t callback_in;
+	usbhc_iface_transfer_out_callback_t callback_out;
+	void *arg;
+	char *buffer;
+	char *data_buffer;
+	size_t buffer_size;
+	char *setup_buffer;
+	size_t setup_size;
+	size_t transfered_size;
+	void (*next_step)(usb_transfer_batch_t *);
+	int error;
+	ddf_fun_t *fun;
+	void *private_data;
+	void (*private_data_dtor)(void *p_data);
+};
+
+void usb_transfer_batch_init(
+    usb_transfer_batch_t *instance,
+    endpoint_t *ep,
+    char *buffer,
+    char *data_buffer,
+    size_t buffer_size,
+    char *setup_buffer,
+    size_t setup_size,
+    usbhc_iface_transfer_in_callback_t func_in,
+    usbhc_iface_transfer_out_callback_t func_out,
+    void *arg,
+    ddf_fun_t *fun,
+    void *private_data,
+    void (*private_data_dtor)(void *p_data)
+);
+
+void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance);
+void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance);
+void usb_transfer_batch_finish(usb_transfer_batch_t *instance);
+void usb_transfer_batch_dispose(usb_transfer_batch_t *instance);
+
+static inline void usb_transfer_batch_finish_error(
+    usb_transfer_batch_t *instance, int error)
+{
+	assert(instance);
+	instance->error = error;
+	usb_transfer_batch_finish(instance);
+}
+
+static inline usb_transfer_batch_t *usb_transfer_batch_from_link(link_t *l)
+{
+	assert(l);
+	return list_get_instance(l, usb_transfer_batch_t, link);
+}
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/include/usb/host/device_keeper.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/device_keeper.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/include/usb/host/device_keeper.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Device keeper structure and functions.
+ *
+ * Typical USB host controller needs to keep track of various settings for
+ * each device that is connected to it.
+ * State of toggle bit, device speed etc. etc.
+ * This structure shall simplify the management.
+ */
+#ifndef LIBUSB_HOST_DEVICE_KEEPER_H
+#define LIBUSB_HOST_DEVICE_KEEPER_H
+
+#include <adt/list.h>
+#include <devman.h>
+#include <fibril_synch.h>
+#include <usb/usb.h>
+#include <usb/host/endpoint.h>
+
+/** Number of USB address for array dimensions. */
+#define USB_ADDRESS_COUNT (USB11_ADDRESS_MAX + 1)
+
+/** Information about attached USB device. */
+struct usb_device_info {
+	usb_speed_t speed;
+	bool occupied;
+	devman_handle_t handle;
+};
+
+/** Host controller device keeper.
+ * You shall not access members directly but only using functions below.
+ */
+typedef struct {
+	struct usb_device_info devices[USB_ADDRESS_COUNT];
+	fibril_mutex_t guard;
+	usb_address_t last_address;
+} usb_device_keeper_t;
+
+void usb_device_keeper_init(usb_device_keeper_t *instance);
+
+usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
+    usb_speed_t speed);
+
+void usb_device_keeper_bind(usb_device_keeper_t *instance,
+    usb_address_t address, devman_handle_t handle);
+
+void usb_device_keeper_release(usb_device_keeper_t *instance,
+    usb_address_t address);
+
+usb_address_t usb_device_keeper_find(usb_device_keeper_t *instance,
+    devman_handle_t handle);
+
+bool usb_device_keeper_find_by_address(usb_device_keeper_t *instance,
+    usb_address_t address, devman_handle_t *handle);
+
+usb_speed_t usb_device_keeper_get_speed(usb_device_keeper_t *instance,
+    usb_address_t address);
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libusb
+ * @{
+ */
+/** @file
+ *
+ */
+#ifndef LIBUSB_HOST_ENDPOINT_H
+#define LIBUSB_HOST_ENDPOINT_H
+
+#include <assert.h>
+#include <bool.h>
+#include <adt/list.h>
+#include <fibril_synch.h>
+
+#include <usb/usb.h>
+
+typedef struct endpoint {
+	usb_address_t address;
+	usb_endpoint_t endpoint;
+	usb_direction_t direction;
+	usb_transfer_type_t transfer_type;
+	usb_speed_t speed;
+	size_t max_packet_size;
+	unsigned toggle:1;
+	fibril_mutex_t guard;
+	fibril_condvar_t avail;
+	volatile bool active;
+	struct {
+		void *data;
+		int (*toggle_get)(void *);
+		void (*toggle_set)(void *, int);
+	} hc_data;
+} endpoint_t;
+
+int endpoint_init(endpoint_t *instance, usb_address_t address,
+    usb_endpoint_t endpoint, usb_direction_t direction,
+    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size);
+
+void endpoint_destroy(endpoint_t *instance);
+
+void endpoint_set_hc_data(endpoint_t *instance,
+    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int));
+
+void endpoint_clear_hc_data(endpoint_t *instance);
+
+void endpoint_use(endpoint_t *instance);
+
+void endpoint_release(endpoint_t *instance);
+
+int endpoint_toggle_get(endpoint_t *instance);
+
+void endpoint_toggle_set(endpoint_t *instance, int toggle);
+
+void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target);
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Device keeper structure and functions.
+ *
+ * Typical USB host controller needs to keep track of various settings for
+ * each device that is connected to it.
+ * State of toggle bit, device speed etc. etc.
+ * This structure shall simplify the management.
+ */
+#ifndef LIBUSB_HOST_USB_ENDPOINT_MANAGER_H
+#define LIBUSB_HOST_YSB_ENDPOINT_MANAGER_H
+
+#include <adt/hash_table.h>
+#include <fibril_synch.h>
+#include <usb/usb.h>
+#include <usb/host/endpoint.h>
+
+#define BANDWIDTH_TOTAL_USB11 12000000
+#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9)
+
+typedef struct usb_endpoint_manager {
+	hash_table_t ep_table;
+	fibril_mutex_t guard;
+	fibril_condvar_t change;
+	size_t free_bw;
+} usb_endpoint_manager_t;
+
+size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
+    size_t size, size_t max_packet_size);
+
+int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
+    size_t available_bandwidth);
+
+void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance);
+
+int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
+    endpoint_t *ep, size_t data_size);
+
+int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
+
+endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,
+    size_t *bw);
+
+void usb_endpoint_manager_reset_if_need(
+    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
+
+static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
+    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
+    size_t data_size)
+{
+	endpoint_t *ep = malloc(sizeof(endpoint_t));
+	if (ep == NULL)
+		return ENOMEM;
+
+	int ret = endpoint_init(ep, address, endpoint, direction, type, speed,
+	    max_packet_size);
+	if (ret != EOK) {
+		free(ep);
+		return ret;
+	}
+
+	ret = usb_endpoint_manager_register_ep(instance, ep, data_size);
+	if (ret != EOK) {
+		endpoint_destroy(ep);
+		return ret;
+	}
+	return EOK;
+}
+#endif
+/**
+ * @}
+ */
+
Index: uspace/lib/usbhost/src/addrkeep.c
===================================================================
--- uspace/lib/usbhost/src/addrkeep.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/src/addrkeep.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,347 @@
+/*
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * @brief Address keeping.
+ */
+#include <usb/addrkeep.h>
+#include <errno.h>
+#include <assert.h>
+
+/** For loop over all used addresses in address keeping.
+ *
+ * @param link Iterator.
+ * @param addresses Addresses keeping structure to iterate.
+ */
+#define for_all_used_addresses(link, addresses) \
+	for (link = (addresses)->used_addresses.next; \
+	    link != &(addresses)->used_addresses; \
+	    link = link->next)
+
+/** Get instance of usb_address_keeping_used_t. */
+#define used_address_get_instance(lnk) \
+	list_get_instance(lnk, usb_address_keeping_used_t, link)
+
+/** Invalid value of devman handle. */
+#define INVALID_DEVMAN_HANDLE \
+	((devman_handle_t)-1)
+
+/** Creates structure for used USB address.
+ *
+ * @param address USB address.
+ * @return Initialized structure.
+ * @retval NULL Out of memory.
+ */
+static usb_address_keeping_used_t *usb_address_keeping_used_create(
+    usb_address_t address)
+{
+	usb_address_keeping_used_t *info
+	    = malloc(sizeof(usb_address_keeping_used_t));
+	if (info == NULL) {
+		return NULL;
+	}
+
+	info->address = address;
+	info->devman_handle = INVALID_DEVMAN_HANDLE;
+	list_initialize(&info->link);
+	return info;
+}
+
+/** Destroys structure for used USB address.
+ *
+ * @param info Structure to be destroyed.
+ */
+static void usb_address_keeping_used_destroy(usb_address_keeping_used_t *info)
+{
+	free(info);
+}
+
+/** Find used USB address structure by USB address.
+ *
+ * It is expected that guard mutex is already locked.
+ *
+ * @param addresses Address keeping info.
+ * @param address Address to be found.
+ * @return Structure describing looked for address.
+ * @retval NULL Address not found.
+ */
+static usb_address_keeping_used_t *usb_address_keeping_used_find_no_lock(
+    usb_address_keeping_t *addresses, usb_address_t address)
+{
+	link_t *link;
+	for_all_used_addresses(link, addresses) {
+		usb_address_keeping_used_t *info
+		    = used_address_get_instance(link);
+
+		if (info->address == address) {
+			return info;
+		}
+	}
+
+	return NULL;
+}
+
+/** Initialize address keeping structure.
+ *
+ * @param addresses Address keeping info.
+ * @param max_address Maximum USB address (exclusive bound).
+ */
+void usb_address_keeping_init(usb_address_keeping_t *addresses,
+    usb_address_t max_address)
+{
+	/*
+	 * Items related with used addresses.
+	 */
+	addresses->max_address = max_address;
+	list_initialize(&addresses->used_addresses);
+	fibril_mutex_initialize(&addresses->used_addresses_guard);
+	fibril_condvar_initialize(&addresses->used_addresses_condvar);
+
+	/*
+	 * Items related with default address.
+	 */
+	addresses->default_available = true;
+	fibril_condvar_initialize(&addresses->default_condvar);
+	fibril_mutex_initialize(&addresses->default_condvar_guard);
+}
+
+/** Reserved default USB address.
+ *
+ * This function blocks until reserved address is available.
+ *
+ * @see usb_address_keeping_release_default
+ *
+ * @param addresses Address keeping info.
+ */
+void usb_address_keeping_reserve_default(usb_address_keeping_t *addresses)
+{
+	fibril_mutex_lock(&addresses->default_condvar_guard);
+	while (!addresses->default_available) {
+		fibril_condvar_wait(&addresses->default_condvar,
+			&addresses->default_condvar_guard);
+	}
+	addresses->default_available = false;
+	fibril_mutex_unlock(&addresses->default_condvar_guard);
+}
+
+/** Releases default USB address.
+ *
+ * @see usb_address_keeping_reserve_default
+ *
+ * @param addresses Address keeping info.
+ */
+void usb_address_keeping_release_default(usb_address_keeping_t *addresses)
+{
+	fibril_mutex_lock(&addresses->default_condvar_guard);
+	addresses->default_available = true;
+	fibril_condvar_signal(&addresses->default_condvar);
+	fibril_mutex_unlock(&addresses->default_condvar_guard);
+}
+
+/** Request free address assignment.
+ *
+ * This function does not block when there are not free addresses to be
+ * assigned.
+ *
+ * @param addresses Address keeping info.
+ * @return USB address that could be used or negative error code.
+ * @retval ELIMIT No more addresses to assign.
+ * @retval ENOMEM Out of memory.
+ */
+usb_address_t usb_address_keeping_request(usb_address_keeping_t *addresses)
+{
+	usb_address_t previous_address = 0;
+	usb_address_t free_address = 0;
+
+	fibril_mutex_lock(&addresses->used_addresses_guard);
+	link_t *new_address_position;
+	if (list_empty(&addresses->used_addresses)) {
+		free_address = 1;
+		new_address_position = addresses->used_addresses.next;
+	} else {
+		usb_address_keeping_used_t *first
+		    = used_address_get_instance(addresses->used_addresses.next);
+		previous_address = first->address;
+		
+		for_all_used_addresses(new_address_position, addresses) {
+			usb_address_keeping_used_t *info
+			    = used_address_get_instance(new_address_position);
+			if (info->address > previous_address + 1) {
+				free_address = previous_address + 1;
+				break;
+			}
+			previous_address = info->address;
+		}
+
+		if (free_address == 0) {
+			usb_address_keeping_used_t *last
+			    = used_address_get_instance(addresses->used_addresses.next);
+			free_address = last->address + 1;
+		}
+	}
+
+	if (free_address >= addresses->max_address) {
+		free_address = ELIMIT;
+		goto leave;
+	}
+
+	usb_address_keeping_used_t *used
+	    = usb_address_keeping_used_create(free_address);
+	if (used == NULL) {
+		free_address = ENOMEM;
+		goto leave;
+	}
+
+	list_prepend(&used->link, new_address_position);
+
+leave:
+	fibril_mutex_unlock(&addresses->used_addresses_guard);
+
+	return free_address;
+}
+
+/** Release USB address.
+ *
+ * @param addresses Address keeping info.
+ * @param address Address to be released.
+ * @return Error code.
+ * @retval ENOENT Address is not in use.
+ */
+int usb_address_keeping_release(usb_address_keeping_t *addresses,
+    usb_address_t address)
+{
+	int rc = ENOENT;
+
+	fibril_mutex_lock(&addresses->used_addresses_guard);
+
+	usb_address_keeping_used_t *info
+	    = usb_address_keeping_used_find_no_lock(addresses, address);
+
+	if (info != NULL) {
+		rc = EOK;
+		list_remove(&info->link);
+		usb_address_keeping_used_destroy(info);
+	}
+
+	fibril_mutex_unlock(&addresses->used_addresses_guard);
+
+	return rc;
+}
+
+/** Bind devman handle with USB address.
+ *
+ * When the @p address is invalid (e.g. no such entry), the request
+ * is silently ignored.
+ *
+ * @param addresses Address keeping info.
+ * @param address USB address.
+ * @param handle Devman handle.
+ */
+void usb_address_keeping_devman_bind(usb_address_keeping_t *addresses,
+    usb_address_t address, devman_handle_t handle)
+{
+	fibril_mutex_lock(&addresses->used_addresses_guard);
+
+	usb_address_keeping_used_t *info
+	    = usb_address_keeping_used_find_no_lock(addresses, address);
+	if (info == NULL) {
+		goto leave;
+	}
+
+	assert(info->address == address);
+	info->devman_handle = handle;
+
+	/*
+	 * Inform that new handle was added.
+	 */
+	fibril_condvar_broadcast(&addresses->used_addresses_condvar);
+
+leave:
+	fibril_mutex_unlock(&addresses->used_addresses_guard);
+}
+
+/** Find address by its devman handle.
+ *
+ * @param addresses Address keeping info.
+ * @param handle Devman handle.
+ * @return USB address or negative error code.
+ * @retval ENOENT No such address.
+ */
+static usb_address_t usb_address_keeping_find_no_lock(
+    usb_address_keeping_t *addresses, devman_handle_t handle)
+{
+	usb_address_t address = ENOENT;
+
+	link_t *link;
+	for_all_used_addresses(link, addresses) {
+		usb_address_keeping_used_t *info
+		    = used_address_get_instance(link);
+
+		if (info->devman_handle == handle) {
+			address = info->address;
+			break;
+		}
+	}
+
+	return address;
+}
+
+/** Find USB address by its devman handle.
+ *
+ * This function blocks until corresponding address is found.
+ *
+ * @param addresses Address keeping info.
+ * @param handle Devman handle.
+ * @return USB address or negative error code.
+ */
+usb_address_t usb_address_keeping_find(usb_address_keeping_t *addresses,
+    devman_handle_t handle)
+{
+	usb_address_t address = ENOENT;
+
+	fibril_mutex_lock(&addresses->used_addresses_guard);
+	while (true) {
+		address = usb_address_keeping_find_no_lock(addresses, handle);
+		if (address != ENOENT) {
+			break;
+		}
+		fibril_condvar_wait(&addresses->used_addresses_condvar,
+		    &addresses->used_addresses_guard);
+	}
+
+	fibril_mutex_unlock(&addresses->used_addresses_guard);
+
+	return address;
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/src/batch.c
===================================================================
--- uspace/lib/usbhost/src/batch.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/src/batch.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * USB transfer transaction structures (implementation).
+ */
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb/usb.h>
+#include <usb/debug.h>
+#include <usb/host/batch.h>
+
+void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
+void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
+
+void usb_transfer_batch_init(
+    usb_transfer_batch_t *instance,
+    endpoint_t *ep,
+    char *buffer,
+    char *data_buffer,
+    size_t buffer_size,
+    char *setup_buffer,
+    size_t setup_size,
+    usbhc_iface_transfer_in_callback_t func_in,
+    usbhc_iface_transfer_out_callback_t func_out,
+    void *arg,
+    ddf_fun_t *fun,
+    void *private_data,
+    void (*private_data_dtor)(void *p_data)
+    )
+{
+	assert(instance);
+	link_initialize(&instance->link);
+	instance->ep = ep;
+	instance->callback_in = func_in;
+	instance->callback_out = func_out;
+	instance->arg = arg;
+	instance->buffer = buffer;
+	instance->data_buffer = data_buffer;
+	instance->buffer_size = buffer_size;
+	instance->setup_buffer = setup_buffer;
+	instance->setup_size = setup_size;
+	instance->fun = fun;
+	instance->private_data = private_data;
+	instance->private_data_dtor = private_data_dtor;
+	instance->transfered_size = 0;
+	instance->next_step = NULL;
+	instance->error = EOK;
+	endpoint_use(instance->ep);
+}
+/*----------------------------------------------------------------------------*/
+/** Helper function, calls callback and correctly destroys batch structure.
+ *
+ * @param[in] instance Batch structure to use.
+ */
+void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	usb_transfer_batch_call_in(instance);
+	usb_transfer_batch_dispose(instance);
+}
+/*----------------------------------------------------------------------------*/
+/** Helper function calls callback and correctly destroys batch structure.
+ *
+ * @param[in] instance Batch structure to use.
+ */
+void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	usb_transfer_batch_call_out(instance);
+	usb_transfer_batch_dispose(instance);
+}
+/*----------------------------------------------------------------------------*/
+/** Mark batch as finished and continue with next step.
+ *
+ * @param[in] instance Batch structure to use.
+ *
+ */
+void usb_transfer_batch_finish(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	assert(instance->ep);
+	endpoint_release(instance->ep);
+	instance->next_step(instance);
+}
+/*----------------------------------------------------------------------------*/
+/** Prepare data, get error status and call callback in.
+ *
+ * @param[in] instance Batch structure to use.
+ * Copies data from transport buffer, and calls callback with appropriate
+ * parameters.
+ */
+void usb_transfer_batch_call_in(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	assert(instance->callback_in);
+	assert(instance->ep);
+
+	/* We are data in, we need data */
+	memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
+
+	usb_log_debug("Batch(%p) done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
+	    instance, instance->ep->address, instance->ep->endpoint,
+	    usb_str_speed(instance->ep->speed),
+	    usb_str_transfer_type_short(instance->ep->transfer_type),
+	    instance->transfered_size, str_error(instance->error),
+	    instance->error);
+
+	instance->callback_in(instance->fun, instance->error,
+	    instance->transfered_size, instance->arg);
+}
+/*----------------------------------------------------------------------------*/
+/** Get error status and call callback out.
+ *
+ * @param[in] instance Batch structure to use.
+ */
+void usb_transfer_batch_call_out(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	assert(instance->callback_out);
+
+	usb_log_debug("Batch(%p) done (T%d.%d, %s %s out): %s (%d).\n",
+	    instance, instance->ep->address, instance->ep->endpoint,
+	    usb_str_speed(instance->ep->speed),
+	    usb_str_transfer_type_short(instance->ep->transfer_type),
+	    str_error(instance->error), instance->error);
+
+	instance->callback_out(instance->fun,
+	    instance->error, instance->arg);
+}
+/*----------------------------------------------------------------------------*/
+/** Correctly dispose all used data structures.
+ *
+ * @param[in] instance Batch structure to use.
+ */
+void usb_transfer_batch_dispose(usb_transfer_batch_t *instance)
+{
+	assert(instance);
+	usb_log_debug("Batch(%p) disposing.\n", instance);
+	if (instance->private_data) {
+		assert(instance->private_data_dtor);
+		instance->private_data_dtor(instance->private_data);
+	}
+	free(instance);
+}
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/src/device_keeper.c
===================================================================
--- uspace/lib/usbhost/src/device_keeper.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/src/device_keeper.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 libusb
+ * @{
+ */
+/** @file
+ * Device keeper structure and functions (implementation).
+ */
+#include <assert.h>
+#include <errno.h>
+#include <usb/debug.h>
+#include <usb/host/device_keeper.h>
+
+/*----------------------------------------------------------------------------*/
+/** Initialize device keeper structure.
+ *
+ * @param[in] instance Memory place to initialize.
+ *
+ * Set all values to false/0.
+ */
+void usb_device_keeper_init(usb_device_keeper_t *instance)
+{
+	assert(instance);
+	unsigned i = 0;
+	for (; i < USB_ADDRESS_COUNT; ++i) {
+		instance->devices[i].occupied = false;
+		instance->devices[i].handle = 0;
+		instance->devices[i].speed = USB_SPEED_MAX;
+	}
+	// TODO: is this hack enough?
+	// (it is needed to allow smooth registration at default address)
+	instance->devices[0].occupied = true;
+	instance->last_address = 0;
+	fibril_mutex_initialize(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+/** Get a free USB address
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] speed Speed of the device requiring address.
+ * @return Free address, or error code.
+ */
+usb_address_t device_keeper_get_free_address(
+    usb_device_keeper_t *instance, usb_speed_t speed)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+
+	usb_address_t new_address = instance->last_address;
+	do {
+		++new_address;
+		if (new_address > USB11_ADDRESS_MAX)
+			new_address = 1;
+		if (new_address == instance->last_address) {
+			fibril_mutex_unlock(&instance->guard);
+			return ENOSPC;
+		}
+	} while (instance->devices[new_address].occupied);
+
+	assert(new_address != USB_ADDRESS_DEFAULT);
+	assert(instance->devices[new_address].occupied == false);
+
+	instance->devices[new_address].occupied = true;
+	instance->devices[new_address].speed = speed;
+	instance->last_address = new_address;
+
+	fibril_mutex_unlock(&instance->guard);
+	return new_address;
+}
+/*----------------------------------------------------------------------------*/
+/** Bind USB address to devman handle.
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] address Device address
+ * @param[in] handle Devman handle of the device.
+ */
+void usb_device_keeper_bind(usb_device_keeper_t *instance,
+    usb_address_t address, devman_handle_t handle)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+
+	assert(address > 0);
+	assert(address <= USB11_ADDRESS_MAX);
+	assert(instance->devices[address].occupied);
+
+	instance->devices[address].handle = handle;
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+/** Release used USB address.
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] address Device address
+ */
+void usb_device_keeper_release(
+    usb_device_keeper_t *instance, usb_address_t address)
+{
+	assert(instance);
+	assert(address > 0);
+	assert(address <= USB11_ADDRESS_MAX);
+
+	fibril_mutex_lock(&instance->guard);
+	assert(instance->devices[address].occupied);
+
+	instance->devices[address].occupied = false;
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+/** Find USB address associated with the device
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] handle Devman handle of the device seeking its address.
+ * @return USB Address, or error code.
+ */
+usb_address_t usb_device_keeper_find(
+    usb_device_keeper_t *instance, devman_handle_t handle)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	usb_address_t address = 1;
+	while (address <= USB11_ADDRESS_MAX) {
+		if (instance->devices[address].handle == handle) {
+			assert(instance->devices[address].occupied);
+			fibril_mutex_unlock(&instance->guard);
+			return address;
+		}
+		++address;
+	}
+	fibril_mutex_unlock(&instance->guard);
+	return ENOENT;
+}
+
+/** Find devman handled assigned to USB address.
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] address Address the caller wants to find.
+ * @param[out] handle Where to store found handle.
+ * @return Whether such address is currently occupied.
+ */
+bool usb_device_keeper_find_by_address(usb_device_keeper_t *instance,
+    usb_address_t address, devman_handle_t *handle)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
+		fibril_mutex_unlock(&instance->guard);
+		return false;
+	}
+	if (!instance->devices[address].occupied) {
+		fibril_mutex_unlock(&instance->guard);
+		return false;
+	}
+
+	if (handle != NULL) {
+		*handle = instance->devices[address].handle;
+	}
+
+	fibril_mutex_unlock(&instance->guard);
+	return true;
+}
+
+/*----------------------------------------------------------------------------*/
+/** Get speed associated with the address
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] address Address of the device.
+ * @return USB speed.
+ */
+usb_speed_t usb_device_keeper_get_speed(
+    usb_device_keeper_t *instance, usb_address_t address)
+{
+	assert(instance);
+	assert(address >= 0);
+	assert(address <= USB11_ADDRESS_MAX);
+
+	return instance->devices[address].speed;
+}
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/src/endpoint.c
===================================================================
--- uspace/lib/usbhost/src/endpoint.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/src/endpoint.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * 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 drvusbuhcihc
+ * @{
+ */
+/** @file
+ * @brief UHCI host controller driver structure
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <usb/host/endpoint.h>
+
+int endpoint_init(endpoint_t *instance, usb_address_t address,
+    usb_endpoint_t endpoint, usb_direction_t direction,
+    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size)
+{
+	assert(instance);
+	instance->address = address;
+	instance->endpoint = endpoint;
+	instance->direction = direction;
+	instance->transfer_type = type;
+	instance->speed = speed;
+	instance->max_packet_size = max_packet_size;
+	instance->toggle = 0;
+	instance->active = false;
+	fibril_mutex_initialize(&instance->guard);
+	fibril_condvar_initialize(&instance->avail);
+	endpoint_clear_hc_data(instance);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_destroy(endpoint_t *instance)
+{
+	assert(instance);
+	assert(!instance->active);
+	free(instance);
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_set_hc_data(endpoint_t *instance,
+    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int))
+{
+	assert(instance);
+	instance->hc_data.data = data;
+	instance->hc_data.toggle_get = toggle_get;
+	instance->hc_data.toggle_set = toggle_set;
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_clear_hc_data(endpoint_t *instance)
+{
+	assert(instance);
+	instance->hc_data.data = NULL;
+	instance->hc_data.toggle_get = NULL;
+	instance->hc_data.toggle_set = NULL;
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_use(endpoint_t *instance)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	while (instance->active)
+		fibril_condvar_wait(&instance->avail, &instance->guard);
+	instance->active = true;
+	fibril_mutex_unlock(&instance->guard);
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_release(endpoint_t *instance)
+{
+	assert(instance);
+	fibril_mutex_lock(&instance->guard);
+	instance->active = false;
+	fibril_mutex_unlock(&instance->guard);
+	fibril_condvar_signal(&instance->avail);
+}
+/*----------------------------------------------------------------------------*/
+int endpoint_toggle_get(endpoint_t *instance)
+{
+	assert(instance);
+	if (instance->hc_data.toggle_get)
+		instance->toggle =
+		    instance->hc_data.toggle_get(instance->hc_data.data);
+	return (int)instance->toggle;
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_toggle_set(endpoint_t *instance, int toggle)
+{
+	assert(instance);
+	assert(toggle == 0 || toggle == 1);
+	if (instance->hc_data.toggle_set)
+		instance->hc_data.toggle_set(instance->hc_data.data, toggle);
+	instance->toggle = toggle;
+}
+/*----------------------------------------------------------------------------*/
+void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target)
+{
+	assert(instance);
+	if (instance->address == target.address &&
+	    (instance->endpoint == target.endpoint || target.endpoint == 0))
+		endpoint_toggle_set(instance, 0);
+}
+/**
+ * @}
+ */
Index: uspace/lib/usbhost/src/usb_endpoint_manager.c
===================================================================
--- uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
+++ uspace/lib/usbhost/src/usb_endpoint_manager.c	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2011 Jan Vesely
+ * All rights eps.
+ *
+ * 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.
+ */
+
+#include <bool.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <usb/debug.h>
+#include <usb/host/usb_endpoint_manager.h>
+
+#define BUCKET_COUNT 7
+
+#define MAX_KEYS (3)
+typedef struct {
+	link_t link;
+	size_t bw;
+	endpoint_t *ep;
+} node_t;
+/*----------------------------------------------------------------------------*/
+static hash_index_t node_hash(unsigned long key[])
+{
+	hash_index_t hash = 0;
+	unsigned i = 0;
+	for (;i < MAX_KEYS; ++i) {
+		hash ^= key[i];
+	}
+	hash %= BUCKET_COUNT;
+	return hash;
+}
+/*----------------------------------------------------------------------------*/
+static int node_compare(unsigned long key[], hash_count_t keys, link_t *item)
+{
+	assert(item);
+	node_t *node = hash_table_get_instance(item, node_t, link);
+	assert(node);
+	assert(node->ep);
+	bool match = true;
+	switch (keys) {
+	case 3:
+		match = match && (key[2] == node->ep->direction);
+	case 2:
+		match = match && (key[1] == (unsigned long)node->ep->endpoint);
+	case 1:
+		match = match && (key[0] == (unsigned long)node->ep->address);
+		break;
+	default:
+		match = false;
+	}
+	return match;
+}
+/*----------------------------------------------------------------------------*/
+static void node_remove(link_t *item)
+{
+	assert(item);
+	node_t *node = hash_table_get_instance(item, node_t, link);
+	endpoint_destroy(node->ep);
+	free(node);
+}
+/*----------------------------------------------------------------------------*/
+static void node_toggle_reset_filtered(link_t *item, void *arg)
+{
+	assert(item);
+	node_t *node = hash_table_get_instance(item, node_t, link);
+	usb_target_t *target = arg;
+	endpoint_toggle_reset_filtered(node->ep, *target);
+}
+/*----------------------------------------------------------------------------*/
+static hash_table_operations_t op = {
+	.hash = node_hash,
+	.compare = node_compare,
+	.remove_callback = node_remove,
+};
+/*----------------------------------------------------------------------------*/
+size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
+    size_t size, size_t max_packet_size)
+{
+	/* We care about bandwidth only for interrupt and isochronous. */
+	if ((type != USB_TRANSFER_INTERRUPT)
+	    && (type != USB_TRANSFER_ISOCHRONOUS)) {
+		return 0;
+	}
+
+	const unsigned packet_count =
+	    (size + max_packet_size - 1) / max_packet_size;
+	/* TODO: It may be that ISO and INT transfers use only one data packet
+	 * per transaction, but I did not find text in UB spec that confirms
+	 * this */
+	/* NOTE: All data packets will be considered to be max_packet_size */
+	switch (speed)
+	{
+	case USB_SPEED_LOW:
+		assert(type == USB_TRANSFER_INTERRUPT);
+		/* Protocol overhead 13B
+		 * (3 SYNC bytes, 3 PID bytes, 2 Endpoint + CRC bytes, 2
+		 * CRC bytes, and a 3-byte interpacket delay)
+		 * see USB spec page 45-46. */
+		/* Speed penalty 8: low speed is 8-times slower*/
+		return packet_count * (13 + max_packet_size) * 8;
+	case USB_SPEED_FULL:
+		/* Interrupt transfer overhead see above
+		 * or page 45 of USB spec */
+		if (type == USB_TRANSFER_INTERRUPT)
+			return packet_count * (13 + max_packet_size);
+
+		assert(type == USB_TRANSFER_ISOCHRONOUS);
+		/* Protocol overhead 9B
+		 * (2 SYNC bytes, 2 PID bytes, 2 Endpoint + CRC bytes, 2 CRC
+		 * bytes, and a 1-byte interpacket delay)
+		 * see USB spec page 42 */
+		return packet_count * (9 + max_packet_size);
+	default:
+		return 0;
+	}
+}
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
+    size_t available_bandwidth)
+{
+	assert(instance);
+	fibril_mutex_initialize(&instance->guard);
+	fibril_condvar_initialize(&instance->change);
+	instance->free_bw = available_bandwidth;
+	bool ht =
+	    hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op);
+	return ht ? EOK : ENOMEM;
+}
+/*----------------------------------------------------------------------------*/
+void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance)
+{
+	hash_table_destroy(&instance->ep_table);
+}
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
+    endpoint_t *ep, size_t data_size)
+{
+	assert(ep);
+	size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
+	    data_size, ep->max_packet_size);
+	assert(instance);
+
+	unsigned long key[MAX_KEYS] =
+	    {ep->address, ep->endpoint, ep->direction};
+	fibril_mutex_lock(&instance->guard);
+
+	link_t *item =
+	    hash_table_find(&instance->ep_table, key);
+	if (item != NULL) {
+		fibril_mutex_unlock(&instance->guard);
+		return EEXISTS;
+	}
+
+	if (bw > instance->free_bw) {
+		fibril_mutex_unlock(&instance->guard);
+		return ENOSPC;
+	}
+
+	node_t *node = malloc(sizeof(node_t));
+	if (node == NULL) {
+		fibril_mutex_unlock(&instance->guard);
+		return ENOMEM;
+	}
+
+	node->bw = bw;
+	node->ep = ep;
+	link_initialize(&node->link);
+
+	hash_table_insert(&instance->ep_table, key, &node->link);
+	instance->free_bw -= bw;
+	fibril_mutex_unlock(&instance->guard);
+	fibril_condvar_broadcast(&instance->change);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
+{
+	assert(instance);
+	unsigned long key[MAX_KEYS] = {address, endpoint, direction};
+
+	fibril_mutex_lock(&instance->guard);
+	link_t *item = hash_table_find(&instance->ep_table, key);
+	if (item == NULL) {
+		fibril_mutex_unlock(&instance->guard);
+		return EINVAL;
+	}
+
+	node_t *node = hash_table_get_instance(item, node_t, link);
+	if (node->ep->active)
+		return EBUSY;
+
+	instance->free_bw += node->bw;
+	hash_table_remove(&instance->ep_table, key, MAX_KEYS);
+
+	fibril_mutex_unlock(&instance->guard);
+	fibril_condvar_broadcast(&instance->change);
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
+    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
+    size_t *bw)
+{
+	assert(instance);
+	unsigned long key[MAX_KEYS] = {address, endpoint, direction};
+
+	fibril_mutex_lock(&instance->guard);
+	link_t *item = hash_table_find(&instance->ep_table, key);
+	if (item == NULL) {
+		fibril_mutex_unlock(&instance->guard);
+		return NULL;
+	}
+	node_t *node = hash_table_get_instance(item, node_t, link);
+	if (bw)
+		*bw = node->bw;
+
+	fibril_mutex_unlock(&instance->guard);
+	return node->ep;
+}
+/*----------------------------------------------------------------------------*/
+/** Check setup packet data for signs of toggle reset.
+ *
+ * @param[in] instance Device keeper structure to use.
+ * @param[in] target Device to receive setup packet.
+ * @param[in] data Setup packet data.
+ *
+ * Really ugly one.
+ */
+void usb_endpoint_manager_reset_if_need(
+    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data)
+{
+	assert(instance);
+	if (target.endpoint > 15 || target.endpoint < 0
+	    || target.address >= USB11_ADDRESS_MAX || target.address < 0) {
+		usb_log_error("Invalid data when checking for toggle reset.\n");
+		return;
+	}
+
+	switch (data[1])
+	{
+	case 0x01: /*clear feature*/
+		/* recipient is endpoint, value is zero (ENDPOINT_STALL) */
+		if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
+			/* endpoint number is < 16, thus first byte is enough */
+			usb_target_t reset_target =
+			    { .address = target.address, data[4] };
+			fibril_mutex_lock(&instance->guard);
+			hash_table_apply(&instance->ep_table,
+			    node_toggle_reset_filtered, &reset_target);
+			fibril_mutex_unlock(&instance->guard);
+		}
+	break;
+
+	case 0x9: /* set configuration */
+	case 0x11: /* set interface */
+		/* target must be device */
+		if ((data[0] & 0xf) == 0) {
+			usb_target_t reset_target =
+			    { .address = target.address, 0 };
+			fibril_mutex_lock(&instance->guard);
+			hash_table_apply(&instance->ep_table,
+			    node_toggle_reset_filtered, &reset_target);
+			fibril_mutex_unlock(&instance->guard);
+		}
+	break;
+	}
+}
Index: uspace/lib/usbvirt/Makefile
===================================================================
--- uspace/lib/usbvirt/Makefile	(revision 05e21ffcff51b021954802037024afcf3b41df9d)
+++ uspace/lib/usbvirt/Makefile	(revision 4a7a8d427937ae0479a15cd9e3a60473b09b1098)
@@ -30,5 +30,9 @@
 LIBRARY = libusbvirt
 
-EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIBDRV_PREFIX)/include -Iinclude
+EXTRA_CFLAGS = \
+	-I$(LIBDRV_PREFIX)/include \
+	-I$(LIBUSB_PREFIX)/include \
+	-I$(LIBUSBDEV_PREFIX)/include \
+	-Iinclude
 
 SOURCES = \
