Index: uspace/drv/usbhid/Makefile
===================================================================
--- uspace/drv/usbhid/Makefile	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhid/Makefile	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -39,6 +39,4 @@
 SOURCES = \
 	main.c \
-	descparser.c \
-	descdump.c \
 	conv.c \
 	$(STOLEN_LAYOUT_SOURCES)
Index: uspace/drv/usbhid/conv.c
===================================================================
--- uspace/drv/usbhid/conv.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhid/conv.c	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -36,4 +36,6 @@
 #include <io/keycode.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <usb/debug.h>
 #include "conv.h"
 
@@ -141,4 +143,22 @@
 	//[0xe7] = KC_R	// TODO: right GUI
 	
+	[0x53] = KC_NUM_LOCK,
+	[0x54] = KC_NSLASH,
+	[0x55] = KC_NTIMES,
+	[0x56] = KC_NMINUS,
+	[0x57] = KC_NPLUS,
+	[0x58] = KC_NENTER,
+	[0x59] = KC_N1,
+	[0x5a] = KC_N2,
+	[0x5b] = KC_N3,
+	[0x5c] = KC_N4,
+	[0x5d] = KC_N5,
+	[0x5e] = KC_N6,
+	[0x5f] = KC_N7,
+	[0x60] = KC_N8,
+	[0x61] = KC_N9,
+	[0x62] = KC_N0,
+	[0x63] = KC_NPERIOD
+	
 };
 
@@ -189,4 +209,17 @@
 
 	key = map[scancode];
+	
+	if (scancode == 0x53) {
+		usb_log_debug("\n\nWe have a NUM LOCK!, sending key %u\n\n", key);
+	}
+	
+	if (scancode == 0x47) {
+		usb_log_debug("\n\nWe have a SCROLL LOCK!, sending key %u\n\n", key);
+	}
+	
+	if (scancode == 0x39) {
+		usb_log_debug("\n\nWe have a CAPS LOCK!, sending key %u\n\n", key);
+	}
+	
 //	if (key != 0)
 //		kbd_push_ev(type, key);
