Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -766,4 +766,49 @@
 
 /*----------------------------------------------------------------------------*/
+
+static int usb_kbd_create_function(usb_hid_dev_t *hid_dev)
+{
+	assert(hid_dev != NULL);
+	assert(hid_dev->usb_dev != NULL);
+	
+	/* Create the function exposed under /dev/devices. */
+	usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
+	ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
+	    HID_KBD_FUN_NAME);
+	if (fun == NULL) {
+		usb_log_error("Could not create DDF function node.\n");
+		return ENOMEM;
+	}
+	
+	/*
+	 * Store the initialized HID device and HID ops
+	 * to the DDF function.
+	 */
+	fun->ops = &hid_dev->ops;
+	fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
+
+	int rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		usb_log_error("Could not bind DDF function: %s.\n",
+		    str_error(rc));
+		ddf_fun_destroy(fun);
+		return rc;
+	}
+	
+	usb_log_debug("Adding DDF function to class %s...\n", 
+	    HID_KBD_CLASS_NAME);
+	rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME);
+	if (rc != EOK) {
+		usb_log_error(
+		    "Could not add DDF function to class %s: %s.\n",
+		    HID_KBD_CLASS_NAME, str_error(rc));
+		ddf_fun_destroy(fun);
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
 /* API functions                                                              */
 /*----------------------------------------------------------------------------*/
@@ -930,4 +975,11 @@
 	usb_log_debug("HID/KBD device structure initialized.\n");
 	
+	usb_log_debug("Creating KBD function...\n");
+	int rc = usb_kbd_create_function(hid_dev);
+	if (rc != EOK) {
+		usb_kbd_free(&kbd_dev);
+		return rc;
+	}
+	
 	return EOK;
 }
Index: uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
===================================================================
--- uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -58,4 +58,34 @@
 } usb_lgtch_flags;
 
+/*----------------------------------------------------------------------------*/
+/**
+ * Logitech UltraX device type.
+ */
+typedef struct usb_lgtch_ultrax_t {
+	/** Previously pressed keys (not translated to key codes). */
+	int32_t *keys_old;
+	/** Currently pressed keys (not translated to key codes). */
+	int32_t *keys;
+	/** Count of stored keys (i.e. number of keys in the report). */
+	size_t key_count;
+	
+	/** IPC phone to the console device (for sending key events). */
+	int console_phone;
+
+	/** Information for auto-repeat of keys. */
+//	usb_kbd_repeat_t repeat;
+	
+	/** Mutex for accessing the information about auto-repeat. */
+//	fibril_mutex_t *repeat_mtx;
+
+	/** State of the structure (for checking before use). 
+	 * 
+	 * 0 - not initialized
+	 * 1 - initialized
+	 * -1 - ready for destroying
+	 */
+	int initialized;
+} usb_lgtch_ultrax_t;
+
 
 /*----------------------------------------------------------------------------*/
@@ -208,57 +238,6 @@
 /*----------------------------------------------------------------------------*/
 
