Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ kernel/generic/include/ipc/ipc.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -43,6 +43,10 @@
 #define IPC_CALL_LEN  6
 
-/** Maximum active async calls per phone */
-#define IPC_MAX_ASYNC_CALLS  4
+/** Maximum active async calls per thread */
+#ifdef CONFIG_DEBUG
+	#define IPC_MAX_ASYNC_CALLS  16
+#else
+	#define IPC_MAX_ASYNC_CALLS  4000
+#endif
 
 /* Flags for calls */
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ kernel/generic/include/proc/task.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -93,4 +93,9 @@
 	phone_t phones[IPC_MAX_PHONES];
 	stats_ipc_t ipc_info;   /**< IPC statistics */
+	/**
+	 * Active asynchronous messages. It is used for limiting uspace to
+	 * certain extent.
+	 */
+	atomic_t active_calls;
 	/** List of synchronous answerboxes. */
 	link_t sync_box_head;
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ kernel/generic/src/ipc/ipc.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -655,4 +655,12 @@
 		    (call->flags & IPC_CALL_NOTIF));
 		
+		/*
+		 * Record the receipt of this call in the current task's counter
+		 * of active calls. IPC_M_PHONE_HUNGUP calls do not contribute
+		 * to this counter so do not record answers to them either.
+		 */
+		if (!(call->flags & IPC_CALL_DISCARD_ANSWER))
+			atomic_dec(&TASK->active_calls);
+		
 		ipc_call_free(call);
 	}
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ kernel/generic/src/ipc/sysipc.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -644,15 +644,15 @@
 }
 
-/** Check that the task did not exceed the allowed limit of asynchronous calls
- * made over a phone.
- *
- * @param phone Phone to check the limit against. 
+/** Check that the task did not exceed the allowed limit of asynchronous calls.
+ *
  * @return 0 if limit not reached or -1 if limit exceeded.
  *
  */
-static int check_call_limit(phone_t *phone)
-{
-	if (atomic_get(&phone->active_calls) >= IPC_MAX_ASYNC_CALLS)
+static int check_call_limit(void)
+{
+	if (atomic_preinc(&TASK->active_calls) > IPC_MAX_ASYNC_CALLS) {
+		atomic_dec(&TASK->active_calls);
 		return -1;
+	}
 	
 	return 0;
@@ -680,10 +680,10 @@
     unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4)
 {
+	if (check_call_limit())
+		return IPC_CALLRET_TEMPORARY;
+	
 	phone_t *phone;
 	if (phone_get(phoneid, &phone) != EOK)
 		return IPC_CALLRET_FATAL;
-
-	if (check_call_limit(phone))
-		return IPC_CALLRET_TEMPORARY;
 	
 	call_t *call = ipc_call_alloc(0);
@@ -720,10 +720,10 @@
 unative_t sys_ipc_call_async_slow(unative_t phoneid, ipc_data_t *data)
 {
+	if (check_call_limit())
+		return IPC_CALLRET_TEMPORARY;
+	
 	phone_t *phone;
 	if (phone_get(phoneid, &phone) != EOK)
 		return IPC_CALLRET_FATAL;
-
-	if (check_call_limit(phone))
-		return IPC_CALLRET_TEMPORARY;
 
 	call_t *call = ipc_call_alloc(0);
@@ -1046,4 +1046,11 @@
 			ipc_call_free(call);
 			goto restart;
+		} else {
+			/*
+			 * Decrement the counter of active calls only if the
+			 * call is not an answer to IPC_M_PHONE_HUNGUP,
+			 * which doesn't contribute to the counter.
+			 */
+			atomic_dec(&TASK->active_calls);
 		}
 		
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ kernel/generic/src/proc/task.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -151,4 +151,5 @@
 	atomic_set(&task->refcount, 0);
 	atomic_set(&task->lifecount, 0);
+	atomic_set(&task->active_calls, 0);
 	
 	irq_spinlock_initialize(&task->lock, "task_t_lock");
@@ -477,6 +478,6 @@
 #ifdef __32_BITS__
 	if (*additional)
-		printf("%-8" PRIu64 " %9" PRIua, task->taskid,
-		    atomic_get(&task->refcount));
+		printf("%-8" PRIu64 " %9" PRIua " %7" PRIua, task->taskid,
+		    atomic_get(&task->refcount), atomic_get(&task->active_calls));
 	else
 		printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p"
@@ -489,6 +490,7 @@
 	if (*additional)
 		printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c "
-		    "%9" PRIua, task->taskid, ucycles, usuffix, kcycles,
-		    ksuffix, atomic_get(&task->refcount));
+		    "%9" PRIua " %7" PRIua,
+		    task->taskid, ucycles, usuffix, kcycles, ksuffix,
+		    atomic_get(&task->refcount), atomic_get(&task->active_calls));
 	else
 		printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n",
