Index: uspace/drv/ohci/root_hub.c
===================================================================
--- uspace/drv/ohci/root_hub.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/ohci/root_hub.c	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -251,9 +251,9 @@
 	int opResult;
 	if (request->ep->transfer_type == USB_TRANSFER_CONTROL) {
-		usb_log_info("Root hub got CONTROL packet\n");
+		usb_log_debug("Root hub got CONTROL packet\n");
 		opResult = process_ctrl_request(instance, request);
 		usb_transfer_batch_finish_error(request, opResult);
 	} else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) {
-		usb_log_info("Root hub got INTERRUPT packet\n");
+		usb_log_debug("Root hub got INTERRUPT packet\n");
 		create_interrupt_mask_in_instance(instance);
 		if (is_zeros(instance->interrupt_buffer,
Index: uspace/drv/usbhid/Makefile
===================================================================
--- uspace/drv/usbhid/Makefile	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/Makefile	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -43,16 +43,18 @@
 BINARY = usbhid
 
+SUBDRIVER_SOURCES = \
+	kbd/conv.c \
+	kbd/kbddev.c \
+	kbd/kbdrepeat.c \
+	mouse/mousedev.c \
+	multimedia/multimedia.c \
+	multimedia/keymap.c
+
 SOURCES = \
 	main.c \
 	usbhid.c \
 	subdrivers.c \
-	kbd/conv.c \
-	kbd/kbddev.c \
-	kbd/kbdrepeat.c \
 	generic/hiddev.c \
-	mouse/mousedev.c \
-	multimedia/multimedia.c \
-	multimedia/keymap.c \
-	$(STOLEN_LAYOUT_SOURCES)
+	$(SUBDRIVER_SOURCES)
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/usbhid/generic/hiddev.c
===================================================================
--- uspace/drv/usbhid/generic/hiddev.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/generic/hiddev.c	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -231,10 +231,6 @@
 /*----------------------------------------------------------------------------*/
 
-bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data, 
-    uint8_t *buffer, size_t buffer_size)
-{
-	usb_log_debug2("usb_hid_polling_callback(%p, %p, %zu)\n",
-	    hid_dev, buffer, buffer_size);
-	usb_debug_str_buffer(buffer, buffer_size, 0);
+bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data)
+{
 	return true;
 }
Index: uspace/drv/usbhid/generic/hiddev.h
===================================================================
--- uspace/drv/usbhid/generic/hiddev.h	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/generic/hiddev.h	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -50,6 +50,5 @@
 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data);
 
-bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data,
-    uint8_t *buffer, size_t buffer_size);
+bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data);
 
 #endif // USB_HID_HIDDDEV_H_
Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -434,27 +434,14 @@
  *     usb_hid_parse_report().
  */