Index: pace/drv/usbhid/descparser.c
===================================================================
--- uspace/drv/usbhid/descparser.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ 	(revision )
@@ -1,352 +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 drvusbhid
- * @{
- */
-/** @file
- * Descriptor parser.
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.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 %zu)\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: pace/drv/usbhid/descparser.h
===================================================================
--- uspace/drv/usbhid/descparser.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ 	(revision )
@@ -1,50 +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 drvusbhid
- * @{
- */
-/** @file
- * Descriptor parser.
- */
-
-#ifndef USBHID_DESCPARSER_H_
-#define USBHID_DESCPARSER_H_
-
-#include "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/usbhid/hid.h
===================================================================
--- uspace/drv/usbhid/hid.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhid/hid.h	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -37,27 +37,9 @@
 #define USBHID_HID_H_
 
+#include <stdint.h>
+
 #include <usb/classes/hid.h>
 #include <ddf/driver.h>
 #include <usb/pipes.h>
-
-/**
- *
- */
-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;
 
 /**
@@ -68,13 +50,21 @@
 typedef struct {
 	ddf_dev_t *device;
-	usb_hid_configuration_t *conf;
-	usb_hid_report_parser_t *parser;
 
 	usb_device_connection_t wire;
 	usb_endpoint_pipe_t ctrl_pipe;
 	usb_endpoint_pipe_t poll_pipe;
+	
+	uint16_t iface;
+	
+	uint8_t *report_desc;
+	usb_hid_report_parser_t *parser;
+	
+	uint8_t *keycodes;
+	size_t keycode_count;
+	uint8_t modifiers;
+	
+	unsigned mods;
+	unsigned lock_keys;
 } usb_hid_dev_kbd_t;
 
-// TODO: more configurations!
-
 #endif
Index: uspace/drv/usbhid/main.c
===================================================================
--- uspace/drv/usbhid/main.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhid/main.c	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -51,14 +51,18 @@
 #include <usb/descriptor.h>
 #include <io/console.h>
+#include <stdint.h>
+#include <usb/dp.h>
 #include "hid.h"
-#include "descparser.h"
-#include "descdump.h"
 #include "conv.h"
 #include "layout.h"
 
 #define BUFFER_SIZE 8
+#define BUFFER_OUT_SIZE 1
 #define NAME "usbhid"
 
-#define GUESSED_POLL_ENDPOINT 1
+//#define GUESSED_POLL_ENDPOINT 1
+#define BOOTP_REPORT_SIZE 6
+
+static unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
 
 /** Keyboard polling endpoint description for boot protocol class. */
@@ -120,5 +124,5 @@
 
 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
-{
+{uint8_t buffer[BUFFER_SIZE];
 	printf("%s\n", msg);
 	
@@ -137,9 +141,9 @@
  */
 
-/** Currently active modifiers. 
+/** Currently active modifiers (locks is probably better word).
  *
  * TODO: put to device?
  */
-static unsigned mods = KM_NUM_LOCK;
+//static unsigned mods = KM_NUM_LOCK;
 
 /** Currently pressed lock keys. We track these to tackle autorepeat.  
@@ -147,5 +151,5 @@
  * TODO: put to device? 
  */
-static unsigned lock_keys;
+//static unsigned lock_keys;
 
 #define NUM_LAYOUTS 3
@@ -159,5 +163,116 @@
 static int active_layout = 0;
 
-static void kbd_push_ev(int type, unsigned int key)
+static void usbkbd_req_set_report(usb_hid_dev_kbd_t *kbd_dev, uint16_t iface,
+    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
+{
+	int rc, sess_rc;
+	
+	sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
+	if (sess_rc != EOK) {
+		usb_log_warning("Failed to start a session: %s.\n",
+		    str_error(sess_rc));
+		return;
+	}
+
+	usb_log_debug("Sending Set_Report request to the device.\n");
+	
+	rc = usb_control_request_set(&kbd_dev->ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_SET_REPORT, type, iface, buffer, buf_size);
+
+	sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return;
+	}
+
+	if (sess_rc != EOK) {
+		usb_log_warning("Error closing session: %s.\n",
+		    str_error(sess_rc));
+		return;
+	}
+}
+
+static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev,
+    usb_hid_protocol_t protocol)
+{
+	int rc, sess_rc;
+	
+	sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
+	if (sess_rc != EOK) {
+		usb_log_warning("Failed to start a session: %s.\n",
+		    str_error(sess_rc));
+		return;
+	}
+
+	usb_log_debug("Sending Set_Protocol request to the device ("
+	    "protocol: %d, iface: %d).\n", protocol, kbd_dev->iface);
+	
+	rc = usb_control_request_set(&kbd_dev->ctrl_pipe, 
+	    USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
+	    USB_HIDREQ_SET_PROTOCOL, protocol, kbd_dev->iface, NULL, 0);
+
+	sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
+
+	if (rc != EOK) {
+		usb_log_warning("Error sending output report to the keyboard: "
+		    "%s.\n", str_error(rc));
+		return;
+	}
+
+	if (sess_rc != EOK) {
+		usb_log_warning("Error closing session: %s.\n",
+		    str_error(sess_rc));
+		return;
+	}
+}
+
+static void usbkbd_set_led(usb_hid_dev_kbd_t *kbd_dev) 
+{
+	uint8_t buffer[BUFFER_OUT_SIZE];
+	int rc= 0, i;
+	
+	memset(buffer, 0, BUFFER_OUT_SIZE);
+	uint8_t leds = 0;
+
+	if (kbd_dev->mods & KM_NUM_LOCK) {
+		leds |= USB_HID_LED_NUM_LOCK;
+	}
+	
+	if (kbd_dev->mods & KM_CAPS_LOCK) {
+		leds |= USB_HID_LED_CAPS_LOCK;
+	}
+	
+	if (kbd_dev->mods & KM_SCROLL_LOCK) {
+		leds |= USB_HID_LED_SCROLL_LOCK;
+	}
+
+	// TODO: COMPOSE and KANA
+	
+	usb_log_debug("Creating output report.\n");
+	usb_log_debug("Leds: 0x%x\n", leds);
+	if ((rc = usb_hid_boot_keyboard_output_report(
+	    leds, buffer, BUFFER_OUT_SIZE)) != EOK) {
+		usb_log_warning("Error composing output report to the keyboard:"
+		    "%s.\n", str_error(rc));
+		return;
+	}
+	
+	usb_log_debug("Output report buffer: ");
+	for (i = 0; i < BUFFER_OUT_SIZE; ++i) {
+		usb_log_debug("0x%x ", buffer[i]);
+	}
+	usb_log_debug("\n");
+	
+	uint16_t value = 0;
+	value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);
+
+	usbkbd_req_set_report(kbd_dev, kbd_dev->iface, value, buffer, 
+	    BUFFER_OUT_SIZE);
+}
+
+static void kbd_push_ev(int type, unsigned int key, usb_hid_dev_kbd_t *kbd_dev)
 {
 	console_event_t ev;
@@ -177,18 +292,23 @@
 	if (mod_mask != 0) {
 		if (type == KEY_PRESS)
-			mods = mods | mod_mask;
+			kbd_dev->mods = kbd_dev->mods | mod_mask;
 		else
-			mods = mods & ~mod_mask;
+			kbd_dev->mods = kbd_dev->mods & ~mod_mask;
 	}
 
 	switch (key) {
-	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
-	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
-	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
+	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; usb_log_debug2("\n\nPushing CAPS LOCK! (mask: %u)\n\n", mod_mask); break;
+	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; usb_log_debug2("\n\nPushing NUM LOCK! (mask: %u)\n\n", mod_mask); break;
+	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; usb_log_debug2("\n\nPushing SCROLL LOCK! (mask: %u)\n\n", mod_mask); break;
 	default: mod_mask = 0; break;
 	}
 
 	if (mod_mask != 0) {
+		usb_log_debug2("\n\nChanging mods and lock keys\n");
+		usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);
+		usb_log_debug2("\nLock keys before:0x%x\n\n", kbd_dev->lock_keys);
+		
 		if (type == KEY_PRESS) {
+			usb_log_debug2("\nKey pressed.\n");
 			/*
 			 * Only change lock state on transition from released
@@ -196,22 +316,20 @@
 			 * up the lock state.
 			 */
-			mods = mods ^ (mod_mask & ~lock_keys);
-			lock_keys = lock_keys | mod_mask;
+			kbd_dev->mods = 
+			    kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
+			kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask;
 
 			/* Update keyboard lock indicator lights. */
-			// TODO
-			//kbd_ctl_set_ind(mods);
+ 			usbkbd_set_led(kbd_dev);
 		} else {
-			lock_keys = lock_keys & ~mod_mask;
-		}
-	}
-/*
-	printf("type: %d\n", type);
-	printf("mods: 0x%x\n", mods);
-	printf("keycode: %u\n", key);
-*/
-	
-	if (type == KEY_PRESS && (mods & KM_LCTRL) &&
-		key == KC_F1) {
+			usb_log_debug2("\nKey released.\n");
+			kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
+		}
+	}
+
+	usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);
+	usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);
+	
+	if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) {
 		active_layout = 0;
 		layout[active_layout]->reset();
@@ -219,6 +337,5 @@
 	}
 
-	if (type == KEY_PRESS && (mods & KM_LCTRL) &&
-		key == KC_F2) {
+	if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) {
 		active_layout = 1;
 		layout[active_layout]->reset();
@@ -226,6 +343,5 @@
 	}
 
