Index: uspace/app/virtusbkbd/virtusbkbd.c
===================================================================
--- uspace/app/virtusbkbd/virtusbkbd.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/app/virtusbkbd/virtusbkbd.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -271,8 +271,8 @@
 	printf("%s: Simulating keyboard events...\n", NAME);
 	fibril_sleep(10);
-	while (1) {
+	//while (1) {
 		kb_process_events(&status, keyboard_events, keyboard_events_count,
 			on_keyboard_change);
-	}
+	//}
 	
 	printf("%s: Terminating...\n", NAME);
Index: uspace/drv/usbhub/main.c
===================================================================
--- uspace/drv/usbhub/main.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/drv/usbhub/main.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -52,5 +52,5 @@
 	while(true){
 		usb_hub_check_hub_changes();
-		async_usleep(1000 * 1000);
+		async_usleep(1000 * 1000 );/// \TODO proper number once
 	}
 	return 0;
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/drv/usbhub/usbhub.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -46,4 +46,5 @@
 #include "usbhub_private.h"
 #include "port_status.h"
+#include "usb/usb.h"
 
 static usb_iface_t hub_usb_iface = {
@@ -85,10 +86,4 @@
 
 	// get hub descriptor
-	usb_target_t target;
-	target.address = addr;
-	target.endpoint = 0;
-	usb_device_request_setup_packet_t request;
-	//printf("[usb_hub] creating descriptor request\n");
-	usb_hub_set_descriptor_request(&request);
 
 	//printf("[usb_hub] creating serialized descriptor\n");
@@ -98,7 +93,10 @@
 	int opResult;
 	//printf("[usb_hub] starting control transaction\n");
-	opResult = usb_drv_sync_control_read(
-			hc, target, &request, serialized_descriptor,
+	
+	opResult = usb_drv_req_get_descriptor(hc, addr,
+			USB_REQUEST_TYPE_CLASS,
+			USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
 			USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
+
 	if (opResult != EOK) {
 		dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult);
@@ -155,5 +153,4 @@
 	int port;
 	int opResult;
-	usb_device_request_setup_packet_t request;
 	usb_target_t target;
 	target.address = hub_info->usb_device->address;
@@ -173,4 +170,5 @@
 	if(std_descriptor.configuration_count<1){
 		dprintf(1,"[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE");
+		//shouldn`t I return?
 	}
 	/// \TODO check other configurations
@@ -184,15 +182,12 @@
 	}
 	//set configuration
-	request.request_type = 0;
-	request.request = USB_DEVREQ_SET_CONFIGURATION;
-	request.index=0;
-	request.length=0;
-	request.value_high=0;
-	request.value_low = config_descriptor.configuration_number;
-	opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
+	opResult = usb_drv_req_set_configuration(hc, target.address,
+    config_descriptor.configuration_number);
+
 	if (opResult != EOK) {
 		dprintf(1,"[usb_hub]something went wrong when setting hub`s configuration, %d", opResult);
 	}
 
+	usb_device_request_setup_packet_t request;
 	for (port = 1; port < hub_info->port_count+1; ++port) {
 		usb_hub_set_power_port_request(&request, port);
@@ -229,5 +224,4 @@
 
 
-
 //*********************************************
 //
@@ -237,6 +231,6 @@
 
 /**
- * convenience function for releasing default address and writing debug info
- * (these few lines are used too often to be written again and again)
+ * Convenience function for releasing default address and writing debug info
+ * (these few lines are used too often to be written again and again).
  * @param hc
  * @return
@@ -253,5 +247,5 @@
 
 /**
- * reset the port with new device and reserve the default address
+ * Reset the port with new device and reserve the default address.
  * @param hc
  * @param port
@@ -282,5 +276,5 @@
 
 /**
- * finalize adding new device after port reset
+ * Finalize adding new device after port reset
  * @param hc
  * @param port
@@ -345,5 +339,5 @@
 
 /**
- * unregister device address in hc
+ * Unregister device address in hc
  * @param hc
  * @param port
@@ -355,5 +349,7 @@
 	int opResult;
 	
-	/// \TODO remove device
+	/** \TODO remove device from device manager - not yet implemented in
+	 * devide manager
+	 */
 
 	hub->attached_devs[port].devman_handle=0;
@@ -376,5 +372,5 @@
 
 /**
- * process interrupts on given hub port
+ * Process interrupts on given hub port
  * @param hc
  * @param port
@@ -434,6 +430,7 @@
 	usb_port_set_reset_completed(&status, false);
 	usb_port_set_dev_connected(&status, false);
-	if (status) {
-		dprintf(1,"[usb_hub]there was some unsupported change on port %d",port);
+	if (status>>16) {
+		dprintf(1,"[usb_hub]there was some unsupported change on port %d: %X",port,status);
+
 	}
 	/// \TODO handle other changes
@@ -442,5 +439,6 @@
 }
 
-/* Check changes on all known hubs.
+/**
+ * Check changes on all known hubs.
  */
 void usb_hub_check_hub_changes(void) {
@@ -462,6 +460,6 @@
 		target.address = hub_info->usb_device->address;
 		target.endpoint = 1;/// \TODO get from endpoint descriptor
-		dprintf(1,"[usb_hub] checking changes for hub at addr %d",
-		    target.address);
+		/*dprintf(1,"[usb_hub] checking changes for hub at addr %d",
+		    target.address);*/
 
 		size_t port_count = hub_info->port_count;
Index: uspace/drv/usbhub/usbhub_private.h
===================================================================
--- uspace/drv/usbhub/usbhub_private.h	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/drv/usbhub/usbhub_private.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @brief Hub driver.
+ * @brief Hub driver private definitions
  */
 
@@ -68,5 +68,5 @@
 
 /**
- * create hub structure instance
+ * Create hub structure instance
  *
  * Set the address and port count information most importantly.
@@ -78,21 +78,21 @@
 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc);
 
-/** list of hubs maanged by this driver */
+/** List of hubs maanged by this driver */
 extern usb_general_list_t usb_hub_list;
 
-/** lock for hub list*/
+/** Lock for hub list*/
 extern futex_t usb_hub_list_lock;
 
 
 /**
- * perform complete control read transaction
+ * Perform complete control read transaction
  *
- * manages all three steps of transaction: setup, read and finalize
+ * Manages all three steps of transaction: setup, read and finalize
  * @param phone
  * @param target
- * @param request request for data
- * @param rcvd_buffer received data
+ * @param request Request packet
+ * @param rcvd_buffer Received data
  * @param rcvd_size
- * @param actual_size actual size of received data
+ * @param actual_size Actual size of received data
  * @return error code
  */
@@ -104,10 +104,10 @@
 
 /**
- * perform complete control write transaction
+ * Perform complete control write transaction
  *
- * manages all three steps of transaction: setup, write and finalize
+ * Manages all three steps of transaction: setup, write and finalize
  * @param phone
  * @param target
- * @param request request to send data
+ * @param request Request packet to send data
  * @param sent_buffer
  * @param sent_size
@@ -121,5 +121,5 @@
 
 /**
- * set the device request to be a get hub descriptor request.
+ * Set the device request to be a get hub descriptor request.
  * @warning the size is allways set to USB_HUB_MAX_DESCRIPTOR_SIZE
  * @param request
@@ -137,4 +137,13 @@
 }
 
+/**
+ * Clear feature on hub port.
+ *
+ * @param hc Host controller telephone
+ * @param address Hub address
+ * @param port_index Port
+ * @param feature Feature selector
+ * @return Operation result
+ */
 static inline int usb_hub_clear_port_feature(int hc, usb_address_t address,
     int port_index,
Index: uspace/drv/usbkbd/Makefile
===================================================================
--- uspace/drv/usbkbd/Makefile	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/drv/usbkbd/Makefile	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -33,5 +33,7 @@
 
 SOURCES = \
-	main.c
+	main.c \
+	descparser.c \
+	descdump.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/usbkbd/descdump.c
===================================================================
--- uspace/drv/usbkbd/descdump.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
+++ uspace/drv/usbkbd/descdump.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+#include <usb/classes/hid.h>
+
+#include "descdump.h"
+
+/*----------------------------------------------------------------------------*/
+
+#define BYTES_PER_LINE 12
+
+static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
+{
+	printf("%s\n", msg);
+
+	size_t i;
+	for (i = 0; i < length; i++) {
+		printf("  0x%02X", buffer[i]);
+		if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
+		    || (i + 1 == length)) {
+			printf("\n");
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+
+#define INDENT "  "
+
+void dump_standard_configuration_descriptor(
+    int index, const usb_standard_configuration_descriptor_t *d)
+{
+	bool self_powered = d->attributes & 64;
+	bool remote_wakeup = d->attributes & 32;
+	
+	printf("Standard configuration descriptor #%d\n", index);
+	printf(INDENT "bLength = %d\n", d->length);
+	printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
+	printf(INDENT "wTotalLength = %d\n", d->total_length);
+	printf(INDENT "bNumInterfaces = %d\n", d->interface_count);
+	printf(INDENT "bConfigurationValue = %d\n", d->configuration_number);
+	printf(INDENT "iConfiguration = %d\n", d->str_configuration);
+	printf(INDENT "bmAttributes = %d [%s%s%s]\n", d->attributes,
+	    self_powered ? "self-powered" : "",
+	    (self_powered & remote_wakeup) ? ", " : "",
+	    remote_wakeup ? "remote-wakeup" : "");
+	printf(INDENT "MaxPower = %d (%dmA)\n", d->max_power,
+	    2 * d->max_power);
+	// printf(INDENT " = %d\n", d->);
+}
+
+void dump_standard_interface_descriptor(
+    const usb_standard_interface_descriptor_t *d)
+{
+	printf("Standard interface descriptor\n");
+	printf(INDENT "bLength = %d\n", d->length);
+	printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
+	printf(INDENT "bInterfaceNumber = %d\n", d->interface_number);
+	printf(INDENT "bAlternateSetting = %d\n", d->alternate_setting);
+	printf(INDENT "bNumEndpoints = %d\n", d->endpoint_count);
+	printf(INDENT "bInterfaceClass = %d\n", d->interface_class);
+	printf(INDENT "bInterfaceSubClass = %d\n", d->interface_subclass);
+	printf(INDENT "bInterfaceProtocol = %d\n", d->interface_protocol);
+	printf(INDENT "iInterface = %d\n", d->str_interface);
+}
+
+void dump_standard_endpoint_descriptor(
+    const usb_standard_endpoint_descriptor_t *d)
+{
+	const char *transfer_type;
+	switch (d->attributes & 3) {
+	case USB_TRANSFER_CONTROL:
+		transfer_type = "control";
+		break;
+	case USB_TRANSFER_ISOCHRONOUS:
+		transfer_type = "isochronous";
+		break;
+	case USB_TRANSFER_BULK:
+		transfer_type = "bulk";
+		break;
+	case USB_TRANSFER_INTERRUPT:
+		transfer_type = "interrupt";
+		break;
+	}
+
+	printf("Standard endpoint descriptor\n");
+	printf(INDENT "bLength = %d\n", d->length);
+	printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
+	printf(INDENT "bmAttributes = %d [%s]\n", d->attributes, transfer_type);
+	printf(INDENT "wMaxPacketSize = %d\n", d->max_packet_size);
+	printf(INDENT "bInterval = %d\n", d->poll_interval);
+}
+
+void dump_standard_hid_descriptor_header(
+    const usb_standard_hid_descriptor_t *d)
+{
+	printf("Standard HID descriptor\n");
+	printf(INDENT "bLength = %d\n", d->length);
+	printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
+	printf(INDENT "bcdHID = %d\n", d->spec_release);
+	printf(INDENT "bCountryCode = %d\n", d->country_code);
+	printf(INDENT "bNumDescriptors = %d\n", d->class_desc_count);
+	printf(INDENT "bDescriptorType = %d\n", d->report_desc_info.type);
+	printf(INDENT "wDescriptorLength = %d\n", d->report_desc_info.length);
+}
+
+void dump_standard_hid_class_descriptor_info(
+    const usb_standard_hid_class_descriptor_info_t *d)
+{
+	printf(INDENT "bDescriptorType = %d\n", d->type);
+	printf(INDENT "wDescriptorLength = %d\n", d->length);
+}
+
+void dump_hid_class_descriptor(int index, uint8_t type, 
+    const uint8_t *d, size_t size )
+{
+	printf("Class-specific descriptor #%d (type: %u)\n", index, type);
+	assert(d != NULL);
+	dump_buffer("", d, size);
+}
Index: uspace/drv/usbkbd/descdump.h
===================================================================
--- uspace/drv/usbkbd/descdump.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
+++ uspace/drv/usbkbd/descdump.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+#ifndef USBHID_DESCDUMP_H_
+#define USBHID_DESCDUMP_H_
+
+#include <usb/classes/hid.h>
+
+void dump_standard_configuration_descriptor(
+    int index, const usb_standard_configuration_descriptor_t *d);
+
+void dump_standard_interface_descriptor(
+    const usb_standard_interface_descriptor_t *d);
+
+void dump_standard_endpoint_descriptor(
+    const usb_standard_endpoint_descriptor_t *d);
+
+void dump_standard_hid_descriptor_header(
+    const usb_standard_hid_descriptor_t *d);
+
+void dump_standard_hid_class_descriptor_info(
+    const usb_standard_hid_class_descriptor_info_t *d);
+
+void dump_hid_class_descriptor(int index, uint8_t type, 
+    const uint8_t *d, size_t size);
+
+#endif /* USBHID_DESCDUMP_H_ */
Index: uspace/drv/usbkbd/descparser.c
===================================================================
--- uspace/drv/usbkbd/descparser.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
+++ uspace/drv/usbkbd/descparser.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+#include <errno.h>
+#include <stdint.h>
+#include <usb/usb.h>
+#include <usb/classes/hid.h>
+#include <usb/descriptor.h>
+#include "descparser.h"
+#include "descdump.h"
+
+static void usbkbd_config_free(usb_hid_configuration_t *config)
+{
+	if (config == NULL) {
+		return;
+	}
+	
+	if (config->interfaces == NULL) {
+		return;
+	}
+	
+	int i;
+	for (i = 0; i < config->config_descriptor.interface_count; ++i) {
+		
+		usb_hid_iface_t *iface = &config->interfaces[i];
+		
+		if (iface->endpoints != NULL) {
+			free(config->interfaces[i].endpoints);
+		}
+		/*if (iface->class_desc_info != NULL) {
+			free(iface->class_desc_info);
+		}
+		if (iface->class_descs != NULL) {
+			int j;
+			for (j = 0; 
+			     j < iface->hid_desc.class_desc_count;
+			     ++j) {
+				if (iface->class_descs[j] != NULL) {
+					free(iface->class_descs[j]);
+				}
+			}
+		}*/
+	}
+	
+	free(config->interfaces);	
+}
+
+/*----------------------------------------------------------------------------*/
+
+
+
+/*----------------------------------------------------------------------------*/
+
+int usbkbd_parse_descriptors(const uint8_t *data, size_t size,
+                             usb_hid_configuration_t *config)
+{
+	if (config == NULL) {
+		return EINVAL;
+	}
+	
+	const uint8_t *pos = data;
+	
+	// get the configuration descriptor (should be first) || *config == NULL
+	if (*pos != sizeof(usb_standard_configuration_descriptor_t)
+	    || *(pos + 1) != USB_DESCTYPE_CONFIGURATION) {
+		fprintf(stderr, "Wrong format of configuration descriptor.\n");
+		return EINVAL;
+	}
+	
+	memcpy(&config->config_descriptor, pos, 
+	    sizeof(usb_standard_configuration_descriptor_t));
+	pos += sizeof(usb_standard_configuration_descriptor_t);
+
+	//printf("Parsed configuration descriptor: \n");
+	//dump_standard_configuration_descriptor(0, &config->config_descriptor);
+	
+	int ret = EOK;
+
+	// first descriptor after configuration should be interface
+	if (*(pos + 1) != USB_DESCTYPE_INTERFACE) {
+		fprintf(stderr, "Expected interface descriptor, but got %u.\n", 
+		    *(pos + 1));
+		return EINVAL;
+	}
+	
+	// prepare place for interface descriptors
+	config->interfaces = (usb_hid_iface_t *)calloc(
+	    config->config_descriptor.interface_count, sizeof(usb_hid_iface_t));
+	
+	int iface_i = 0;
+	// as long as these are < 0, there is no space allocated for
+	// the respective structures
+	int ep_i = -1;
+	//int hid_i = -1;
+	
+	usb_hid_iface_t *actual_iface = NULL;
+	//usb_standard_endpoint_descriptor_t *actual_ep = NULL;
+	
+	// parse other descriptors
+	while ((size_t)(pos - data) < size) {
+		uint8_t desc_size = *pos;
+		uint8_t desc_type = *(pos + 1);  // 2nd byte is descriptor size
+		
+		switch (desc_type) {
+		case USB_DESCTYPE_INTERFACE:
+			if (desc_size != 
+			    sizeof(usb_standard_interface_descriptor_t)) {
+				ret = EINVAL;
+				goto end;
+			}
+			
+			actual_iface = &config->interfaces[iface_i++];
+			
+			memcpy(&actual_iface->iface_desc, pos, desc_size);
+			pos += desc_size;
+
+			//printf("Parsed interface descriptor: \n");
+			//dump_standard_interface_descriptor(&actual_iface->iface_desc);
+			
+			// allocate space for endpoint descriptors
+			uint8_t eps = actual_iface->iface_desc.endpoint_count;
+			actual_iface->endpoints = 
+			    (usb_standard_endpoint_descriptor_t *)malloc(
+			     eps * sizeof(usb_standard_endpoint_descriptor_t));
+			if (actual_iface->endpoints == NULL) {
+				ret = ENOMEM;
+				goto end;
+			}
+			ep_i = 0;
+
+			//printf("Remaining size: %d\n", size - (size_t)(pos - data));
+			
+			break;
+		case USB_DESCTYPE_ENDPOINT:
+			if (desc_size != 
+			    sizeof(usb_standard_endpoint_descriptor_t)) {
+				ret = EINVAL;
+				goto end;
+			}
+			
+			if (ep_i < 0) {
+				fprintf(stderr, "Missing interface descriptor "
+				    "before endpoint descriptor.\n");
+				ret = EINVAL;
+				goto end;
+			}
+			if (ep_i > actual_iface->iface_desc.endpoint_count) {
+				fprintf(stderr, "More endpoint descriptors than"
+					" expected.\n");
+				ret = EINVAL;
+				goto end;
+			}
+			
+			// save the endpoint descriptor
+			memcpy(&actual_iface->endpoints[ep_i], pos, desc_size);
+			pos += desc_size;
+
+			//printf("Parsed endpoint descriptor: \n");
+			//dump_standard_endpoint_descriptor(&actual_iface->endpoints[ep_i]);
+			++ep_i;
+			
+			break;
+		case USB_DESCTYPE_HID:
+			if (desc_size < sizeof(usb_standard_hid_descriptor_t)) {
+				printf("Wrong size of descriptor: %d (should be %d)\n",
+				    desc_size, sizeof(usb_standard_hid_descriptor_t));
+				ret = EINVAL;
+				goto end;
+			}
+			
+			// copy the header of the hid descriptor
+			memcpy(&actual_iface->hid_desc, pos, 
+			       sizeof(usb_standard_hid_descriptor_t));
+			pos += sizeof(usb_standard_hid_descriptor_t);
+			
+			/*if (actual_iface->hid_desc.class_desc_count
+			    * sizeof(usb_standard_hid_class_descriptor_info_t)
+			    != desc_size 
+			        - sizeof(usb_standard_hid_descriptor_t)) {
+				fprintf(stderr, "Wrong size of HID descriptor."
+					"\n");
+				ret = EINVAL;
+				goto end;
+			}*/
+
+			//printf("Parsed HID descriptor header: \n");
+			//dump_standard_hid_descriptor_header(&actual_iface->hid_desc);
+			
+			// allocate space for all class-specific descriptor info
+			/*actual_iface->class_desc_info = 
+			    (usb_standard_hid_class_descriptor_info_t *)malloc(
+			    actual_iface->hid_desc.class_desc_count
+			    * sizeof(usb_standard_hid_class_descriptor_info_t));
+			if (actual_iface->class_desc_info == NULL) {
+				ret = ENOMEM;
+				goto end;
+			}*/
+			
+			// allocate space for all class-specific descriptors
+			/*actual_iface->class_descs = (uint8_t **)calloc(
+			    actual_iface->hid_desc.class_desc_count,
+			    sizeof(uint8_t *));
+			if (actual_iface->class_descs == NULL) {
+				ret = ENOMEM;
+				goto end;
+			}*/
+
+			// copy all class-specific descriptor info
+			// TODO: endianness
+			/*
+			memcpy(actual_iface->class_desc_info, pos, 
+			    actual_iface->hid_desc.class_desc_count
+			    * sizeof(usb_standard_hid_class_descriptor_info_t));
+			pos += actual_iface->hid_desc.class_desc_count
+			    * sizeof(usb_standard_hid_class_descriptor_info_t);
+
+			printf("Parsed HID descriptor info:\n");
+			dump_standard_hid_class_descriptor_info(
+			    actual_iface->class_desc_info);
+			*/
+			
+			/*size_t tmp = (size_t)(pos - data);
+			printf("Parser position: %d, remaining: %d\n",
+			       pos - data, size - tmp);*/
+
+			//hid_i = 0;
+			
+			break;
+/*		case USB_DESCTYPE_HID_REPORT:
+		case USB_DESCTYPE_HID_PHYSICAL: {
+			// check if the type matches
+			uint8_t exp_type = 
+			    actual_iface->class_desc_info[hid_i].type;
+			if (exp_type != desc_type) {
+				fprintf(stderr, "Expected descriptor type %u, "
+				    "but got %u.\n", exp_type, desc_type);
+				ret = EINVAL;
+				goto end;
+			}
+			
+			// the size of this descriptor is stored in the
+			// class-specific descriptor info
+			uint16_t length = 
+			    actual_iface->class_desc_info[hid_i].length;
+			
+			printf("Saving class-specific descriptor #%d\n", hid_i);
+			
+			actual_iface->class_descs[hid_i] = 
+			    (uint8_t *)malloc(length);
+			if (actual_iface->class_descs[hid_i] == NULL) {
+				ret = ENOMEM;
+				goto end;
+			}
+			
+			memcpy(actual_iface->class_descs[hid_i], pos, length);
+			pos += length;
+
+			printf("Parsed class-specific descriptor:\n");
+			dump_hid_class_descriptor(hid_i, desc_type, 
+			                          actual_iface->class_descs[hid_i], length);
+			                          
+			++hid_i;
+			
+			break; }*/
+		default:
+			fprintf(stderr, "Got descriptor of unknown type: %u.\n",
+				desc_type);
+			ret = EINVAL;
+			goto end;
+			break;
+		}
+	}
+
+end:
+	if (ret != EOK) {
+		usbkbd_config_free(config);
+	}
+	
+	return ret;
+}
+
+void usbkbd_print_config(const usb_hid_configuration_t *config)
+{
+	dump_standard_configuration_descriptor(0, &config->config_descriptor);
+	int i = 0;
+	for (; i < config->config_descriptor.interface_count; ++i) {
+		usb_hid_iface_t *iface_d = &config->interfaces[i];
+		dump_standard_interface_descriptor(&iface_d->iface_desc);
+		printf("\n");
+		int j = 0;
+		for (; j < iface_d->iface_desc.endpoint_count; ++j) {
+			dump_standard_endpoint_descriptor(
+			    &iface_d->endpoints[j]);
+			printf("\n");
+		}
+		dump_standard_hid_descriptor_header(&iface_d->hid_desc);
+		printf("\n");
+		dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT, 
+		    iface_d->report_desc, iface_d->hid_desc.report_desc_info.length);
+		printf("\n");
+//		printf("%d class-specific descriptors\n", 
+//		    iface_d->hid_desc.class_desc_count);
+		/*for (j = 0; j < iface_d->hid_desc.class_desc_count; ++j) {
+			dump_standard_hid_class_descriptor_info(
+			    &iface_d->class_desc_info[j]);
+		}
+		
+		for (j = 0; j < iface_d->hid_desc.class_desc_count; ++j) {
+			dump_hid_class_descriptor(j, 
+			    iface_d->class_desc_info[j].type,
+			    iface_d->class_descs[j],
+			    iface_d->class_desc_info[j].length);
+		}*/
+	}
+}
Index: uspace/drv/usbkbd/descparser.h
===================================================================
--- uspace/drv/usbkbd/descparser.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
+++ uspace/drv/usbkbd/descparser.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+#ifndef USBHID_DESCPARSER_H_
+#define USBHID_DESCPARSER_H_
+
+#include <usb/classes/hid.h>
+
+int usbkbd_parse_descriptors(const uint8_t *data, size_t size,
+                             usb_hid_configuration_t *config);
+
+void usbkbd_print_config(const usb_hid_configuration_t *config);
+
+#endif
Index: uspace/drv/usbkbd/main.c
===================================================================
--- uspace/drv/usbkbd/main.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/drv/usbkbd/main.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -38,4 +38,6 @@
 #include <usb/devreq.h>
 #include <usb/descriptor.h>
+#include "descparser.h"
+#include "descdump.h"
 
 #define BUFFER_SIZE 32
@@ -88,8 +90,13 @@
  * Callbacks for parser
  */
-static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
-                                    void *arg)
-{
-
+static void usbkbd_process_keycodes(const uint8_t *key_codes, size_t count,
+                                    uint8_t modifiers, void *arg)
+{
+	printf("Got keys: ");
+	unsigned i;
+	for (i = 0; i < count; ++i) {
+		printf("%d ", key_codes[i]);
+	}
+	printf("\n");
 }
 
@@ -97,45 +104,40 @@
  * Kbd functions
  */
-static int usbkbd_parse_descriptors(usb_hid_dev_kbd_t *kbd_dev,
-                                    const uint8_t *data, size_t size)
-{
-//	const uint8_t *pos = data;
-	
-//	// get the configuration descriptor (should be first)
-//	if (*pos != sizeof(usb_standard_configuration_descriptor_t)
-//	    || *(pos + 1) != USB_DESCTYPE_CONFIGURATION) {
-//		fprintf(stderr, "Wrong format of configuration descriptor");
-//		return EINVAL;
-//	}
-	
-//	usb_standard_configuration_descriptor_t config_descriptor;
-//	memcpy(&config_descriptor, pos, 
-//	    sizeof(usb_standard_configuration_descriptor_t));
-//	pos += sizeof(usb_standard_configuration_descriptor_t);
-	
-//	// parse other descriptors
-//	while (pos - data < size) {
-//		//uint8_t desc_size = *pos;
-//		uint8_t desc_type = *(pos + 1);
-//		switch (desc_type) {
-//		case USB_DESCTYPE_INTERFACE:
-//			break;
-//		case USB_DESCTYPE_ENDPOINT:
-//			break;
-//		case USB_DESCTYPE_HID:
-//			break;
-//		case USB_DESCTYPE_HID_REPORT:
-//			break;
-//		case USB_DESCTYPE_HID_PHYSICAL:
-//			break;
-//		}
-//	}
-	
+static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)
+{
+	// iterate over all configurations and interfaces
+	// TODO: more configurations!!
+	unsigned i;
+	for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
+		// TODO: endianness
+		uint16_t length = 
+		    kbd_dev->conf->interfaces[i].hid_desc.report_desc_info.length;
+		size_t actual_size = 0;
+
+		// allocate space for the report descriptor
+		kbd_dev->conf->interfaces[i].report_desc = (uint8_t *)malloc(length);
+		
+		// get the descriptor from the device
+		int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone,
+		    kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 
+		    0, i, kbd_dev->conf->interfaces[i].report_desc, length, 
+		    &actual_size);
+
+		if (rc != EOK) {
+			return rc;
+		}
+
+		assert(actual_size == length);
+
+		//dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT, 
+		//    kbd_dev->conf->interfaces[i].report_desc, length);
+	}
+
 	return EOK;
 }
 
-static int usbkbd_get_descriptors(usb_hid_dev_kbd_t *kbd_dev)
-{
-	// get the first configuration descriptor (TODO: or some other??)
+static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev)
+{
+	// get the first configuration descriptor (TODO: parse also other!)
 	usb_standard_configuration_descriptor_t config_desc;
 	
@@ -166,14 +168,43 @@
 	}
 	
-	rc = usbkbd_parse_descriptors(kbd_dev, descriptors, transferred);
+	kbd_dev->conf = (usb_hid_configuration_t *)calloc(1, 
+	    sizeof(usb_hid_configuration_t));
+	if (kbd_dev->conf == NULL) {
+		free(descriptors);
+		return ENOMEM;
+	}
+	
+	rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
 	free(descriptors);
-	
-	return rc;
+	if (rc != EOK) {
+		printf("Problem with parsing standard descriptors.\n");
+		return rc;
+	}
+
+	// get and report descriptors
+	rc = usbkbd_get_report_descriptor(kbd_dev);
+	if (rc != EOK) {
+		printf("Problem with parsing HID REPORT descriptor.\n");
+		return rc;
+	}
+	
+	//usbkbd_print_config(kbd_dev->conf);
+
+	/*
+	 * TODO: 
+	 * 1) select one configuration (lets say the first)
+	 * 2) how many interfaces?? how to select one??
+     *    ("The default setting for an interface is always alternate setting zero.")
+	 * 3) find endpoint which is IN and INTERRUPT (parse), save its number
+     *    as the endpoint for polling
+	 */
+	
+	return EOK;
 }
 
 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
 {
-	usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc(
-			sizeof(usb_hid_dev_kbd_t));
+	usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 
+	    sizeof(usb_hid_dev_kbd_t));
 
 	if (kbd_dev == NULL) {
@@ -186,8 +217,17 @@
 	// get phone to my HC and save it as my parent's phone
 	// TODO: maybe not a good idea if DDF will use parent_phone
-	kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
-
-	kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
-	    dev);
+	int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
+	if (rc < 0) {
+		printf("Problem setting phone to HC.\n");
+		free(kbd_dev);
+		return NULL;
+	}
+
+	rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev);
+	if (rc < 0) {
+		printf("Problem getting address of the device.\n");
+		free(kbd_dev);
+		return NULL;
+	}
 
 	// doesn't matter now that we have no address
@@ -208,7 +248,6 @@
 	 */
 
-	// TODO: get descriptors
-	usbkbd_get_descriptors(kbd_dev);
-	// TODO: parse descriptors and save endpoints
+	// TODO: get descriptors, parse descriptors and save endpoints
+	usbkbd_process_descriptors(kbd_dev);
 
 	return kbd_dev;
@@ -218,9 +257,4 @@
                                         uint8_t *buffer, size_t actual_size)
 {
-	/*
-	 * here, the parser will be called, probably with some callbacks
-	 * now only take last 6 bytes and process, i.e. send to kbd
-	 */
-
 	usb_hid_report_in_callbacks_t *callbacks =
 	    (usb_hid_report_in_callbacks_t *)malloc(
@@ -228,10 +262,14 @@
 	callbacks->keyboard = usbkbd_process_keycodes;
 
-	usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 
-	    NULL);
+	//usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 
+	//    NULL);
+	printf("Calling usb_hid_boot_keyboard_input_report()...\n)");
+	usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks, NULL);
 }
 
 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
 {
+	return;
+	
 	int rc;
 	usb_handle_t handle;
Index: uspace/drv/vhc/hcd.c
===================================================================
--- uspace/drv/vhc/hcd.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/drv/vhc/hcd.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -116,5 +116,5 @@
 	sleep(5);
 
-	usb_dprintf_enable(NAME, 0);
+	usb_dprintf_enable(NAME, -1);
 
 	printf(NAME ": virtual USB host controller driver.\n");
Index: uspace/lib/usb/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid.h	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/lib/usb/include/usb/classes/hid.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -39,4 +39,5 @@
 #include <driver.h>
 #include <usb/classes/hidparser.h>
+#include <usb/descriptor.h>
 
 /** USB/HID device requests. */
@@ -63,9 +64,9 @@
  */
 typedef struct {
-	/** Type of class descriptor (Report or Physical). */
-	uint8_t class_descriptor_type;
-	/** Length of class descriptor. */
-	uint16_t class_descriptor_length;
-} __attribute__ ((packed)) usb_standard_hid_descriptor_class_item_t;
+	/** 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.
@@ -73,9 +74,14 @@
  * (See HID Specification, p.22)
  * 
- * It is actually only the "header" of the descriptor, as it may have arbitrary
- * length if more than one class descritor is provided.
+ * 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 {
-	/** Size of this descriptor in bytes. */
+	/** 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). */
@@ -85,10 +91,33 @@
 	/** Country code of localized hardware. */
 	uint8_t country_code;
-	/** Total number of class (i.e. Report and Physical) descriptors. */
-	uint8_t class_count;
-	/** First mandatory class descriptor info. */
-	usb_standard_hid_descriptor_class_item_t class_descriptor;
+	/** 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;
 
+/**
+ *
+ */
+typedef struct {
+	usb_standard_interface_descriptor_t iface_desc;
+	usb_standard_endpoint_descriptor_t *endpoints;
+	usb_standard_hid_descriptor_t hid_desc;
+	uint8_t *report_desc;
+	//usb_standard_hid_class_descriptor_info_t *class_desc_info;
+	//uint8_t **class_descs;
+} usb_hid_iface_t;
+
+/**
+ *
+ */
+typedef struct {
+	usb_standard_configuration_descriptor_t config_descriptor;
+	usb_hid_iface_t *interfaces;
+} usb_hid_configuration_t;
 
 /**
@@ -99,4 +128,5 @@
 typedef struct {
 	device_t *device;
+	usb_hid_configuration_t *conf;
 	usb_address_t address;
 	usb_endpoint_t poll_endpoint;
@@ -104,4 +134,6 @@
 } usb_hid_dev_kbd_t;
 
+// TODO: more configurations!
+
 #endif
 /**
Index: uspace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/lib/usb/include/usb/classes/hidparser.h	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -38,7 +38,24 @@
 #include <stdint.h>
 
+/**
+ * Description of report items
+ */
+typedef struct {
+
+	uint8_t usage_min;
+	uint8_t usage_max;
+	uint8_t logical_min;
+	uint8_t logical_max;
+	uint8_t size;
+	uint8_t count;
+	uint8_t offset;
+
+} usb_hid_report_item_t;
+
+
 /** HID report parser structure. */
 typedef struct {
 } usb_hid_report_parser_t;
+
 
 /** HID parser callbacks for IN items. */
@@ -50,6 +67,21 @@
 	 * @param arg Custom argument.
 	 */
-	void (*keyboard)(const uint16_t *key_codes, size_t count, void *arg);
+	void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t modifiers, void *arg);
 } usb_hid_report_in_callbacks_t;