-int usb_lgtch_init(struct usb_hid_dev *hid_dev)
-{
-	if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
-		return EINVAL; /*! @todo Other return code? */
-	}
-	
-	usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
-	
-	usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
-	    sizeof(usb_lgtch_ultrax_t));
-	if (lgtch_dev == NULL) {
-		return ENOMEM;
-	}
-	
-	lgtch_dev->console_phone = -1;
-	
-	usb_hid_report_path_t *path = usb_hid_report_path();
-	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
-	
-	usb_hid_report_path_set_report_id(path, 1);
-	
-	lgtch_dev->key_count = usb_hid_report_input_length(
-	    hid_dev->report, path, 
-	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
-	usb_hid_report_path_free(path);
-	
-	usb_log_debug(NAME " Size of the input report: %zu\n", 
-	    lgtch_dev->key_count);
-	
-	lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count, 
-	    sizeof(int32_t));
-	
-	if (lgtch_dev->keys == NULL) {
-		usb_log_fatal("No memory!\n");
-		free(lgtch_dev);
-		return ENOMEM;
-	}
-	
-	lgtch_dev->keys_old = 
-		(int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
-	
-	if (lgtch_dev->keys_old == NULL) {
-		usb_log_fatal("No memory!\n");
-		free(lgtch_dev->keys);
-		free(lgtch_dev);
-		return ENOMEM;
-	}
-	
-	/*! @todo Autorepeat */
-	
-	// save the KBD device structure into the HID device structure
-	hid_dev->data = lgtch_dev;
-	
+static int usb_lgtch_create_function(usb_hid_dev_t *hid_dev)
+{
 	/* Create the function exposed under /dev/devices. */
 	ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
@@ -269,7 +248,4 @@
 	}
 	
-	lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
-	usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
-	
 	/*
 	 * Store the initialized HID device and HID ops
@@ -279,15 +255,4 @@
 	fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
 	
-	/*
-	 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
-	 *    do nej.
-	 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 
-	 *    vyplnenu strukturu usbhid_iface_t.
-	 * 3) klientska aplikacia - musi si rucne vytvorit telefon
-	 *    (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 
-	 *    k tej fcii.
-	 *    pouzit usb/classes/hid/iface.h - prvy int je telefon
-	 */
-
 	int rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
@@ -296,5 +261,4 @@
 		// TODO: Can / should I destroy the DDF function?
 		ddf_fun_destroy(fun);
-		usb_lgtch_free(&lgtch_dev);
 		return rc;
 	}
@@ -307,4 +271,70 @@
 		// TODO: Can / should I destroy the DDF function?
 		ddf_fun_destroy(fun);
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
+int usb_lgtch_init(struct usb_hid_dev *hid_dev)
+{
+	if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
+		return EINVAL; /*! @todo Other return code? */
+	}
+	
+	usb_log_debug(NAME " Initializing HID/lgtch_ultrax structure...\n");
+	
+	usb_lgtch_ultrax_t *lgtch_dev = (usb_lgtch_ultrax_t *)malloc(
+	    sizeof(usb_lgtch_ultrax_t));
+	if (lgtch_dev == NULL) {
+		return ENOMEM;
+	}
+	
+	lgtch_dev->console_phone = -1;
+	
+	usb_hid_report_path_t *path = usb_hid_report_path();
+	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
+	
+	usb_hid_report_path_set_report_id(path, 1);
+	
+	lgtch_dev->key_count = usb_hid_report_input_length(
+	    hid_dev->report, path, 
+	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
+	usb_hid_report_path_free(path);
+	
+	usb_log_debug(NAME " Size of the input report: %zu\n", 
+	    lgtch_dev->key_count);
+	
+	lgtch_dev->keys = (int32_t *)calloc(lgtch_dev->key_count, 
+	    sizeof(int32_t));
+	
+	if (lgtch_dev->keys == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(lgtch_dev);
+		return ENOMEM;
+	}
+	
+	lgtch_dev->keys_old = 
+		(int32_t *)calloc(lgtch_dev->key_count, sizeof(int32_t));
+	
+	if (lgtch_dev->keys_old == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(lgtch_dev->keys);
+		free(lgtch_dev);
+		return ENOMEM;
+	}
+	
+	/*! @todo Autorepeat */
+	
+	// save the KBD device structure into the HID device structure
+	hid_dev->data = lgtch_dev;
+	
+	lgtch_dev->initialized = USB_LGTCH_STATUS_INITIALIZED;
+	usb_log_debug(NAME " HID/lgtch_ultrax device structure initialized.\n");
+	
+	int rc = usb_lgtch_create_function(hid_dev);
+	if (rc != EOK) {
 		usb_lgtch_free(&lgtch_dev);
 		return rc;
Index: uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h
===================================================================
--- uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.h	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -42,43 +42,4 @@
 
 /*----------------------------------------------------------------------------*/
-/**
- * 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 usb_lgtch_ultrax_t {
-	/** Previously pressed keys (not translated to key codes). */
-	int32_t *keys_old;
-	/** Currently pressed keys (not translated to key codes). */
-	int32_t *keys;
-	/** Count of stored keys (i.e. number of keys in the report). */
-	size_t key_count;
-	
-	/** IPC phone to the console device (for sending key events). */
-	int console_phone;
-
-	/** Information for auto-repeat of keys. */
-//	usb_kbd_repeat_t repeat;
-	
-	/** Mutex for accessing the information about auto-repeat. */
-//	fibril_mutex_t *repeat_mtx;
-
-	/** State of the structure (for checking before use). 
-	 * 
-	 * 0 - not initialized
-	 * 1 - initialized
-	 * -1 - ready for destroying
-	 */
-	int initialized;
-} usb_lgtch_ultrax_t;
-
-/*----------------------------------------------------------------------------*/
 
 int usb_lgtch_init(struct usb_hid_dev *hid_dev);
Index: uspace/drv/usbhid/main.c
===================================================================
--- uspace/drv/usbhid/main.c	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/main.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -99,20 +99,4 @@
 	usb_log_debug("USB/HID device structure initialized.\n");
 	
-	/* Create the function exposed under /dev/devices. */
-	ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 
-	    usb_hid_get_function_name(hid_dev));
-	if (hid_fun == NULL) {
-		usb_log_error("Could not create DDF function node.\n");
-		usb_hid_free(&hid_dev);
-		return ENOMEM;
-	}
-	
-	/*
-	 * Store the initialized HID device and HID ops
-	 * to the DDF function.
-	 */
-	hid_fun->ops = &hid_dev->ops;
-	hid_fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
-	
 	/*
 	 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
@@ -125,25 +109,4 @@
 	 *    pouzit usb/classes/hid/iface.h - prvy int je telefon
 	 */
