Index: uspace/drv/usbhid/generic/hiddev.c
===================================================================
--- uspace/drv/usbhid/generic/hiddev.c	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/generic/hiddev.c	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -62,8 +62,13 @@
 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun);
 
-static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 
+static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 
     size_t size, size_t *act_size, unsigned int flags);
 
 static int usb_generic_hid_client_connected(ddf_fun_t *fun);
+
+static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun);
+
+static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 
+    size_t size, size_t *actual_size);
 
 /*----------------------------------------------------------------------------*/
@@ -71,5 +76,7 @@
 static usbhid_iface_t usb_generic_iface = {
 	.get_event = usb_generic_hid_get_event,
-	.get_event_length = usb_generic_hid_get_event_length
+	.get_event_length = usb_generic_hid_get_event_length,
+	.get_report_descriptor_length = usb_generic_get_report_descriptor_length,
+	.get_report_descriptor = usb_generic_get_report_descriptor
 };
 
@@ -83,5 +90,8 @@
 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
 {
-	if (fun == NULL || fun->driver_data) {
+	usb_log_debug("Generic HID: Get event length (fun: %p, "
+	    "fun->driver_data: %p.\n", fun, fun->driver_data);
+	
+	if (fun == NULL || fun->driver_data == NULL) {
 		return 0;
 	}
@@ -89,13 +99,19 @@
 	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
 	
-	return hid_dev->input_report_size;
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int usb_generic_hid_get_event(ddf_fun_t *fun, int32_t *buffer, 
+	usb_log_debug("hid_dev: %p, Max input report size (%d).\n",
+	    hid_dev, hid_dev->max_input_report_size);
+	
+	return hid_dev->max_input_report_size;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 
     size_t size, size_t *act_size, unsigned int flags)
 {
-	if (fun == NULL || fun->driver_data) {
+	usb_log_debug("Generic HID: Get event.\n");
+	
+	if (fun == NULL || fun->driver_data == NULL) {
+		usb_log_debug("No function");
 		return EINVAL;
 	}
@@ -126,6 +142,49 @@
 /*----------------------------------------------------------------------------*/
 
+static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun)
+{
+	usb_log_debug("Generic HID: Get report descriptor length.\n");
+	
+	if (fun == NULL || fun->driver_data == NULL) {
+		usb_log_debug("No function");
+		return EINVAL;
+	}
+	
+	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
+	
+	printf("hid_dev->report_desc_size = %zu\n", hid_dev->report_desc_size);
+	
+	return hid_dev->report_desc_size;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 
+    size_t size, size_t *actual_size)
+{
+	usb_log_debug("Generic HID: Get report descriptor.\n");
+	
+	if (fun == NULL || fun->driver_data == NULL) {
+		usb_log_debug("No function");
+		return EINVAL;
+	}
+	
+	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
+	
+	if (hid_dev->report_desc_size > size) {
+		return EINVAL;	// TODO: other error code
+	}
+	
+	memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size);
+	*actual_size = hid_dev->report_desc_size;
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
 static int usb_generic_hid_client_connected(ddf_fun_t *fun)
 {
+	usb_log_debug("Generic HID: Client connected.\n");
 	usb_hid_report_received();
 	return EOK;
@@ -145,4 +204,7 @@
 		return ENOMEM;
 	}
+	
+	fun->ops = &usb_generic_hid_ops;
+	fun->driver_data = hid_dev;
 
 	int rc = ddf_fun_bind(fun);
@@ -154,6 +216,5 @@
 	}
 	
-	fun->ops = &usb_generic_hid_ops;
-	fun->driver_data = hid_dev;
+	usb_log_debug("HID function created. Handle: %d\n", fun->handle);
 	
 	return EOK;
Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -798,4 +798,7 @@
 	}
 	
+	usb_log_debug("%s function created. Handle: %d\n", HID_KBD_FUN_NAME,
+	    fun->handle);
+	
 	usb_log_debug("Adding DDF function to class %s...\n", 
 	    HID_KBD_CLASS_NAME);
Index: uspace/drv/usbhid/multimedia/keymap.c
===================================================================
--- uspace/drv/usbhid/multimedia/keymap.c	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/multimedia/keymap.c	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -75,675 +75,4 @@
 };
 