+
+#define USB_HID_BOOT_KEYBOARD_NUM_LOCK		0x01
+#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK		0x02
+#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK	0x04
+#define USB_HID_BOOT_KEYBOARD_COMPOSE		0x08
+#define USB_HID_BOOT_KEYBOARD_KANA			0x10
+
+/*
+ * modifiers definitions
+ */
+
+int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,
+	const usb_hid_report_in_callbacks_t *callbacks, void *arg);
+
+int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size);
 
 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 
@@ -60,4 +92,7 @@
     const usb_hid_report_in_callbacks_t *callbacks, void *arg);
 
+
+int usb_hid_free_report_parser(usb_hid_report_parser_t *parser);
+
 #endif
 /**
Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/lib/usb/src/hidparser.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -40,5 +40,4 @@
  * @param parser Opaque HID report parser structure.
  * @param data Data describing the report.
- * @param size Size of the descriptor in bytes.
  * @return Error code.
  */
@@ -55,5 +54,4 @@
  * @param parser Opaque HID report parser structure.
  * @param data Data for the report.
- * @param size Size of the data in bytes.
  * @param callbacks Callbacks for report actions.
  * @param arg Custom argument (passed through to the callbacks).
@@ -66,7 +64,10 @@
 	int i;
 	
-	// TODO: parse report
+	/* main parsing loop */
+	while(0){
+	}
 	
