Index: uspace/app/virtusbkbd/Makefile
===================================================================
--- uspace/app/virtusbkbd/Makefile	(revision 03171de3c5da5094495087ad838f0b49c4ec6188)
+++ uspace/app/virtusbkbd/Makefile	(revision 2e15ac408aa6d5ce089d57231c2eda5fe5db57d0)
@@ -33,5 +33,5 @@
 
 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a
-EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX)
+EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include
 
 SOURCES = \
Index: uspace/drv/usbkbd/main.c
===================================================================
--- uspace/drv/usbkbd/main.c	(revision 03171de3c5da5094495087ad838f0b49c4ec6188)
+++ uspace/drv/usbkbd/main.c	(revision 2e15ac408aa6d5ce089d57231c2eda5fe5db57d0)
@@ -28,10 +28,47 @@
 #include <usb/usbdrv.h>
 #include <driver.h>
+#include <ipc/driver.h>
 #include <errno.h>
+#include <fibril.h>
+#include <usb/classes/hid.h>
 
 #define BUFFER_SIZE 32
+#define NAME "usbkbd"
+
+static const usb_endpoint_t CONTROL_EP = 0;
+
+static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
+{
+	usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)malloc(
+			sizeof(usb_hid_dev_kbd_t));
+
+	if (kbd_dev == NULL) {
+		fprintf(stderr, NAME ": No memory!\n");
+		return NULL;
+	}
+
+	kbd_dev->device = dev;
+
+	kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
+	    dev);
+
+	if (kbd_dev->address < 0) {
+		fprintf(stderr, NAME ": No device address!\n");
+		free(kbd_dev);
+		return NULL;
+	}
+
+	// default endpoint
+	kbd_dev->default_ep = CONTROL_EP;
+
+	// TODO: get descriptors
+
+	// TODO: parse descriptors and save endpoints
+
+	return kbd_dev;
+}
 
 /* Call this periodically to check keyboard status changes. */
-static void poll_keyboard(device_t *dev)
+static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
 {
 	int rc;
@@ -39,19 +76,20 @@
 	char buffer[BUFFER_SIZE];
 	size_t actual_size;
-	usb_endpoint_t poll_endpoint = 1;
+	//usb_endpoint_t poll_endpoint = 1;
 
-	usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
-	    dev);
-	if (my_address < 0) {
-		return;
-	}
+//	usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
+//	    dev);
+//	if (my_address < 0) {
+//		return;
+//	}
 
 	usb_target_t poll_target = {
-		.address = my_address,
-		.endpoint = poll_endpoint
+		.address = kbd_dev->address,
+		.endpoint = kbd_dev->default_ep
 	};
 
-	rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target,
-	    buffer, BUFFER_SIZE, &actual_size, &handle);
+	rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
+	    poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
+
 	if (rc != EOK) {
 		return;
@@ -72,9 +110,28 @@
 
 	/*
-	 * Process pressed keys.
+	 * TODO: Process pressed keys.
 	 */
 }
 
-static int add_kbd_device(device_t *dev)
+static int usbkbd_fibril_device(void *arg)
+{
+	printf("!!! USB device fibril\n");
+
+	if (arg == NULL) {
+		printf("No device!\n");
+		return -1;
+	}
+
+	device_t *dev = (device_t *)arg;
+
+	// initialize device (get and process descriptors, get address, etc.)
+	usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
+
+	usbkbd_poll_keyboard(kbd_dev);
+
+	return EOK;
+}
+
+static int usbkbd_add_device(device_t *dev)
 {
 	/* For now, fail immediately. */
@@ -83,20 +140,27 @@
 	/*
 	 * When everything is okay, connect to "our" HC.
+	 *
+	 * Not supported yet, skip..
 	 */
-	int phone = usb_drv_hc_connect(dev, 0);
-	if (phone < 0) {
-		/*
-		 * Connecting to HC failed, roll-back and announce
-		 * failure.
-		 */
-		return phone;
-	}
+//	int phone = usb_drv_hc_connect(dev, 0);
+//	if (phone < 0) {
+//		/*
+//		 * Connecting to HC failed, roll-back and announce
+//		 * failure.
+//		 */
+//		return phone;
+//	}
 
-	dev->parent_phone = phone;
+//	dev->parent_phone = phone;
 
 	/*
-	 * Just for fun ;-).
+	 * Create new fibril for handling this keyboard
 	 */
-	poll_keyboard(dev);
+	fid_t fid = fibril_create(usbkbd_fibril_device, dev);
+	if (fid == 0) {
+		printf("%s: failed to start fibril for HID device\n", NAME);
+		return ENOMEM;
+	}
+	fibril_add_ready(fid);
 
 	/*
@@ -107,9 +171,9 @@
 
 static driver_ops_t kbd_driver_ops = {
-	.add_device = add_kbd_device,
+	.add_device = usbkbd_add_device,
 };
 
 static driver_t kbd_driver = {
-	.name = "usbkbd",
+	.name = NAME,
 	.driver_ops = &kbd_driver_ops
 };
Index: uspace/lib/usb/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid.h	(revision 03171de3c5da5094495087ad838f0b49c4ec6188)
+++ uspace/lib/usb/include/usb/classes/hid.h	(revision 2e15ac408aa6d5ce089d57231c2eda5fe5db57d0)
@@ -36,4 +36,7 @@
 #define LIBUSB_HID_H_
 
+#include <usb/usb.h>
+#include <driver.h>
+
 /** USB/HID device requests. */
 typedef enum {
@@ -54,4 +57,15 @@
 } usb_hid_protocol_t;
 
+/**
+ * @brief USB/HID keyboard device type.
+ *
+ * Quite dummy right now.
+ */
+typedef struct {
+	device_t *device;
+	usb_address_t address;
+	usb_endpoint_t default_ep;
+} usb_hid_dev_kbd_t;
+
 #endif
 /**