-static const char *usb_hid_consumer_usage_str[0x29d] = {
-	[0x01] = "Consumer Control",
-	[0x02] = "Numeric Key Pad",
-	[0x03] = "Programmable Buttons",
-	[0x04] = "Microphone",
-	[0x05] = "Headphone",
-	[0x06] = "Graphic Equalizer",
-	[0x07] = "Reserved",
-	[0x08] = "Reserved",
-	[0x09] = "Reserved",
-	[0x0a] = "Reserved",
-	[0x0b] = "Reserved",
-	[0x0c] = "Reserved",
-	[0x0d] = "Reserved",
-	[0x0e] = "Reserved",
-	[0x0f] = "Reserved",
-	[0x10] = "Reserved",
-	[0x11] = "Reserved",
-	[0x12] = "Reserved",
-	[0x13] = "Reserved",
-	[0x14] = "Reserved",
-	[0x15] = "Reserved",
-	[0x16] = "Reserved",
-	[0x17] = "Reserved",
-	[0x18] = "Reserved",
-	[0x19] = "Reserved",
-	[0x1a] = "Reserved",
-	[0x1b] = "Reserved",
-	[0x1c] = "Reserved",
-	[0x1d] = "Reserved",
-	[0x1e] = "Reserved",
-	[0x1f] = "Reserved",
-	[0x20] = "+10",
-	[0x21] = "+100",
-	[0x22] = "AM/PM",
-	[0x23] = "Reserved",
-	[0x24] = "Reserved",
-	[0x25] = "Reserved",
-	[0x26] = "Reserved",
-	[0x27] = "Reserved",
-	[0x28] = "Reserved",
-	[0x29] = "Reserved",
-	[0x2a] = "Reserved",
-	[0x2b] = "Reserved",
-	[0x2c] = "Reserved",
-	[0x2d] = "Reserved",
-	[0x2e] = "Reserved",
-	[0x2f] = "Reserved",
-	[0x30] = "Reserved",
-	[0x31] = "Reserved",
-	[0x32] = "Reserved",
-	[0x33] = "Reserved",
-	[0x34] = "Reserved",
-	[0x35] = "Reserved",
-	[0x36] = "Reserved",
-	[0x37] = "Reserved",
-	[0x38] = "Reserved",
-	[0x39] = "Reserved",
-	[0x3a] = "Reserved",
-	[0x3b] = "Reserved",
-	[0x3c] = "Reserved",
-	[0x3d] = "Reserved",
-	[0x3e] = "Reserved",
-	[0x3f] = "Reserved",
-	[0x40] = "Menu",
-	[0x41] = "Menu Pick",
-	[0x42] = "Menu Up",
-	[0x43] = "Menu Down",
-	[0x44] = "Menu Left",
-	[0x45] = "Menu Right",
-	[0x46] = "Menu Escape",
-	[0x47] = "Menu Value Increase",
-	[0x48] = "Menu Value Decrease",
-	[0x49] = "Reserved",
-	[0x4a] = "Reserved",
-	[0x4b] = "Reserved",
-	[0x4c] = "Reserved",
-	[0x4d] = "Reserved",
-	[0x4e] = "Reserved",
-	[0x4f] = "Reserved",
-	[0x50] = "Reserved",
-	[0x51] = "Reserved",
-	[0x52] = "Reserved",
-	[0x53] = "Reserved",
-	[0x54] = "Reserved",
-	[0x55] = "Reserved",
-	[0x56] = "Reserved",
-	[0x57] = "Reserved",
-	[0x58] = "Reserved",
-	[0x59] = "Reserved",
-	[0x5a] = "Reserved",
-	[0x5b] = "Reserved",
-	[0x5c] = "Reserved",
-	[0x5d] = "Reserved",
-	[0x5e] = "Reserved",
-	[0x5f] = "Reserved",
-	[0x60] = "Data On Screen",
-	[0x61] = "Closed Caption",
-	[0x62] = "Closed Caption Select",
-	[0x63] = "VCR/TV",
-	[0x64] = "Broadcast Mode",
-	[0x65] = "Snapshot",
-	[0x66] = "Still",
-	[0x67] = "Reserved",
-	[0x68] = "Reserved",
-	[0x69] = "Reserved",
-	[0x6a] = "Reserved",
-	[0x6b] = "Reserved",
-	[0x6c] = "Reserved",
-	[0x6d] = "Reserved",
-	[0x6e] = "Reserved",
-	[0x6f] = "Reserved",
-	[0x70] = "Reserved",
-	[0x71] = "Reserved",
-	[0x72] = "Reserved",
-	[0x73] = "Reserved",
-	[0x74] = "Reserved",
-	[0x75] = "Reserved",
-	[0x76] = "Reserved",
-	[0x77] = "Reserved",
-	[0x78] = "Reserved",
-	[0x79] = "Reserved",
-	[0x7a] = "Reserved",
-	[0x7b] = "Reserved",
-	[0x7c] = "Reserved",
-	[0x7d] = "Reserved",
-	[0x7e] = "Reserved",
-	[0x7f] = "Reserved",
-	[0x80] = "Selection",
-	[0x81] = "Assign Selection",
-	[0x82] = "Mode Step",
-	[0x83] = "Recall Last",
-	[0x84] = "Enter Channel",
-	[0x85] = "Order Movie",
-	[0x86] = "Channel",
-	[0x87] = "Media Selection",
-	[0x88] = "Media Select Computer",
-	[0x89] = "Media Select TV",
-	[0x8a] = "Media Select WWW",
-	[0x8b] = "Media Select DVD",
-	[0x8c] = "Media Select Telephone",
-	[0x8d] = "Media Select Program Guide",
-	[0x8e] = "Media Select Video Phone",
-	[0x8f] = "Media Select Games",
-	[0x90] = "Media Select Messages",
-	[0x91] = "Media Select CD",
-	[0x92] = "Media Select VCR",
-	[0x93] = "Media Select Tuner",
-	[0x94] = "Quit",
-	[0x95] = "Help",
-	[0x96] = "Media Select Tape",
-	[0x97] = "Media Select Cable",
-	[0x98] = "Media Select Satellite",
-	[0x99] = "Media Select Security",
-	[0x9a] = "Media Select Home",
-	[0x9b] = "Media Select Call",
-	[0x9c] = "Channel Increment",
-	[0x9d] = "Channel Decrement",
-	[0x9e] = "Media Select SAP",
-	[0x9f] = "Reserved",
-	[0xa0] = "VCR Plus",
-	[0xa1] = "Once",
-	[0xa2] = "Daily",
-	[0xa3] = "Weekly",
-	[0xa4] = "Monthly",
-	[0xa5] = "Reserved",
-	[0xa6] = "Reserved",
-	[0xa7] = "Reserved",
-	[0xa8] = "Reserved",
-	[0xa9] = "Reserved",
-	[0xaa] = "Reserved",
-	[0xab] = "Reserved",
-	[0xac] = "Reserved",
-	[0xad] = "Reserved",
-	[0xae] = "Reserved",
-	[0xaf] = "Reserved",
-	[0xb0] = "Play",
-	[0xb1] = "Pause",
-	[0xb2] = "Record",
-	[0xb3] = "Fast Forward",
-	[0xb4] = "Rewind",
-	[0xb5] = "Scan Next Track",
-	[0xb6] = "Scan Previous Trac",
-	[0xb7] = "Stop",
-	[0xb8] = "Eject",
-	[0xb9] = "Random Play",
-	[0xba] = "Select Disc",
-	[0xbb] = "Enter Disc",
-	[0xbc] = "Repeat",
-	[0xbd] = "Tracking",
-	[0xbe] = "Track Normal",
-	[0xbf] = "Slow Tracking",
-	[0xc0] = "Frame Forward",
-	[0xc1] = "Frame Back",
-	[0xc2] = "Mark",
-	[0xc3] = "Clear Mark",
-	[0xc4] = "Repeat From Mark",
-	[0xc5] = "Return to Mark",
-	[0xc6] = "Search Mark Forward",
-	[0xc7] = "Search Mark Backwards",
-	[0xc8] = "Counter Reset",
-	[0xc9] = "Show Counter",
-	[0xca] = "Tracking Increment",
-	[0xcb] = "Tracking Decrement",
-	[0xcc] = "Stop/Eject",
-	[0xcd] = "Play/Pause",
-	[0xce] = "Play/Skip",
-	[0xcf] = "Reserved",
-	[0xd0] = "Reserved",
-	[0xd1] = "Reserved",
-	[0xd2] = "Reserved",
-	[0xd3] = "Reserved",
-	[0xd4] = "Reserved",
-	[0xd5] = "Reserved",
-	[0xd6] = "Reserved",
-	[0xd7] = "Reserved",
-	[0xd8] = "Reserved",
-	[0xd9] = "Reserved",
-	[0xda] = "Reserved",
-	[0xdb] = "Reserved",
-	[0xdc] = "Reserved",
-	[0xdd] = "Reserved",
-	[0xde] = "Reserved",
-	[0xdf] = "Reserved",
-	[0xe0] = "Volume",
-	[0xe1] = "Balance",
-	[0xe2] = "Mute",
-	[0xe3] = "Bass",
-	[0xe4] = "Treble",
-	[0xe5] = "Bass Boost",
-	[0xe6] = "Surround Mode",
-	[0xe7] = "Loudness",
-	[0xe8] = "MPX",
-	[0xe9] = "Volume Increment",
-	[0xea] = "Volume Decrement",
-	[0xeb] = "Reserved",
-	[0xec] = "Reserved",
-	[0xed] = "Reserved",
-	[0xee] = "Reserved",
-	[0xef] = "Reserved",
-	[0xf0] = "Speed Select",
-	[0xf1] = "Playback Speed",
-	[0xf2] = "Standard Play",
-	[0xf3] = "Long Play",
-	[0xf4] = "Extended Play",
-	[0xf5] = "Slow",
-	[0xf6] = "Reserved",
-	[0xf7] = "Reserved",
-	[0xf8] = "Reserved",
-	[0xf9] = "Reserved",
-	[0xfa] = "Reserved",
-	[0xfb] = "Reserved",
-	[0xfc] = "Reserved",
-	[0xfd] = "Reserved",
-	[0xfe] = "Reserved",
-	[0xff] = "Reserved",
-	[0x100] = "Fan Enable",
-	[0x101] = "Fan Speed",
-	[0x102] = "Light Enable",
-	[0x103] = "Light Illumination Level",
-	[0x104] = "Climate Control Enable",
-	[0x105] = "Room Temperature",
-	[0x106] = "Security Enable",
-	[0x107] = "Fire Alarm",
-	[0x108] = "Police Alarm",
-	[0x109] = "Proximity",
-	[0x10a] = "Motion",
-	[0x10b] = "Duress Alarm",
-	[0x10c] = "Holdup Alarm",
-	[0x10d] = "Medical Alarm",
-	[0x10e] = "Reserved",
-	[0x10f] = "Reserved",
-	[0x110] = "Reserved",
-	[0x111] = "Reserved",
-	[0x112] = "Reserved",
-	[0x113] = "Reserved",
-	[0x114] = "Reserved",
-	[0x115] = "Reserved",
-	[0x116] = "Reserved",
-	[0x117] = "Reserved",
-	[0x118] = "Reserved",
-	[0x119] = "Reserved",
-	[0x11a] = "Reserved",
-	[0x11b] = "Reserved",
-	[0x11c] = "Reserved",
-	[0x11d] = "Reserved",
-	[0x11e] = "Reserved",
-	[0x11f] = "Reserved",
-	[0x120] = "Reserved", 
-	[0x121] = "Reserved",
-	[0x122] = "Reserved",
-	[0x123] = "Reserved",
-	[0x124] = "Reserved",
-	[0x125] = "Reserved",
-	[0x126] = "Reserved",
-	[0x127] = "Reserved",
-	[0x128] = "Reserved",
-	[0x129] = "Reserved",
-	[0x12a] = "Reserved",
-	[0x12b] = "Reserved",
-	[0x12c] = "Reserved",
-	[0x12d] = "Reserved",
-	[0x12e] = "Reserved",
-	[0x12f] = "Reserved",
-	[0x130] = "Reserved", 
-	[0x131] = "Reserved",
-	[0x132] = "Reserved",
-	[0x133] = "Reserved",
-	[0x134] = "Reserved",
-	[0x135] = "Reserved",
-	[0x136] = "Reserved",
-	[0x137] = "Reserved",
-	[0x138] = "Reserved",
-	[0x139] = "Reserved",
-	[0x13a] = "Reserved",
-	[0x13b] = "Reserved",
-	[0x13c] = "Reserved",
-	[0x13d] = "Reserved",
-	[0x13e] = "Reserved",
-	[0x13f] = "Reserved",
-	[0x140] = "Reserved", 
-	[0x141] = "Reserved",
-	[0x142] = "Reserved",
-	[0x143] = "Reserved",
-	[0x144] = "Reserved",
-	[0x145] = "Reserved",
-	[0x146] = "Reserved",
-	[0x147] = "Reserved",
-	[0x148] = "Reserved",
-	[0x149] = "Reserved",
-	[0x14a] = "Reserved",
-	[0x14b] = "Reserved",
-	[0x14c] = "Reserved",
-	[0x14d] = "Reserved",
-	[0x14e] = "Reserved",
-	[0x14f] = "Reserved",
-	[0x150] = "Balance Right",
-	[0x151] = "Balance Left",
-	[0x152] = "Bass Increment",
-	[0x153] = "Bass Decrement",
-	[0x154] = "Treble Increment",
-	[0x155] = "Treble Decrement",
-	[0x156] = "Reserved",
-	[0x157] = "Reserved",
-	[0x158] = "Reserved",
-	[0x159] = "Reserved",
-	[0x15a] = "Reserved",
-	[0x15b] = "Reserved",
-	[0x15c] = "Reserved",
-	[0x15d] = "Reserved",
-	[0x15e] = "Reserved",
-	[0x15f] = "Reserved",
-	[0x160] = "Speaker System",
-	[0x161] = "Channel Left",
-	[0x162] = "Channel Right",
-	[0x163] = "Channel Center",
-	[0x164] = "Channel Front",
-	[0x165] = "Channel Center Front",
-	[0x166] = "Channel Side",
-	[0x167] = "Channel Surround",
-	[0x168] = "Channel Low Frequency Enhancement",
-	[0x169] = "Channel Top",
-	[0x16a] = "Channel Unknown",
-	[0x16b] = "Reserved",
-	[0x16c] = "Reserved",
-	[0x16d] = "Reserved",
-	[0x16e] = "Reserved",
-	[0x16f] = "Reserved",
-	[0x170] = "Sub-channel",
-	[0x171] = "Sub-channel Increment",
-	[0x172] = "Sub-channel Decrement",
-	[0x173] = "Alternate Audio Increment",
-	[0x174] = "Alternate Audio Decrement",
-	[0x175] = "Reserved",
-	[0x176] = "Reserved",
-	[0x177] = "Reserved",
-	[0x178] = "Reserved",
-	[0x179] = "Reserved",
-	[0x17a] = "Reserved",
-	[0x17b] = "Reserved",
-	[0x17c] = "Reserved",
-	[0x17d] = "Reserved",
-	[0x17e] = "Reserved",
-	[0x17f] = "Reserved",
-	[0x180] = "Application Launch Buttons",
-	[0x181] = "AL Launch Buttion Configuration Tool",
-	[0x182] = "AL Programmable Button Configuration",
-	[0x183] = "AL Consumer Control Configuration",
-	[0x184] = "AL Word Processor",
-	[0x185] = "AL Text Editor",
-	[0x186] = "AL Spreadsheet",
-	[0x187] = "AL Graphics Editor",
-	[0x188] = "AL Presentation App",
-	[0x189] = "AL Database App",
-	[0x18a] = "AL Email Reader",
-	[0x18b] = "AL Newsreader",
-	[0x18c] = "AL Voicemail",
-	[0x18d] = "AL Contacts/Address Book",
-	[0x18e] = "AL Calendar/Schedule",
-	[0x18f] = "AL Task/Project Manager",
-	[0x190] = "AL Log/Journal/Timecard",
-	[0x191] = "AL Checkbook/Finance",
-	[0x192] = "AL Calculator",
-	[0x193] = "AL A/V Capture/Playback",
-	[0x194] = "AL Local Machine Browser",
-	[0x195] = "AL LAN/WAN Browser",
-	[0x196] = "AL Internet Browser",
-	[0x197] = "AL Remote Networking/ISP Connect",
-	[0x198] = "AL Network Conference",
-	[0x199] = "AL Network Chat",
-	[0x19a] = "AL Telephony/Dialer",
-	[0x19b] = "AL Logon",
-	[0x19c] = "AL Logoff",
-	[0x19d] = "AL Logon/Logoff",
-	[0x19e] = "AL Terminal Lock/Screensaver",
-	[0x19f] = "AL Control Panel",
-	[0x1a0] = "AL Command Line Processor/Run",
-	[0x1a1] = "AL Process/Task Manager",
-	[0x1a2] = "AL Select Task/Application",
-	[0x1a3] = "AL Next Task/Application",
-	[0x1a4] = "AL Previous Task/Application",
-	[0x1a5] = "AL Preemptive Halt Task/Application",
-	[0x1a6] = "AL Integrated Help Center",
-	[0x1a7] = "AL Documents",
-	[0x1a8] = "AL Thesaurus",
-	[0x1a9] = "AL Dictionary",
-	[0x1aa] = "AL Desktop",
-	[0x1ab] = "AL Spell Check",
-	[0x1ac] = "AL Grammar Check",
-	[0x1ad] = "AL Wireless Status",
-	[0x1ae] = "AL Keyboard Layout",
-	[0x1af] = "AL Virus Protection",
-	[0x1b0] = "AL Encryption",
-	[0x1b1] = "AL Screen Saver",
-	[0x1b2] = "AL Alarms",
-	[0x1b3] = "AL Clock",
-	[0x1b4] = "AL File Browser",
-	[0x1b5] = "AL Power Status",
-	[0x1b6] = "AL Image Browser",
-	[0x1b7] = "AL Audio Browser",
-	[0x1b8] = "AL Movie Browser",
-	[0x1b9] = "AL Digital Rights Manager",
-	[0x1ba] = "AL Digital Wallet",
-	[0x1bb] = "Reserved",
-	[0x1bc] = "AL Instant Messaging",
-	[0x1bd] = "AL OEM Features Tips/Tutorial Browser",
-	[0x1be] = "AL OEM Help",
-	[0x1bf] = "AL Online Community",
-	[0x1c0] = "AL Entertainment Content Browser",
-	[0x1c1] = "AL Online Shopping Browser",
-	[0x1c2] = "AL SmartCard Information/Help",
-	[0x1c3] = "AL Market Monitor/Finance Browser",
-	[0x1c4] = "AL Customized Corporate News Browser",
-	[0x1c5] = "AL Online Activity Browser",
-	[0x1c6] = "AL Research/Search Browser",
-	[0x1c7] = "AL Audio Player",
-	[0x1c8] = "Reserved",
-	[0x1c9] = "Reserved",
-	[0x1ca] = "Reserved",
-	[0x1cb] = "Reserved",
-	[0x1cc] = "Reserved",
-	[0x1cd] = "Reserved",
-	[0x1ce] = "Reserved",
-	[0x1cf] = "Reserved",
-	[0x1d0] = "Reserved",
-	[0x1d1] = "Reserved",
-	[0x1d2] = "Reserved",
-	[0x1d3] = "Reserved",
-	[0x1d4] = "Reserved",
-	[0x1d5] = "Reserved",
-	[0x1d6] = "Reserved",
-	[0x1d7] = "Reserved",
-	[0x1d8] = "Reserved",
-	[0x1d9] = "Reserved",
-	[0x1da] = "Reserved",
-	[0x1db] = "Reserved",
-	[0x1dc] = "Reserved",
-	[0x1dd] = "Reserved",
-	[0x1de] = "Reserved",
-	[0x1df] = "Reserved",
-	[0x1e0] = "Reserved",
-	[0x1e1] = "Reserved",
-	[0x1e2] = "Reserved",
-	[0x1e3] = "Reserved",
-	[0x1e4] = "Reserved",
-	[0x1e5] = "Reserved",
-	[0x1e6] = "Reserved",
-	[0x1e7] = "Reserved",
-	[0x1e8] = "Reserved",
-	[0x1e9] = "Reserved",
-	[0x1ea] = "Reserved",
-	[0x1eb] = "Reserved",
-	[0x1ec] = "Reserved",
-	[0x1ed] = "Reserved",
-	[0x1ee] = "Reserved",
-	[0x1ef] = "Reserved",
-	[0x1f0] = "Reserved",
-	[0x1f1] = "Reserved",
-	[0x1f2] = "Reserved",
-	[0x1f3] = "Reserved",
-	[0x1f4] = "Reserved",
-	[0x1f5] = "Reserved",
-	[0x1f6] = "Reserved",
-	[0x1f7] = "Reserved",
-	[0x1f8] = "Reserved",
-	[0x1f9] = "Reserved",
-	[0x1fa] = "Reserved",
-	[0x1fb] = "Reserved",
-	[0x1fc] = "Reserved",
-	[0x1fd] = "Reserved",
-	[0x1fe] = "Reserved",
-	[0x1ff] = "Reserved",
-	[0x200] = "Generic GUI Application Controls",
-	[0x201] = "AC New",
-	[0x202] = "AC Open",
-	[0x203] = "AC Close",
-	[0x204] = "AC Exit",
-	[0x205] = "AC Maximize",
-	[0x206] = "AC Minimize",
-	[0x207] = "AC Save",
-	[0x208] = "AC Print",
-	[0x209] = "AC Properties",
-	[0x20a] = "",
-	[0x20b] = "",
-	[0x20c] = "",
-	[0x20d] = "",
-	[0x20e] = "",
-	[0x20f] = "",
-	[0x210] = "",
-	[0x211] = "",
-	[0x212] = "",
-	[0x213] = "",
-	[0x214] = "",
-	[0x215] = "",
-	[0x216] = "",
-	[0x217] = "",
-	[0x218] = "",
-	[0x219] = "",
-	[0x21a] = "AC Undo",
-	[0x21b] = "AC Copy",
-	[0x21c] = "AC Cut",
-	[0x21d] = "AC Paste",
-	[0x21e] = "AC Select All",
-	[0x21f] = "AC Find",
-	[0x220] = "AC Find and Replace",
-	[0x221] = "AC Search",
-	[0x222] = "AC Go To",
-	[0x223] = "AC Home",
-	[0x224] = "AC Back",
-	[0x225] = "AC Forward",
-	[0x226] = "AC Stop",
-	[0x227] = "AC Refresh",
-	[0x228] = "AC Previous Link",
-	[0x229] = "AC Next Link",
-	[0x22a] = "AC Bookmarks",
-	[0x22b] = "AC History",
-	[0x22c] = "AC Subscriptions",
-	[0x22d] = "AC Zoom In",
-	[0x22e] = "AC Zoom Out",
-	[0x22f] = "AC Zoom",
-	[0x230] = "AC Full Screen View",
-	[0x231] = "AC Normal View",
-	[0x232] = "AC View Toggle",
-	[0x233] = "AC Scroll Up",
-	[0x234] = "AC Scroll Down",
-	[0x235] = "AC Scroll",
-	[0x236] = "AC Pan Left",
-	[0x237] = "AC Pan Right",
-	[0x238] = "AC Pan",
-	[0x239] = "AC New Window",
-	[0x23a] = "AC Tile Horizontally",
-	[0x23b] = "AC Tile Vertically",
-	[0x23c] = "AC Format",
-	[0x23d] = "AC Edit",
-	[0x23e] = "AC Bold",
-	[0x23f] = "AC Italics",
-	[0x240] = "AC Undeline",
-	[0x241] = "AC Strikethrough",
-	[0x242] = "AC Subscript",
-	[0x243] = "AC Superscript",
-	[0x244] = "AC All Caps",
-	[0x245] = "AC Rotate",
-	[0x246] = "AC Resize",
-	[0x247] = "AC Flip Horizontal",
-	[0x248] = "AC Flip Vertical",
-	[0x249] = "AC Mirror Horizontal",
-	[0x24a] = "AC Mirror Vertical",
-	[0x24b] = "AC Font Select",
-	[0x24c] = "AC Font Color",
-	[0x24d] = "AC Font Size",
-	[0x24e] = "AC Justify Left",
-	[0x24f] = "AC Justify Center H",
-	[0x250] = "AC Justify Right",
-	[0x251] = "AC Justify Block H",
-	[0x252] = "AC Justify Top",
-	[0x253] = "AC Justify Center V",
-	[0x254] = "AC Justify Bottom",
-	[0x255] = "AC Justify Block V",
-	[0x256] = "AC Indent Decrease",
-	[0x257] = "AC Indent Increase",
-	[0x258] = "AC Numbered List",
-	[0x259] = "AC Restart Numbering",
-	[0x25a] = "AC Bulleted List",
-	[0x25b] = "AC Promote",
-	[0x25c] = "AC Demote",
-	[0x25d] = "AC Yes",
-	[0x25e] = "AC No",
-	[0x25f] = "AC Cancel",
-	[0x260] = "AC Catalog",
-	[0x261] = "AC Buy/Checkout",
-	[0x262] = "AC Add to Cart",
-	[0x263] = "AC Expand",
-	[0x264] = "AC Expand All",
-	[0x265] = "AC Collapse",
-	[0x266] = "AC Collapse All",
-	[0x267] = "AC Print Preview",
-	[0x268] = "AC Paste Special",
-	[0x269] = "AC Insert Mode",
-	[0x26a] = "AC Delete",
-	[0x26b] = "AC Lock",
-	[0x26c] = "AC Unlock",
-	[0x26d] = "AC Protect",
-	[0x26e] = "AC Unprotect",
-	[0x26f] = "AC Attach Comment",
-	[0x270] = "AC Delete Comment",
-	[0x271] = "AC View Comment",
-	[0x272] = "AC Select Word",
-	[0x273] = "AC Select Sentence",
-	[0x274] = "AC Select Paragraph",
-	[0x275] = "AC Select Column",
-	[0x276] = "AC Select Row",
-	[0x277] = "AC Select Table",
-	[0x278] = "AC Select Object",
-	[0x279] = "AC Redo/Repeat",
-	[0x27a] = "AC Sort",
-	[0x27b] = "AC Sort Ascending",
-	[0x27c] = "AC Sort Descending",
-	[0x27d] = "AC Filter",
-	[0x27e] = "AC Set Clock",
-	[0x27f] = "AC View Clock",
-	[0x280] = "AC Select Time Zone",
-	[0x281] = "AC Edit Time Zones",
-	[0x282] = "AC Set Alarm",
-	[0x283] = "AC Clear Alarm",
-	[0x284] = "AC Snooze Alarm",
-	[0x285] = "AC Reset Alarm",
-	[0x286] = "AC Synchronize",
-	[0x287] = "AC Send/Receive",
-	[0x288] = "AC Send To",
-	[0x289] = "AC Reply",
-	[0x28a] = "AC Reply All",
-	[0x28b] = "AC Forward Msg",
-	[0x28c] = "AC Send",
-	[0x28d] = "AC Attach File",
-	[0x28e] = "AC Upload",
-	[0x28f] = "AC Download (Save Target As)",
-	[0x290] = "AC Set Borders",
-	[0x291] = "AC Insert Row",
-	[0x292] = "AC Insert Column",
-	[0x293] = "AC Insert File",
-	[0x294] = "AC Insert Picture",
-	[0x295] = "AC Insert Object",
-	[0x296] = "AC Insert Symbol",
-	[0x297] = "AC Save and Close",
-	[0x298] = "AC Rename",
-	[0x299] = "AC Merge",
-	[0x29a] = "AC Split",
-	[0x29b] = "AC Distrubute Horizontally",
-	[0x29c] = "AC Distrubute Vertically"
-};
-
 /**
  * Translates USB HID Usages from the Consumer Page into HelenOS keycodes.
@@ -769,23 +98,4 @@
 
 /**
- * Translates USB HID Usages from the Consumer Page into their string 
- * representation.
- *
- * @param usage USB HID Consumer Page Usage number.
- * 
- * @retval HelenOS key code corresponding to the given USB Consumer Page Usage.
- */
-const char *usb_multimedia_usage_to_str(int usage)
-{
-	size_t map_length = sizeof(usb_hid_consumer_usage_str) / sizeof(char *);
-
-	if ((usage < 0) || ((size_t)usage >= map_length))
-		return "Unknown usage";
-
-	/*! @todo What if the usage is not in the table? */
-	return usb_hid_consumer_usage_str[usage];
-}
-
-/**
  * @}
  */