-static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev,
-                                 uint8_t *buffer, size_t actual_size)
+static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
 {
 	assert(hid_dev->report != NULL);
 	assert(hid_dev != NULL);
 	assert(kbd_dev != NULL);
-
-	usb_log_debug("Calling usb_hid_parse_report() with "
-	    "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
 	
 	usb_hid_report_path_t *path = usb_hid_report_path();
 	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
 
-	uint8_t report_id;
-	int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size, 
-	    &report_id);
-	
-	if (rc != EOK) {
-		usb_log_warning("Error in usb_hid_parse_report():"
-		    "%s\n", str_error(rc));
-	}
-	
-	usb_hid_report_path_set_report_id (path, report_id);
+	usb_hid_report_path_set_report_id (path, hid_dev->report_id);
 	
 	// fill in the currently pressed keys
@@ -756,8 +743,7 @@
 /*----------------------------------------------------------------------------*/
 
-bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data, 
-     uint8_t *buffer, size_t buffer_size)
-{
-	if (hid_dev == NULL || buffer == NULL || data == NULL) {
+bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data)
+{
+	if (hid_dev == NULL/* || buffer == NULL*/ || data == NULL) {
 		// do not continue polling (???)
 		return false;
@@ -768,5 +754,5 @@
 	
 	// TODO: add return value from this function
-	usb_kbd_process_data(hid_dev, kbd_dev, buffer, buffer_size);
+	usb_kbd_process_data(hid_dev, kbd_dev);
 	
 	return true;
@@ -804,4 +790,6 @@
 	if ((*kbd_dev)->repeat_mtx != NULL) {
 		//assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
+		// FIXME - the fibril_mutex_is_locked may not cause
+		// fibril scheduling
 		while (fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)) {}
 		free((*kbd_dev)->repeat_mtx);
Index: uspace/drv/usbhid/kbd/kbddev.h
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.h	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/kbd/kbddev.h	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -125,6 +125,5 @@
 int usb_kbd_init(struct usb_hid_dev *hid_dev, void **data);
 
-bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data, 
-                              uint8_t *buffer, size_t buffer_size);
+bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, void *data);
 
 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
Index: uspace/drv/usbhid/kbd/main.c
===================================================================
--- uspace/drv/usbhid/kbd/main.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ 	(revision )
@@ -1,244 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * Copyright (c) 2011 Lubos Slovak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup drvusbhid
- * @{
- */
-/**
- * @file
- * Main routines of USB KBD driver.
- */
-
-#include <ddf/driver.h>
-#include <usb/debug.h>
-#include <errno.h>
-#include <str_error.h>
-
-#include <usb/dev/driver.h>
-
-#include "kbddev.h"
-#include "kbdrepeat.h"
-
-/*----------------------------------------------------------------------------*/
-
-#define NAME "usbkbd"
-
-/**
- * Function for adding a new device of type USB/HID/keyboard.
- *
- * This functions initializes required structures from the device's descriptors
- * and starts new fibril for polling the keyboard for events and another one for
- * handling auto-repeat of keys.
- *
- * During initialization, the keyboard is switched into boot protocol, the idle
- * rate is set to 0 (infinity), resulting in the keyboard only reporting event
- * when a key is pressed or released. Finally, the LED lights are turned on 
- * according to the default setup of lock keys.
- *
- * @note By default, the keyboards is initialized with Num Lock turned on and 
- *       other locks turned off.
- * @note Currently supports only boot-protocol keyboards.
- *
- * @param dev Device to add.
- *
- * @retval EOK if successful.
- * @retval ENOMEM if there
- * @return Other error code inherited from one of functions usb_kbd_init(),
- *         ddf_fun_bind() and ddf_fun_add_to_class().
- *
- * @sa usb_kbd_fibril(), usb_kbd_repeat_fibril()
- */
-static int usb_kbd_try_add_device(usb_device_t *dev)
-{
-	/* Create the function exposed under /dev/devices. */
-	ddf_fun_t *kbd_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 
-	    "keyboard");
-	if (kbd_fun == NULL) {
-		usb_log_error("Could not create DDF function node.\n");
-		return ENOMEM;
-	}
-	
-	/* 
-	 * Initialize device (get and process descriptors, get address, etc.)
-	 */
-	usb_log_debug("Initializing USB/HID KBD device...\n");
-	
-	usb_kbd_t *kbd_dev = usb_kbd_new();
-	if (kbd_dev == NULL) {
-		usb_log_error("Error while creating USB/HID KBD device "
-		    "structure.\n");
-		ddf_fun_destroy(kbd_fun);
-		return ENOMEM;  // TODO: some other code??
-	}
-	
-	int rc = usb_kbd_init(kbd_dev, dev);
-	
-	if (rc != EOK) {
-		usb_log_error("Failed to initialize USB/HID KBD device.\n");
-		ddf_fun_destroy(kbd_fun);
-		usb_kbd_free(&kbd_dev);
-		return rc;
-	}	
-	
-	usb_log_debug("USB/HID KBD device structure initialized.\n");
-	
-	/*
-	 * Store the initialized keyboard device and keyboard ops
-	 * to the DDF function.
-	 */
-	kbd_fun->driver_data = kbd_dev;
-	kbd_fun->ops = &keyboard_ops;
-
-	rc = ddf_fun_bind(kbd_fun);
-	if (rc != EOK) {
-		usb_log_error("Could not bind DDF function: %s.\n",
-		    str_error(rc));
-		// TODO: Can / should I destroy the DDF function?
-		ddf_fun_destroy(kbd_fun);
-		usb_kbd_free(&kbd_dev);
-		return rc;
-	}
-	
-	rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
-	if (rc != EOK) {
-		usb_log_error(
-		    "Could not add DDF function to class 'keyboard': %s.\n",
-		    str_error(rc));
-		ddf_fun_destroy(kbd_fun);
-		usb_kbd_free(&kbd_dev);
-		return rc;
-	}
-	
-	/* Start automated polling function.
-	 * This will create a separate fibril that will query the device
-	 * for the data continuously 
-	 */
-       rc = usb_device_auto_poll(dev,
-	   /* Index of the polling pipe. */
-	   USB_KBD_POLL_EP_NO,
-	   /* Callback when data arrives. */
-	   usb_kbd_polling_callback,
-	   /* How much data to request. */
-	   dev->pipes[USB_KBD_POLL_EP_NO].pipe->max_packet_size,
-	   /* Callback when the polling ends. */
-	   usb_kbd_polling_ended_callback,
-	   /* Custom argument. */
-	   kbd_dev);
-	
-	
-	if (rc != EOK) {
-		usb_log_error("Failed to start polling fibril for `%s'.\n",
-		    dev->ddf_dev->name);
-		return rc;
-	}
-	
-	/*
-	 * Create new fibril for auto-repeat
-	 */
-	fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
-	if (fid == 0) {
-		usb_log_error("Failed to start fibril for KBD auto-repeat");
-		return ENOMEM;
-	}
-	fibril_add_ready(fid);
-
-	(void)keyboard_ops;
-
-	/*
-	 * Hurrah, device is initialized.
-	 */
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-/**
- * Callback for passing a new device to the driver.
- *
- * @note Currently, only boot-protocol keyboards are supported by this driver.
- *
- * @param dev Structure representing the new device.
- *
- * @retval EOK if successful. 
- * @retval EREFUSED if the device is not supported.
- */
-static int usb_kbd_add_device(usb_device_t *dev)
-{
-	usb_log_debug("usb_kbd_add_device()\n");
-	
-	if (dev->interface_no < 0) {
-		usb_log_warning("Device is not a supported keyboard.\n");
-		usb_log_error("Failed to add USB KBD device: endpoint not "
-		    "found.\n");
-		return ENOTSUP;
-	}
-	
-	int rc = usb_kbd_try_add_device(dev);
-	
-	if (rc != EOK) {
-		usb_log_warning("Device is not a supported keyboard.\n");
-		usb_log_error("Failed to add KBD device: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-	
-	usb_log_info("Keyboard `%s' ready to use.\n", dev->ddf_dev->name);
-
-	return EOK;
-}
-
-/*----------------------------------------------------------------------------*/
-
-/* Currently, the framework supports only device adding. Once the framework
- * supports unplug, more callbacks will be added. */
-static usb_driver_ops_t usb_kbd_driver_ops = {
-        .add_device = usb_kbd_add_device,
-};
-
-
-/* The driver itself. */
-static usb_driver_t usb_kbd_driver = {
-        .name = NAME,
-        .ops = &usb_kbd_driver_ops,
-        .endpoints = usb_kbd_endpoints
-};
-
-/*----------------------------------------------------------------------------*/
-
-int main(int argc, char *argv[])
-{
-	printf(NAME ": HelenOS USB KBD driver.\n");
-
-	usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
-
-	return usb_driver_main(&usb_kbd_driver);
-}
-
-/**
- * @}
- */
Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -229,12 +229,8 @@
 /*----------------------------------------------------------------------------*/
 
-static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, 
-                                     usb_mouse_t *mouse_dev, uint8_t *buffer,
-                                     size_t buffer_size)
+static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev,
+    usb_mouse_t *mouse_dev)
 {
 	assert(mouse_dev != NULL);
-	
-	usb_log_debug2("got buffer: %s.\n",
-	    usb_debug_str_buffer(buffer, buffer_size, 0));
 	
 	if (mouse_dev->mouse_phone < 0) {
@@ -243,22 +239,4 @@
 	}
 
-	/*
-	 * parse the input report
-	 */
-	
-	usb_log_debug(NAME " Calling usb_hid_parse_report() with "
-	    "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0));
-	
-	uint8_t report_id;
-	
-	int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 
-	    &report_id);
-	
-	if (rc != EOK) {
-		usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 
-		    str_error(rc));
-		return true;
-	}
-	
 	/*
 	 * X
@@ -270,5 +248,5 @@
 	    USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
 
-	usb_hid_report_path_set_report_id(path, report_id);
+	usb_hid_report_path_set_report_id(path, hid_dev->report_id);
 
 	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
@@ -293,5 +271,5 @@
 	    USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
 
-	usb_hid_report_path_set_report_id(path, report_id);
+	usb_hid_report_path_set_report_id(path, hid_dev->report_id);
 
 	field = usb_hid_report_get_sibling(
@@ -321,5 +299,5 @@
 	    USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
 
-	usb_hid_report_path_set_report_id(path, report_id);
+	usb_hid_report_path_set_report_id(path, hid_dev->report_id);
 	
 	field = usb_hid_report_get_sibling(
@@ -345,5 +323,5 @@
 	path = usb_hid_report_path();
 	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
-	usb_hid_report_path_set_report_id(path, report_id);
+	usb_hid_report_path_set_report_id(path, hid_dev->report_id);
 	
 	field = usb_hid_report_get_sibling(
@@ -510,9 +488,7 @@
 /*----------------------------------------------------------------------------*/
 
-bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data, 
-     uint8_t *buffer, size_t buffer_size)
+bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data)
 {
 	usb_log_debug("usb_mouse_polling_callback()\n");
-	usb_debug_str_buffer(buffer, buffer_size, 0);
 	
 	if (hid_dev == NULL || data == NULL) {
@@ -524,6 +500,5 @@
 	usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
 		
-	return usb_mouse_process_report(hid_dev, mouse_dev, buffer, 
-	                                buffer_size);
+	return usb_mouse_process_report(hid_dev, mouse_dev);
 }
 
Index: uspace/drv/usbhid/mouse/mousedev.h
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.h	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/mouse/mousedev.h	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -65,6 +65,5 @@
 int usb_mouse_init(struct usb_hid_dev *hid_dev, void **data);
 
-bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data, 
-    uint8_t *buffer, size_t buffer_size);
+bool usb_mouse_polling_callback(struct usb_hid_dev *hid_dev, void *data);
 
 void usb_mouse_deinit(struct usb_hid_dev *hid_dev, void *data);