Index: uspace/app/usbinfo/dump.c
===================================================================
--- uspace/app/usbinfo/dump.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/app/usbinfo/dump.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -69,17 +69,4 @@
 }
 
-void dump_match_ids(match_id_list_t *matches)
-{
-	printf("Match ids:\n");
-	link_t *link;
-	for (link = matches->ids.next;
-	    link != &matches->ids;
-	    link = link->next) {
-		match_id_t *match = list_get_instance(link, match_id_t, link);
-
-		printf(INDENT "%d %s\n", match->score, match->id);
-	}
-}
-
 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *d)
 {
Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/app/usbinfo/main.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -112,18 +112,4 @@
 
 	/*
-	 * Dump information about possible match ids.
-	 */
-	match_id_list_t match_id_list;
-	init_match_ids(&match_id_list);
-	rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);
-	if (rc != EOK) {
-		fprintf(stderr,
-		    NAME ": failed to fetch match ids of the device: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-	dump_match_ids(&match_id_list);
-
-	/*
 	 * Get device descriptor and dump it.
 	 */
Index: uspace/app/usbinfo/usbinfo.h
===================================================================
--- uspace/app/usbinfo/usbinfo.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/app/usbinfo/usbinfo.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -39,5 +39,4 @@
 #include <usb/descriptor.h>
 #include <usb/debug.h>
-#include <ipc/devman.h>
 
 
@@ -45,5 +44,4 @@
 
 void dump_buffer(const char *, const uint8_t *, size_t);
-void dump_match_ids(match_id_list_t *matches);
 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *);
 void dump_standard_configuration_descriptor(int, 
Index: uspace/app/virtusbkbd/Makefile
===================================================================
--- uspace/app/virtusbkbd/Makefile	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/app/virtusbkbd/Makefile	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -33,5 +33,5 @@
 
 LIBS = $(LIBUSB_PREFIX)/libusb.a $(LIBUSBVIRT_PREFIX)/libusbvirt.a
-EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX) -I$(LIBDRV_PREFIX)/include
+EXTRA_CFLAGS = -I$(LIBUSB_PREFIX)/include -I$(LIB_PREFIX)
 
 SOURCES = \
Index: uspace/drv/usbkbd/main.c
===================================================================
--- uspace/drv/usbkbd/main.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/drv/usbkbd/main.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -28,263 +28,75 @@
 #include <usb/usbdrv.h>
 #include <driver.h>
-#include <ipc/driver.h>
 #include <errno.h>
-#include <fibril.h>
-#include <usb/classes/hid.h>
-#include <usb/classes/hidparser.h>
-#include <usb/devreq.h>
-#include <usb/descriptor.h>
 
 #define BUFFER_SIZE 32
-#define NAME "usbkbd"
 
-static const usb_endpoint_t CONTROL_EP = 0;
-
-/*
- * Callbacks for parser
- */
-static void usbkbd_process_keycodes(const uint16_t *key_codes, size_t count,
-                                    void *arg)
-{
-
-}
-
-/*
- * Kbd functions
- */
-static int usbkbd_parse_descriptors(usb_hid_dev_kbd_t *kbd_dev,
-                                    const uint8_t *data, size_t size)
-{
-//	const uint8_t *pos = data;
-	
-//	// get the configuration descriptor (should be first)
-//	if (*pos != sizeof(usb_standard_configuration_descriptor_t)
-//	    || *(pos + 1) != USB_DESCTYPE_CONFIGURATION) {
-//		fprintf(stderr, "Wrong format of configuration descriptor");
-//		return EINVAL;
-//	}
-	
-//	usb_standard_configuration_descriptor_t config_descriptor;
-//	memcpy(&config_descriptor, pos, 
-//	    sizeof(usb_standard_configuration_descriptor_t));
-//	pos += sizeof(usb_standard_configuration_descriptor_t);
-	
-//	// parse other descriptors
-//	while (pos - data < size) {
-//		//uint8_t desc_size = *pos;
-//		uint8_t desc_type = *(pos + 1);
-//		switch (desc_type) {
-//		case USB_DESCTYPE_INTERFACE:
-//			break;
-//		case USB_DESCTYPE_ENDPOINT:
-//			break;
-//		case USB_DESCTYPE_HID:
-//			break;
-//		case USB_DESCTYPE_HID_REPORT:
-//			break;
-//		case USB_DESCTYPE_HID_PHYSICAL:
-//			break;
-//		}
-//	}
-	
-	return EOK;
-}
-
-static int usbkbd_get_descriptors(usb_hid_dev_kbd_t *kbd_dev)
-{
-	// get the first configuration descriptor (TODO: or some other??)
-	usb_standard_configuration_descriptor_t config_desc;
-	
-	int rc = usb_drv_req_get_bare_configuration_descriptor(
-	    kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
-	
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	// prepare space for all underlying descriptors
-	uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
-	if (descriptors == NULL) {
-		return ENOMEM;
-	}
-	
-	size_t transferred = 0;
-	// get full configuration descriptor
-	rc = usb_drv_req_get_full_configuration_descriptor(
-	    kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
-	    config_desc.total_length, &transferred);
-	
-	if (rc != EOK) {
-		return rc;
-	}
-	if (transferred != config_desc.total_length) {
-		return ELIMIT;
-	}
-	
-	rc = usbkbd_parse_descriptors(kbd_dev, descriptors, transferred);
-	free(descriptors);
-	
-	return rc;
-}
-
-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;
-
-	// get phone to my HC and save it as my parent's phone
-	// TODO: maybe not a good idea if DDF will use parent_phone
-	kbd_dev->device->parent_phone = usb_drv_hc_connect(dev, 0);
-
-	kbd_dev->address = usb_drv_get_my_address(dev->parent_phone,
-	    dev);
-
-	// doesn't matter now that we have no address
-//	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;
-	
-	/*
-	 * will need all descriptors:
-	 * 1) choose one configuration from configuration descriptors 
-	 *    (set it to the device)
-	 * 2) set endpoints from endpoint descriptors
-	 */
-
-	// TODO: get descriptors
-	usbkbd_get_descriptors(kbd_dev);
-	// TODO: parse descriptors and save endpoints
-
-	return kbd_dev;
-}
-
-static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
-                                        uint8_t *buffer, size_t actual_size)
-{
-	/*
-	 * here, the parser will be called, probably with some callbacks
-	 * now only take last 6 bytes and process, i.e. send to kbd
-	 */
-
-	usb_hid_report_in_callbacks_t *callbacks =
-	    (usb_hid_report_in_callbacks_t *)malloc(
-		sizeof(usb_hid_report_in_callbacks_t));
-	callbacks->keyboard = usbkbd_process_keycodes;
-
-	usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 
-	    NULL);
-}
-
-static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
+/* Call this periodically to check keyboard status changes. */
+static void poll_keyboard(device_t *dev)
 {
 	int rc;
 	usb_handle_t handle;
-	uint8_t buffer[BUFFER_SIZE];
+	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 = kbd_dev->address,
-		.endpoint = kbd_dev->default_ep
+		.address = my_address,
+		.endpoint = poll_endpoint
 	};
 
