Index: uspace/drv/pciintel/pci.c
===================================================================
--- uspace/drv/pciintel/pci.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/pciintel/pci.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -49,4 +49,8 @@
 #include <ipc/devman.h>
 #include <ipc/dev_iface.h>
+#include <ipc/irc.h>
+#include <ipc/ns.h>
+#include <ipc/services.h>
+#include <sysinfo.h>
 #include <ops/hw_res.h>
 #include <device/hw_res.h>
@@ -72,7 +76,36 @@
 static bool pciintel_enable_child_interrupt(device_t *dev)
 {
-	/* TODO */
-	
-	return false;
+	/* This is an old ugly way, copied from ne2000 driver */
+	assert(dev);
+	pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
+
+  sysarg_t apic;
+  sysarg_t i8259;
+	int irc_phone = -1;
+	int irc_service = 0;
+
+  if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
+    irc_service = SERVICE_APIC;
+	} else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
+    irc_service = SERVICE_I8259;
+	}
+
+  if (irc_service) {
+    while (irc_phone < 0)
+      irc_phone = service_connect_blocking(irc_service, 0, 0);
+  } else {
+		return false;
+	}
+
+	size_t i;
+  for (i = 0; i < dev_data->hw_resources.count; i++) {
+		if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
+			int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
+			async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
+		}
+	}
+
+	async_hangup(irc_phone);
+	return true;
 }
 
Index: uspace/drv/uhci-hcd/batch.c
===================================================================
--- uspace/drv/uhci-hcd/batch.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/batch.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -141,5 +141,4 @@
 	usb_log_debug("Checking(%p) %d packet for completion.\n",
 	    instance, instance->packets);
-	/* This is just an ugly trick to support the old API */
 	instance->transfered_size = 0;
 	size_t i = 0;
@@ -157,4 +156,5 @@
 		    transfer_descriptor_actual_size(&instance->tds[i]);
 	}
+	/* This is just an ugly trick to support the old API */
 	instance->transfered_size -= instance->setup_size;
 	return true;
@@ -191,4 +191,6 @@
 	    0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
 
+	instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
+
 	instance->next_step = batch_call_out_and_dispose;
 	batch_schedule(instance);
@@ -221,4 +223,6 @@
 	transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
 	    0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
+
+	instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
 
 	instance->next_step = batch_call_in_and_dispose;
@@ -244,4 +248,6 @@
 	}
 
+	instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
+
 	instance->next_step = batch_call_in_and_dispose;
 	batch_schedule(instance);
@@ -268,4 +274,6 @@
 	}
 
+	instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
+
 	instance->next_step = batch_call_out_and_dispose;
 	batch_schedule(instance);
Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/iface.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -54,5 +54,5 @@
 }
 /*----------------------------------------------------------------------------*/
-static int reserve_default_address(device_t *dev, bool full_speed)
+static int reserve_default_address(device_t *dev, usb_speed_t speed)
 {
 	assert(dev);
@@ -72,5 +72,5 @@
 }
 /*----------------------------------------------------------------------------*/