Index: uspace/drv/usbhid/multimedia/multimedia.c
===================================================================
--- uspace/drv/usbhid/multimedia/multimedia.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/multimedia/multimedia.c	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -94,5 +94,4 @@
 	
 	usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
-	//usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
 	
 	if (multim_dev == NULL) {
@@ -274,35 +273,17 @@
 /*----------------------------------------------------------------------------*/
 
-bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data, 
-    uint8_t *buffer, size_t buffer_size)
+bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data)
 {
 	// TODO: checks
-	if (hid_dev == NULL || data == NULL || buffer == NULL) {
+	if (hid_dev == NULL || data == NULL) {
 		return false;
 	}
-	
-	usb_log_debug(NAME " usb_lgtch_polling_callback(%p, %p, %zu)\n",
-	    hid_dev, buffer, buffer_size);
-	
+
 	usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
-
-	usb_log_debug(NAME " Calling usb_hid_parse_report() with "
-	    "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0));
 	
 	usb_hid_report_path_t *path = usb_hid_report_path();
 	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
 
-	uint8_t report_id;
-	
-	int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 
-	    &report_id);
-	
-	if (rc != EOK) {
-		usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 
-		    str_error(rc));
-		return true;
-	}
-	
-	usb_hid_report_path_set_report_id(path, report_id);
+	usb_hid_report_path_set_report_id(path, hid_dev->report_id);
 
 	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
Index: uspace/drv/usbhid/multimedia/multimedia.h
===================================================================
--- uspace/drv/usbhid/multimedia/multimedia.h	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/multimedia/multimedia.h	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -47,6 +47,5 @@
 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data);
 
-bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data,
-    uint8_t *buffer, size_t buffer_size);
+bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data);
 
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/usbhid/subdrivers.h
===================================================================
--- uspace/drv/usbhid/subdrivers.h	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/subdrivers.h	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -49,13 +49,33 @@
 /*----------------------------------------------------------------------------*/
 
-/* TODO: This mapping must contain some other information to get the proper
- *       interface.
+/** Structure representing the mapping between device requirements and the 
+ *  subdriver supposed to handle this device.
+ *
+ * By filling in this structure and adding it to the usb_hid_subdrivers array,
+ * a new subdriver mapping will be created and used by the HID driver when it
+ * searches for appropriate subdrivers for a device.
  */
 typedef struct usb_hid_subdriver_mapping {
+	/** Usage path that the device's Input reports must contain. 
+	 *
+	 * It is an array of pairs <usage_page, usage>, terminated by a <0, 0>
+	 * pair. If you do not wish to specify the device in this way, set this
+	 * to NULL.
+	 */
 	const usb_hid_subdriver_usage_t *usage_path;
+	
+	/** Report ID for which the path should apply. */
 	int report_id;
+	
+	/** Compare type for the Usage path. */
 	int compare;
+	
+	/** Vendor ID (set to -1 if not specified). */
 	int vendor_id;
+	
+	/** Product ID (set to -1 if not specified). */
 	int product_id;
+	
+	/** Subdriver for controlling this device. */
 	usb_hid_subdriver_t subdriver;
 } usb_hid_subdriver_mapping_t;