-
-	rc = ddf_fun_bind(hid_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(hid_fun);
-		usb_hid_free(&hid_dev);
-		return rc;
-	}
-	
-	rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev));
-	if (rc != EOK) {
-		usb_log_error(
-		    "Could not add DDF function to class 'hid': %s.\n",
-		    str_error(rc));
-		// TODO: Can / should I destroy the DDF function?
-		ddf_fun_destroy(hid_fun);
-		usb_hid_free(&hid_dev);
-		return rc;
-	}
 	
 	/* Start automated polling function.
Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -300,4 +300,46 @@
 /*----------------------------------------------------------------------------*/
 
+static int usb_mouse_create_function(usb_hid_dev_t *hid_dev)
+{
+	/* Create the function exposed under /dev/devices. */
+	usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
+	ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
+	    HID_MOUSE_FUN_NAME);
+	if (fun == NULL) {
+		usb_log_error("Could not create DDF function node.\n");
+		return ENOMEM;
+	}
+	
+	/*
+	 * Store the initialized HID device and HID ops
+	 * to the DDF function.
+	 */
+	fun->ops = &hid_dev->ops;
+	fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
+
+	int rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		usb_log_error("Could not bind DDF function: %s.\n",
+		    str_error(rc));
+		ddf_fun_destroy(fun);
+		return rc;
+	}
+	
+	usb_log_debug("Adding DDF function to class %s...\n", 
+	    HID_MOUSE_CLASS_NAME);
+	rc = ddf_fun_add_to_class(fun, HID_MOUSE_CLASS_NAME);
+	if (rc != EOK) {
+		usb_log_error(
+		    "Could not add DDF function to class %s: %s.\n",
+		    HID_MOUSE_CLASS_NAME, str_error(rc));
+		ddf_fun_destroy(fun);
+		return rc;
+	}
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
 int usb_mouse_init(usb_hid_dev_t *hid_dev)
 {
@@ -317,16 +359,4 @@
 	}
 	