-	if (type == KEY_PRESS && (mods & KM_LCTRL) &&
-		key == KC_F3) {
+	if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) {
 		active_layout = 2;
 		layout[active_layout]->reset();
@@ -235,11 +351,16 @@
 	ev.type = type;
 	ev.key = key;
-	ev.mods = mods;
+	ev.mods = kbd_dev->mods;
+	
+	if (ev.mods & KM_NUM_LOCK) {
+		usb_log_debug("\n\nNum Lock turned on.\n\n");
+	}
 
 	ev.c = layout[active_layout]->parse_ev(&ev);
 
-	printf("Sending key %d to the console\n", ev.key);
+	usb_log_debug2("Sending key %d to the console\n", ev.key);
 	assert(console_callback_phone != -1);
-	async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
+	async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, 
+	    ev.mods, ev.c);
 }
 /*
@@ -249,9 +370,112 @@
 	/*
 	 * TODO:
-	 * 1) key press / key release - how does the keyboard notify about release?
+	 * 1) key press / key release - how does the keyboard notify about 
+	 *    release?
 	 * 2) layouts (use the already defined), not important now
 	 * 3) 
 	 */
 
+static const keycode_t usb_hid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
+	KC_LCTRL,         /* USB_HID_MOD_LCTRL */
+	KC_LSHIFT,        /* USB_HID_MOD_LSHIFT */
+	KC_LALT,          /* USB_HID_MOD_LALT */
+	0,                /* USB_HID_MOD_LGUI */
+	KC_RCTRL,         /* USB_HID_MOD_RCTRL */
+	KC_RSHIFT,        /* USB_HID_MOD_RSHIFT */
+	KC_RALT,          /* USB_HID_MOD_RALT */
+	0,                /* USB_HID_MOD_RGUI */
+};
+
+static void usbkbd_check_modifier_changes(usb_hid_dev_kbd_t *kbd_dev,
+    uint8_t modifiers)
+{
+	/*
+	 * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
+	 *       both as modifiers and as keys with their own scancodes???
+	 *
+	 * modifiers should be sent as normal keys to usbkbd_parse_scancode()!!
+	 * so maybe it would be better if I received it from report parser in 
+	 * that way
+	 */
+	
+	int i;
+	for (i = 0; i < USB_HID_MOD_COUNT; ++i) {
+		if ((modifiers & usb_hid_modifiers_consts[i]) &&
+		    !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
+			// modifier pressed
+			if (usb_hid_modifiers_keycodes[i] != 0) {
+				kbd_push_ev(KEY_PRESS, 
+				    usb_hid_modifiers_keycodes[i], kbd_dev);
+			}
+		} else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
+		    (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
+			// modifier released
+			if (usb_hid_modifiers_keycodes[i] != 0) {
+				kbd_push_ev(KEY_RELEASE, 
+				    usb_hid_modifiers_keycodes[i], kbd_dev);
+			}
+		}	// no change
+	}
+	
+	kbd_dev->modifiers = modifiers;
+}
+
+static void usbkbd_check_key_changes(usb_hid_dev_kbd_t *kbd_dev, 
+    const uint8_t *key_codes)
+{
+	// TODO: phantom state!!
+	
+	unsigned int key;
+	unsigned int i, j;
+	
+	// TODO: quite dummy right now, think of better implementation
+	
+	// key releases
+	for (j = 0; j < kbd_dev->keycode_count; ++j) {
+		// try to find the old key in the new key list
+		i = 0;
+		while (i < kbd_dev->keycode_count
+		    && key_codes[i] != kbd_dev->keycodes[j]) {
+			++i;
+		}
+		
+		if (i == kbd_dev->keycode_count) {
+			// not found, i.e. the key was released
+			key = usbkbd_parse_scancode(kbd_dev->keycodes[j]);
+			kbd_push_ev(KEY_RELEASE, key, kbd_dev);
+			usb_log_debug2("\nKey released: %d\n", key);
+		} else {
+			// found, nothing happens
+		}
+	}
+	
+	// key presses
+	for (i = 0; i < kbd_dev->keycode_count; ++i) {
+		// try to find the new key in the old key list
+		j = 0;
+		while (j < kbd_dev->keycode_count 
+		    && kbd_dev->keycodes[j] != key_codes[i]) { 
+			++j;
+		}
+		
+		if (j == kbd_dev->keycode_count) {
+			// not found, i.e. new key pressed
+			key = usbkbd_parse_scancode(key_codes[i]);
+			usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,
+			    key_codes[i]);
+			kbd_push_ev(KEY_PRESS, key, kbd_dev);
+		} else {
+			// found, nothing happens
+		}
+	}
+	
+	memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
+	
+	usb_log_debug2("\nNew stored keycodes: ");
+	for (i = 0; i < kbd_dev->keycode_count; ++i) {
+		usb_log_debug2("%d ", kbd_dev->keycodes[i]);
+	}
+}
+
 /*
  * Callbacks for parser
@@ -260,23 +484,27 @@
     uint8_t modifiers, void *arg)
 {
-	printf("Got keys: ");
+	if (arg == NULL) {
+		usb_log_warning("Missing argument in callback "
+		    "usbkbd_process_keycodes().\n");
+		return;
+	}
+
+	usb_log_debug2("Got keys from parser: ");
 	unsigned i;
 	for (i = 0; i < count; ++i) {
-		printf("%d ", key_codes[i]);
-	}
-	printf("\n");
-
-	for (i = 0; i < count; ++i) {
-		// TODO: Key press / release
-
-		// TODO: NOT WORKING
-		unsigned int key = usbkbd_parse_scancode(key_codes[i]);
-
-		if (key == 0) {
-			continue;
-		}
-		kbd_push_ev(KEY_PRESS, key);
-	}
-	printf("\n");
+		usb_log_debug2("%d ", key_codes[i]);
+	}
+	usb_log_debug2("\n");
+	
+	usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;
+	
+	if (count != kbd_dev->keycode_count) {
+		usb_log_warning("Number of received keycodes (%d) differs from"
+		    " expected number (%d).\n", count, kbd_dev->keycode_count);
+		return;
+	}
+	
+	usbkbd_check_modifier_changes(kbd_dev, modifiers);
+	usbkbd_check_key_changes(kbd_dev, key_codes);
 }
 
@@ -284,37 +512,125 @@
  * Kbd functions
  */