-static int request_address(device_t *dev, bool full_speed,
+static int request_address(device_t *dev, usb_speed_t speed,
     usb_address_t *address)
 {
@@ -164,98 +164,6 @@
 	return EOK;
 }
-/*----------------------------------------------------------------------------*/
-static int control_write_setup(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	dev_speed_t speed = FULL_SPEED;
 
-	usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
-	batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
-	    max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_control_setup_old(batch);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int control_write_data(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	dev_speed_t speed = FULL_SPEED;
 
-	usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
-	batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
-	    max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_control_write_data_old(batch);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int control_write_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	size_t max_packet_size = 8;
-	dev_speed_t speed = FULL_SPEED;
-
-	usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
-	batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
-	    max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_control_write_status_old(batch);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int control_read_setup(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	dev_speed_t speed = FULL_SPEED;
-
-	usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
-	batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
-	    max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_control_setup_old(batch);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int control_read_data(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	dev_speed_t speed = FULL_SPEED;
-
-	usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
-	batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
-	    max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_control_read_data_old(batch);
-	return EOK;
-}
-/*----------------------------------------------------------------------------*/
-static int control_read_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	size_t max_packet_size = 8;
-	dev_speed_t speed = FULL_SPEED;
-
-	usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
-	batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
-	    max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg);
-	if (!batch)
-		return ENOMEM;
-	batch_control_read_status_old(batch);
-	return EOK;
-}
 /*----------------------------------------------------------------------------*/
 usbhc_iface_t uhci_iface = {
@@ -273,12 +181,4 @@
 	.control_read = control_read,
 	.control_write = control_write,
-
-	.control_write_setup = control_write_setup,
-	.control_write_data = control_write_data,
-	.control_write_status = control_write_status,
-
-	.control_read_setup = control_read_setup,
-	.control_read_data = control_read_data,
-	.control_read_status = control_read_status
 };
 /**
Index: uspace/drv/uhci-hcd/main.c
===================================================================
--- uspace/drv/uhci-hcd/main.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/main.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -34,4 +34,5 @@
 #include <driver.h>
 #include <usb_iface.h>
+#include <device/hw_res.h>
 
 #include <errno.h>
@@ -46,4 +47,7 @@
 #define NAME "uhci-hcd"
 
+static int uhci_add_device(device_t *device);
+static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle);
+/*----------------------------------------------------------------------------*/
 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
 {
@@ -54,13 +58,37 @@
 	return EOK;
 }
-
+/*----------------------------------------------------------------------------*/
 static usb_iface_t hc_usb_iface = {
 	.get_hc_handle = usb_iface_get_hc_handle
 };
-
+/*----------------------------------------------------------------------------*/
 static device_ops_t uhci_ops = {
 	.interfaces[USB_DEV_IFACE] = &hc_usb_iface,
 	.interfaces[USBHC_DEV_IFACE] = &uhci_iface
 };
+/*----------------------------------------------------------------------------*/
+static driver_ops_t uhci_driver_ops = {
+	.add_device = uhci_add_device,
+};
+/*----------------------------------------------------------------------------*/
+static driver_t uhci_driver = {
+	.name = NAME,
+	.driver_ops = &uhci_driver_ops
+};
+/*----------------------------------------------------------------------------*/
+static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
+{
+	assert(device);
+	uhci_t *hc = dev_to_uhci(device);
+	uint16_t status = IPC_GET_ARG1(*call);
+	assert(hc);
+	uhci_interrupt(hc, status);
+}
+/*----------------------------------------------------------------------------*/
+#define CHECK_RET_RETURN(ret, message...) \
+if (ret != EOK) { \
+	usb_log_error(message); \
+	return ret; \
+}
 
 static int uhci_add_device(device_t *device)
@@ -75,33 +103,41 @@
 	int irq;
 
-	int rc = pci_get_my_registers(device,
-	    &io_reg_base, &io_reg_size, &irq);
+	int ret =
+	    pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
 
-	if (rc != EOK) {
-		usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n",
-		    rc, device->handle);
-		return rc;
-	}
-
+	CHECK_RET_RETURN(ret,
+	    "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
 	usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
 	    io_reg_base, io_reg_size, irq);
 
+	ret = pci_enable_interrupts(device);
+	CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
+
 	uhci_t *uhci_hc = malloc(sizeof(uhci_t));
-	if (!uhci_hc) {
-		usb_log_error("Failed to allocaete memory for uhci hcd driver.\n");
-		return ENOMEM;
+	ret = (uhci_hc != NULL) ? EOK : ENOMEM;
+	CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
+
+	ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
+	if (ret != EOK) {
+		usb_log_error("Failed to init uhci-hcd.\n");
+		free(uhci_hc);
+		return ret;
 	}
 
-	int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
+	ret = register_interrupt_handler(device, irq, irq_handler,
+	    &uhci_hc->interrupt_code);
 	if (ret != EOK) {
-		usb_log_error("Failed to init uhci-hcd.\n");
+		usb_log_error("Failed to register interrupt handler.\n");
+		uhci_fini(uhci_hc);
+		free(uhci_hc);
 		return ret;
 	}
+
 	device_t *rh;
 	ret = setup_root_hub(&rh, device);
-
 	if (ret != EOK) {
 		usb_log_error("Failed to setup uhci root hub.\n");
-		/* TODO: destroy uhci here */
+		uhci_fini(uhci_hc);
+		free(uhci_hc);
 		return ret;
 	}
@@ -110,29 +146,18 @@
 	if (ret != EOK) {
 		usb_log_error("Failed to register root hub.\n");
-		/* TODO: destroy uhci here */
+		uhci_fini(uhci_hc);
+		free(uhci_hc);
+		free(rh);
 		return ret;
 	}
 
 	device->driver_data = uhci_hc;
-
 	return EOK;
 }
-
-static driver_ops_t uhci_driver_ops = {
-	.add_device = uhci_add_device,
-};
-
-static driver_t uhci_driver = {
-	.name = NAME,
-	.driver_ops = &uhci_driver_ops
-};
-
+/*----------------------------------------------------------------------------*/
 int main(int argc, char *argv[])
 {
-	/*
-	 * Do some global initializations.
-	 */
-	sleep(5);
-	usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
+	sleep(3);
+	usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
 
 	return driver_main(&uhci_driver);
Index: uspace/drv/uhci-hcd/pci.c
===================================================================
--- uspace/drv/uhci-hcd/pci.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/pci.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -121,5 +121,12 @@
 	return rc;
 }
-
+/*----------------------------------------------------------------------------*/
+int pci_enable_interrupts(device_t *device)
+{
+	int parent_phone = devman_parent_device_connect(device->handle,
+	    IPC_FLAG_BLOCKING);
+	bool enabled = hw_res_enable_interrupt(parent_phone);
+	return enabled ? EOK : EIO;
+}
 /**
  * @}
Index: uspace/drv/uhci-hcd/pci.h
===================================================================
--- uspace/drv/uhci-hcd/pci.h	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/pci.h	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -39,4 +39,5 @@
 
 int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *);
+int pci_enable_interrupts(device_t *device);
 
 #endif
Index: uspace/drv/uhci-hcd/transfer_list.c
===================================================================
--- uspace/drv/uhci-hcd/transfer_list.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/transfer_list.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -111,9 +111,9 @@
 	/* I'm the first one here */
 	if (batch->link.prev == &instance->batch_list) {
-		usb_log_debug("Removing tracer %p was first, next element %x.\n",
+		usb_log_debug("Removing batch %p was first, next element %x.\n",
 			batch, batch->qh->next_queue);
 		instance->queue_head->element = batch->qh->next_queue;
 	} else {
-		usb_log_debug("Removing tracer %p was NOT first, next element %x.\n",
+		usb_log_debug("Removing batch %p was NOT first, next element %x.\n",
 			batch, batch->qh->next_queue);
 		batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
Index: uspace/drv/uhci-hcd/uhci-hcd.ma
===================================================================
--- uspace/drv/uhci-hcd/uhci-hcd.ma	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/uhci-hcd.ma	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -1,2 +1,2 @@
 10 pci/ven=8086&dev=7020
-
+10 pci/ven=8086&dev=7112
Index: uspace/drv/uhci-hcd/uhci.c
===================================================================
--- uspace/drv/uhci-hcd/uhci.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/uhci.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -39,14 +39,31 @@
 
 #include "uhci.h"
+static irq_cmd_t uhci_cmds[] = {
+	{
+		.cmd = CMD_PIO_READ_16,
+		.addr = (void*)0xc022,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_PIO_WRITE_16,
+		.addr = (void*)0xc022,
+		.value = 0x1f
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
 
 static int uhci_init_transfer_lists(uhci_t *instance);
-static int uhci_clean_finished(void *arg);
+static int uhci_init_mem_structures(uhci_t *instance);
+static void uhci_init_hw(uhci_t *instance);
+
+static int uhci_interrupt_emulator(void *arg);
 static int uhci_debug_checker(void *arg);
+
 static bool allowed_usb_packet(
 	bool low_speed, usb_transfer_type_t, size_t size);
 
-int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
-{
-#define CHECK_RET_RETURN(message...) \
+#define CHECK_RET_RETURN(ret, message...) \
 	if (ret != EOK) { \
 		usb_log_error(message); \
@@ -54,26 +71,72 @@
 	} else (void) 0
 
-	/* init address keeper(libusb) */
-	usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
-	usb_log_debug("Initialized address manager.\n");
+int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
+{
+	assert(reg_size >= sizeof(regs_t));
 
 	/* allow access to hc control registers */
 	regs_t *io;
-	assert(reg_size >= sizeof(regs_t));
 	int ret = pio_enable(regs, reg_size, (void**)&io);
-	CHECK_RET_RETURN("Failed to gain access to registers at %p.\n", io);
+	CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
 	instance->registers = io;
 	usb_log_debug("Device registers accessible.\n");
 
+	ret = uhci_init_mem_structures(instance);
+	CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
+
+	uhci_init_hw(instance);
+
+	instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
+//	fibril_add_ready(instance->cleaner);
+
+	instance->debug_checker = fibril_create(uhci_debug_checker, instance);
+	fibril_add_ready(instance->debug_checker);
+
+	return EOK;
+}
+/*----------------------------------------------------------------------------*/
+void uhci_init_hw(uhci_t *instance)
+{
+
+	/* set framelist pointer */
+	const uint32_t pa = addr_to_phys(instance->frame_list);
+	pio_write_32(&instance->registers->flbaseadd, pa);
+
+	/* enable all interrupts, but resume interrupt */
+	pio_write_16(&instance->registers->usbintr,
+		  UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
+
+	/* Start the hc with large(64B) packet FSBR */
+	pio_write_16(&instance->registers->usbcmd,
+	    UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
+	usb_log_debug("Started UHCI HC.\n");
+}
+/*----------------------------------------------------------------------------*/
+int uhci_init_mem_structures(uhci_t *instance)
+{
+	assert(instance);
+
+	/* init interrupt code */
+	irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds));
+	if (interrupt_commands == NULL) {
+		return ENOMEM;
+	}
+	memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
+	interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
+	interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
+	instance->interrupt_code.cmds = interrupt_commands;
+	instance->interrupt_code.cmdcount =
+	    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
+
 	/* init transfer lists */
-	ret = uhci_init_transfer_lists(instance);
-	CHECK_RET_RETURN("Failed to initialize transfer lists.\n");
-	usb_log_debug("Transfer lists initialized.\n");
-
-
-	usb_log_debug("Initializing frame list.\n");
+	int ret = uhci_init_transfer_lists(instance);
+	CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
+	usb_log_debug("Initialized transfer lists.\n");
+
+	/* frame list initialization */
 	instance->frame_list = get_page();
 	ret = instance ? EOK : ENOMEM;
-	CHECK_RET_RETURN("Failed to get frame list page.\n");
+	CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
+	usb_log_debug("Initialized frame list.\n");
 
 	/* initialize all frames to point to the first queue head */
@@ -86,24 +149,7 @@
 	}
 
-	const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
-	pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
-
-	list_initialize(&instance->batch_list);
-	fibril_mutex_initialize(&instance->batch_list_mutex);
-
-	instance->cleaner = fibril_create(uhci_clean_finished, instance);
-	fibril_add_ready(instance->cleaner);
-
-	instance->debug_checker = fibril_create(uhci_debug_checker, instance);
-	fibril_add_ready(instance->debug_checker);
-
-	/* Start the hc with large(64B) packet FSBR */
-	pio_write_16(&instance->registers->usbcmd,
-	    UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
-	usb_log_debug("Started UHCI HC.\n");
-
-	uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
-	cmd |= UHCI_CMD_DEBUG;
-	pio_write_16(&instance->registers->usbcmd, cmd);
+	/* init address keeper(libusb) */
+	usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
+	usb_log_debug("Initialized address manager.\n");
 
 	return EOK;
@@ -114,5 +160,5 @@
 	assert(instance);
 
-	/* initialize */
+	/* initialize TODO: check errors */
 	int ret;
 	ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
@@ -146,6 +192,6 @@
 	instance->transfers[1][USB_TRANSFER_CONTROL] =
 	  &instance->transfers_control_slow;
-	instance->transfers[0][USB_TRANSFER_CONTROL] =
-	  &instance->transfers_control_full;
+	instance->transfers[0][USB_TRANSFER_BULK] =
+	  &instance->transfers_bulk_full;
 
 	return EOK;
@@ -174,15 +220,25 @@
 }
 /*----------------------------------------------------------------------------*/
-int uhci_clean_finished(void* arg)
-{
-	usb_log_debug("Started cleaning fibril.\n");
+void uhci_interrupt(uhci_t *instance, uint16_t status)
+{
+	assert(instance);
+	if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
+		return;
+	usb_log_debug("UHCI interrupt: %X.\n", status);
+	transfer_list_check(&instance->transfers_interrupt);
+	transfer_list_check(&instance->transfers_control_slow);
+	transfer_list_check(&instance->transfers_control_full);
+	transfer_list_check(&instance->transfers_bulk_full);
+}
+/*----------------------------------------------------------------------------*/
+int uhci_interrupt_emulator(void* arg)
+{
+	usb_log_debug("Started interrupt emulator.\n");
 	uhci_t *instance = (uhci_t*)arg;
 	assert(instance);
 
 	while(1) {
-		transfer_list_check(&instance->transfers_interrupt);
-		transfer_list_check(&instance->transfers_control_slow);
-		transfer_list_check(&instance->transfers_control_full);
-		transfer_list_check(&instance->transfers_bulk_full);
+		uint16_t status = pio_read_16(&instance->registers->usbsts);
+		uhci_interrupt(instance, status);
 		async_usleep(UHCI_CLEANER_TIMEOUT);
 	}
@@ -195,10 +251,12 @@
 	assert(instance);
 	while (1) {
-		uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
-		uint16_t sts = pio_read_16(&instance->registers->usbsts);
-		usb_log_debug("Command register: %X Status register: %X\n", cmd, sts);
+		const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
+		const uint16_t sts = pio_read_16(&instance->registers->usbsts);
+		const uint16_t intr = pio_read_16(&instance->registers->usbintr);
+		usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
+		    cmd, sts, intr);
 
 		uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
-		if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {
+		if (frame_list != addr_to_phys(instance->frame_list)) {
 			usb_log_debug("Framelist address: %p vs. %p.\n",
 				frame_list, addr_to_phys(instance->frame_list));
Index: uspace/drv/uhci-hcd/uhci.h
===================================================================
--- uspace/drv/uhci-hcd/uhci.h	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-hcd/uhci.h	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -66,4 +66,9 @@
 
 	uint16_t usbintr;
+#define UHCI_INTR_SHORT_PACKET (1 << 3)
+#define UHCI_INTR_COMPLETE (1 << 2)
+#define UHCI_INTR_RESUME (1 << 1)
+#define UHCI_INTR_CRC (1 << 0)
+
 	uint16_t frnum;
 	uint32_t flbaseadd;
@@ -81,7 +86,4 @@
 	link_pointer_t *frame_list;
 
-	link_t batch_list;
-	fibril_mutex_t batch_list_mutex;
-
 	transfer_list_t transfers_bulk_full;
 	transfer_list_t transfers_control_full;
@@ -90,4 +92,6 @@
 
 	transfer_list_t *transfers[2][4];
+
+	irq_code_t interrupt_code;
 
 	fid_t cleaner;
@@ -98,23 +102,13 @@
 int uhci_init(uhci_t *instance, void *regs, size_t reg_size);
 
-int uhci_fini(uhci_t *device);
-
-int uhci_transfer(
-  uhci_t *instance,
-  device_t *dev,
-  usb_target_t target,
-  usb_transfer_type_t transfer_type,
-	bool toggle,
-  usb_packet_id pid,
-	bool low_speed,
-  void *buffer, size_t size,
-  usbhc_iface_transfer_out_callback_t callback_out,
-  usbhc_iface_transfer_in_callback_t callback_in,
-  void *arg );
+static inline void uhci_fini(uhci_t *instance) {};
 
 int uhci_schedule(uhci_t *instance, batch_t *batch);
 
+void uhci_interrupt(uhci_t *instance, uint16_t status);
+
 static inline uhci_t * dev_to_uhci(device_t *dev)
 	{ return (uhci_t*)dev->driver_data; }
+
 
 #endif
Index: uspace/drv/uhci-rhd/port.c
===================================================================
--- uspace/drv/uhci-rhd/port.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-rhd/port.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -131,49 +131,24 @@
 	return EOK;
 }
-/*----------------------------------------------------------------------------*/
-static int uhci_port_new_device(uhci_port_t *port)
-{
-	assert(port);
-	assert(usb_hc_connection_is_opened(&port->hc_connection));
-
-	usb_log_info("Adding new device on port %d.\n", port->number);
-
-	/* get address of the future device */
-	const usb_address_t usb_address = usb_hc_request_address(
-	    &port->hc_connection, true);
-
-	if (usb_address <= 0) {
-		usb_log_error("Recieved invalid address(%d).\n", usb_address);
-		return usb_address;
-	}
-	usb_log_debug("Sucessfully obtained address %d for port %d.\n",
-	    usb_address, port->number);
-
-	/* get default address */
-	int ret = usb_hc_reserve_default_address(&port->hc_connection, true);
-	if (ret != EOK) {
-		usb_log_error("Failed to reserve default address on port %d.\n",
-		    port->number);
-		int ret2 = usb_hc_unregister_device(&port->hc_connection,
-		    usb_address);
-		if (ret2 != EOK) {
-			usb_log_fatal("Failed to return requested address on port %d.\n",
-			   port->number);
-			return ret2;
-		}
-		usb_log_debug("Successfully returned reserved address on port %d.\n",
-			port->number);
-		return ret;
-	}
-	usb_log_debug("Sucessfully obtained default address for port %d.\n",
-	    port->number);
+
+/** Callback for enabling port during adding a new device.
+ *
+ * @param portno Port number (unused).
+ * @param arg Pointer to uhci_port_t of port with the new device.
+ * @return Error code.
+ */
+static int new_device_enable_port(int portno, void *arg)
+{
+	uhci_port_t *port = (uhci_port_t *) arg;
+
+	usb_log_debug("new_device_enable_port(%d)\n", port->number);
 
 	/*
-	 * the host then waits for at least 100 ms to allow completion of
+	 * The host then waits for at least 100 ms to allow completion of
 	 * an insertion process and for power at the device to become stable.
 	 */
 	async_usleep(100000);
 
-	/* enable port */
+	/* Enable the port. */
 	uhci_port_set_enabled(port, true);
 
@@ -197,78 +172,33 @@
 	}
 
-	/*
-	 * Initialize connection to the device.
-	 */
-	/* FIXME: check for errors. */
-	usb_device_connection_t new_dev_connection;
-	usb_endpoint_pipe_t new_dev_ctrl_pipe;
-	usb_device_connection_initialize_on_default_address(
-	    &new_dev_connection, &port->hc_connection);
-	usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
-	    &new_dev_connection);
-
-	/*
-	 * Assign new address to the device. This function updates
-	 * the backing connection to still point to the same device.
-	 */
-	/* FIXME: check for errors. */
-	usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
-	ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
-	usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
-
-	if (ret != EOK) { /* address assigning went wrong */
-		usb_log_error("Failed(%d) to assign address to the device.\n", ret);
+	return EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+static int uhci_port_new_device(uhci_port_t *port)
+{
+	assert(port);
+	assert(usb_hc_connection_is_opened(&port->hc_connection));
+
+	usb_log_info("Detected new device on port %u.\n", port->number);
+
+	usb_address_t dev_addr;
+	int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
+	    USB_SPEED_FULL,
+	    new_device_enable_port, port->number, port,
+	    &dev_addr, &port->attached_device);
+	if (rc != EOK) {
+		usb_log_error("Failed adding new device on port %u: %s.\n",
+		    port->number, str_error(rc));
 		uhci_port_set_enabled(port, false);
-		int release = usb_hc_release_default_address(&port->hc_connection);
-		if (release != EOK) {
-			usb_log_error("Failed to release default address on port %d.\n",
-			    port->number);
-			return release;
-		}
-		usb_log_debug("Sucessfully released default address on port %d.\n",
-		    port->number);
-		return ret;
-	}
-	usb_log_debug("Sucessfully assigned address %d for port %d.\n",
-	    usb_address, port->number);
-
-	/* release default address */
-	ret = usb_hc_release_default_address(&port->hc_connection);
-	if (ret != EOK) {
-		usb_log_error("Failed to release default address on port %d.\n",
-		    port->number);
-		return ret;
-	}
-	usb_log_debug("Sucessfully released default address on port %d.\n",
-	    port->number);
-
-	/* communicate and possibly report to devman */
-	assert(port->attached_device == 0);
-
-	ret = usb_device_register_child_in_devman(new_dev_connection.address,
-	    new_dev_connection.hc_handle, port->rh, &port->attached_device);
-
-	if (ret != EOK) { /* something went wrong */
-		usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
-		uhci_port_set_enabled(port, false);
-		return ENOMEM;
-	}
-	usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
-		port->number, usb_address, port->attached_device);
-
-	/*
-	 * Register the device in the host controller.
-	 */
-	usb_hc_attached_device_t new_device = {
-		.address = new_dev_connection.address,
-		.handle = port->attached_device
-	};
-
-	ret = usb_hc_register_device(&port->hc_connection, &new_device);
-	// TODO: proper error check here
-	assert(ret == EOK);
-
-	return EOK;
-}
+		return rc;
+	}
+
+	usb_log_info("New device on port %u has address %d (handle %zu).\n",
+	    port->number, dev_addr, port->attached_device);
+
+	return EOK;
+}
+
 /*----------------------------------------------------------------------------*/
 static int uhci_port_remove_device(uhci_port_t *port)
Index: uspace/drv/uhci-rhd/root_hub.c
===================================================================
--- uspace/drv/uhci-rhd/root_hub.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/uhci-rhd/root_hub.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -47,5 +47,5 @@
 	assert(rh);
 	int ret;
-	ret = usb_drv_find_hc(rh, &instance->hc_handle);
+	ret = usb_hc_find(rh->handle, &instance->hc_handle);
 	usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle);
 	if (ret != EOK) {
Index: uspace/drv/usbhub/usbhub.c
===================================================================
--- uspace/drv/usbhub/usbhub.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/usbhub/usbhub.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -52,6 +52,11 @@
 #include "usb/pipes.h"
 
+static int iface_get_hc_handle(device_t *device, devman_handle_t *handle)
+{
+	return usb_hc_find(device->handle, handle);
+}
+
 static usb_iface_t hub_usb_iface = {
-	.get_hc_handle = usb_drv_find_hc
+	.get_hc_handle = iface_get_hc_handle
 };
 
@@ -263,5 +268,5 @@
 	//get default address
 	//opResult = usb_drv_reserve_default_address(hc);
-	opResult = usb_hc_reserve_default_address(&hub->connection, false);
+	opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
 	if (opResult != EOK) {
 		dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
@@ -320,5 +325,5 @@
 	usb_address_t new_device_address = usb_hc_request_address(
 			&hub->connection,
-			false/// \TODO fullspeed??
+			USB_SPEED_LOW/// \TODO fullspeed??
 			);
 	if (new_device_address < 0) {
Index: uspace/drv/vhc/connhost.c
===================================================================
--- uspace/drv/vhc/connhost.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/drv/vhc/connhost.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -234,24 +234,4 @@
 }
 
-static int enqueue_transfer_setup(device_t *dev,
-    usb_target_t target, usb_transfer_type_t transfer_type,
-    void *buffer, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n",
-	    target.address, target.endpoint,
-	    usb_str_transfer_type(transfer_type),
-	    size);
-
-	transfer_info_t *transfer
-	    = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
-	transfer->out_callback = callback;
-
-	hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
-	    universal_callback, transfer);
-
-	return EOK;
-}
-
 static int enqueue_transfer_in(device_t *dev,
     usb_target_t target, usb_transfer_type_t transfer_type,
@@ -292,32 +272,4 @@
 	return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
 	    data, size,
-	    callback, arg);
-}
-
-static int control_write_setup(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_data(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_write_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
 	    callback, arg);
 }
@@ -341,32 +293,4 @@
 }
 
-static int control_read_setup(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_data(device_t *dev, usb_target_t target,
-    size_t max_packet_size,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
-	    data, size,
-	    callback, arg);
-}
-
-static int control_read_status(device_t *dev, usb_target_t target,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
-	    NULL, 0,
-	    callback, arg);
-}
-
 static int control_read(device_t *dev, usb_target_t target,
     size_t max_packet_size,
@@ -390,5 +314,5 @@
 
 
-static int reserve_default_address(device_t *dev, bool ignored)
+static int reserve_default_address(device_t *dev, usb_speed_t ignored)
 {
 	usb_address_keeping_reserve_default(&addresses);
@@ -402,5 +326,6 @@
 }
 
-static int request_address(device_t *dev, bool ignored, usb_address_t *address)
+static int request_address(device_t *dev, usb_speed_t ignored,
+    usb_address_t *address)
 {
 	usb_address_t addr = usb_address_keeping_request(&addresses);
@@ -454,14 +379,5 @@
 	.interrupt_in = interrupt_in,
 
-	.control_write_setup = control_write_setup,
-	.control_write_data = control_write_data,
-	.control_write_status = control_write_status,
-
 	.control_write = control_write,
-
-	.control_read_setup = control_read_setup,
-	.control_read_data = control_read_data,
-	.control_read_status = control_read_status,
-
 	.control_read = control_read
 };
Index: uspace/lib/c/generic/str_error.c
===================================================================
--- uspace/lib/c/generic/str_error.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/c/generic/str_error.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -73,4 +73,6 @@
 		case EBADCHECKSUM:
 			return "Bad checksum";
+		case ESTALL:
+			return "Operation stalled";
 		case EAGAIN:
 			return "Resource temporarily unavailable";
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/c/include/errno.h	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -59,4 +59,7 @@
 #define EBADCHECKSUM  (-300)
 
+/** USB: stalled operation. */
+#define ESTALL (-301)
+
 /** An API function is called while another blocking function is in progress. */
 #define EINPROGRESS  (-10036)
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -46,10 +46,4 @@
 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -75,12 +69,4 @@
 	remote_usbhc_interrupt_in,
 
-	remote_usbhc_control_write_setup,
-	remote_usbhc_control_write_data,
-	remote_usbhc_control_write_status,
-
-	remote_usbhc_control_read_setup,
-	remote_usbhc_control_read_data,
-	remote_usbhc_control_read_status,
-
 	remote_usbhc_control_write,
 	remote_usbhc_control_read
@@ -166,7 +152,7 @@
 	}
 	
-	bool full_speed = DEV_IPC_GET_ARG1(*call);
+	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
 	
-	int rc = usb_iface->reserve_default_address(device, full_speed);
+	int rc = usb_iface->reserve_default_address(device, speed);
 
 	async_answer_0(callid, rc);
@@ -198,8 +184,8 @@
 	}
 	
-	bool full_speed = DEV_IPC_GET_ARG1(*call);
+	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
 
 	usb_address_t address;
-	int rc = usb_iface->request_address(device, full_speed, &address);
+	int rc = usb_iface->request_address(device, speed, &address);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -297,5 +283,5 @@
 	}
 
-	size_t expected_len = DEV_IPC_GET_ARG3(*call);
+	size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
 	usb_target_t target = {
 		.address = DEV_IPC_GET_ARG1(*call),
@@ -305,13 +291,12 @@
 	size_t len = 0;
 	void *buffer = NULL;
-	if (expected_len > 0) {
-		int rc = async_data_write_accept(&buffer, false,
-		    1, USB_MAX_PAYLOAD_SIZE,
-		    0, &len);
-
-		if (rc != EOK) {
-			async_answer_0(callid, rc);
-			return;
-		}
+
+	int rc = async_data_write_accept(&buffer, false,
+	    1, USB_MAX_PAYLOAD_SIZE,
+	    0, &len);
+
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
 	}
 
@@ -328,5 +313,5 @@
 	trans->size = len;
 
-	int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE,
+	rc = transfer_func(device, target, max_packet_size,
 	    buffer, len,
 	    callback_out, trans);
@@ -354,5 +339,5 @@
 	}
 
-	size_t len = DEV_IPC_GET_ARG3(*call);
+	size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
 	usb_target_t target = {
 		.address = DEV_IPC_GET_ARG1(*call),
@@ -360,4 +345,5 @@
 	};
 
+	size_t len;
 	ipc_callid_t data_callid;
 	if (!async_data_read_receive(&data_callid, &len)) {
@@ -375,5 +361,5 @@
 	trans->size = len;
 
-	int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE_INTERRUPT_IN,
+	int rc = transfer_func(device, target, max_packet_size,
 	    trans->buffer, len,
 	    callback_in, trans);
@@ -385,72 +371,4 @@
 }
 
-/** Process status part of control transfer.
- *
- * @param device Target device.
- * @param callid Initiating caller.
- * @param call Initiating call.
- * @param direction Transfer direction (read ~ in, write ~ out).
- * @param transfer_in_func Transfer function for control read (might be NULL).
- * @param transfer_out_func Transfer function for control write (might be NULL).
- */
-static void remote_usbhc_status_transfer(device_t *device,
-    ipc_callid_t callid, ipc_call_t *call,
-    usb_direction_t direction,
-    int (*transfer_in_func)(device_t *, usb_target_t,
-        usbhc_iface_transfer_in_callback_t, void *),
-    int (*transfer_out_func)(device_t *, usb_target_t,
-        usbhc_iface_transfer_out_callback_t, void *))
-{
-	switch (direction) {
-		case USB_DIRECTION_IN:
-			if (!transfer_in_func) {
-				async_answer_0(callid, ENOTSUP);
-				return;
-			}
-			break;
-		case USB_DIRECTION_OUT:
-			if (!transfer_out_func) {
-				async_answer_0(callid, ENOTSUP);
-				return;
-			}
-			break;
-		default:
-			assert(false && "unreachable code");
-			break;
-	}
-
-	usb_target_t target = {
-		.address = DEV_IPC_GET_ARG1(*call),
-		.endpoint = DEV_IPC_GET_ARG2(*call)
-	};
-
-	async_transaction_t *trans = async_transaction_create(callid);
-	if (trans == NULL) {
-		async_answer_0(callid, ENOMEM);
-		return;
-	}
-
-	int rc;
-	switch (direction) {
-		case USB_DIRECTION_IN:
-			rc = transfer_in_func(device, target,
-			    callback_in, trans);
-			break;
-		case USB_DIRECTION_OUT:
-			rc = transfer_out_func(device, target,
-			    callback_out, trans);
-			break;
-		default:
-			assert(false && "unreachable code");
-			break;
-	}
-
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_transaction_destroy(trans);
-	}
-}
-
-
 void remote_usbhc_interrupt_out(device_t *device, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
@@ -471,64 +389,4 @@
 	return remote_usbhc_in_transfer(device, callid, call,
 	    usb_iface->interrupt_in);
-}
-
-void remote_usbhc_control_write_setup(device_t *device, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
-	assert(usb_iface != NULL);
-
-	return remote_usbhc_out_transfer(device, callid, call,
-	    usb_iface->control_write_setup);
-}
-
-void remote_usbhc_control_write_data(device_t *device, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
-	assert(usb_iface != NULL);
-
-	return remote_usbhc_out_transfer(device, callid, call,
-	    usb_iface->control_write_data);
-}
-
-void remote_usbhc_control_write_status(device_t *device, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
-	assert(usb_iface != NULL);
-
-	return remote_usbhc_status_transfer(device, callid, call,
-	    USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
-}
-
-void remote_usbhc_control_read_setup(device_t *device, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
-	assert(usb_iface != NULL);
-
-	return remote_usbhc_out_transfer(device, callid, call,
-	    usb_iface->control_read_setup);
-}
-
-void remote_usbhc_control_read_data(device_t *device, void *iface,
-	    ipc_callid_t callid, ipc_call_t *call)
-{
-	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
-	assert(usb_iface != NULL);
-
-	return remote_usbhc_in_transfer(device, callid, call,
-	    usb_iface->control_read_data);
-}
-
-void remote_usbhc_control_read_status(device_t *device, void *iface,
-	    ipc_callid_t callid, ipc_call_t *call)
-{
-	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
-	assert(usb_iface != NULL);
-
-	return remote_usbhc_status_transfer(device, callid, call,
-	    USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
 }
 
@@ -549,4 +407,5 @@
 	};
 	size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
+	size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
 
 	int rc;
@@ -584,5 +443,5 @@
 	trans->size = data_buffer_len;
 
-	rc = usb_iface->control_write(device, target, HACK_MAX_PACKET_SIZE,
+	rc = usb_iface->control_write(device, target, max_packet_size,
 	    setup_packet, setup_packet_len,
 	    data_buffer, data_buffer_len,
@@ -611,4 +470,5 @@
 		.endpoint = DEV_IPC_GET_ARG2(*call)
 	};
+	size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
 
 	int rc;
@@ -648,5 +508,5 @@
 	}
 
-	rc = usb_iface->control_read(device, target, HACK_MAX_PACKET_SIZE,
+	rc = usb_iface->control_read(device, target, max_packet_size,
 	    setup_packet, setup_packet_len,
 	    trans->buffer, trans->size,
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -53,5 +53,5 @@
  *   - argument #1 is target address
  *   - argument #2 is target endpoint
- *   - argument #3 is buffer size
+ *   - argument #3 is max packet size of the endpoint
  * - this call is immediately followed by IPC data write (from caller)
  * - the initial call (and the whole transaction) is answer after the
@@ -66,5 +66,5 @@
  *   - argument #1 is target address
  *   - argument #2 is target endpoint
- *   - argument #3 is buffer size
+ *   - argument #3 is max packet size of the endpoint
  * - this call is immediately followed by IPC data read (async version)
  * - the call is not answered until the device returns some data (or until
@@ -153,37 +153,4 @@
 	IPC_M_USBHC_INTERRUPT_IN,
 
-
-	/** Start WRITE control transfer.
-	 * See explanation at usb_iface_funcs_t (OUT transaction).
-	 */
-	IPC_M_USBHC_CONTROL_WRITE_SETUP,
-
-	/** Send control-transfer data to device.
-	 * See explanation at usb_iface_funcs_t (OUT transaction).
-	 */
-	IPC_M_USBHC_CONTROL_WRITE_DATA,
-
-	/** Terminate WRITE control transfer.
-	 * See explanation at usb_iface_funcs_t (NO-DATA transaction).
-	 */
-	IPC_M_USBHC_CONTROL_WRITE_STATUS,
-
-
-
-	/** Start READ control transfer.
-	 * See explanation at usb_iface_funcs_t (OUT transaction).
-	 */
-	IPC_M_USBHC_CONTROL_READ_SETUP,
-
-	/** Get control-transfer data from device.
-	 * See explanation at usb_iface_funcs_t (IN transaction).
-	 */
-	IPC_M_USBHC_CONTROL_READ_DATA,
-
-	/** Terminate READ control transfer.
-	 * See explanation at usb_iface_funcs_t (NO-DATA transaction).
-	 */
-	IPC_M_USBHC_CONTROL_READ_STATUS,
-
 	/** Issue control WRITE transfer.
 	 * See explanation at usb_iface_funcs_t (OUT transaction) for
@@ -194,10 +161,9 @@
 	IPC_M_USBHC_CONTROL_WRITE,
 
-	/** Issue control WRITE transfer.
+	/** Issue control READ transfer.
 	 * See explanation at usb_iface_funcs_t (IN transaction) for
 	 * call parameters.
-	 * This call is immediately followed by IPC data read from the caller
-	 * (setup packet).
-	 * Actual data are retrieved through IPC_M_USBHC_GET_BUFFER.
+	 * This call is immediately followed by IPC data write from the caller
+	 * (setup packet) and IPC data read (buffer that was read).
 	 */
 	IPC_M_USBHC_CONTROL_READ,
@@ -232,7 +198,7 @@
 	int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
 
-	int (*reserve_default_address)(device_t *, bool);
+	int (*reserve_default_address)(device_t *, usb_speed_t);
 	int (*release_default_address)(device_t *);
-	int (*request_address)(device_t *, bool, usb_address_t *);
+	int (*request_address)(device_t *, usb_speed_t, usb_address_t *);
 	int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
 	int (*release_address)(device_t *, usb_address_t);
@@ -240,14 +206,4 @@
 	usbhc_iface_transfer_out_t interrupt_out;
 	usbhc_iface_transfer_in_t interrupt_in;
-
-	usbhc_iface_transfer_setup_t control_write_setup;
-	usbhc_iface_transfer_out_t control_write_data;
-	int (*control_write_status)(device_t *, usb_target_t,
-	    usbhc_iface_transfer_in_callback_t, void *);
-
-	usbhc_iface_transfer_setup_t control_read_setup;
-	usbhc_iface_transfer_in_t control_read_data;
-	int (*control_read_status)(device_t *, usb_target_t,
-	    usbhc_iface_transfer_out_callback_t, void *);
 
 	int (*control_write)(device_t *, usb_target_t,
Index: uspace/lib/usb/include/usb/hub.h
===================================================================
--- uspace/lib/usb/include/usb/hub.h	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/usb/include/usb/hub.h	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -39,4 +39,6 @@
 #include <usb/usbdevice.h>
 
+int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t,
+    int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *);
 
 /** Info about device attached to host controller.
@@ -53,8 +55,8 @@
 } usb_hc_attached_device_t;
 
-int usb_hc_reserve_default_address(usb_hc_connection_t *, bool);
+int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t);
 int usb_hc_release_default_address(usb_hc_connection_t *);
 
-usb_address_t usb_hc_request_address(usb_hc_connection_t *, bool);
+usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
 int usb_hc_register_device(usb_hc_connection_t *,
     const usb_hc_attached_device_t *);
Index: uspace/lib/usb/include/usb/usb.h
===================================================================
--- uspace/lib/usb/include/usb/usb.h	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/usb/include/usb/usb.h	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -68,4 +68,14 @@
 	USB_DIRECTION_BOTH
 } usb_direction_t;
+
+/** USB speeds. */
+typedef enum {
+	/** USB 1.1 low speed (1.5Mbits/s). */
+	USB_SPEED_LOW,
+	/** USB 1.1 full speed (12Mbits/s). */
+	USB_SPEED_FULL,
+	/** USB 2.0 high speed (480Mbits/s). */
+	USB_SPEED_HIGH
+} usb_speed_t;
 
 /** USB request type target. */
Index: uspace/lib/usb/src/hub.c
===================================================================
--- uspace/lib/usb/src/hub.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/usb/src/hub.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -34,4 +34,7 @@
  */
 #include <usb/hub.h>
+#include <usb/pipes.h>
+#include <usb/request.h>
+#include <usb/recognise.h>
 #include <usbhc_iface.h>
 #include <errno.h>
@@ -56,5 +59,5 @@
  */
 int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
-    bool full_speed)
+    usb_speed_t speed)
 {
 	CHECK_CONNECTION(connection);
@@ -62,5 +65,5 @@
 	return async_req_2_0(connection->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, full_speed);
+	    IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
 }
 
@@ -85,5 +88,5 @@
  */
 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
-    bool full_speed)
+    usb_speed_t speed)
 {
 	CHECK_CONNECTION(connection);
@@ -92,5 +95,5 @@
 	int rc = async_req_2_1(connection->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REQUEST_ADDRESS, full_speed,
+	    IPC_M_USBHC_REQUEST_ADDRESS, speed,
 	    &address);
 	if (rc != EOK) {
@@ -138,4 +141,165 @@
 
 
+/** Wrapper for registering attached device to the hub.
+ *
+ * The @p enable_port function is expected to enable singalling on given
+ * port.
+ * The two arguments to it can have arbitrary meaning
+ * (the @p port_no is only a suggestion)
+ * and are not touched at all by this function
+ * (they are passed as is to the @p enable_port function).
+ *
+ * If the @p enable_port fails (i.e. does not return EOK), the device
+ * addition is cancelled.
+ * The return value is then returned (it is good idea to use different
+ * error codes than those listed as return codes by this function itself).
+ *
+ * @param parent Parent device (i.e. the hub device).
+ * @param connection Opened connection to host controller.
+ * @param dev_speed New device speed.
+ * @param enable_port Function for enabling signalling through the port the
+ *	device is attached to.
+ * @param port_no Port number (passed through to @p enable_port).
+ * @param arg Any data argument to @p enable_port.
+ * @param[out] assigned_address USB address of the device.
+ * @param[out] assigned_handle Devman handle of the new device.
+ * @return Error code.
+ * @retval ENOENT Connection to HC not opened.
+ * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
+ * @retval EBUSY Failed reserving default USB address.
+ * @retval ENOTCONN Problem connecting to the host controller via USB pipe.
+ * @retval ESTALL Problem communication with device (either SET_ADDRESS
+ *	request or requests for descriptors when creating match ids).
+ */
+int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection,
+    usb_speed_t dev_speed,
+    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
+    usb_address_t *assigned_address, devman_handle_t *assigned_handle)
+{
+	CHECK_CONNECTION(connection);
+
+	/*
+	 * Request new address.
+	 */
+	usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
+	if (dev_addr < 0) {
+		return EADDRNOTAVAIL;
+	}
+
+	int rc;
+
+	/*
+	 * Reserve the default address.
+	 */
+	rc = usb_hc_reserve_default_address(connection, dev_speed);
+	if (rc != EOK) {
+		rc = EBUSY;
+		goto leave_release_free_address;
+	}
+
+	/*
+	 * Enable the port (i.e. allow signalling through this port).
+	 */
+	rc = enable_port(port_no, arg);
+	if (rc != EOK) {
+		goto leave_release_default_address;
+	}
+
+	/*
+	 * Change the address from default to the free one.
+	 * We need to create a new control pipe for that.
+	 */
+	usb_device_connection_t dev_conn;
+	rc = usb_device_connection_initialize_on_default_address(&dev_conn,
+	    connection);
+	if (rc != EOK) {
+		rc = ENOTCONN;
+		goto leave_release_default_address;
+	}
+
+	usb_endpoint_pipe_t ctrl_pipe;
+	rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe,
+	    &dev_conn);
+	if (rc != EOK) {
+		rc = ENOTCONN;
+		goto leave_release_default_address;
+	}
+
+	rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
+	if (rc != EOK) {
+		rc = ENOTCONN;
+		goto leave_release_default_address;
+	}
+
+	rc = usb_request_set_address(&ctrl_pipe, dev_addr);
+	if (rc != EOK) {
+		rc = ESTALL;
+		goto leave_stop_session;
+	}
+
+	usb_endpoint_pipe_end_session(&ctrl_pipe);
+
+	/*
+	 * Once the address is changed, we can return the default address.
+	 */
+	usb_hc_release_default_address(connection);
+
+	/*
+	 * It is time to register the device with devman.
+	 */
+	/* FIXME: create device_register that will get opened ctrl pipe. */
+	devman_handle_t child_handle;
+	rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
+	    parent, &child_handle);
+	if (rc != EOK) {
+		rc = ESTALL;
+		goto leave_release_free_address;
+	}
+
+	/*
+	 * And now inform the host controller about the handle.
+	 */
+	usb_hc_attached_device_t new_device = {
+		.address = dev_addr,
+		.handle = child_handle
+	};
+	rc = usb_hc_register_device(connection, &new_device);
+	if (rc != EOK) {
+		rc = EDESTADDRREQ;
+		goto leave_release_free_address;
+	}
+
+	/*
+	 * And we are done.
+	 */
+	if (assigned_address != NULL) {
+		*assigned_address = dev_addr;
+	}
+	if (assigned_handle != NULL) {
+		*assigned_handle = child_handle;
+	}
+
+	return EOK;
+
+
+
+	/*
+	 * Error handling (like nested exceptions) starts here.
+	 * Completely ignoring errors here.
+	 */
+
+leave_stop_session:
+	usb_endpoint_pipe_end_session(&ctrl_pipe);
+
+leave_release_default_address:
+	usb_hc_release_default_address(connection);
+
+leave_release_free_address:
+	usb_hc_unregister_device(connection, dev_addr);
+
+	return rc;
+}
+
+
 /**
  * @}
Index: uspace/lib/usb/src/pipes.c
===================================================================
--- uspace/lib/usb/src/pipes.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/usb/src/pipes.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -35,7 +35,27 @@
 #include <usb/usb.h>
 #include <usb/pipes.h>
+#include <usbhc_iface.h>
 #include <errno.h>
 #include <assert.h>
-#include <usb/usbdrv.h>
+
+/** Tell USB address assigned to given device.
+ *
+ * @param phone Phone to my HC.
+ * @param dev Device in question.
+ * @return USB address or error code.
+ */
+static usb_address_t get_my_address(int phone, device_t *dev)
+{
+	sysarg_t address;
+	int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_GET_ADDRESS,
+	    dev->handle, &address);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return (usb_address_t) address;
+}
 
 /** Initialize connection to USB device.
@@ -55,5 +75,5 @@
 	usb_address_t my_address;
 
-	rc = usb_drv_find_hc(device, &hc_handle);
+	rc = usb_hc_find(device->handle, &hc_handle);
 	if (rc != EOK) {
 		return rc;
@@ -65,5 +85,5 @@
 	}
 
-	my_address = usb_drv_get_my_address(hc_phone, device);
+	my_address = get_my_address(hc_phone, device);
 	if (my_address < 0) {
 		rc = my_address;
Index: uspace/lib/usb/src/pipesio.c
===================================================================
--- uspace/lib/usb/src/pipesio.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/usb/src/pipesio.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -78,7 +78,8 @@
 	 * Make call identifying target USB device and type of transfer.
 	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
+	aid_t opening_request = async_send_4(pipe->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
 	    pipe->wire->address, pipe->endpoint_no,
+	    pipe->max_packet_size,
 	    NULL);
 	if (opening_request == 0) {
@@ -201,7 +202,8 @@
 	 * Make call identifying target USB device and type of transfer.
 	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
+	aid_t opening_request = async_send_4(pipe->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
 	    pipe->wire->address, pipe->endpoint_no,
+	    pipe->max_packet_size,
 	    NULL);
 	if (opening_request == 0) {
@@ -283,7 +285,8 @@
 	 * Make call identifying target USB device and control transfer type.
 	 */
