Index: uspace/drv/uhci-hcd/utils/device_keeper.c
===================================================================
--- uspace/drv/uhci-hcd/utils/device_keeper.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/uhci-hcd/utils/device_keeper.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -35,4 +35,5 @@
 #include <assert.h>
 #include <errno.h>
+#include <usb/debug.h>
 
 #include "device_keeper.h"
@@ -120,5 +121,8 @@
 	case 0x9: /* set configuration */
 	case 0x11: /* set interface */
-		instance->devices[target.address].toggle_status = 0;
+		/* target must be device */
+		if ((data[0] & 0xf) == 0) {
+			instance->devices[target.address].toggle_status = 0;
+		}
 	break;
 	}
Index: uspace/drv/usbhid/Makefile
===================================================================
--- uspace/drv/usbhid/Makefile	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/Makefile	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -42,4 +42,5 @@
 	hidreq.c \
 	kbddev.c \
+	kbdrepeat.c \
 	hiddev.c \
 	$(STOLEN_LAYOUT_SOURCES)
Index: uspace/drv/usbhid/conv.c
===================================================================
--- uspace/drv/usbhid/conv.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/conv.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -40,4 +40,8 @@
 #include "conv.h"
 
+/**
+ * Mapping between USB HID key codes (from HID Usage Tables) and corresponding
+ * HelenOS key codes.
+ */
 static int scanmap_simple[255] = {
 
@@ -163,4 +167,12 @@
 };
 
+/**
+ * Translate USB HID key codes (from HID Usage Tables) to generic key codes
+ * recognized by HelenOS.
+ *
+ * @param scancode USB HID key code (from HID Usage Tables).
+ * 
+ * @retval HelenOS key code corresponding to the given USB HID key code.
+ */
 unsigned int usbhid_parse_scancode(int scancode)
 {
Index: uspace/drv/usbhid/descdump.c
===================================================================
--- uspace/drv/usbhid/descdump.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/descdump.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -44,4 +44,11 @@
 #define BYTES_PER_LINE 12
 
+/**
+ * Dumps the given buffer in hexadecimal format to standard output.
+ *
+ * @param msg Message to print before the buffer.
+ * @param buffer Buffer to print.
+ * @param length Size of the buffer in bytes.
+ */
 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
 {
@@ -62,4 +69,10 @@
 #define INDENT "  "
 
+/**
+ * Print standard configuration descriptor to standard output.
+ *
+ * @param index Index of the descriptor.
+ * @param d Standard configuration descriptor to print.
+ */
 void dump_standard_configuration_descriptor(
     int index, const usb_standard_configuration_descriptor_t *d)
@@ -84,4 +97,9 @@
 }
 
+/**
+ * Print standard interface descriptor to standard output.
+ *
+ * @param d Standard interface descriptor to print.
+ */
 void dump_standard_interface_descriptor(
     const usb_standard_interface_descriptor_t *d)
@@ -99,4 +117,9 @@
 }
 
+/**
+ * Print standard endpoint descriptor to standard output.
+ *
+ * @param d Standard endpoint descriptor to print.
+ */
 void dump_standard_endpoint_descriptor(
     const usb_standard_endpoint_descriptor_t *d)
@@ -126,4 +149,9 @@
 }
 
+/**
+ * Print standard HID descriptor to standard output.
+ *
+ * @param d Standard HID descriptor to print.
+ */
 void dump_standard_hid_descriptor_header(
     const usb_standard_hid_descriptor_t *d)
@@ -139,4 +167,10 @@
 }
 
+/**
+ * Print HID class-specific descriptor header (type and length) to standard 
+ * output.
+ * 
+ * @param d HID class-specific descriptor header to print.
+ */
 void dump_standard_hid_class_descriptor_info(
     const usb_standard_hid_class_descriptor_info_t *d)
@@ -146,4 +180,12 @@
 }
 
+/**
+ * Print HID class-specific descriptor (without the header) to standard output.
+ *
+ * @param index Index of the descriptor.
+ * @param type Type of the HID class-specific descriptor (Report or Physical).
+ * @param d HID class descriptor to print.
+ * @param size Size of the descriptor in bytes.
+ */
 void dump_hid_class_descriptor(int index, uint8_t type, 
     const uint8_t *d, size_t size )
Index: uspace/drv/usbhid/hiddev.c
===================================================================
--- uspace/drv/usbhid/hiddev.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/hiddev.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -53,5 +53,28 @@
 /* Non-API functions                                                          */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Retreives HID Report descriptor from the device.
