Index: uspace/drv/usbhid/hiddev.c
===================================================================
--- uspace/drv/usbhid/hiddev.c	(revision e93e3195d166b575313289de729c76e84528e0d2)
+++ uspace/drv/usbhid/hiddev.c	(revision 9863722457c4c56109584892ea40fb0de04d7a04)
@@ -158,4 +158,6 @@
 	}
 	
+	hid_dev->report_desc_size = length;
+	
 	usb_log_debug("Done.\n");
 	
@@ -262,8 +264,18 @@
 	
 	if (rc != EOK) {
-		usb_log_warning("Problem with parsing Report descriptor: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
+		usb_log_warning("Problem with getting Report descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	
+	rc = usb_hid_parse_report_descriptor(hid_dev->parser, 
+	    hid_dev->report_desc, hid_dev->report_desc_size);
+	if (rc != EOK) {
+		usb_log_warning("Problem parsing Report descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	
+	usb_hid_descriptor_print(hid_dev->parser);
 	
 	return EOK;
@@ -289,4 +301,12 @@
 	
 	memset(dev, 0, sizeof(usbhid_dev_t));
+	
+	dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
+	    usb_hid_report_parser_t)));
+	if (dev->parser == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(dev);
+		return NULL;
+	}
 	
 	dev->initialized = 0;
@@ -399,4 +419,13 @@
 
 	/*
+	 * Initialize the report parser.
+	 */
+	rc = usb_hid_parser_init(hid_dev->parser);
+	if (rc != EOK) {
+		usb_log_error("Failed to initialize report parser.\n");
+		return rc;
+	}
+
+	/*
 	 * Get descriptors, parse descriptors and save endpoints.
 	 */
Index: uspace/drv/usbhid/hiddev.h
===================================================================
--- uspace/drv/usbhid/hiddev.h	(revision e93e3195d166b575313289de729c76e84528e0d2)
+++ uspace/drv/usbhid/hiddev.h	(revision 9863722457c4c56109584892ea40fb0de04d7a04)
@@ -75,4 +75,7 @@
 	/** Report descriptor. */
 	uint8_t *report_desc;
+
+	size_t report_desc_size;
+
 	/** HID Report parser. */
 	usb_hid_report_parser_t *parser;
Index: uspace/drv/usbhid/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbddev.c	(revision e93e3195d166b575313289de729c76e84528e0d2)
+++ uspace/drv/usbhid/kbddev.c	(revision 9863722457c4c56109584892ea40fb0de04d7a04)
@@ -51,4 +51,5 @@
 #include <usb/classes/hidparser.h>
 #include <usb/classes/classes.h>
+#include <usb/classes/hidut.h>
 
 #include "kbddev.h"
@@ -122,4 +123,17 @@
 	KC_RALT,          /* USB_HID_MOD_RALT */
 	0,                /* USB_HID_MOD_RGUI */
+};
+
+typedef enum usbhid_lock_code {
+	USBHID_LOCK_NUM = 0x53,
+	USBHID_LOCK_CAPS = 0x39,
+	USBHID_LOCK_SCROLL = 0x47,
+	USBHID_LOCK_COUNT = 3
+} usbhid_lock_code;
+
+static const usbhid_lock_code usbhid_lock_codes[USBHID_LOCK_COUNT] = {
+	USBHID_LOCK_NUM,
+	USBHID_LOCK_CAPS,
+	USBHID_LOCK_SCROLL
 };
 
@@ -346,36 +360,45 @@
  * @sa usbhid_kbd_push_ev()
  */
-static void usbhid_kbd_check_modifier_changes(usbhid_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 usbhid_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 (usbhid_modifiers_keycodes[i] != 0) {
-				usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, 
-				    usbhid_modifiers_keycodes[i]);
-			}
-		} else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
-		    (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
-			// modifier released
-			if (usbhid_modifiers_keycodes[i] != 0) {
-				usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, 
-				    usbhid_modifiers_keycodes[i]);
-			}
-		}	// no change
-	}
-	
-	kbd_dev->modifiers = modifiers;
+//static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev, 
+//    const uint8_t *key_codes, size_t count)
+//{
+//	/*
+//	 * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
+//	 *       both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes???
+//	 *
+//	 * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
+//	 * so maybe it would be better if I received it from report parser in 
+//	 * that way
+//	 */
+	
+//	int i;
+//	for (i = 0; i < count; ++i) {
+//		if ((modifiers & usb_hid_modifiers_consts[i]) &&
+//		    !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
+//			// modifier pressed
+//			if (usbhid_modifiers_keycodes[i] != 0) {
+//				usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, 
+//				    usbhid_modifiers_keycodes[i]);
+//			}
+//		} else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
+//		    (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
+//			// modifier released
+//			if (usbhid_modifiers_keycodes[i] != 0) {
+//				usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, 
+//				    usbhid_modifiers_keycodes[i]);
+//			}
+//		}	// no change
+//	}
+	
+//	kbd_dev->modifiers = modifiers;
+//}
+
+/*----------------------------------------------------------------------------*/
+
+static inline int usbhid_kbd_is_lock(unsigned int key_code) 
+{
+	return (key_code == KC_NUM_LOCK
+	    || key_code == KC_SCROLL_LOCK
+	    || key_code == KC_CAPS_LOCK);
 }
 