-	aid_t opening_request = async_send_3(pipe->hc_phone,
+	aid_t opening_request = async_send_4(pipe->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
 	    pipe->wire->address, pipe->endpoint_no,
+	    pipe->max_packet_size,
 	    NULL);
 	if (opening_request == 0) {
@@ -402,8 +405,9 @@
 	 * Make call identifying target USB device and control transfer type.
 	 */
-	aid_t opening_request = async_send_4(pipe->hc_phone,
+	aid_t opening_request = async_send_5(pipe->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
 	    pipe->wire->address, pipe->endpoint_no,
 	    data_buffer_size,
+	    pipe->max_packet_size,
 	    NULL);
 	if (opening_request == 0) {
Index: uspace/lib/usb/src/usbdrv.c
===================================================================
--- uspace/lib/usb/src/usbdrv.c	(revision 6bb83c7617113ccde4bfaaec20df6a91f8b48ebd)
+++ uspace/lib/usb/src/usbdrv.c	(revision 62066b4b9236cbb36a30b4ca96c26e641093692c)
@@ -34,28 +34,6 @@
  */
 #include <usb/usbdrv.h>
-#include <usbhc_iface.h>
-#include <usb_iface.h>
 #include <errno.h>
-#include <str_error.h>
-
-/** Information about pending transaction on HC. */
-typedef struct {
-	/** Phone to host controller driver. */
-	int phone;
-	/** Data buffer. */
-	void *buffer;
-	/** Buffer size. */
-	size_t size;
-	/** Storage for actual number of bytes transferred. */
-	size_t *size_transferred;
-	/** Initial call reply data. */
-	ipc_call_t reply;
-	/** Initial call identifier. */
-	aid_t request;
-	/** Reply data for data read call. */
-	ipc_call_t read_reply;
-	/** Data read call identifier. */
-	aid_t read_request;
-} transfer_info_t;
+
 
 /** Find handle of host controller the device is physically attached to.
@@ -67,30 +45,5 @@
 int usb_drv_find_hc(device_t *dev, devman_handle_t *handle)
 {
-	if (dev == NULL) {
-		return EBADMEM;
-	}
-	if (handle == NULL) {
-		return EBADMEM;
-	}
-
-	int parent_phone = devman_parent_device_connect(dev->handle,
-	    IPC_FLAG_BLOCKING);
-	if (parent_phone < 0) {
-		return parent_phone;
-	}
-
-	devman_handle_t h;
-	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
-
-	async_hangup(parent_phone);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	*handle = h;
-
-	return EOK;
+	return ENOTSUP;
 }
 
@@ -105,5 +58,5 @@
     unsigned int flags)
 {
-	return devman_device_connect(hc_handle, flags);
+	return ENOTSUP;
 }
 
@@ -116,16 +69,5 @@
 int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags)
 {
-	int rc;
-	devman_handle_t hc_handle;
-
-	/*
-	 * Call parent hub to obtain device handle of respective HC.
-	 */
-	rc = usb_drv_find_hc(dev, &hc_handle);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	return usb_drv_hc_connect(dev, hc_handle, flags);
+	return ENOTSUP;
 }
 
@@ -138,14 +80,5 @@
 usb_address_t usb_drv_get_my_address(int phone, device_t *dev)
 {
-	sysarg_t address;
-	int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_GET_ADDRESS,
-	    dev->handle, &address);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	return (usb_address_t) address;
+	return ENOTSUP;
 }
 
@@ -157,6 +90,5 @@
 int usb_drv_reserve_default_address(int phone)
 {
-	return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
+	return ENOTSUP;
 }
 
@@ -168,6 +100,5 @@
 int usb_drv_release_default_address(int phone)
 {
-	return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
+	return ENOTSUP;
 }
 
@@ -179,12 +110,5 @@
 usb_address_t usb_drv_request_address(int phone)
 {
-	sysarg_t address;
-	int rc = async_req_1_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REQUEST_ADDRESS, &address);
-	if (rc != EOK) {
-		return rc;
-	} else {
-		return (usb_address_t) address;
-	}
+	return ENOTSUP;
 }
 
@@ -199,9 +123,5 @@
     devman_handle_t handle)
 {
-	int rc = async_req_3_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_BIND_ADDRESS,
-	    address, handle);
-
-	return rc;
+	return ENOTSUP;
 }
 