+ *
+ * This function first parses the HID descriptor from the Interface descriptor
+ * to get the size of the Report descriptor and then requests the Report 
+ * descriptor from the device.
+ *
+ * @param hid_dev HID device structure.
+ * @param config_desc Full configuration descriptor (including all nested
+ *                    descriptors).
+ * @param config_desc_size Size of the full configuration descriptor (in bytes).
+ * @param iface_desc Pointer to the interface descriptor inside the full
+ *                   configuration descriptor (@a config_desc) for the interface
+ *                   assigned with this device (@a hid_dev).
+ *
+ * @retval EOK if successful.
+ * @retval ENOENT if no HID descriptor could be found.
+ * @retval EINVAL if the HID descriptor  or HID report descriptor have different
+ *                size than expected.
+ * @retval ENOMEM if some allocation failed.
+ * @return Other value inherited from function usb_request_get_descriptor().
+ *
+ * @sa usb_request_get_descriptor()
+ */
 static int usbhid_dev_get_report_descriptor(usbhid_dev_t *hid_dev, 
     uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)
@@ -143,5 +166,25 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Retreives descriptors from the device, initializes pipes and stores 
+ * important information from descriptors.
+ *
+ * Initializes the polling pipe described by the given endpoint description
+ * (@a poll_ep_desc).
+ * 
+ * Information retreived from descriptors and stored in the HID device structure:
+ *    - Assigned interface number (the interface controlled by this instance of
+ *                                 the driver)
+ *    - Polling interval (from the interface descriptor)
+ *    - Report descriptor
+ *
+ * @param hid_dev HID device structure to be initialized.
+ * @param poll_ep_desc Description of the polling (Interrupt In) endpoint
+ *                     that has to be present in the device in order to
+ *                     successfuly initialize the structure.
+ *
+ * @sa usb_endpoint_pipe_initialize_from_configuration(), 
+ *     usbhid_dev_get_report_descriptor()
+ */
 static int usbhid_dev_process_descriptors(usbhid_dev_t *hid_dev, 
     usb_endpoint_description_t *poll_ep_desc) 
@@ -242,5 +285,9 @@
 /* API functions                                                              */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Creates new uninitialized HID device structure.
