Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision 450198656434e7e94937231839fa4d58efe9da6b)
+++ uspace/lib/usb/Makefile	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -36,4 +36,5 @@
 	src/class.c \
 	src/debug.c \
+	src/dp.c \
 	src/drvpsync.c \
 	src/hcdhubd.c \
Index: uspace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision 450198656434e7e94937231839fa4d58efe9da6b)
+++ uspace/lib/usb/include/usb/classes/hidparser.h	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -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/include/usb/dp.h
===================================================================
--- uspace/lib/usb/include/usb/dp.h	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
+++ uspace/lib/usb/include/usb/dp.h	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -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
+ * @brief USB descriptor parser.
+ */
+#ifndef LIBUSB_DP_H_
+#define LIBUSB_DP_H_
+
+#include <sys/types.h>
+#include <usb/usb.h>
+#include <usb/descriptor.h>
+
+typedef struct {
+	int child;
+	int parent;
+} usb_dp_descriptor_nesting_t;
+
+typedef struct {
+	usb_dp_descriptor_nesting_t *nesting;
+} usb_dp_parser_t;
+
+typedef struct {
+	uint8_t *data;
+	size_t size;
+	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 *);
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/src/dp.c
===================================================================
--- uspace/lib/usb/src/dp.c	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
+++ uspace/lib/usb/src/dp.c	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -0,0 +1,234 @@
+/*
+ * 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
+ * @brief USB descriptor parser (implementation).
+ */
+#include <stdio.h>
+#include <str_error.h>
+#include <errno.h>
+#include <usb/usbdrv.h>
+#include <bool.h>
+#include <usb/dp.h>
+
+/** Tells whether pointer points inside descriptor data.
+ *
+ * @param data Parser data.
+ * @param ptr Pointer to be verified.
+ * @return Whether @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;
+	}
+}
+
+
+/** @}
+ */
Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision 450198656434e7e94937231839fa4d58efe9da6b)
+++ uspace/lib/usb/src/hidparser.c	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -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/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision 450198656434e7e94937231839fa4d58efe9da6b)
+++ uspace/lib/usb/src/recognise.c	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -346,4 +346,6 @@
     usb_address_t address, devman_handle_t *child_handle)
 {
+	static size_t device_name_index = 0;
+
 	device_t *child = NULL;
 	char *child_name = NULL;
@@ -357,7 +359,8 @@
 
 	/*
-	 * TODO: some better child naming
-	 */
-	rc = asprintf(&child_name, "usb%p", child);
+	 * TODO: Once the device driver framework support persistent
+	 * naming etc., something more descriptive could be created.
+	 */
+	rc = asprintf(&child_name, "usbdev%02zu", device_name_index);
 	if (rc < 0) {
 		goto failure;
@@ -381,4 +384,6 @@
 	}
 	
+	device_name_index++;
+
 	return EOK;
 
Index: uspace/lib/usb/src/usbdrvreq.c
===================================================================
--- uspace/lib/usb/src/usbdrvreq.c	(revision 450198656434e7e94937231839fa4d58efe9da6b)
+++ uspace/lib/usb/src/usbdrvreq.c	(revision df175fa3961788f08af68b16c0db02c0f91f8cee)
@@ -60,5 +60,5 @@
 #define PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \
     p_request, p_value, p_index, p_length) \
-	usb_device_request_setup_packet_t setup_packet = { \
+	usb_device_request_setup_packet_t name = { \
 		.request_type = \
 			((p_direction) == USB_DIRECTION_IN ? 128 : 0) \
