Index: uspace/drv/usbhid/generic/hiddev.c
===================================================================
--- uspace/drv/usbhid/generic/hiddev.c	(revision ba358ed1a4aba4117ec596f5a482ee72d3380d6f)
+++ 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 ba358ed1a4aba4117ec596f5a482ee72d3380d6f)
+++ 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);