@@ -214,132 +134,6 @@
 int usb_drv_release_address(int phone, usb_address_t address)
 {
-	return async_req_2_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RELEASE_ADDRESS, address);
-}
-
-/** Send data to HCD.
- *
- * @param phone Phone to HC.
- * @param method Method used for calling.
- * @param target Targeted device.
- * @param buffer Data buffer (NULL to skip data transfer phase).
- * @param size Buffer size (must be zero when @p buffer is NULL).
- * @param handle Storage for transaction handle (cannot be NULL).
- * @return Error status.
- * @retval EINVAL Invalid parameter.
- * @retval ENOMEM Not enough memory to complete the operation.
- */
-static int async_send_buffer(int phone, int method,
-    usb_target_t target,
-    void *buffer, size_t size,
-    usb_handle_t *handle)
-{
-	if (phone < 0) {
-		return EINVAL;
-	}
-
-	if ((buffer == NULL) && (size > 0)) {
-		return EINVAL;
-	}
-
-	if (handle == NULL) {
-		return EINVAL;
-	}
-
-	transfer_info_t *transfer
-	    = (transfer_info_t *) malloc(sizeof(transfer_info_t));
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->read_request = 0;
-	transfer->size_transferred = NULL;
-	transfer->buffer = NULL;
-	transfer->size = 0;
-	transfer->phone = phone;
-
-	int rc;
-
-	transfer->request = async_send_4(phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    method,
-	    target.address, target.endpoint,
-	    size,
-	    &transfer->reply);
-
-	if (size > 0) {
-		rc = async_data_write_start(phone, buffer, size);
-		if (rc != EOK) {
-			async_wait_for(transfer->request, NULL);
-			return rc;
-		}
-	}
-
-	*handle = (usb_handle_t) transfer;
-
-	return EOK;
-}
-
-/** Prepare data retrieval.
- *
- * @param phone Opened phone to HCD.
- * @param method Method used for calling.
- * @param target Targeted device.
- * @param buffer Buffer where to store retrieved data
- * 	(NULL to skip data transfer phase).
- * @param size Buffer size (must be zero when @p buffer is NULL).
- * @param actual_size Storage where actual number of bytes transferred will
- * 	be stored.
- * @param handle Storage for transaction handle (cannot be NULL).
- * @return Error status.
- * @retval EINVAL Invalid parameter.
- * @retval ENOMEM Not enough memory to complete the operation.
- */
-static int async_recv_buffer(int phone, int method,
-    usb_target_t target,
-    void *buffer, size_t size, size_t *actual_size,
-    usb_handle_t *handle)
-{
-	if (phone < 0) {
-		return EINVAL;
-	}
-
-	if ((buffer == NULL) && (size > 0)) {
-		return EINVAL;
-	}
-
-	if (handle == NULL) {
-		return EINVAL;
-	}
-
-	transfer_info_t *transfer
-	    = (transfer_info_t *) malloc(sizeof(transfer_info_t));
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->read_request = 0;
-	transfer->size_transferred = actual_size;
-	transfer->buffer = buffer;
-	transfer->size = size;
-	transfer->phone = phone;
-
-	transfer->request = async_send_4(phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    method,
-	    target.address, target.endpoint,
-	    size,
-	    &transfer->reply);
-
-	if (buffer != NULL) {
-		transfer->read_request = async_data_read(phone, buffer, size,
-		    &transfer->read_reply);
-	}
-
-	*handle = (usb_handle_t) transfer;
-
-	return EOK;
-}
-
+	return ENOTSUP;
+}
 
 /** Blocks caller until given USB transaction is finished.
@@ -355,42 +149,5 @@
 int usb_drv_async_wait_for(usb_handle_t handle)
 {
-	if (handle == 0) {
-		return EBADMEM;
-	}
-
-	int rc = EOK;
-
-	transfer_info_t *transfer = (transfer_info_t *) handle;
-
-	sysarg_t answer_rc;
-
-	/*
-	 * If the buffer is not NULL, we must accept some data.
-	 */
-	if ((transfer->buffer != NULL) && (transfer->size > 0)) {
-		async_wait_for(transfer->read_request, &answer_rc);
-
-		if (answer_rc != EOK) {
-			rc = (int) answer_rc;
-			goto leave;
-		}
-
-		if (transfer->size_transferred != NULL) {
-			*(transfer->size_transferred)
-			    = IPC_GET_ARG2(transfer->read_reply);
-		}
-	}
-
-	async_wait_for(transfer->request, &answer_rc);
-
-	if (answer_rc != EOK) {
-		rc = (int) answer_rc;
-		goto leave;
-	}
-
-leave:
-	free(transfer);
-
-	return rc;
+	return ENOTSUP;
 }
 