-	while (true) {
-		rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
-		    poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
-
-		if (rc != EOK) {
-			continue;
-		}
-
-		rc = usb_drv_async_wait_for(handle);
-		if (rc != EOK) {
-			continue;
-		}
-
-		/*
-		 * If the keyboard answered with NAK, it returned no data.
-		 * This implies that no change happened since last query.
-		 */
-		if (actual_size == 0) {
-			continue;
-		}
-
-		/*
-		 * TODO: Process pressed keys.
-		 */
-		usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
+	rc = usb_drv_async_interrupt_in(dev->parent_phone, poll_target,
+	    buffer, BUFFER_SIZE, &actual_size, &handle);
+	if (rc != EOK) {
+		return;
 	}
 
-	// not reached
-	assert(0);
+	rc = usb_drv_async_wait_for(handle);
+	if (rc != EOK) {
+		return;
+	}
+
+	/*
+	 * If the keyboard answered with NAK, it returned no data.
+	 * This implies that no change happened since last query.
+	 */
+	if (actual_size == 0) {
+		return;
+	}
+
+	/*
+	 * Process pressed keys.
+	 */
 }
 
-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)
+static int add_kbd_device(device_t *dev)
 {
 	/* For now, fail immediately. */
-	//return ENOTSUP;
+	return ENOTSUP;
 
 	/*
 	 * 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;
 
 	/*
-	 * Create new fibril for handling this keyboard
+	 * Just for fun ;-).
 	 */
-	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);
+	poll_keyboard(dev);
 
 	/*
@@ -295,9 +107,9 @@
 
 static driver_ops_t kbd_driver_ops = {
-	.add_device = usbkbd_add_device,
+	.add_device = add_kbd_device,
 };
 
 static driver_t kbd_driver = {
-	.name = NAME,
+	.name = "usbkbd",
 	.driver_ops = &kbd_driver_ops
 };
Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/Makefile	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -34,5 +34,4 @@
 SOURCES = \
 	src/addrkeep.c \
-	src/class.c \
 	src/debug.c \
 	src/drvpsync.c \
@@ -41,5 +40,4 @@
 	src/hidparser.c \
 	src/localdrv.c \
-	src/recognise.c \
 	src/remotedrv.c \
 	src/usb.c \
Index: uspace/lib/usb/include/usb/classes/classes.h
===================================================================
--- uspace/lib/usb/include/usb/classes/classes.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/include/usb/classes/classes.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -60,5 +60,4 @@
 } usb_class_t;
 
-const char *usb_str_class(usb_class_t);
 
 #endif
Index: uspace/lib/usb/include/usb/classes/hid.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hid.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/include/usb/classes/hid.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -36,8 +36,4 @@
 #define LIBUSB_HID_H_
 
-#include <usb/usb.h>
-#include <driver.h>
-#include <usb/classes/hidparser.h>
-
 /** USB/HID device requests. */
 typedef enum {
@@ -58,50 +54,4 @@
 } usb_hid_protocol_t;
 