+ *
+ * @return Pointer to the new HID device structure, or NULL if an error occured.
+ */
 usbhid_dev_t *usbhid_dev_new(void)
 {
@@ -269,5 +316,12 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Properly destroys the HID device structure.
+ *
+ * @note Currently does not clean-up the used pipes, as there are no functions
+ *       offering such functionality.
+ * 
+ * @param hid_dev Pointer to the structure to be destroyed.
+ */
 void usbhid_dev_free(usbhid_dev_t **hid_dev)
 {
@@ -292,5 +346,23 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Initializes HID device structure.
+ *
+ * @param hid_dev HID device structure to be initialized.
+ * @param dev DDF device representing the HID device.
+ * @param poll_ep_desc Description of the polling (Interrupt In) endpoint
+ *                     that has to be present in the device in order to
+ *                     successfuly initialize the structure.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if some argument is missing.
+ * @return Other value inherited from one of functions 
+ *         usb_device_connection_initialize_from_device(),
+ *         usb_endpoint_pipe_initialize_default_control(),
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usbhid_dev_process_descriptors().
+ *
+ * @sa usbhid_dev_process_descriptors()
+ */
 int usbhid_dev_init(usbhid_dev_t *hid_dev, ddf_dev_t *dev, 
     usb_endpoint_description_t *poll_ep_desc)
@@ -352,10 +424,14 @@
 	 * Get descriptors, parse descriptors and save endpoints.
 	 */
-	usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
+	rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
+	if (rc != EOK) {
+		usb_log_error("Failed to start session on the control pipe: %s"
+		    ".\n", str_error(rc));
+		return rc;
+	}
 	
 	rc = usbhid_dev_process_descriptors(hid_dev, poll_ep_desc);
-	
-	usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
-	if (rc != EOK) {
+	if (rc != EOK) {
+		/* TODO: end session?? */
 		usb_log_error("Failed to process descriptors: %s.\n",
 		    str_error(rc));
@@ -363,4 +439,11 @@
 	}
 	
+	rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
+	if (rc != EOK) {
+		usb_log_warning("Failed to start session on the control pipe: "
+		    "%s.\n", str_error(rc));
+		return rc;
+	}
+	
 	hid_dev->initialized = 1;
 	usb_log_info("HID device structure initialized.\n");
Index: uspace/drv/usbhid/hiddev.h
===================================================================
--- uspace/drv/usbhid/hiddev.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/hiddev.h	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -48,21 +48,38 @@
 
 /**
- * @brief USB/HID device type.
+ * USB/HID device type.
+ *
+ * Holds a reference to DDF device structure, and HID-specific data, such 
+ * as information about used pipes (one Control pipe and one Interrupt In pipe),
+ * polling interval, assigned interface number, Report descriptor and a
+ * reference to the Report parser used to parse incoming reports and composing
+ * outgoing reports.
  */
 typedef struct {
+	/** DDF device representing the controlled HID device. */
 	ddf_dev_t *device;
 
+	/** Physical connection to the device. */
 	usb_device_connection_t wire;
+	/** USB pipe corresponding to the default Control endpoint. */
 	usb_endpoint_pipe_t ctrl_pipe;
+	/** USB pipe corresponding to the Interrupt In (polling) pipe. */
 	usb_endpoint_pipe_t poll_pipe;
 	
+	/** Polling interval retreived from the Interface descriptor. */
 	short poll_interval;
 	
+	/** Interface number assigned to this device. */
 	uint16_t iface;
 	
+	/** Report descriptor. */
 	uint8_t *report_desc;
+
 	size_t report_desc_size;
+
+	/** HID Report parser. */
 	usb_hid_report_parser_t *parser;
 	
+	/** State of the structure (for checking before use). */
 	int initialized;
 } usbhid_dev_t;
Index: uspace/drv/usbhid/hidreq.c
===================================================================
--- uspace/drv/usbhid/hidreq.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/hidreq.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -46,5 +46,18 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Send Set Report request to the HID device.
+ *
+ * @param hid_dev HID device to send the request to.
+ * @param type Type of the report.
+ * @param buffer Report data.
+ * @param buf_size Report data size (in bytes).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usb_control_request_set().
+ */
 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
@@ -97,5 +110,16 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Send Set Protocol request to the HID device.
+ *
+ * @param hid_dev HID device to send the request to.
+ * @param protocol Protocol to set.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usb_control_request_set().
+ */
 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
 {
@@ -145,5 +169,17 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Send Set Idle request to the HID device.
+ *
+ * @param hid_dev HID device to send the request to.
+ * @param duration Duration value (is multiplicated by 4 by the device to
+ *                 get real duration in miliseconds).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usb_control_request_set().
+ */
 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
 {
@@ -195,5 +231,20 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Send Get Report request to the HID device.
+ *
+ * @param[in] hid_dev HID device to send the request to.
+ * @param[in] type Type of the report.
+ * @param[in][out] buffer Buffer for the report data.
+ * @param[in] buf_size Size of the buffer (in bytes).
+ * @param[out] actual_size Actual size of report received from the device 
+ *                         (in bytes).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usb_control_request_set().
+ */
 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 
     uint8_t *buffer, size_t buf_size, size_t *actual_size)
@@ -246,4 +297,17 @@
 }
 
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Get Protocol request to the HID device.
+ *
+ * @param[in] hid_dev HID device to send the request to.
+ * @param[out] protocol Current protocol of the device.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usb_control_request_set().
+ */
 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
 {
@@ -303,4 +367,18 @@
 }
 
+/*----------------------------------------------------------------------------*/
+/**
+ * Send Get Idle request to the HID device.
+ *
+ * @param[in] hid_dev HID device to send the request to.
+ * @param[out] duration Duration value (multiplicate by 4 to get real duration
+ *                      in miliseconds).
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if no HID device is given.
+ * @return Other value inherited from one of functions 
+ *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
+ *         usb_control_request_set().
+ */
 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
 {
Index: uspace/drv/usbhid/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbddev.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/kbddev.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -37,5 +37,4 @@
 #include <errno.h>
 #include <str_error.h>
-#include <fibril.h>
 #include <stdio.h>
 
@@ -43,4 +42,6 @@
 #include <ipc/kbd.h>
 #include <async.h>
+#include <fibril.h>
+#include <fibril_synch.h>
 
 #include <usb/usb.h>
@@ -56,13 +57,30 @@
 #include "layout.h"
 #include "conv.h"
-
-/*----------------------------------------------------------------------------*/
-
+#include "kbdrepeat.h"
+
+/*----------------------------------------------------------------------------*/
+/** Default modifiers when the keyboard is initialized. */
 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
+
+/** Boot protocol report size (key part). */
 static const size_t BOOTP_REPORT_SIZE = 6;
+
+/** Boot protocol total report size. */
 static const size_t BOOTP_BUFFER_SIZE = 8;
+
+/** Boot protocol output report size. */
 static const size_t BOOTP_BUFFER_OUT_SIZE = 1;
+
+/** Boot protocol error key code. */
 static const uint8_t BOOTP_ERROR_ROLLOVER = 1;
+
+/** Default idle rate for keyboards. */
 static const uint8_t IDLE_RATE = 0;
+
+/** Delay before a pressed key starts auto-repeating. */
+static const unsigned int DEFAULT_DELAY_BEFORE_FIRST_REPEAT = 500 * 1000;
+
+/** Delay between two repeats of a pressed key when auto-repeating. */
+static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000;
 
 /** Keyboard polling endpoint description for boot protocol class. */
@@ -82,4 +100,5 @@
 #define NUM_LAYOUTS 3
 
+/** Keyboard layout map. */
 static layout_op_t *layout[NUM_LAYOUTS] = {
 	&us_qwerty_op,
@@ -93,5 +112,5 @@
 /* Modifier constants                                                         */
 /*----------------------------------------------------------------------------*/
-
+/** Mapping of USB modifier key codes to generic modifier key codes. */
 static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
 	KC_LCTRL,         /* USB_HID_MOD_LCTRL */
@@ -114,7 +133,12 @@
 };
 
-/** Default handler for IPC methods not handled by DDF.
- *
- * @param dev Device handling the call.
+/** 
+ * Default handler for IPC methods not handled by DDF.
+ *
+ * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it
+ * assumes the caller is the console and thus it stores IPC phone to it for 
+ * later use by the driver to notify about key events.
+ *
+ * @param fun Device function handling the call.
  * @param icallid Call id.
  * @param icall Call data.
@@ -147,5 +171,16 @@
 /* Key processing functions                                                   */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Handles turning of LED lights on and off.
+ *
+ * In case of USB keyboards, the LEDs are handled in the driver, not in the 
+ * device. When there should be a change (lock key was pressed), the driver
+ * uses a Set_Report request sent to the device to set the state of the LEDs.
+ *
+ * This functions sets the LED lights according to current settings of modifiers
+ * kept in the keyboard device structure.
+ *
+ * @param kbd_dev Keyboard device structure.
+ */
 static void usbhid_kbd_set_led(usbhid_kbd_t *kbd_dev) 
 {
@@ -189,12 +224,31 @@
 
 /*----------------------------------------------------------------------------*/
-
-static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, 
-    unsigned int key)
+/**
+ * Processes key events.
+ *
+ * @note This function was copied from AT keyboard driver and modified to suit
+ *       USB keyboard.
+ *
+ * @note Lock keys are not sent to the console, as they are completely handled
+ *       in the driver. It may, however, be required later that the driver
+ *       sends also these keys to application (otherwise it cannot use those
+ *       keys at all).
+ * 
+ * @param kbd_dev Keyboard device structure.
+ * @param type Type of the event (press / release). Recognized values: 
+ *             KEY_PRESS, KEY_RELEASE
+ * @param key Key code of the key according to HID Usage Tables.
+ */
+void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)
 {
 	console_event_t ev;
 	unsigned mod_mask;
 
-	// TODO: replace by our own parsing?? or are the key codes identical??
+	/*
+	 * These parts are copy-pasted from the AT keyboard driver.
+	 *
+	 * They definitely require some refactoring, but will keep it for later
+	 * when the console and keyboard system is changed in HelenOS.
+	 */
 	switch (key) {
 	case KC_LCTRL: mod_mask = KM_LCTRL; break;
@@ -228,4 +282,6 @@
 			 * up the lock state.
 			 */
+			unsigned int locks_old = kbd_dev->lock_keys;
+			
 			kbd_dev->mods = 
 			    kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
@@ -233,5 +289,7 @@
 
 			/* Update keyboard lock indicator lights. */
- 			usbhid_kbd_set_led(kbd_dev);
+			if (kbd_dev->lock_keys != locks_old) {
+				usbhid_kbd_set_led(kbd_dev);
+			}
 		} else {
 			kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
@@ -280,5 +338,12 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Checks if modifiers were pressed or released and generates key events.
+ *
+ * @param kbd_dev Keyboard device structure.
+ * @param modifiers Bitmap of modifiers.
+ *
+ * @sa usbhid_kbd_push_ev()
+ */
 static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
     uint8_t modifiers)
@@ -316,7 +381,21 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Checks if some keys were pressed or released and generates key events.
+ *
+ * An event is created only when key is pressed or released. Besides handling
+ * the events (usbhid_kbd_push_ev()), the auto-repeat fibril is notified about
+ * key presses and releases (see usbhid_kbd_repeat_start() and 
+ * usbhid_kbd_repeat_stop()).
+ *
+ * @param kbd_dev Keyboard device structure.
+ * @param key_codes Parsed keyboard report - codes of currently pressed keys 
+ *                  according to HID Usage Tables.
+ * @param count Number of key codes in report (size of the report).
+ *
+ * @sa usbhid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop()
+ */
 static void usbhid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev, 
-    const uint8_t *key_codes)
+    const uint8_t *key_codes, size_t count)
 {
 	unsigned int key;
@@ -328,9 +407,9 @@
 	i = 0;
 	// all fields should report Error Rollover
-	while (i < kbd_dev->keycode_count &&
+	while (i < count &&
 	    key_codes[i] == BOOTP_ERROR_ROLLOVER) {
 		++i;
 	}
-	if (i == kbd_dev->keycode_count) {
+	if (i == count) {
 		usb_log_debug("Phantom state occured.\n");
 		// phantom state, do nothing
@@ -338,20 +417,22 @@
 	}
 	
-	// TODO: quite dummy right now, think of better implementation
+	/* TODO: quite dummy right now, think of better implementation */
+	assert(count == kbd_dev->key_count);
 	
 	/*
 	 * 1) Key releases
 	 */
-	for (j = 0; j < kbd_dev->keycode_count; ++j) {
+	for (j = 0; j < 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]) {
+		while (i < kbd_dev->key_count
+		    && key_codes[i] != kbd_dev->keys[j]) {
 			++i;
 		}
 		
-		if (i == kbd_dev->keycode_count) {
+		if (i == count) {
 			// not found, i.e. the key was released
-			key = usbhid_parse_scancode(kbd_dev->keycodes[j]);
+			key = usbhid_parse_scancode(kbd_dev->keys[j]);
+			usbhid_kbd_repeat_stop(kbd_dev, key);
 			usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
 			usb_log_debug2("Key released: %d\n", key);
@@ -364,13 +445,12 @@
 	 * 1) Key presses
 	 */
-	for (i = 0; i < kbd_dev->keycode_count; ++i) {
+	for (i = 0; i < kbd_dev->key_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]) { 
+		while (j < count && kbd_dev->keys[j] != key_codes[i]) { 
 			++j;
 		}
 		
-		if (j == kbd_dev->keycode_count) {
+		if (j == count) {
 			// not found, i.e. new key pressed
 			key = usbhid_parse_scancode(key_codes[i]);
@@ -378,22 +458,14 @@
 			    key_codes[i]);
 			usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
-		} else {
+			usbhid_kbd_repeat_start(kbd_dev, key);
+		} else {size_t
 			// found, nothing happens
 		}
 	}
-//	// report all currently pressed keys
-//	for (i = 0; i < kbd_dev->keycode_count; ++i) {
-//		if (key_codes[i] != 0) {
-//			key = usbhid_parse_scancode(key_codes[i]);
-//			usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
-//			    key_codes[i]);
-//			usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
-//		}
-//	}
-	
-	memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
+	
+	memcpy(kbd_dev->keys, key_codes, count);
 
 	usb_log_debug("New stored keycodes: %s\n", 
-	    usb_debug_str_buffer(kbd_dev->keycodes, kbd_dev->keycode_count, 0));
+	    usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0));
 }
 
@@ -401,5 +473,20 @@
 /* Callbacks for parser                                                       */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Callback function for the HID report parser.
+ *
+ * This function is called by the HID report parser with the parsed report.
+ * The parsed report is used to check if any events occured (key was pressed or
+ * released, modifier was pressed or released).
+ *
+ * @param key_codes Parsed keyboard report - codes of currently pressed keys 
+ *                  according to HID Usage Tables.
+ * @param count Number of key codes in report (size of the report).
+ * @param modifiers Bitmap of modifiers (Ctrl, Alt, Shift, GUI).
+ * @param arg User-specified argument. Expects pointer to the keyboard device
+ *            structure representing the keyboard.
+ *
+ * @sa usbhid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes()
+ */
 static void usbhid_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
     uint8_t modifiers, void *arg)
@@ -415,14 +502,14 @@
 
 	usb_log_debug("Got keys from parser: %s\n", 
-	    usb_debug_str_buffer(key_codes, kbd_dev->keycode_count, 0));
-	
-	if (count != kbd_dev->keycode_count) {
+	    usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
+	
+	if (count != kbd_dev->key_count) {
 		usb_log_warning("Number of received keycodes (%d) differs from"
-		    " expected number (%d).\n", count, kbd_dev->keycode_count);
+		    " expected number (%d).\n", count, kbd_dev->key_count);
 		return;
 	}
 	
 	usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
-	usbhid_kbd_check_key_changes(kbd_dev, key_codes);
+	usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
 }
 
@@ -430,5 +517,19 @@
 /* General kbd functions                                                      */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Processes data received from the device in form of report.
+ *
+ * This function uses the HID report parser to translate the data received from
+ * the device into generic USB HID key codes and into generic modifiers bitmap.
+ * The parser then calls the given callback (usbhid_kbd_process_keycodes()).
+ *
+ * @note Currently, only the boot protocol is supported.
+ *
+ * @param kbd_dev Keyboard device structure (must be initialized).
+ * @param buffer Data from the keyboard (i.e. the report).
+ * @param actual_size Size of the data from keyboard (report size) in bytes.
+ *
+ * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report().
+ */
 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
                                     uint8_t *buffer, size_t actual_size)
@@ -457,5 +558,13 @@
 /* HID/KBD structure manipulation                                             */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Creates a new USB/HID keyboard structure.
+ *
+ * The structure returned by this function is not initialized. Use 
+ * usbhid_kbd_init() to initialize it prior to polling.
+ *
+ * @return New uninitialized structure for representing a USB/HID keyboard or
+ *         NULL if not successful (memory error).
+ */
 static usbhid_kbd_t *usbhid_kbd_new(void)
 {
@@ -483,5 +592,9 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Properly destroys the USB/HID keyboard structure.
+ *
+ * @param kbd_dev Pointer to the structure to be destroyed.
+ */
 static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
 {
@@ -498,4 +611,10 @@
 	}
 	
+	if ((*kbd_dev)->repeat_mtx != NULL) {
+		/* TODO: replace by some check and wait */
+		assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
+		free((*kbd_dev)->repeat_mtx);
+	}
+
 	usb_hid_free_report_parser((*kbd_dev)->parser);
 	
@@ -505,5 +624,24 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Initialization of the USB/HID keyboard structure.
+ *
+ * This functions initializes required structures from the device's descriptors.
+ *
+ * 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.
+ *
+ * @param kbd_dev Keyboard device structure to be initialized.
+ * @param dev DDF device structure of the keyboard.
+ *
+ * @retval EOK if successful.
+ * @retval EINVAL if some parameter is not given.
+ * @return Other value inherited from function usbhid_dev_init().
+ */
 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
 {
@@ -540,11 +678,11 @@
 	
 	// 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) {
+	kbd_dev->key_count = BOOTP_REPORT_SIZE;
+	kbd_dev->keys = (uint8_t *)calloc(
+	    kbd_dev->key_count, sizeof(uint8_t));
+	
+	if (kbd_dev->keys == NULL) {
 		usb_log_fatal("No memory!\n");
-		return rc;
+		return ENOMEM;
 	}
 	
@@ -553,4 +691,19 @@
 	kbd_dev->lock_keys = 0;
 	
+	kbd_dev->repeat.key_new = 0;
+	kbd_dev->repeat.key_repeated = 0;
+	kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
+	kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
+	
+	kbd_dev->repeat_mtx = (fibril_mutex_t *)(
+	    malloc(sizeof(fibril_mutex_t)));
+	if (kbd_dev->repeat_mtx == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(kbd_dev->keys);
+		return ENOMEM;
+	}
+	
+	fibril_mutex_initialize(kbd_dev->repeat_mtx);
+	
 	/*
 	 * Set boot protocol.
@@ -575,5 +728,17 @@
 /* HID/KBD polling                                                            */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * Main keyboard polling function.
+ *
+ * This function uses the Interrupt In pipe of the keyboard to poll for events.
+ * The keyboard is initialized in a way that it reports only when a key is 
+ * pressed or released, so there is no actual need for any sleeping between
+ * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
+ *
+ * @param kbd_dev Initialized keyboard structure representing the device to 
+ *                poll.
+ *
+ * @sa usbhid_kbd_process_data()
+ */
 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
 {
@@ -598,5 +763,5 @@
 			usb_log_warning("Failed to start a session: %s.\n",
 			    str_error(sess_rc));
-			continue;
+			break;
 		}
 
@@ -610,5 +775,5 @@
 			usb_log_warning("Error polling the keyboard: %s.\n",
 			    str_error(rc));
-			continue;
+			break;
 		}
 
@@ -616,5 +781,5 @@
 			usb_log_warning("Error closing session: %s.\n",
 			    str_error(sess_rc));
-			continue;
+			break;
 		}
 
@@ -637,11 +802,24 @@
 		//async_usleep(kbd_dev->hid_dev->poll_interval);
 	}