-//	usb_hid_report_path_t *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, 0);
-	
-//	mouse_dev->button_count = usb_hid_report_input_length(
-//	    hid_dev->report, path, 
-//	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
-//	usb_hid_report_path_free(path);
-	
-//	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
-	
 	mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT, 
 	    sizeof(int32_t));
@@ -348,4 +378,10 @@
 //	    hid_dev->usb_dev->interface_no, IDLE_RATE);
 	
+	int rc = usb_mouse_create_function(hid_dev);
+	if (rc != EOK) {
+		usb_mouse_free(&mouse_dev);
+		return rc;
+	}
+	
 	return EOK;
 }
Index: uspace/drv/usbhid/usbhid.c
===================================================================
--- uspace/drv/usbhid/usbhid.c	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/usbhid.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -490,4 +490,30 @@
 	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);
+			}
+		}
+	}
+	
+	/*! @todo This should probably be atomic. */
+	memcpy(hid_dev->input_report, buffer, buffer_size);
+	hid_dev->input_report_size = buffer_size;
+	
 	bool cont = false;
 	
@@ -528,36 +554,36 @@
 /*----------------------------------------------------------------------------*/
 
-const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
-{
-	switch (hid_dev->poll_pipe_index) {
-	case USB_HID_KBD_POLL_EP_NO:
-		return HID_KBD_FUN_NAME;
-		break;
-	case USB_HID_MOUSE_POLL_EP_NO:
-		return HID_MOUSE_FUN_NAME;
-		break;
-	default:
-		return HID_GENERIC_FUN_NAME;
-	}
-}
-
-/*----------------------------------------------------------------------------*/
-
-const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
-{
-	// this means that only boot protocol keyboards will be connected
-	// to the console; there is probably no better way to do this
-	
-	switch (hid_dev->poll_pipe_index) {
-	case USB_HID_KBD_POLL_EP_NO:
-		return HID_KBD_CLASS_NAME;
-		break;
-	case USB_HID_MOUSE_POLL_EP_NO:
-		return HID_MOUSE_CLASS_NAME;
-		break;
-	default:
-		return HID_GENERIC_CLASS_NAME;
-	}
-}
+//const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev)
+//{
+//	switch (hid_dev->poll_pipe_index) {
+//	case USB_HID_KBD_POLL_EP_NO:
+//		return HID_KBD_FUN_NAME;
+//		break;
+//	case USB_HID_MOUSE_POLL_EP_NO:
+//		return HID_MOUSE_FUN_NAME;
+//		break;
+//	default:
+//		return HID_GENERIC_FUN_NAME;
+//	}
+//}
+
+/*----------------------------------------------------------------------------*/
+
+//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev)
+//{
+//	// this means that only boot protocol keyboards will be connected
+//	// to the console; there is probably no better way to do this
+	
+//	switch (hid_dev->poll_pipe_index) {
+//	case USB_HID_KBD_POLL_EP_NO:
+//		return HID_KBD_CLASS_NAME;
+//		break;
+//	case USB_HID_MOUSE_POLL_EP_NO:
+//		return HID_MOUSE_CLASS_NAME;
+//		break;
+//	default:
+//		return HID_GENERIC_CLASS_NAME;
+//	}
+//}
 
 /*----------------------------------------------------------------------------*/
Index: uspace/drv/usbhid/usbhid.h
===================================================================
--- uspace/drv/usbhid/usbhid.h	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
+++ uspace/drv/usbhid/usbhid.h	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
@@ -93,4 +93,8 @@
 	usb_hid_report_t *report;
 	
+	uint8_t *input_report;
+	
+	size_t input_report_size;
+	
 	/** Arbitrary data (e.g. a special structure for handling keyboard). */
 	void *data;
@@ -120,7 +124,7 @@
      void *arg);
 
-const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
+//const char *usb_hid_get_function_name(const usb_hid_dev_t *hid_dev);
 
-const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
+//const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev);
 
 void usb_hid_free(usb_hid_dev_t **hid_dev);