-/** Part of standard USB HID descriptor specifying one class descriptor.
- *
- * (See HID Specification, p.22)
- */
-typedef struct {
-	/** Type of class descriptor (Report or Physical). */
-	uint8_t class_descriptor_type;
-	/** Length of class descriptor. */
-	uint16_t class_descriptor_length;
-} __attribute__ ((packed)) usb_standard_hid_descriptor_class_item_t;
-
-/** Standard USB HID descriptor.
- *
- * (See HID Specification, p.22)
- * 
- * It is actually only the "header" of the descriptor, as it may have arbitrary
- * length if more than one class descritor is provided.
- */
-typedef struct {
-	/** Size of this descriptor in bytes. */
-	uint8_t length;
-	/** Descriptor type (USB_DESCTYPE_HID). */
-	uint8_t descriptor_type;
-	/** HID Class Specification release. */
-	uint16_t spec_release;
-	/** Country code of localized hardware. */
-	uint8_t country_code;
-	/** Total number of class (i.e. Report and Physical) descriptors. */
-	uint8_t class_count;
-	/** First mandatory class descriptor info. */
-	usb_standard_hid_descriptor_class_item_t class_descriptor;
-} __attribute__ ((packed)) usb_standard_hid_descriptor_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_report_parser_t *parser;
-} usb_hid_dev_kbd_t;
-
 #endif
 /**
Index: uspace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/include/usb/classes/hidparser.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -50,12 +50,12 @@
 	 * @param arg Custom argument.
 	 */