-	uint16_t keys[6];
+	
+	uint8_t keys[6];
 	
 	for (i = 0; i < 6; ++i) {
@@ -74,6 +75,17 @@
 	}
 	
-	callbacks->keyboard(keys, 6, arg);
-	
+	callbacks->keyboard(keys, 6, 0, arg);
+
+	return EOK;
+}
+
+/** Free the HID report parser structure 
+ *
+ * @param parser Opaque HID report parser structure
+ * @return Error code
+ */
+int usb_hid_free_report_parser(usb_hid_report_parser_t *parser)
+{
+
 	return EOK;
 }
@@ -81,4 +93,64 @@
 
 /**
+ * Parse input report.
+ *
+ * @param data Data for report
+ * @param size Size of report
+ * @param callbacks Callbacks for report actions
+ * @param arg Custom arguments
+ *
+ * @return Error code
+ */
+int usb_hid_boot_keyboard_input_report(const uint8_t *data, size_t size,
+	const usb_hid_report_in_callbacks_t *callbacks, void *arg)
+{
+	int i;
+	usb_hid_report_item_t item;
+
+	/* fill item due to the boot protocol report descriptor */
+	// modifier keys are in the first byte
+	uint8_t modifiers = data[0];
+
+	item.offset = 2; /* second byte is reserved */
+	item.size = 8;
+	item.count = 6;
+	item.usage_min = 0;
+	item.usage_max = 255;
+	item.logical_min = 0;
+	item.logical_max = 255;
+
+	if(size != 8){
+		return -1;
+	}
+
+	uint8_t keys[6];
+	for(i=item.offset; i<item.count; i++) {
+		keys[i-2] = data[i];
+	}
+
+	callbacks->keyboard(keys, 6, modifiers, arg);
+	return EOK;
+}
+
+/**
+ * Makes output report for keyboard boot protocol
+ *
+ * @param leds
+ * @param output Output report data buffer
+ * @param size Size of the output buffer
+ * @return Error code
+ */
+int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
+{
+	if(size != 1){
+		return -1;
+	}
+
+	/* used only first five bits, others are only padding*/
+	*data = leds;
+	return EOK;
+}
+
+/**
  * @}
  */
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision c9d5577cfba2ae0264c71b27709c24b1f5f95541)
+++ uspace/srv/devman/main.c	(revision ff8ed0664753d1c7238ca60e6fc612287d9bc8b7)
@@ -479,6 +479,6 @@
 	}
 
-	printf(NAME ": devman_forward: forward connection to device %s to "
-	    "driver %s.\n", dev->pathname, driver->name);
+//	printf(NAME ": devman_forward: forward connection to device %s to "
+//	    "driver %s.\n", dev->pathname, driver->name);
 	ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE);
 }