-
-	// not reached
-	assert(0);
-}
-
-/*----------------------------------------------------------------------------*/
-
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Function executed by the main driver fibril.
+ *
+ * Just starts polling the keyboard for events.
+ * 
+ * @param arg Initialized keyboard device structure (of type usbhid_kbd_t) 
+ *            representing the device.
+ *
+ * @retval EOK if the fibril finished polling the device.
+ * @retval EINVAL if no device was given in the argument.
+ *
+ * @sa usbhid_kbd_poll()
+ *
+ * @todo Change return value - only case when the fibril finishes is in case
+ *       of some error, so the error should probably be propagated from function
+ *       usbhid_kbd_poll() to here and up.
+ */
 static int usbhid_kbd_fibril(void *arg)
 {
@@ -665,5 +843,29 @@
 /* API functions                                                              */
 /*----------------------------------------------------------------------------*/
-
+/**
+ * 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 usbhid_kbd_init(),
+ *         ddf_fun_bind() and ddf_fun_add_to_class().
+ *
+ * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril()
+ */
 int usbhid_kbd_try_add_device(ddf_dev_t *dev)
 {
@@ -687,5 +889,5 @@
 		    "structure.\n");
 		ddf_fun_destroy(kbd_fun);
-		return EINVAL;  // TODO: some other code??
+		return ENOMEM;  // TODO: some other code??
 	}
 	