-	void (*keyboard)(const uint16_t *key_codes, size_t count, void *arg);
+	void (*keyboard)(const uint32_t *key_codes, size_t count, void *arg);
 } usb_hid_report_in_callbacks_t;
 
 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 
-    const uint8_t *data, size_t size);
+    const uint8_t *data);
 
 int usb_hid_parse_report(const usb_hid_report_parser_t *parser,  
-    const uint8_t *data, size_t size,
+    const uint8_t *data,
     const usb_hid_report_in_callbacks_t *callbacks, void *arg);
 
Index: uspace/lib/usb/include/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/include/usb/usbdrv.h	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/include/usb/usbdrv.h	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -94,8 +94,4 @@
 int usb_drv_async_wait_for(usb_handle_t);
 
-int usb_drv_create_device_match_ids(int, match_id_list_t *, usb_address_t);
-int usb_drv_register_child_in_devman(int, device_t *, usb_address_t,
-    devman_handle_t *);
-
 
 #endif
Index: pace/lib/usb/src/class.c
===================================================================
--- uspace/lib/usb/src/class.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ 	(revision )
@@ -1,92 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 libusb usb
- * @{
- */
-/** @file
- * @brief Class related functions.
- */
-#include <usb/classes/classes.h>
-#include <errno.h>
-
-/** Tell string representation of USB class.
- *
- * @param cls Class code.
- * @return String representation.
- */
-const char *usb_str_class(usb_class_t cls)
-{
-	switch (cls) {
-		case USB_CLASS_USE_INTERFACE:
-			return "use-interface";
-		case USB_CLASS_AUDIO:
-			return "audio";
-		case USB_CLASS_COMMUNICATIONS_CDC_CONTROL:
-			return "communications";
-		case USB_CLASS_HID:
-			return "HID";
-		case USB_CLASS_PHYSICAL:
-			return "physical";
-		case USB_CLASS_IMAGE:
-			return "image";
-		case USB_CLASS_PRINTER:
-			return "printer";
-		case USB_CLASS_MASS_STORAGE:
-			return "mass-storage";
-		case USB_CLASS_HUB:
-			return "hub";
-		case USB_CLASS_CDC_DATA:
-			return "CDC";
-		case USB_CLASS_SMART_CARD:
-			return "smart-card";
-		case USB_CLASS_CONTENT_SECURITY:
-			return "security";
-		case USB_CLASS_VIDEO:
-			return "video";
-		case USB_CLASS_PERSONAL_HEALTHCARE:
-			return "healthcare";
-		case USB_CLASS_DIAGNOSTIC:
-			return "diagnostic";
-		case USB_CLASS_WIRELESS_CONTROLLER:
-			return "wireless";
-		case USB_CLASS_MISCELLANEOUS:
-			return "misc";
-		case USB_CLASS_APPLICATION_SPECIFIC:
-			return "application";
-		case USB_CLASS_VENDOR_SPECIFIC:
-			return "vendor";
-		default:
-			return "unknown";
-	}
-}
-
-
-/**
- * @}
- */
Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/src/hidparser.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -40,9 +40,8 @@
  * @param parser Opaque HID report parser structure.
  * @param data Data describing the report.
- * @param size Size of the descriptor in bytes.
  * @return Error code.
  */
 int usb_hid_parse_report_descriptor(usb_hid_report_parser_t *parser, 
-    const uint8_t *data, size_t size)
+    const uint8_t *data)
 {
 	return ENOTSUP;
@@ -55,5 +54,4 @@
  * @param parser Opaque HID report parser structure.
  * @param data Data for the report.
- * @param size Size of the data in bytes.
  * @param callbacks Callbacks for report actions.
  * @param arg Custom argument (passed through to the callbacks).
@@ -61,20 +59,8 @@
  */
 int usb_hid_parse_report(const usb_hid_report_parser_t *parser,  
-    const uint8_t *data, size_t size,
+    const uint8_t *data,
     const usb_hid_report_in_callbacks_t *callbacks, void *arg)
 {
-	int i;
-	
-	// TODO: parse report
-	
-	uint16_t keys[6];
-	
-	for (i = 0; i < 6; ++i) {
-		keys[i] = data[i];
-	}
-	
-	callbacks->keyboard(keys, 6, arg);
-	
-	return EOK;
+	return ENOTSUP;
 }
 
Index: pace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ 	(revision )
@@ -1,239 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 libusb usb
- * @{
- */
-/** @file
- * @brief Functions for recognising kind of attached devices.
- */
-#include <usb/usbdrv.h>
-#include <usb/classes/classes.h>
-#include <stdio.h>
-#include <errno.h>
-
-
-#define BCD_INT(a) (((unsigned int)(a)) / 256)
-#define BCD_FRAC(a) (((unsigned int)(a)) % 256)
-
-#define BCD_FMT "%x.%x"
-#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
-
-/* FIXME: make this dynamic */
-#define MATCH_STRING_MAX 256
-
-/** Add formatted match id.
- *
- * @param matches List of match ids where to add to.
- * @param score Score of the match.
- * @param format Printf-like format
- * @return Error code.
- */
-static int usb_add_match_id(match_id_list_t *matches, int score,
-    const char *format, ...)
-{
-	char *match_str = NULL;
-	match_id_t *match_id = NULL;
-	int rc;
-	
-	match_str = malloc(MATCH_STRING_MAX + 1);
-	if (match_str == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-
-	/*
-	 * FIXME: replace with dynamic allocation of exact size
-	 */
-	va_list args;
-	va_start(args, format	);
-	vsnprintf(match_str, MATCH_STRING_MAX, format, args);
-	match_str[MATCH_STRING_MAX] = 0;
-	va_end(args);
-
-	match_id = create_match_id();
-	if (match_id == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-
-	match_id->id = match_str;
-	match_id->score = score;
-	add_match_id(matches, match_id);
-
-	return EOK;
-	
-failure:
-	if (match_str != NULL) {
-		free(match_str);
-	}
-	if (match_id != NULL) {
-		match_id->id = NULL;
-		delete_match_id(match_id);
-	}
-	
-	return rc;
-}
-
-/** Create match ids describing attached device.
- *
- * @warning The list of match ids @p matches may change even when
- * function exits with error.
- *
- * @param hc Open phone to host controller.
- * @param matches Initialized list of match ids.
- * @param address USB address of the attached device.
- * @return Error code.
- */
-int usb_drv_create_device_match_ids(int hc, match_id_list_t *matches,
-    usb_address_t address)
-{
-	int rc;
-	usb_standard_device_descriptor_t device_descriptor;
-
-	rc = usb_drv_req_get_device_descriptor(hc, address,
-	    &device_descriptor);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	/*
-	 * Unless the vendor id is 0, the pair idVendor-idProduct
-	 * quite uniquely describes the device.
-	 */
-	if (device_descriptor.vendor_id != 0) {
-		/* First, with release number. */
-		rc = usb_add_match_id(matches, 100,
-		    "usb&vendor=%d&product=%d&release=" BCD_FMT,
-		    (int) device_descriptor.vendor_id,
-		    (int) device_descriptor.product_id,
-		    BCD_ARGS(device_descriptor.device_version));
-		if (rc != EOK) {
-			return rc;
-		}
-		
-		/* Next, without release number. */
-		rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
-		    (int) device_descriptor.vendor_id,
-		    (int) device_descriptor.product_id);
-		if (rc != EOK) {
-			return rc;
-		}
-
-	}	
-
-	/*
-	 * If the device class does not point to interface,
-	 * it is added immediatelly, otherwise full configuration
-	 * descriptor must be obtained and parsed.
-	 */
-	if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) {
-		rc = usb_add_match_id(matches, 50, "usb&class=%s",
-		    usb_str_class(device_descriptor.device_class));
-		if (rc != EOK) {
-			return rc;
-		}
-	} else {
-		/* TODO */
-	}
-
-	/*
-	 * As a fallback, provide the simplest match id possible.
-	 */
-	rc = usb_add_match_id(matches, 1, "usb&fallback");
-	if (rc != EOK) {
-		return rc;
-	}
-
-	return EOK;
-}
-
-
-/** Probe for device kind and register it in devman.
- *
- * @param hc Open phone to the host controller.
- * @param parent Parent device.
- * @param address Address of the (unknown) attached device.
- * @return Error code.
- */
-int usb_drv_register_child_in_devman(int hc, device_t *parent,
-    usb_address_t address, devman_handle_t *child_handle)
-{
-	device_t *child = NULL;
-	char *child_name = NULL;
-	int rc;
-
-	child = create_device();
-	if (child == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-
-	/*
-	 * TODO: some better child naming
-	 */
-	rc = asprintf(&child_name, "usb%p", child);
-	if (rc < 0) {
-		goto failure;
-	}
-	child->name = child_name;
-	
-	rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	rc = child_device_register(child, parent);
-	if (rc != EOK) {
-		goto failure;
-	}
-
-	if (child_handle != NULL) {
-		*child_handle = child->handle;
-	}
-	
-	return EOK;
-
-failure:
-	if (child != NULL) {
-		child->name = NULL;
-		/* This takes care of match_id deallocation as well. */
-		delete_device(child);
-	}
-	if (child_name != NULL) {
-		free(child_name);
-	}
-
-	return rc;
-
-}
-
-
-/**
- * @}
- */
Index: uspace/lib/usb/src/usbdrvreq.c
===================================================================
--- uspace/lib/usb/src/usbdrvreq.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/lib/usb/src/usbdrvreq.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -162,5 +162,5 @@
 		.request = USB_DEVREQ_GET_DESCRIPTOR,
 		.index = 0,
-		.length = sizeof(usb_standard_configuration_descriptor_t)
+		.length = sizeof(usb_standard_device_descriptor_t)
 	};
 	setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
@@ -225,5 +225,5 @@
 		.request = USB_DEVREQ_GET_DESCRIPTOR,
 		.index = 0,
-		.length = buffer_size
+		.length = sizeof(usb_standard_device_descriptor_t)
 	};
 	setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision b666608e2a8e30364304b3bc1171c7baa7727130)
+++ uspace/srv/devman/devman.c	(revision 94c19b8850e15cf253c7e79006f1fe44b2c4b815)
@@ -686,4 +686,6 @@
 }
 
+static FIBRIL_MUTEX_INITIALIZE(add_device_guard);
+
 /** Pass a device to running driver.
  *
@@ -693,4 +695,6 @@
 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
 {
+	fibril_mutex_lock(&add_device_guard);
+
 	/*
 	 * We do not expect to have driver's mutex locked as we do not
@@ -723,4 +727,6 @@
 	/* Wait for answer from the driver. */
 	async_wait_for(req, &rc);
+
+	fibril_mutex_unlock(&add_device_guard);
 
 	switch(rc) {