Index: uspace/drv/usbhid/multimedia/keymap.h
===================================================================
--- uspace/drv/usbhid/multimedia/keymap.h	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/multimedia/keymap.h	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -39,6 +39,4 @@
 unsigned int usb_multimedia_map_usage(int usage);
 
-const char *usb_multimedia_usage_to_str(int usage);
-
 #endif /* USB_HID_MULTIMEDIA_KEYMAP_H_ */
 
Index: uspace/drv/usbhid/multimedia/multimedia.c
===================================================================
--- uspace/drv/usbhid/multimedia/multimedia.c	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/multimedia/multimedia.c	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -43,4 +43,5 @@
 #include <usb/debug.h>
 #include <usb/hid/usages/core.h>
+#include <usb/hid/usages/consumer.h>
 
 #include <errno.h>
@@ -210,4 +211,6 @@
 	}
 	
+	usb_log_debug("%s function created. Handle: %d\n", NAME, fun->handle);
+	
 	rc = ddf_fun_add_to_class(fun, "keyboard");
 	if (rc != EOK) {
@@ -357,5 +360,5 @@
 			    usb_multimedia_map_usage(field->usage);
 			const char *key_str = 
-			    usb_multimedia_usage_to_str(field->usage);
+			    usbhid_multimedia_usage_to_str(field->usage);
 			usb_log_info("Pressed key: %s\n", key_str);
 			usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS, 
Index: uspace/drv/usbhid/subdrivers.c
===================================================================
--- uspace/drv/usbhid/subdrivers.c	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/subdrivers.c	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -38,7 +38,7 @@
 #include <usb/hid/hidpath.h>
 
-//#include "lgtch-ultrax/lgtch-ultrax.h"
 #include "multimedia/multimedia.h"
 #include "mouse/mousedev.h"
+#include "generic/hiddev.h"
 
 static usb_hid_subdriver_usage_t path_kbd[] = {
@@ -58,8 +58,12 @@
 };
 
+//static usb_hid_subdriver_usage_t generic_hid_key_path[] = {
+//	{0, 0}
+//};
+
 const usb_hid_subdriver_mapping_t usb_hid_subdrivers[] = {
 	{
 		path_kbd,
-		-1,
+		0,
 		USB_HID_PATH_COMPARE_BEGIN,
 		-1,
@@ -88,5 +92,5 @@
 	{
 		path_mouse,
-		-1,
+		0,
 		USB_HID_PATH_COMPARE_BEGIN,
 		-1,
@@ -99,4 +103,17 @@
 		}
 	},
+//	{
+//		generic_hid_key_path,
+//		0,
+//		USB_HID_PATH_COMPARE_ANYWHERE,
+//		-1,
+//		-1,
+//		{
+//			.init = usb_generic_hid_init,
+//			.deinit = NULL,
+//			.poll = usb_generic_hid_polling_callback,
+//			.poll_end = NULL
+//		}
+//	},
 	{NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}
 };
Index: uspace/drv/usbhid/usbhid.c
===================================================================
--- uspace/drv/usbhid/usbhid.c	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/usbhid.c	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -234,5 +234,7 @@
 	}
 	