@@ -736,4 +938,14 @@
 	}
 	fibril_add_ready(fid);
+	
+	/*
+	 * Create new fibril for auto-repeat
+	 */
+	fid = fibril_create(usbhid_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;
Index: uspace/drv/usbhid/kbddev.h
===================================================================
--- uspace/drv/usbhid/kbddev.h	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/kbddev.h	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -39,4 +39,6 @@
 #include <stdint.h>
 
+#include <fibril_synch.h>
+
 #include <usb/classes/hid.h>
 #include <usb/classes/hidparser.h>
@@ -47,22 +49,59 @@
 
 /*----------------------------------------------------------------------------*/
+/**
+ * Structure for keeping information needed for auto-repeat of keys.
+ */
+typedef struct {
+	/** Last pressed key. */
+	unsigned int key_new;
+	/** Key to be repeated. */
+	unsigned int key_repeated;
+	/** Delay before first repeat in microseconds. */
+	unsigned int delay_before;
+	/** Delay between repeats in microseconds. */
+	unsigned int delay_between;
+} usbhid_kbd_repeat_t;
 
 /**
- * @brief USB/HID keyboard device type.
+ * USB/HID keyboard device type.
+ *
+ * Holds a reference to generic USB/HID device structure and keyboard-specific
+ * data, such as currently pressed keys, modifiers and lock keys.
+ *
+ * Also holds a IPC phone to the console (since there is now no other way to 
+ * communicate with it).
+ *
+ * @note Storing active lock keys in this structure results in their setting
+ *       being device-specific.
  */
 typedef struct {
+	/** Structure holding generic USB/HID device information. */
 	usbhid_dev_t *hid_dev;
 	
-	uint8_t *keycodes;
-	size_t keycode_count;
+	/** Currently pressed keys (not translated to key codes). */
+	uint8_t *keys;
+	/** Count of stored keys (i.e. number of keys in the report). */
+	size_t key_count;
+	/** Currently pressed modifiers (bitmap). */
 	uint8_t modifiers;
 	
+	/** Currently active modifiers including locks. Sent to the console. */
 	unsigned mods;
+	
+	/** Currently active lock keys. */
 	unsigned lock_keys;
 	
+	/** IPC phone to the console device (for sending key events). */
 	int console_phone;
 	
+	/** Information for auto-repeat of keys. */
+	usbhid_kbd_repeat_t repeat;
+	
+	/** Mutex for accessing the information about auto-repeat. */
+	fibril_mutex_t *repeat_mtx;
+
 	usb_hid_report_parser_t *parser;
 	
+	/** State of the structure (for checking before use). */
 	int initialized;
 } usbhid_kbd_t;
@@ -72,4 +111,6 @@
 int usbhid_kbd_try_add_device(ddf_dev_t *dev);
 
+void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);
+
 #endif /* USBHID_KBDDEV_H_ */
 