-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);
+//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_request_get_descriptor(&kbd_dev->ctrl_pipe,
-		    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
-		    i, 0,
-		    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);
-	}
-
+//		// get the descriptor from the device
+//		int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
+//		    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
+//		    i, 0,
+//		    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_report_descriptor(usb_hid_dev_kbd_t *kbd_dev, 
+    uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)
+{
+	assert(kbd_dev != NULL);
+	assert(config_desc != NULL);
+	assert(config_desc_size != 0);
+	assert(iface_desc != NULL);
+	
+	usb_dp_parser_t parser =  {
+		.nesting = usb_dp_standard_descriptor_nesting
+	};
+	
+	usb_dp_parser_data_t parser_data = {
+		.data = config_desc,
+		.size = config_desc_size,
+		.arg = NULL
+	};
+	
+	/*
+	 * First nested descriptor of interface descriptor.
+	 */
+	uint8_t *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_fatal("HID descriptor hass wrong size (%u, expected %u"
+		    ")\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.
+	 */
+	kbd_dev->report_desc = (uint8_t *)malloc(length);
+	if (kbd_dev->report_desc == NULL) {
+		usb_log_fatal("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(&kbd_dev->ctrl_pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DESCTYPE_HID_REPORT, 0,
+	    kbd_dev->iface, kbd_dev->report_desc, length, &actual_size);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (actual_size != length) {
+		free(kbd_dev->report_desc);
+		kbd_dev->report_desc = NULL;
+		usb_log_fatal("Report descriptor has wrong size (%u, expected "
+		    "%u)\n", actual_size, length);
+		return EINVAL;
+	}
+	
+	usb_log_debug("Done.\n");
+	
 	return EOK;
 }
+
 static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev)
 {
@@ -364,50 +680,47 @@
 	    descriptors, config_desc.total_length,
 	    &kbd_dev->wire);
+	
 	if (rc != EOK) {
 		usb_log_error("Failed to initialize poll pipe: %s.\n",
 		    str_error(rc));
+		free(descriptors);
 		return rc;
 	}
+	
 	if (!endpoint_mapping[0].present) {
 		usb_log_warning("Not accepting device, " \
 		    "not boot-protocol keyboard.\n");
+		free(descriptors);
 		return EREFUSED;
 	}
-
-
-
-
-	kbd_dev->conf = (usb_hid_configuration_t *)calloc(1, 
-	    sizeof(usb_hid_configuration_t));
-	if (kbd_dev->conf == NULL) {
+	
+	usb_log_debug("Accepted device. Saving interface, and getting Report"
+	    " descriptor.\n");
+	
+	/*
+	 * Save assigned interface number.
+	 */
+	if (endpoint_mapping[0].interface_no < 0) {
+		usb_log_error("Bad interface number.\n");
 		free(descriptors);
-		return ENOMEM;
-	}
-	
-	/*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
+		return EINVAL;
+	}
+	
+	kbd_dev->iface = endpoint_mapping[0].interface_no;
+	
+	assert(endpoint_mapping[0].interface != NULL);
+	
+	rc = usbkbd_get_report_descriptor(kbd_dev, descriptors, transferred,
+	    (uint8_t *)endpoint_mapping[0].interface);
+	
 	free(descriptors);
-	if (rc != EOK) {
-		printf("Problem with parsing standard descriptors.\n");
+	
+	if (rc != EOK) {
+		usb_log_warning("Problem with parsing REPORT descriptor.\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
-	 */
-
+	
+	usb_log_debug("Done parsing descriptors.\n");
+	
 	return EOK;
 }
@@ -421,5 +734,5 @@
 
 	if (kbd_dev == NULL) {
-		fprintf(stderr, NAME ": No memory!\n");
+		usb_log_fatal("No memory!\n");
 		return NULL;
 	}
@@ -449,19 +762,35 @@
 
 	/*
-	 * will need all descriptors:
-	 * 1) choose one configuration from configuration descriptors
-	 *    (set it to the device)
-	 * 2) set endpoints from endpoint descriptors
-	 */
-
-	// TODO: get descriptors, parse descriptors and save endpoints
+	 * Get descriptors, parse descriptors and save endpoints.
+	 */
 	usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
-	//usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);
+	
 	rc = usbkbd_process_descriptors(kbd_dev);
+	
 	usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
 	if (rc != EOK) {
 		goto error_leave;
 	}
-
+	
+	// save the size of the report (boot protocol report by default)
+	kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
+	kbd_dev->keycodes = (uint8_t *)calloc(
+	    kbd_dev->keycode_count, sizeof(uint8_t));
+	
+	if (kbd_dev->keycodes == NULL) {
+		usb_log_fatal("No memory!\n");
+		goto error_leave;
+	}
+	
+	kbd_dev->modifiers = 0;
+	kbd_dev->mods = DEFAULT_ACTIVE_MODS;
+	kbd_dev->lock_keys = 0;
+	
+	// set boot protocol
+	usbkbd_req_set_protocol(kbd_dev, USB_HID_PROTOCOL_BOOT);
+	
+	// set LEDs according to internal setup (NUM LOCK enabled)
+	usbkbd_set_led(kbd_dev);
+	
 	return kbd_dev;
 
@@ -476,16 +805,18 @@
 	usb_hid_report_in_callbacks_t *callbacks =
 	    (usb_hid_report_in_callbacks_t *)malloc(
-		sizeof(usb_hid_report_in_callbacks_t));
+	        sizeof(usb_hid_report_in_callbacks_t));
 	callbacks->keyboard = usbkbd_process_keycodes;
 
 	//usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 
 	//    NULL);
-	printf("Calling usb_hid_boot_keyboard_input_report() with size %zu\n",
-	    actual_size);
+	/*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size"
+	    " %zu\n", actual_size);*/
 	//dump_buffer("bufffer: ", buffer, actual_size);
-	int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks, 
-	    NULL);
-	if (rc != EOK) {
-		printf("Error in usb_hid_boot_keyboard_input_report(): %d\n", rc);
+	int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
+	    callbacks, kbd_dev);
+	
+	if (rc != EOK) {
+		usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
+		    "%s\n", str_error(rc));
 	}
 }
@@ -497,5 +828,5 @@
 	size_t actual_size;
 
