Index: uspace/drv/uhci-hcd/iface.c
===================================================================
--- uspace/drv/uhci-hcd/iface.c	(revision 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/drv/uhci-hcd/iface.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -54,5 +54,5 @@
 }
 /*----------------------------------------------------------------------------*/
-static int reserve_default_address(device_t *dev)
+static int reserve_default_address(device_t *dev, usb_speed_t speed)
 {
 	assert(dev);
@@ -72,5 +72,6 @@
 }
 /*----------------------------------------------------------------------------*/
-static int request_address(device_t *dev, usb_address_t *address)
+static int request_address(device_t *dev, usb_speed_t speed,
+    usb_address_t *address)
 {
 	assert(dev);
@@ -163,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 = {
@@ -272,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-rhd/port.c
===================================================================
--- uspace/drv/uhci-rhd/port.c	(revision 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/drv/uhci-rhd/port.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -131,48 +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);
-
-	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);
-	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);
 
@@ -196,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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/drv/uhci-rhd/root_hub.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/drv/usbhub/usbhub.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -50,6 +50,11 @@
 #include "usb/usb.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
 };
 
Index: uspace/drv/vhc/connhost.c
===================================================================
--- uspace/drv/vhc/connhost.c	(revision 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/drv/vhc/connhost.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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)
+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, 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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/c/generic/str_error.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/c/include/errno.h	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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
@@ -165,6 +151,8 @@
 		return;
 	}
-
-	int rc = usb_iface->reserve_default_address(device);
+	
+	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
+	
+	int rc = usb_iface->reserve_default_address(device, speed);
 
 	async_answer_0(callid, rc);
@@ -195,7 +183,9 @@
 		return;
 	}
+	
+	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
 
 	usb_address_t address;
-	int rc = usb_iface->request_address(device, &address);
+	int rc = usb_iface->request_address(device, speed, &address);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -293,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),
@@ -301,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;
 	}
 
@@ -324,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);
@@ -350,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),
@@ -356,4 +345,5 @@
 	};
 
+	size_t len;
 	ipc_callid_t data_callid;
 	if (!async_data_read_receive(&data_callid, &len)) {
@@ -371,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);
@@ -381,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)
@@ -467,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);
 }
 
@@ -545,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;
@@ -580,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,
@@ -607,4 +470,5 @@
 		.endpoint = DEV_IPC_GET_ARG2(*call)
 	};
+	size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
 
 	int rc;
@@ -644,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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -40,4 +40,5 @@
 #include "driver.h"
 #include <usb/usb.h>
+#include <bool.h>
 
 
@@ -52,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
@@ -65,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
@@ -152,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
@@ -193,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,
@@ -231,7 +198,7 @@
 	int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
 
-	int (*reserve_default_address)(device_t *);
+	int (*reserve_default_address)(device_t *, usb_speed_t);
 	int (*release_default_address)(device_t *);
-	int (*request_address)(device_t *, 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);
@@ -239,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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/usb/include/usb/hub.h	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -39,4 +39,7 @@
 #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.
  *
@@ -52,8 +55,8 @@
 } usb_hc_attached_device_t;
 
-int usb_hc_reserve_default_address(usb_hc_connection_t *);
+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 *);
+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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/usb/include/usb/usb.h	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/usb/src/hub.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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>
@@ -55,5 +58,20 @@
  * @return Error code.
  */
-int usb_hc_reserve_default_address(usb_hc_connection_t *connection)
+int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
+    usb_speed_t speed)
+{
+	CHECK_CONNECTION(connection);
+
+	return async_req_2_0(connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
+}
+
+/** Tell host controller to release default address.
+ *
+ * @param connection Opened connection to host controller.
+ * @return Error code.
+ */
+int usb_hc_release_default_address(usb_hc_connection_t *connection)
 {
 	CHECK_CONNECTION(connection);
@@ -61,18 +79,4 @@
 	return async_req_1_0(connection->hc_phone,
 	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
-}
-
-/** Tell host controller to release default address.
- *
- * @param connection Opened connection to host controller.
- * @return Error code.
- */
-int usb_hc_release_default_address(usb_hc_connection_t *connection)
-{
-	CHECK_CONNECTION(connection);
-
-	return async_req_1_0(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
 	    IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
 }
@@ -83,12 +87,14 @@
  * @return Assigned USB address or negative error code.
  */
-usb_address_t usb_hc_request_address(usb_hc_connection_t *connection)
+usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
+    usb_speed_t speed)
 {
 	CHECK_CONNECTION(connection);
 
 	sysarg_t address;
-	int rc = async_req_1_1(connection->hc_phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REQUEST_ADDRESS, &address);
+	int rc = async_req_2_1(connection->hc_phone,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_REQUEST_ADDRESS, speed,
+	    &address);
 	if (rc != EOK) {
 		return (usb_address_t) rc;
@@ -135,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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/usb/src/pipes.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/usb/src/pipesio.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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 7e7f0f558abaec0c4a4e6db35548233dc9e33afe)
+++ uspace/lib/usb/src/usbdrv.c	(revision 6edc69a4683d97891cd9d9dd003acba51a97bb93)
@@ -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;
 }
 