Index: uspace/drv/usbhid/usbhid.c
===================================================================
--- uspace/drv/usbhid/usbhid.c	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/usbhid.c	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -582,4 +582,14 @@
 	}
 	
+	// parse the input report
+	
+	int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 
+	    &hid_dev->report_id);
+	
+	if (rc != EOK) {
+		usb_log_warning("Error in usb_hid_parse_report():"
+		    "%s\n", str_error(rc));
+	}	
+	
 	bool cont = false;
 	
@@ -588,5 +598,5 @@
 		if (hid_dev->subdrivers[i].poll != NULL
 		    && hid_dev->subdrivers[i].poll(hid_dev, 
-		        hid_dev->subdrivers[i].data, buffer, buffer_size)) {
+		        hid_dev->subdrivers[i].data)) {
 			cont = true;
 		}
Index: uspace/drv/usbhid/usbhid.h
===================================================================
--- uspace/drv/usbhid/usbhid.h	(revision 98caf4982b79d4e33b68e85bd8d2cc56a445ada1)
+++ uspace/drv/usbhid/usbhid.h	(revision 54d4b9e8fe58277730b33d96d5352f73f9609a83)
@@ -46,14 +46,41 @@
 #include <bool.h>
 
-struct usb_hid_dev;
+typedef struct usb_hid_dev usb_hid_dev_t;
+typedef struct usb_hid_subdriver usb_hid_subdriver_t;
 
-typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *, void **data);
-typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *, void *data);
-typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, void *data, uint8_t *,
-                                    size_t);
-typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, void *data, 
-                                         bool reason);
+/** Subdriver initialization callback.
+ *
+ * @param dev Backing USB HID device.
+ * @param data Custom subdriver data (pointer where to store them).
+ * @return Error code.
+ */
+typedef int (*usb_hid_driver_init_t)(usb_hid_dev_t *dev, void **data);
 
-typedef struct usb_hid_subdriver {	
+/** Subdriver deinitialization callback.
+ *
+ * @param dev Backing USB HID device.
+ * @param data Custom subdriver data.
+ */
+typedef void (*usb_hid_driver_deinit_t)(usb_hid_dev_t *dev, void *data);
+
+/** Subdriver callback on data from device.
+ *
+ * @param dev Backing USB HID device.
+ * @param data Custom subdriver data.
+ * @return Whether to continue polling (typically true always).
+ */
+typedef bool (*usb_hid_driver_poll_t)(usb_hid_dev_t *dev, void *data);
+
+/** Subdriver callback after communication with the device ceased.
+ *
+ * @param dev Backing USB HID device.
+ * @param data Custom subdriver data.
+ * @param ended_due_to_errors Whether communication ended due to errors in
+ *	communication (true) or deliberately by driver (false).
+ */
+typedef void (*usb_hid_driver_poll_ended_t)(usb_hid_dev_t *dev, void *data,
+    bool ended_due_to_errors);
+
+struct usb_hid_subdriver {
 	/** Function to be called when initializing HID device. */
 	usb_hid_driver_init_t init;
@@ -61,10 +88,10 @@
 	usb_hid_driver_deinit_t deinit;
 	/** Function to be called when data arrives from the device. */
-	usb_hid_driver_poll poll;
+	usb_hid_driver_poll_t poll;
 	/** Function to be called when polling ends. */
-	usb_hid_driver_poll_ended poll_end;
+	usb_hid_driver_poll_ended_t poll_end;
 	/** Arbitrary data needed by the subdriver. */
 	void *data;
-} usb_hid_subdriver_t;
+};
 
 /*----------------------------------------------------------------------------*/
@@ -72,5 +99,5 @@
  * Structure for holding general HID device data.
  */
-typedef struct usb_hid_dev {
+struct usb_hid_dev {
 	/** Structure holding generic USB device information. */
 	usb_device_t *usb_dev;
@@ -94,4 +121,6 @@
 	usb_hid_report_t *report;
 	
+	uint8_t report_id;
+	
 	uint8_t *input_report;
 	
@@ -100,5 +129,5 @@
 	
 	int report_nr;
-} usb_hid_dev_t;
+};
 
 /*----------------------------------------------------------------------------*/