-	printf("Polling keyboard...\n");
+	usb_log_info("Polling keyboard...\n");
 
 	while (true) {
@@ -504,5 +835,5 @@
 		sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
 		if (sess_rc != EOK) {
-			printf("Failed to start a session: %s.\n",
+			usb_log_warning("Failed to start a session: %s.\n",
 			    str_error(sess_rc));
 			continue;
@@ -514,5 +845,5 @@
 
 		if (rc != EOK) {
-			printf("Error polling the keyboard: %s.\n",
+			usb_log_warning("Error polling the keyboard: %s.\n",
 			    str_error(rc));
 			continue;
@@ -520,5 +851,5 @@
 
 		if (sess_rc != EOK) {
-			printf("Error closing session: %s.\n",
+			usb_log_warning("Error closing session: %s.\n",
 			    str_error(sess_rc));
 			continue;
@@ -530,5 +861,5 @@
 		 */
 		if (actual_size == 0) {
-			printf("Keyboard returned NAK\n");
+			usb_log_debug("Keyboard returned NAK\n");
 			continue;
 		}
@@ -537,5 +868,5 @@
 		 * TODO: Process pressed keys.
 		 */
-		printf("Calling usbkbd_process_interrupt_in()\n");
+		usb_log_debug("Calling usbkbd_process_interrupt_in()\n");
 		usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
 	}
@@ -547,19 +878,10 @@
 static int usbkbd_fibril_device(void *arg)
 {
-	printf("!!! USB device fibril\n");
-
 	if (arg == NULL) {
-		printf("No device!\n");
+		usb_log_error("No device!\n");
 		return -1;
 	}
-
-	ddf_dev_t *dev = (ddf_dev_t *)arg;
-
-	// initialize device (get and process descriptors, get address, etc.)
-	usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
-	if (kbd_dev == NULL) {
-		printf("Error while initializing device.\n");
-		return -1;
-	}
+	
+	usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;
 
 	usbkbd_poll_keyboard(kbd_dev);
@@ -570,23 +892,4 @@
 static int usbkbd_add_device(ddf_dev_t *dev)
 {
-	/* For now, fail immediately. */
-	//return ENOTSUP;
-
-	/*
-	 * When everything is okay, connect to "our" HC.
-	 *
-	 * Not supported yet, skip..
-	 */
-//	int phone = usb_drv_hc_connect_auto(dev, 0);
-//	if (phone < 0) {
-//		/*
-//		 * Connecting to HC failed, roll-back and announce
-//		 * failure.
-//		 */
-//		return phone;
-//	}
-
-//	dev->parent_phone = phone;
-
 	/*
 	 * Create default function.
@@ -601,11 +904,22 @@
 	rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
 	assert(rc == EOK);
-
+	
+	/* 
+	 * Initialize device (get and process descriptors, get address, etc.)
+	 */
+	usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
+	if (kbd_dev == NULL) {
+		usb_log_error("Error while initializing device.\n");
+		return -1;
+	}
+
+	usb_log_info("Device initialized.\n");
+	
 	/*
 	 * Create new fibril for handling this keyboard
 	 */
-	fid_t fid = fibril_create(usbkbd_fibril_device, dev);
+	fid_t fid = fibril_create(usbkbd_fibril_device, kbd_dev);
 	if (fid == 0) {
-		printf("%s: failed to start fibril for HID device\n", NAME);
+		usb_log_error("Failed to start fibril for HID device\n");
 		return ENOMEM;
 	}
@@ -634,5 +948,5 @@
 int main(int argc, char *argv[])
 {
-	usb_log_enable(USB_LOG_LEVEL_INFO, "usbhid");
+	usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
 	return ddf_driver_main(&kbd_driver);
 }
Index: uspace/drv/usbhub/main.c
===================================================================
--- uspace/drv/usbhub/main.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhub/main.c	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -34,4 +34,5 @@
 #include <errno.h>
 #include <async.h>
+#include <stdio.h>
 
 #include "usbhub.h"
@@ -51,30 +52,15 @@
 };
 
-int usb_hub_control_loop(void * noparam){
-	while(true){
-		usb_hub_check_hub_changes();
-		async_usleep(1000 * 1000 );/// \TODO proper number once
-	}
-	return 0;
-}
-
-
 int main(int argc, char *argv[])
 {
 	usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
-	
+	dprintf(USB_LOG_LEVEL_INFO, "starting hub driver");
+
+	//this is probably not needed anymore
 	fibril_mutex_initialize(&usb_hub_list_lock);
 	fibril_mutex_lock(&usb_hub_list_lock);
 	usb_lst_init(&usb_hub_list);
 	fibril_mutex_unlock(&usb_hub_list_lock);
-
-	fid_t fid = fibril_create(usb_hub_control_loop, NULL);
-	if (fid == 0) {
-		fprintf(stderr, NAME ": failed to start monitoring fibril," \
-		    " driver aborting.\n");
-		return ENOMEM;
-	}
-	fibril_add_ready(fid);
-
+	
 	return ddf_driver_main(&hub_driver);
 }
Index: uspace/drv/usbhub/port_status.h
===================================================================
--- uspace/drv/usbhub/port_status.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhub/port_status.h	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -177,4 +177,19 @@
 }
 
+/**
+ * set the device request to be a port disable request
+ * @param request
+ * @param port
+ */
+static inline void usb_hub_unset_power_port_request(
+usb_device_request_setup_packet_t * request, uint16_t port
+){
+	request->index = port;
+	request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
+	request->request = USB_HUB_REQUEST_CLEAR_FEATURE;
+	request->value = USB_HUB_FEATURE_PORT_POWER;
+	request->length = 0;
+}
+
 /** get i`th bit of port status */
 static inline bool usb_port_get_bit(usb_port_status_t * status, int idx)
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhub/usbhub.c	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -44,4 +44,5 @@
 #include <usb/request.h>
 #include <usb/classes/hub.h>
+#include <stdio.h>
 
 #include "usbhub.h"
@@ -56,11 +57,25 @@
 };
 
-/** Hub status-change endpoint description */
+/** Hub status-change endpoint description
+ *
+ * For more see usb hub specification in 11.15.1 of
+ */
 static usb_endpoint_description_t status_change_endpoint_description = {
 	.transfer_type = USB_TRANSFER_INTERRUPT,
 	.direction = USB_DIRECTION_IN,
 	.interface_class = USB_CLASS_HUB,
+	.interface_subclass = 0,
+	.interface_protocol = 0,
 	.flags = 0
 };
+
+int usb_hub_control_loop(void * hub_info_param){
+	usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
+	while(true){
+		usb_hub_check_hub_changes(hub_info);
+		async_usleep(1000 * 1000 );/// \TODO proper number once
+	}
+	return 0;
+}
 
 
@@ -135,5 +150,5 @@
 
 	//configuration descriptor
-	/// \TODO check other configurations
+	/// \TODO check other configurations?
 	usb_standard_configuration_descriptor_t config_descriptor;
 	opResult = usb_request_get_bare_configuration_descriptor(
@@ -179,8 +194,4 @@
 	}
 
-	/**
-	 * Initialize the interrupt in endpoint.
-	 * \TODO this code should be checked...
-	 */
 	usb_endpoint_mapping_t endpoint_mapping[1] = {
 		{
@@ -210,11 +221,4 @@
 	return EOK;
 	
-
-	// Initialize the interrupt(=status change) endpoint.
-	/*usb_endpoint_pipe_initialize(
-		&result->endpoints->status_change,
-		&result->device_connection, );USB_TRANSFER_INTERRUPT
-	USB_DIRECTION_IN*/
-
 }
 
@@ -249,6 +253,7 @@
 	usb_endpoint_pipe_start_session(&result->endpoints.control);
 	opResult = usb_request_get_descriptor(&result->endpoints.control,
-			USB_REQUEST_TYPE_CLASS,
-			USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
+			USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
+			USB_DESCTYPE_HUB,
+			0, 0, serialized_descriptor,
 			USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
 	usb_endpoint_pipe_end_session(&result->endpoints.control);
@@ -267,5 +272,4 @@
 	}
 
-	
 	dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
 	result->port_count = descriptor->ports_count;
@@ -329,11 +333,31 @@
 
 	//add the hub to list
+	//is this needed now?
 	fibril_mutex_lock(&usb_hub_list_lock);
 	usb_lst_append(&usb_hub_list, hub_info);
 	fibril_mutex_unlock(&usb_hub_list_lock);
-
 	dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list");
+
+	dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf");
+	ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub");
+	assert(hub_fun != NULL);
+	hub_fun->ops = NULL;
+
+	int rc = ddf_fun_bind(hub_fun);
+	assert(rc == EOK);
+	rc = ddf_fun_add_to_class(hub_fun, "hub");
+	assert(rc == EOK);
+
+	fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
+	if (fid == 0) {
+		dprintf(USB_LOG_LEVEL_ERROR, 
+				": failed to start monitoring fibril for new hub");
+		return ENOMEM;
+	}
+	fibril_add_ready(fid);
+
+	dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created");
 	//(void)hub_info;
-	usb_hub_check_hub_changes();
+	//usb_hub_check_hub_changes();
 	
 	dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
@@ -368,7 +392,8 @@
 	//opResult = usb_drv_reserve_default_address(hc);
 	opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
-
-	if (opResult != EOK) {
-		dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
+	
+	if (opResult != EOK) {
+		dprintf(USB_LOG_LEVEL_WARNING, 
+				"cannot assign default address, it is probably used %d",opResult);
 		return;
 	}
@@ -381,5 +406,6 @@
 			);
 	if (opResult != EOK) {
-		dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port");
+		dprintf(USB_LOG_LEVEL_ERROR, 
+				"something went wrong when reseting a port %d",opResult);
 		//usb_hub_release_default_address(hc);
 		usb_hc_release_default_address(&hub->connection);
@@ -394,5 +420,5 @@
  */
 static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
-		uint16_t port) {
+		uint16_t port, bool isLowSpeed) {
 
 	int opResult;
@@ -417,7 +443,5 @@
 			&new_device_connection);
 	/// \TODO get highspeed info
-
-
-
+	usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
 
 
@@ -425,5 +449,5 @@
 	usb_address_t new_device_address = usb_hc_request_address(
 			&hub->connection,
-			USB_SPEED_LOW/// \TODO fullspeed??
+			speed/// \TODO fullspeed??
 			);
 	if (new_device_address < 0) {
@@ -436,8 +460,10 @@
 	//opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
 	//    new_device_address);
+	usb_endpoint_pipe_start_session(&new_device_pipe);
 	opResult = usb_request_set_address(&new_device_pipe,new_device_address);
-
-	if (opResult != EOK) {
-		dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device");
+	usb_endpoint_pipe_end_session(&new_device_pipe);
+	if (opResult != EOK) {
+		dprintf(USB_LOG_LEVEL_ERROR, 
+				"could not set address for new device %d",opResult);
 		usb_hc_release_default_address(&hub->connection);
 		return;
@@ -458,5 +484,6 @@
 
 	if (opResult != EOK) {
-		dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device");
+		dprintf(USB_LOG_LEVEL_ERROR, 
+				"could not start driver for new device %d",opResult);
 		return;
 	}
@@ -469,5 +496,6 @@
 			&hub->attached_devs[port]);
 	if (opResult != EOK) {
-		dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd");
+		dprintf(USB_LOG_LEVEL_ERROR, 
+				"could not assign address of device in hcd %d",opResult);
 		return;
 	}
@@ -511,4 +539,24 @@
 }
 
+
+/**
+ *Process over current condition on port.
+ * 
+ * Turn off the power on the port.
+ *
+ * @param hub
+ * @param port
+ */
+static void usb_hub_over_current( usb_hub_info_t * hub,
+		uint16_t port){
+	int opResult;
+	opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
+	    port, USB_HUB_FEATURE_PORT_POWER);
+	if(opResult!=EOK){
+		dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d;  %d",
+				port, opResult);
+	}
+}
+
 /**
  * Process interrupts on given hub port
@@ -522,15 +570,6 @@
 	//determine type of change
 	usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
-	int opResult = usb_endpoint_pipe_start_session(pipe);
 	
-	if(opResult != EOK){
-		dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult);
-	}
-
-	/*
-	usb_target_t target;
-	target.address=address;
-	target.endpoint=0;
-	*/
+	int opResult;
 
 	usb_port_status_t status;
@@ -547,9 +586,9 @@
 			);
 	if (opResult != EOK) {
-		dprintf(USB_LOG_LEVEL_ERROR, "ERROR: could not get port status");
+		dprintf(USB_LOG_LEVEL_ERROR, "could not get port status");
 		return;
 	}
 	if (rcvd_size != sizeof (usb_port_status_t)) {
-		dprintf(USB_LOG_LEVEL_ERROR, "ERROR: received status has incorrect size");
+		dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size");
 		return;
 	}
@@ -566,11 +605,21 @@
 		}
 	}
+	//over current
+	if (usb_port_overcurrent_change(&status)) {
+		//check if it was not auto-resolved
+		if(usb_port_over_current(&status)){
+			usb_hub_over_current(hub,port);
+		}else{
+			dprintf(USB_LOG_LEVEL_INFO,
+				"over current condition was auto-resolved on port %d",port);
+		}
+	}
 	//port reset
 	if (usb_port_reset_completed(&status)) {
 		dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
 		if (usb_port_enabled(&status)) {
-			usb_hub_finalize_add_device(hub, port);
+			usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));
 		} else {
-			dprintf(USB_LOG_LEVEL_WARNING, "ERROR: port reset, but port still not enabled");
+			dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled");
 		}
 	}