-	hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count * 
+	// add one generic HID subdriver per device
+	
+	hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 
 	    sizeof(usb_hid_subdriver_t));
 	if (hid_dev->subdrivers == NULL) {
@@ -247,5 +249,10 @@
 	}
 	
-	hid_dev->subdriver_count = count;
+	hid_dev->subdrivers[count].init = usb_generic_hid_init;
+	hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback;
+	hid_dev->subdrivers[count].deinit = NULL;
+	hid_dev->subdrivers[count].poll_end = NULL;
+	
+	hid_dev->subdriver_count = count + 1;
 	
 	return EOK;
@@ -307,4 +314,5 @@
 		
 		if (matched) {
+			usb_log_debug("Subdriver matched.\n");
 			subdrivers[count++] = &mapping->subdriver;
 		}
@@ -348,4 +356,37 @@
 /*----------------------------------------------------------------------------*/
 
+static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
+{
+	assert(hid_dev != NULL && hid_dev->report != NULL);
+	
+	uint8_t report_id = 0;
+	size_t size = usb_hid_report_size(hid_dev->report, report_id, 
+	    USB_HID_REPORT_TYPE_INPUT);
+	
+	size_t max_size = 0;
+	
+	while (size > 0) {
+		max_size = (size > max_size) ? size : max_size;
+		size = usb_hid_report_size(hid_dev->report, report_id, 
+		    USB_HID_REPORT_TYPE_INPUT);
+		++report_id;
+	}
+	
+	usb_log_debug("Max size of input report: %zu\n", max_size);
+	
+	hid_dev->max_input_report_size = max_size;
+	assert(hid_dev->input_report == NULL);
+	
+	hid_dev->input_report = malloc(max_size);
+	if (hid_dev->input_report == NULL) {
+		return ENOMEM;
+	}
+	memset(hid_dev->input_report, 0, max_size);
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
 usb_hid_dev_t *usb_hid_new(void)
 {
@@ -402,5 +443,5 @@
 	/* Get the report descriptor and parse it. */
 	rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 
-	    hid_dev->report);
+	    hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
 	
 	bool fallback = false;
@@ -483,4 +524,10 @@
 	}
 	