@@ -400,9 +157,5 @@
     usb_handle_t *handle)
 {
-	return async_send_buffer(phone,
-	    IPC_M_USBHC_INTERRUPT_OUT,
-	    target,
-	    buffer, size,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -412,9 +165,5 @@
     usb_handle_t *handle)
 {
-	return async_recv_buffer(phone,
-	    IPC_M_USBHC_INTERRUPT_IN,
-	    target,
-	    buffer, size, actual_size,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -424,9 +173,5 @@
     usb_handle_t *handle)
 {
-	return async_send_buffer(phone,
-	    IPC_M_USBHC_CONTROL_WRITE_SETUP,
-	    target,
-	    buffer, size,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -436,9 +181,5 @@
     usb_handle_t *handle)
 {
-	return async_send_buffer(phone,
-	    IPC_M_USBHC_CONTROL_WRITE_DATA,
-	    target,
-	    buffer, size,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -447,9 +188,5 @@
     usb_handle_t *handle)
 {
-	return async_recv_buffer(phone,
-	    IPC_M_USBHC_CONTROL_WRITE_STATUS,
-	    target,
-	    NULL, 0, NULL,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -460,49 +197,5 @@
     usb_handle_t *handle)
 {
-	// FIXME - check input parameters instead of asserting them
-	assert(phone > 0);
-	assert(setup_packet != NULL);
-	assert(setup_packet_size > 0);
-	assert(((buffer != NULL) && (buffer_size > 0))
-	    || ((buffer == NULL) && (buffer_size == 0)));
-	assert(handle != NULL);
-
-	transfer_info_t *transfer
-	    = (transfer_info_t *) malloc(sizeof(transfer_info_t));
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->read_request = 0;
-	transfer->size_transferred = NULL;
-	transfer->buffer = NULL;
-	transfer->size = 0;
-	transfer->phone = phone;
-
-	int rc;
-
-	transfer->request = async_send_3(phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_CONTROL_WRITE,
-	    target.address, target.endpoint,
-	    &transfer->reply);
-
-	rc = async_data_write_start(phone, setup_packet, setup_packet_size);
-	if (rc != EOK) {
-		async_wait_for(transfer->request, NULL);
-		return rc;
-	}
-
-	if (buffer_size > 0) {
-		rc = async_data_write_start(phone, buffer, buffer_size);
-		if (rc != EOK) {
-			async_wait_for(transfer->request, NULL);
-			return rc;
-		}
-	}
-
-	*handle = (usb_handle_t) transfer;
-
-	return EOK;
+	return ENOTSUP;
 }
 
@@ -512,9 +205,5 @@
     usb_handle_t *handle)
 {
-	return async_send_buffer(phone,
-	    IPC_M_USBHC_CONTROL_READ_SETUP,
-	    target,
-	    buffer, size,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -524,9 +213,5 @@
     usb_handle_t *handle)
 {
-	return async_recv_buffer(phone,
-	    IPC_M_USBHC_CONTROL_READ_DATA,
-	    target,
-	    buffer, size, actual_size,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -535,9 +220,5 @@
     usb_handle_t *handle)
 {
-	return async_send_buffer(phone,
-	    IPC_M_USBHC_CONTROL_READ_STATUS,
-	    target,
-	    NULL, 0,
-	    handle);
+	return ENOTSUP;
 }
 
@@ -548,44 +229,5 @@
     usb_handle_t *handle)
 {
-	// FIXME - check input parameters instead of asserting them
-	assert(phone > 0);
-	assert(setup_packet != NULL);
-	assert(setup_packet_size > 0);
-	assert(buffer != NULL);
-	assert(buffer_size > 0);
-	assert(handle != NULL);
-
-	transfer_info_t *transfer
-	    = (transfer_info_t *) malloc(sizeof(transfer_info_t));
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->size_transferred = actual_size;
-	transfer->buffer = buffer;
-	transfer->size = buffer_size;
-	transfer->phone = phone;
-
-	int rc;
-
-	transfer->request = async_send_4(phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_CONTROL_READ,
-	    target.address, target.endpoint,
-	    buffer_size,
-	    &transfer->reply);
-
-	rc = async_data_write_start(phone, setup_packet, setup_packet_size);
-	if (rc != EOK) {
-		async_wait_for(transfer->request, NULL);
-		return rc;
-	}
-
-	transfer->read_request = async_data_read(phone, buffer, buffer_size,
-	    &transfer->read_reply);
-
-	*handle = (usb_handle_t) transfer;
-
-	return EOK;
+	return ENOTSUP;
 }
 