@@ -585,92 +634,71 @@
 	}
 	/// \TODO handle other changes
-	/// \TODO debug log for various situations
-	usb_endpoint_pipe_end_session(pipe);
-
-
-}
-
-/**
- * Check changes on all known hubs.
- */
-void usb_hub_check_hub_changes(void) {
+}
+
+/**
+ * Check changes on particular hub
+ * @param hub_info_param
+ */
+void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
+	int opResult;
+	opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
+	if(opResult != EOK){
+		dprintf(USB_LOG_LEVEL_ERROR,
+				"could not initialize communication for hub; %d", opResult);
+		return;
+	}
+
+	size_t port_count = hub_info->port_count;
+
+	/// FIXME: count properly
+	size_t byte_length = ((port_count+1) / 8) + 1;
+		void *change_bitmap = malloc(byte_length);
+	size_t actual_size;
+
 	/*
-	 * Iterate through all hubs.
+	 * Send the request.
 	 */
-	usb_general_list_t * lst_item;
-	fibril_mutex_lock(&usb_hub_list_lock);
-	for (lst_item = usb_hub_list.next;
-			lst_item != &usb_hub_list;
-			lst_item = lst_item->next) {
-		fibril_mutex_unlock(&usb_hub_list_lock);
-		usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
-		int opResult;
-
-		opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
-		if(opResult != EOK){
-			continue;
+	opResult = usb_endpoint_pipe_read(
+			&hub_info->endpoints.status_change,
+			change_bitmap, byte_length, &actual_size
+			);
+
+	if (opResult != EOK) {
+		free(change_bitmap);
+		dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
+		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+		return;
+	}
+	unsigned int port;
+	opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
+	if(opResult!=EOK){
+		dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d",
+				opResult);
+		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+		return;
+	}
+	opResult = usb_hc_connection_open(&hub_info->connection);
+	if(opResult!=EOK){
+		dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d",
+				opResult);
+		usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
+		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+		return;
+	}
+
+	///todo, opresult check, pre obe konekce
+	for (port = 1; port < port_count+1; ++port) {
+		bool interrupt =
+				(((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
+		if (interrupt) {
+			usb_hub_process_interrupt(
+			        hub_info, port);
 		}
-		/*
-		 * Check status change pipe of this hub.
-		 */
-		/*
-		usb_target_t target;
-		target.address = hub_info->address;
-		target.endpoint = 1;/// \TODO get from endpoint descriptor
-		dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d",
-		    target.address);
-		*/
-		size_t port_count = hub_info->port_count;
-
-		/*
-		 * Connect to respective HC.
-		 *
-		int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
-		if (hc < 0) {
-			continue;
-		}*/
-
-		/// FIXME: count properly
-		size_t byte_length = ((port_count+1) / 8) + 1;
-
-		void *change_bitmap = malloc(byte_length);
-		size_t actual_size;
-		//usb_handle_t handle;
-
-		/*
-		 * Send the request.
-		 */
-		opResult = usb_endpoint_pipe_read(
-				&hub_info->endpoints.status_change,
-				change_bitmap, byte_length, &actual_size
-				);
-
-		//usb_drv_async_wait_for(handle);
-
-		if (opResult != EOK) {
-			free(change_bitmap);
-			dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
-			continue;
-		}
-		unsigned int port;
-		for (port = 1; port < port_count+1; ++port) {
-			bool interrupt =
-					(((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
-			if (interrupt) {
-				usb_hub_process_interrupt(
-				        hub_info, port);
-			}
-		}
-		usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
-		free(change_bitmap);
-		
-
-		//async_hangup(hc);
-		fibril_mutex_lock(&usb_hub_list_lock);
-	}
-	fibril_mutex_unlock(&usb_hub_list_lock);
-}
-
-
+	}
+	usb_hc_connection_close(&hub_info->connection);
+	usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
+	usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
+	free(change_bitmap);
+}
 
 
Index: uspace/drv/usbhub/usbhub.h
===================================================================
--- uspace/drv/usbhub/usbhub.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/drv/usbhub/usbhub.h	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -75,7 +75,7 @@
 /**
  * function running the hub-controlling loop.
- * @param noparam fundtion does not need any parameters
+ * @param hub_info_param hub info pointer
  */
-int usb_hub_control_loop(void * noparam);
+int usb_hub_control_loop(void * hub_info_param);
 
 /** Callback when new hub device is detected.
@@ -87,10 +87,10 @@
 
 /**
- * check changes on all registered hubs
+ * check changes on specified hub
+ * @param hub_info_param pointer to usb_hub_info_t structure
  */
-void usb_hub_check_hub_changes(void);
+void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
 
 
-//int usb_add_hub_device(device_t *);
 
 
Index: uspace/lib/usb/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/lib/usb/include/usb/classes/hid.h	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -51,4 +51,15 @@
 } usb_hid_request_t;
 
+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 enum {
+	USB_HID_PROTOCOL_BOOT = 0,
+	USB_HID_PROTOCOL_REPORT = 1
+} usb_hid_protocol_t;
+
 /** USB/HID subclass constants. */
 typedef enum {
@@ -62,5 +73,5 @@
 	USB_HID_PROTOCOL_KEYBOARD = 1,
 	USB_HID_PROTOCOL_MOUSE = 2
-} usb_hid_protocol_t;
+} usb_hid_iface_protocol_t;
 
 /** Part of standard USB HID descriptor specifying one class descriptor.
Index: uspace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/lib/usb/include/usb/classes/hidparser.h	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -70,9 +70,51 @@
 } 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
+
+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;
+
+typedef enum {
+	USB_HID_LED_NUM_LOCK = 0x1,
+	USB_HID_LED_CAPS_LOCK = 0x2,
+	USB_HID_LED_SCROLL_LOCK = 0x4,
+	USB_HID_LED_COMPOSE = 0x8,
+	USB_HID_LED_KANA = 0x10,
+	USB_HID_LED_COUNT = 5
+} usb_hid_led_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
+};
+
+//static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = {
+//	USB_HID_LED_NUM_LOCK,
+//	USB_HID_LED_CAPS_LOCK,
+//	USB_HID_LED_SCROLL_LOCK,
+//	USB_HID_LED_COMPOSE,
+//	USB_HID_LED_KANA
+//};
+
+//#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
 
 /*
Index: uspace/lib/usb/include/usb/request.h
===================================================================
--- uspace/lib/usb/include/usb/request.h	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/lib/usb/include/usb/request.h	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -96,7 +96,8 @@
 int usb_request_set_address(usb_endpoint_pipe_t *, usb_address_t);
 int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t,
-    uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
+    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 
+    size_t *);
 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t *, usb_request_type_t,
-    uint8_t, uint8_t, uint16_t, void **, size_t *);
+    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void **, size_t *);
 int usb_request_get_device_descriptor(usb_endpoint_pipe_t *,
     usb_standard_device_descriptor_t *);
Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/lib/usb/src/hidparser.c	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -144,10 +144,9 @@
 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
 {
-	if(size != 1){
+	if (size < 1){
 		return -1;
 	}
 
-	/* used only first five bits, others are only padding*/
-	*data = leds;
+	data[0] = leds;
 	return EOK;
 }
