Index: uspace/drv/usbhid/generic/hiddev.c
===================================================================
--- uspace/drv/usbhid/generic/hiddev.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
+++ uspace/drv/usbhid/generic/hiddev.c	(revision 3facf63aa9f232dd359035931c7ad2b9a4934e03)
@@ -37,4 +37,8 @@
 #include <usb/debug.h>
 #include <usb/classes/classes.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usbhid_iface.h>
 
 #include "hiddev.h"
@@ -55,4 +59,99 @@
 /*----------------------------------------------------------------------------*/
 
+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, 
+    size_t size, size_t *act_size, unsigned int flags);
+
+/*----------------------------------------------------------------------------*/
+
+static usbhid_iface_t usb_generic_iface = {
+	.get_event = usb_generic_hid_get_event,
+	.get_event_length = usb_generic_hid_get_event_length
+};
+
+static ddf_dev_ops_t usb_generic_hid_ops = {
+	.interfaces[USBHID_DEV_IFACE] = &usb_generic_iface
+};
+
+/*----------------------------------------------------------------------------*/
+
+static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun)
+{
+	if (fun == NULL || fun->driver_data) {
+		return 0;
+	}
+
+	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, 
+    size_t size, size_t *act_size, unsigned int flags)
+{
+	if (fun == NULL || fun->driver_data) {
+		return EINVAL;
+	}
+
+	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
+	
+	if (hid_dev->input_report_size > size) {
+		return EINVAL;	// TODO: other error code
+	}
+	
+	/*! @todo This should probably be atomic. */
+	memcpy(buffer, hid_dev->input_report, hid_dev->input_report_size);
+	*act_size = hid_dev->input_report_size;
+	
+	// clear the buffer so that it will not be received twice
+	memset(hid_dev->input_report, 0, hid_dev->input_report_size);
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev)
+{	
+	/* Create the function exposed under /dev/devices. */
+	/** @todo Generate numbers for the devices? */
+	usb_log_debug("Creating DDF function %s...\n", HID_GENERIC_FUN_NAME);
+	ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
+	    HID_GENERIC_FUN_NAME);
+	if (fun == NULL) {
+		usb_log_error("Could not create DDF function node.\n");
+		return ENOMEM;
+	}
+
+	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;
+	}
+	
+	fun->ops = &usb_generic_hid_ops;
+	fun->driver_data = hid_dev;
+	
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+
+int usb_generic_hid_init(usb_hid_dev_t *hid_dev)
+{
+	if (hid_dev == NULL) {
+		return EINVAL;
+	}
+	
+	return usb_generic_hid_create_function(hid_dev);
+}
+
+/*----------------------------------------------------------------------------*/
+
 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, 
     uint8_t *buffer, size_t buffer_size)
Index: uspace/drv/usbhid/generic/hiddev.h
===================================================================
--- uspace/drv/usbhid/generic/hiddev.h	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
+++ uspace/drv/usbhid/generic/hiddev.h	(revision 3facf63aa9f232dd359035931c7ad2b9a4934e03)
@@ -46,4 +46,8 @@
 const char *HID_GENERIC_CLASS_NAME;
 
+/*----------------------------------------------------------------------------*/
+
+int usb_generic_hid_init(struct usb_hid_dev *hid_dev);
+
 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev,
     uint8_t *buffer, size_t buffer_size);
Index: uspace/drv/usbhid/usbhid.c
===================================================================
--- uspace/drv/usbhid/usbhid.c	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
+++ uspace/drv/usbhid/usbhid.c	(revision 3facf63aa9f232dd359035931c7ad2b9a4934e03)
@@ -136,5 +136,5 @@
 	
 	// set the init callback
-	hid_dev->subdrivers[0].init = NULL;
+	hid_dev->subdrivers[0].init = usb_generic_hid_init;
 	
 	// set the polling callback
Index: uspace/lib/drv/include/usbhid_iface.h
===================================================================
--- uspace/lib/drv/include/usbhid_iface.h	(revision 31cfee165e90948c9feaa73ec35b98d483ff01ca)
+++ uspace/lib/drv/include/usbhid_iface.h	(revision 3facf63aa9f232dd359035931c7ad2b9a4934e03)
@@ -72,24 +72,21 @@
 /** USB HID device communication interface. */
 typedef struct {
-	/** Get number of items in the event.
+	/** Get size of the event in bytes.
 	 *
 	 * @param[in] fun DDF function answering the request.
 	 * @return Number of events or error code.
 	 */
-	int (*get_event_length)(ddf_fun_t *fun);
+	size_t (*get_event_length)(ddf_fun_t *fun);
 
 	/** Get single event from the HID device.
 	 *
 	 * @param[in] fun DDF function answering the request.
-	 * @param[out] usage_page Array of usage pages and usages.
-	 * @param[out] usage Array of data (1:1 with @p usage).
-	 * @param[in] size Size of @p usage and @p data arrays.
+	 * @param[out] buffer Buffer with raw data from the device.
 	 * @param[out] act_size Actual number of returned events.
 	 * @param[in] flags Flags (see USBHID_IFACE_FLAG_*).
 	 * @return Error code.
 	 */
-	int (*get_event)(ddf_fun_t *fun,
-	    uint16_t *usage_page, uint16_t *usage, size_t size, size_t *act_size,
-	    unsigned int flags);
+	int (*get_event)(ddf_fun_t *fun, int32_t *buffer, size_t size,
+	    size_t *act_size, unsigned int flags);
 } usbhid_iface_t;
 