+	// save max input report size and allocate space for the report
+	rc = usb_hid_init_report(hid_dev);
+	if (rc != EOK) {
+		usb_log_error("Failed to initialize input report buffer.\n");
+	}
+	
 	return rc;
 }
@@ -500,30 +547,33 @@
 	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
 	
-	int allocated = (hid_dev->input_report != NULL);
-	
-	if (!allocated
-	    || hid_dev->input_report_size < buffer_size) {
-		uint8_t *input_old = hid_dev->input_report;
-		uint8_t *input_new = (uint8_t *)malloc(buffer_size);
-		
-		if (input_new == NULL) {
-			usb_log_error("Failed to allocate space for input "
-			    "buffer. This event may not be reported\n");
-			memset(hid_dev->input_report, 0, 
-			    hid_dev->input_report_size);
-		} else {
-			memcpy(input_new, input_old, 
-			    hid_dev->input_report_size);
-			hid_dev->input_report = input_new;
-			if (allocated) {
-				free(input_old);
-			}
-			usb_hid_new_report();
-		}
-	}
+//	int allocated = (hid_dev->input_report != NULL);
+	assert(hid_dev->input_report != NULL);
+	assert(hid_dev->max_input_report_size >= buffer_size);
+	
+//	if (/*!allocated*/
+//	    /*|| *//*hid_dev->input_report_size < buffer_size*/) {
+//		uint8_t *input_old = hid_dev->input_report;
+//		uint8_t *input_new = (uint8_t *)malloc(buffer_size);
+		
+//		if (input_new == NULL) {
+//			usb_log_error("Failed to allocate space for input "
+//			    "buffer. This event may not be reported\n");
+//			memset(hid_dev->input_report, 0, 
+//			    hid_dev->input_report_size);
+//		} else {
+//			memcpy(input_new, input_old, 
+//			    hid_dev->input_report_size);
+//			hid_dev->input_report = input_new;
+//			if (allocated) {
+//				free(input_old);
+//			}
+//			usb_hid_new_report();
+//		}
+//	}
 	
 	/*! @todo This should probably be atomic. */
 	memcpy(hid_dev->input_report, buffer, buffer_size);
 	hid_dev->input_report_size = buffer_size;
+	usb_hid_new_report();
 	
 	bool cont = false;
Index: uspace/drv/usbhid/usbhid.h
===================================================================
--- uspace/drv/usbhid/usbhid.h	(revision 1889786ac51344d84ebf4538a72c2fe2038adf17)
+++ uspace/drv/usbhid/usbhid.h	(revision 8d3f198682cdb8c1557ad7830bae04f88ea18073)
@@ -98,4 +98,5 @@
 	
 	size_t input_report_size;
+	size_t max_input_report_size;
 } usb_hid_dev_t;
 