Index: uspace/lib/usb/src/request.c
===================================================================
--- uspace/lib/usb/src/request.c	(revision 8e1eb4d0c8504ccef0c4207445bf63538c9c480e)
+++ uspace/lib/usb/src/request.c	(revision 299d53e4923f6405cc6c5fc25153881fc851a9fa)
@@ -36,4 +36,5 @@
 #include <errno.h>
 #include <assert.h>
+#include <usb/debug.h>
 
 #define MAX_DATA_LENGTH ((size_t)(0xFFFF))
@@ -209,5 +210,5 @@
  */
 int usb_request_get_descriptor(usb_endpoint_pipe_t *pipe,
-    usb_request_type_t request_type,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
     uint8_t descriptor_type, uint8_t descriptor_index,
     uint16_t language,
@@ -224,5 +225,5 @@
 
 	return usb_control_request_get(pipe,
-	    request_type, USB_REQUEST_RECIPIENT_DEVICE,
+	    request_type, recipient,
 	    USB_DEVREQ_GET_DESCRIPTOR,
 	    wValue, language,
@@ -242,5 +243,5 @@
  */
 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe,
-    usb_request_type_t request_type,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
     uint8_t descriptor_type, uint8_t descriptor_index,
     uint16_t language,
@@ -258,5 +259,5 @@
 	uint8_t tmp_buffer[1];
 	size_t bytes_transfered;
-	rc = usb_request_get_descriptor(pipe, request_type,
+	rc = usb_request_get_descriptor(pipe, request_type, recipient,
 	    descriptor_type, descriptor_index, language,
 	    &tmp_buffer, 1, &bytes_transfered);
@@ -283,5 +284,5 @@
 	}
 
-	rc = usb_request_get_descriptor(pipe, request_type,
+	rc = usb_request_get_descriptor(pipe, request_type, recipient,
 	    descriptor_type, descriptor_index, language,
 	    buffer, size, &bytes_transfered);
@@ -320,6 +321,6 @@
 	usb_standard_device_descriptor_t descriptor_tmp;
 	int rc = usb_request_get_descriptor(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_DEVICE,
-	    0, 0,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 
+	    USB_DESCTYPE_DEVICE, 0, 0,
 	    &descriptor_tmp, sizeof(descriptor_tmp),
 	    &actually_transferred);
@@ -366,6 +367,6 @@
 	usb_standard_configuration_descriptor_t descriptor_tmp;
 	int rc = usb_request_get_descriptor(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION,
-	    index, 0,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_CONFIGURATION, index, 0,
 	    &descriptor_tmp, sizeof(descriptor_tmp),
 	    &actually_transferred);
@@ -406,6 +407,6 @@
 
 	return usb_request_get_descriptor(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION,
-	    index, 0,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_CONFIGURATION, index, 0,
 	    descriptor, descriptor_size, actual_size);
 }
@@ -452,5 +453,6 @@
 	size_t string_descriptor_size = 0;
 	rc = usb_request_get_descriptor_alloc(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_STRING, 0, 0,
 	    (void **) &string_descriptor, &string_descriptor_size);
 	if (rc != EOK) {
@@ -531,6 +533,6 @@
 	size_t string_size;
 	rc = usb_request_get_descriptor_alloc(pipe,
-	    USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING,
-	    index, uint16_host2usb(lang),
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DESCTYPE_STRING, index, uint16_host2usb(lang),
 	    (void **) &string, &string_size);
 	if (rc != EOK) {