Index: uspace/drv/usbhid/kbdrepeat.c
===================================================================
--- uspace/drv/usbhid/kbdrepeat.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
+++ uspace/drv/usbhid/kbdrepeat.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -0,0 +1,176 @@
+/*
+ * 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
+ * USB HID keyboard autorepeat facilities
+ */
+
+#include <fibril_synch.h>
+#include <io/keycode.h>
+#include <io/console.h>
+#include <errno.h>
+
+#include <usb/debug.h>
+
+#include "kbdrepeat.h"
+#include "kbddev.h"
+
+
+/** Delay between auto-repeat state checks when no key is being repeated. */
+static unsigned int CHECK_DELAY = 10000;
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Main loop handling the auto-repeat of keys.
+ *
+ * This functions periodically checks if there is some key to be auto-repeated.
+ *
+ * If a new key is to be repeated, it uses the delay before first repeat stored
+ * in the keyboard structure to wait until the key has to start repeating.
+ *
+ * If the same key is still pressed, it uses the delay between repeats stored
+ * in the keyboard structure to wait until the key should be repeated.
+ * 
+ * If the currently repeated key is not pressed any more (
+ * usbhid_kbd_repeat_stop() was called), it stops repeating it and starts 
+ * checking again.
+ *
+ * @note For accessing the keyboard device auto-repeat information a fibril
+ *       mutex (repeat_mtx) from the @a kbd structure is used.
+ * 
+ * @param kbd Keyboard device structure.
+ */
+static void usbhid_kbd_repeat_loop(usbhid_kbd_t *kbd)
+{
+	unsigned int delay = 0;
+	
+	usb_log_debug("Starting autorepeat loop.\n");
+
+	while (true) {
+		fibril_mutex_lock(kbd->repeat_mtx);
+
+		if (kbd->repeat.key_new > 0) {
+			if (kbd->repeat.key_new == kbd->repeat.key_repeated) {
+				usb_log_debug2("Repeating key: %u.\n", 
+				    kbd->repeat.key_repeated);
+				usbhid_kbd_push_ev(kbd, KEY_PRESS, 
+				    kbd->repeat.key_repeated);
+				delay = kbd->repeat.delay_between;
+			} else {
+				usb_log_debug("New key to repeat: %u.\n", 
+				    kbd->repeat.key_new);
+				kbd->repeat.key_repeated = kbd->repeat.key_new;
+				delay = kbd->repeat.delay_before;
+			}
+		} else {
+			if (kbd->repeat.key_repeated > 0) {
+				usb_log_debug("Stopping to repeat key: %u.\n", 
+				    kbd->repeat.key_repeated);
+				kbd->repeat.key_repeated = 0;
+			}
+			delay = CHECK_DELAY;
+		}
+		fibril_mutex_unlock(kbd->repeat_mtx);
+		
+		async_usleep(delay);
+	}
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Main routine to be executed by a fibril for handling auto-repeat.
+ *
+ * Starts the loop for checking changes in auto-repeat.
+ * 
+ * @param arg User-specified argument. Expects pointer to the keyboard device
+ *            structure representing the keyboard.
+ *
+ * @retval EOK if the routine has finished.
+ * @retval EINVAL if no argument is supplied.
+ */
+int usbhid_kbd_repeat_fibril(void *arg)
+{
+	usb_log_debug("Autorepeat fibril spawned.\n");
+	
+	if (arg == NULL) {
+		usb_log_error("No device!\n");
+		return EINVAL;
+	}
+	
+	usbhid_kbd_t *kbd = (usbhid_kbd_t *)arg;
+	
+	usbhid_kbd_repeat_loop(kbd);
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Start repeating particular key.
+ *
+ * @note Only one key is repeated at any time, so calling this function 
+ *       effectively cancels auto-repeat of the current repeated key (if any)
+ *       and 'schedules' another key for auto-repeat.
+ *
+ * @param kbd Keyboard device structure.
+ * @param key Key to start repeating.
+ */
+void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key)
+{
+	fibril_mutex_lock(kbd->repeat_mtx);
+	kbd->repeat.key_new = key;
+	fibril_mutex_unlock(kbd->repeat_mtx);
+}
+
+/*----------------------------------------------------------------------------*/
+/**
+ * Stop repeating particular key.
+ *
+ * @note Only one key is repeated at any time, but this function may be called
+ *       even with key that is not currently repeated (in that case nothing 
+ *       happens).
+ *
+ * @param kbd Keyboard device structure.
+ * @param key Key to stop repeating.
+ */
+void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key)
+{
+	fibril_mutex_lock(kbd->repeat_mtx);
+	if (key == kbd->repeat.key_new) {
+		kbd->repeat.key_new = 0;
+	}
+	fibril_mutex_unlock(kbd->repeat_mtx);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/usbhid/kbdrepeat.h
===================================================================
--- uspace/drv/usbhid/kbdrepeat.h	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
+++ uspace/drv/usbhid/kbdrepeat.h	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -0,0 +1,53 @@
+/*
+ * 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
+ * USB HID keyboard autorepeat facilities
+ */
+
+#ifndef USBHID_KBDREPEAT_H_
+#define USBHID_KBDREPEAT_H_
+
+#include "kbddev.h"
+
+/*----------------------------------------------------------------------------*/
+
+int usbhid_kbd_repeat_fibril(void *arg);
+
+void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key);
+
+void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key);
+
+#endif /* USBHID_KBDREPEAT_H_ */
+
+/**
+ * @}
+ */
Index: uspace/drv/usbhid/main.c
===================================================================
--- uspace/drv/usbhid/main.c	(revision 7351dc3dbe011ce085a1813b4acde57432b7fc0e)
+++ uspace/drv/usbhid/main.c	(revision e69f10b2b660db6ce1d165fda954a13cef74709f)
@@ -47,5 +47,14 @@
 
 /*----------------------------------------------------------------------------*/
-
+/**
+ * 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 usbhid_add_device(ddf_dev_t *dev)
 {