@@ -404,4 +427,7 @@
 	/*
 	 * First of all, check if the kbd have reported phantom state.
+	 *
+	 * TODO: this must be changed as we don't know which keys are modifiers
+	 *       and which are regular keys.
 	 */
 	i = 0;
@@ -434,5 +460,7 @@
 			// not found, i.e. the key was released
 			key = usbhid_parse_scancode(kbd_dev->keys[j]);
-			usbhid_kbd_repeat_stop(kbd_dev, key);
+			if (!usbhid_kbd_is_lock(key)) {
+				usbhid_kbd_repeat_stop(kbd_dev, key);
+			}
 			usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
 			usb_log_debug2("Key released: %d\n", key);
@@ -458,5 +486,7 @@
 			    key_codes[i]);
 			usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
-			usbhid_kbd_repeat_start(kbd_dev, key);
+			if (!usbhid_kbd_is_lock(key)) {
+				usbhid_kbd_repeat_start(kbd_dev, key);
+			}
 		} else {
 			// found, nothing happens
@@ -502,5 +532,5 @@
 
 	usb_log_debug("Got keys from parser: %s\n", 
-	    usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
+	    usb_debug_str_buffer(key_codes, count, 0));
 	
 	if (count != kbd_dev->key_count) {
@@ -510,5 +540,5 @@
 	}
 	
-	usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
+	///usbhid_kbd_check_modifier_changes(kbd_dev, key_codes, count);
 	usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
 }
@@ -535,4 +565,7 @@
                                     uint8_t *buffer, size_t actual_size)
 {
+	assert(kbd_dev->initialized);
+	assert(kbd_dev->hid_dev->parser != NULL);
+	
 	usb_hid_report_in_callbacks_t *callbacks =
 	    (usb_hid_report_in_callbacks_t *)malloc(
@@ -541,9 +574,11 @@
 	callbacks->keyboard = usbhid_kbd_process_keycodes;
 
-	usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
+	usb_log_debug("Calling usb_hid_parse_report() with "
 	    "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
 	
-	int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
-	    callbacks, kbd_dev);
+//	int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
+//	    callbacks, kbd_dev);
+	int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
+	    actual_size, callbacks, kbd_dev);
 	
 	if (rc != EOK) {
@@ -614,5 +649,5 @@
 		free((*kbd_dev)->repeat_mtx);
 	}
-	
+
 	free(*kbd_dev);
 	*kbd_dev = NULL;
@@ -674,5 +709,13 @@
 	
 	// save the size of the report (boot protocol report by default)
-	kbd_dev->key_count = BOOTP_REPORT_SIZE;
+//	kbd_dev->key_count = BOOTP_REPORT_SIZE;
+	
+	usb_hid_report_path_t path;
+	path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
+	kbd_dev->key_count = usb_hid_report_input_length(
+	    kbd_dev->hid_dev->parser, &path);
+	
+	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
+	
 	kbd_dev->keys = (uint8_t *)calloc(
 	    kbd_dev->key_count, sizeof(uint8_t));
@@ -709,5 +752,5 @@
 	assert(kbd_dev->hid_dev != NULL);
 	assert(kbd_dev->hid_dev->initialized);
-	usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
+	//usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
 	
 	usbhid_kbd_set_led(kbd_dev);
Index: uspace/drv/usbhid/kbddev.h
===================================================================
--- uspace/drv/usbhid/kbddev.h	(revision e93e3195d166b575313289de729c76e84528e0d2)
+++ uspace/drv/usbhid/kbddev.h	(revision 9863722457c4c56109584892ea40fb0de04d7a04)
@@ -42,4 +42,5 @@
 
 #include <usb/classes/hid.h>
+#include <usb/classes/hidparser.h>
 #include <ddf/driver.h>
 #include <usb/pipes.h>
