Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -38,4 +38,5 @@
 	HW_RES_DEV_IFACE = 0,	
 	CHAR_DEV_IFACE,
+	USB_DEV_IFACE,
 	// TODO add more interfaces
 	DEV_IFACE_MAX
Index: uspace/lib/drv/Makefile
===================================================================
--- uspace/lib/drv/Makefile	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/drv/Makefile	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -29,5 +29,5 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude
+EXTRA_CFLAGS = -Iinclude -I$(LIB_PREFIX)
 LIBRARY = libdrv
 
@@ -36,4 +36,5 @@
 	generic/dev_iface.c \
 	generic/remote_res.c \
+	generic/remote_usb.c \
 	generic/remote_char.c
 
Index: uspace/lib/drv/generic/dev_iface.c
===================================================================
--- uspace/lib/drv/generic/dev_iface.c	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/drv/generic/dev_iface.c	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -39,9 +39,11 @@
 #include "remote_res.h"
 #include "remote_char.h"
+#include "remote_usb.h"
 
 static iface_dipatch_table_t remote_ifaces = {
 	.ifaces = {
 		&remote_res_iface,
-		&remote_char_iface
+		&remote_char_iface,
+		&remote_usb_iface
 	}
 };
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
+++ uspace/lib/drv/generic/remote_usb.c	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/ipc.h>
+#include <async.h>
+#include <errno.h>
+
+#include "usb_iface.h"
+#include "driver.h"
+
+static void remote_usb_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
+//static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
+
+/** Remote USB interface operations. */
+static remote_iface_func_ptr_t remote_usb_iface_ops [] = {
+	&remote_usb_get_buffer,
+	&remote_usb_interrupt_out,
+	&remote_usb_interrupt_in
+};
+
+/** Remote USB interface structure.
+ */
+remote_iface_t remote_usb_iface = {
+	.method_count = sizeof(remote_usb_iface_ops) /
+	    sizeof(remote_usb_iface_ops[0]),
+	.methods = remote_usb_iface_ops
+};
+
+
+
+void remote_usb_get_buffer(device_t *device, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_answer_0(callid, ENOTSUP);
+}
+
+void remote_usb_interrupt_out(device_t *device, void *iface,
+	    ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_answer_0(callid, ENOTSUP);
+}
+
+void remote_usb_interrupt_in(device_t *device, void *iface,
+	    ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_answer_0(callid, ENOTSUP);
+}
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/remote_usb.h
===================================================================
--- uspace/lib/drv/include/remote_usb.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
+++ uspace/lib/drv/include/remote_usb.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBDRV_REMOTE_USB_H_
+#define LIBDRV_REMOTE_USB_H_
+
+remote_iface_t remote_usb_iface;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
+++ uspace/lib/drv/include/usb_iface.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2010 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv usb
+ * @{
+ */
+/** @file
+ * @brief USB interface definition.
+ */
+
+#ifndef LIBDRV_USB_IFACE_H_
+#define LIBDRV_USB_IFACE_H_
+
+#include "driver.h"
+#include <usb/usb.h>
+
+
+/** IPC methods for communication with HC through DDF interface.
+ *
+ * Notes for async methods:
+ *
+ * Methods for sending data to device (OUT transactions)
+ * - e.g. IPC_M_USB_INTERRUPT_OUT -
+ * always use the same semantics:
+ * - first, IPC call with given method is made
+ *   - argument #1 is target address
+ *   - argument #2 is target endpoint
+ *   - argument #3 is buffer size
+ * - this call is immediately followed by IPC data write (from caller)
+ * - the initial call (and the whole transaction) is answer after the
+ *   transaction is scheduled by the HC and acknowledged by the device
+ *   or immediately after error is detected
+ * - the answer carries only the error code
+ *
+ * Methods for retrieving data from device (IN transactions)
+ * - e.g. IPC_M_USB_INTERRUPT_IN -
+ * also use the same semantics:
+ * - first, IPC call with given method is made
+ *   - argument #1 is target address
+ *   - argument #2 is target endpoint
+ *   - argument #3 is buffer size
+ * - the call is not answered until the device returns some data (or until
+ *   error occurs)
+ * - if the call is answered with EOK, first argument of the answer is buffer
+ *   hash that could be used to retrieve the actual data
+ *
+ * Some special methods (NO-DATA transactions) do not send any data. These
+ * might behave as both OUT or IN transactions because communication parts
+ * where actual buffers are exchanged are omitted.
+ *
+ * The mentioned data retrieval can be done any time after receiving EOK
+ * answer to IN method.
+ * This retrieval is done using the IPC_M_USB_GET_BUFFER where
+ * the first argument is buffer hash from call answer.
+ * This call must be immediately followed by data read-in and after the
+ * data are transferred, the initial call (IPC_M_USB_GET_BUFFER)
+ * is answered. Each buffer can be retrieved only once.
+ *
+ * For all these methods, wrap functions exists. Important rule: functions
+ * for IN transactions have (as parameters) buffers where retrieved data
+ * will be stored. These buffers must be already allocated and shall not be
+ * touch until the transaction is completed
+ * (e.g. not before calling usb_wait_for() with appropriate handle).
+ * OUT transactions buffers can be freed immediately after call is dispatched
+ * (i.e. after return from wrapping function).
+ *
+ */
+typedef enum {
+	/** Asks for data buffer.
+	 * See explanation at usb_method_t.
+	 */
+	IPC_M_USB_GET_BUFFER,
+
+
+	/** Send interrupt data to device.
+	 * See explanation at usb_method_t (OUT transaction).
+	 */
+	IPC_M_USB_INTERRUPT_OUT,
+
+	/** Get interrupt data from device.
+	 * See explanation at usb_method_t (IN transaction).
+	 */
+	IPC_M_USB_INTERRUPT_IN,
+
+
+	/** Start WRITE control transfer.
+	 * See explanation at usb_method_t (OUT transaction).
+	 */
+	IPC_M_USB_CONTROL_WRITE_SETUP,
+
+	/** Send control-transfer data to device.
+	 * See explanation at usb_method_t (OUT transaction).
+	 */
+	IPC_M_USB_CONTROL_WRITE_DATA,
+
+	/** Terminate WRITE control transfer.
+	 * See explanation at usb_method_t (NO-DATA transaction).
+	 */
+	IPC_M_USB_CONTROL_WRITE_STATUS,
+
+
+
+	/** Start READ control transfer.
+	 * See explanation at usb_method_t (OUT transaction).
+	 */
+	IPC_M_USB_CONTROL_READ_SETUP,
+
+	/** Get control-transfer data from device.
+	 * See explanation at usb_method_t (IN transaction).
+	 */
+	IPC_M_USB_CONTROL_READ_DATA,
+
+	/** Terminate READ control transfer.
+	 * See explanation at usb_method_t (NO-DATA transaction).
+	 */
+	IPC_M_USB_CONTROL_READ_STATUS,
+
+
+	/* IPC_M_USB_ */
+} usb_iface_funcs_t;
+
+/** Callback for outgoing transfer. */
+typedef void (*usb_iface_transfer_out_callback_t)(device_t *,
+    usb_transaction_outcome_t, void *);
+
+/** Callback for incoming transfer. */
+typedef void (*usb_iface_transfer_in_callback_t)(device_t *,
+    usb_transaction_outcome_t, size_t, void *);
+
+/** USB devices communication interface. */
+typedef struct {
+	int (*interrupt_out)(device_t *, usb_endpoint_t,
+	    void *, size_t,
+	    usb_iface_transfer_out_callback_t, void *);
+	int (*interrupt_in)(device_t *, usb_endpoint_t,
+	    void *, size_t,
+	    usb_iface_transfer_in_callback_t, void *);
+} usb_iface_t;
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/Makefile	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -30,5 +30,5 @@
 LIBRARY = libusb
 LIBS = $(LIBDRV_PREFIX)/libdrv.a
-EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIB_PREFIX)
 
 SOURCES = \
Index: uspace/lib/usb/hcd.c
===================================================================
--- uspace/lib/usb/hcd.c	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/hcd.c	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -58,19 +58,4 @@
 #define NAMESPACE "usb"
 
-
-/** String representation of USB transaction outcome. */
-const char * usb_str_transaction_outcome(usb_transaction_outcome_t o)
-{
-	switch (o) {
-		case USB_OUTCOME_OK:
-			return "ok";
-		case USB_OUTCOME_CRCERROR:
-			return "CRC error";
-		case USB_OUTCOME_BABBLE:
-			return "babble";
-		default:
-			return "unknown";
-	}
-}
 
 /** Create necessary phones for communicating with HCD.
Index: uspace/lib/usb/hcd.h
===================================================================
--- uspace/lib/usb/hcd.h	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/hcd.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -49,10 +49,4 @@
 typedef ipcarg_t usb_transaction_handle_t;
 
-/** USB transaction outcome. */
-typedef enum {
-	USB_OUTCOME_OK,
-	USB_OUTCOME_CRCERROR,
-	USB_OUTCOME_BABBLE
-} usb_transaction_outcome_t;
 
 /** USB packet identifier. */
@@ -83,6 +77,4 @@
 } usb_packet_id;
 
-const char * usb_str_transaction_outcome(usb_transaction_outcome_t o);
-
 /** IPC methods for HCD.
  *
Index: uspace/lib/usb/usb.c
===================================================================
--- uspace/lib/usb/usb.c	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/usb.c	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -54,4 +54,19 @@
 }
 
+/** String representation of USB transaction outcome. */
+const char * usb_str_transaction_outcome(usb_transaction_outcome_t o)
+{
+	switch (o) {
+		case USB_OUTCOME_OK:
+			return "ok";
+		case USB_OUTCOME_CRCERROR:
+			return "CRC error";
+		case USB_OUTCOME_BABBLE:
+			return "babble";
+		default:
+			return "unknown";
+	}
+}
+
 
 /**
Index: uspace/lib/usb/usb.h
===================================================================
--- uspace/lib/usb/usb.h	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/usb.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -55,4 +55,13 @@
 } usb_direction_t;
 
+/** USB transaction outcome. */
+typedef enum {
+	USB_OUTCOME_OK,
+	USB_OUTCOME_CRCERROR,
+	USB_OUTCOME_BABBLE
+} usb_transaction_outcome_t;
+
+const char * usb_str_transaction_outcome(usb_transaction_outcome_t o);
+
 /** USB address type.
  * Negative values could be used to indicate error.
Index: uspace/lib/usb/usbdrv.c
===================================================================
--- uspace/lib/usb/usbdrv.c	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/usbdrv.c	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -34,12 +34,28 @@
  */
 #include "usbdrv.h"
+#include <usb_iface.h>
 #include <errno.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 replay data. */
+	ipc_call_t reply;
+	/** Initial call identifier. */
+	aid_t request;
+} transfer_info_t;
+
 /** Connect to host controller the device is physically attached to.
- * This function sets the phone_parent property in the device_t struct.
  *
  * @param handle Device handle.
  * @param flags Connection flags (blocking connection).
- * @return Error code.
+ * @return Phone to corresponding HC or error code.
  */
 int usb_drv_hc_connect(device_t *dev, unsigned int flags)
@@ -51,4 +67,248 @@
 }
 
+/** Send data to HCD.
+ *
+ * @param phone Phone to HC.
+ * @param method Method used for calling.
+ * @param endpoint Device endpoint.
+ * @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_endpoint_t endpoint,
+    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->size_transferred = NULL;
+	transfer->buffer = NULL;
+	transfer->size = 0;
+	transfer->phone = phone;
+
+	int rc;
+
+	transfer->request = async_send_3(phone,
+	    DEV_IFACE_ID(USB_DEV_IFACE),
+	    method,
+	    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 endpoint Device endpoint.
+ * @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_endpoint_t endpoint,
+    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->size_transferred = actual_size;
+	transfer->buffer = buffer;
+	transfer->size = size;
+	transfer->phone = phone;
+
+	transfer->request = async_send_3(phone,
+	    DEV_IFACE_ID(USB_DEV_IFACE),
+	    method,
+	    endpoint,
+	    size,
+	    &transfer->reply);
+
+	*handle = (usb_handle_t) transfer;
+
+	return EOK;
+}
+
+/** Read buffer from HCD.
+ *
+ * @param phone Opened phone to HCD.
+ * @param hash Buffer hash (obtained after completing IN transaction).
+ * @param buffer Buffer where to store data data.
+ * @param size Buffer size.
+ * @param actual_size Storage where actual number of bytes transferred will
+ * 	be stored.
+ * @return Error status.
+ */
+static int read_buffer_in(int phone, ipcarg_t hash,
+    void *buffer, size_t size, size_t *actual_size)
+{
+	ipc_call_t answer_data;
+	ipcarg_t answer_rc;
+	aid_t req;
+	int rc;
+
+	req = async_send_2(phone,
+	    DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_BUFFER,
+	    hash,
+	    &answer_data);
+
+	rc = async_data_read_start(phone, buffer, size);
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return EINVAL;
+	}
+
+	async_wait_for(req, &answer_rc);
+	rc = (int)answer_rc;
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	*actual_size = IPC_GET_ARG1(answer_data);
+
+	return EOK;
+}
+
+/** Blocks caller until given USB transaction is finished.
+ * After the transaction is finished, the user can access all output data
+ * given to initial call function.
+ *
+ * @param handle Transaction handle.
+ * @return Error status.
+ * @retval EOK No error.
+ * @retval EBADMEM Invalid handle.
+ * @retval ENOENT Data buffer associated with transaction does not exist.
+ */
+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;
+
+	ipcarg_t answer_rc;
+	async_wait_for(transfer->request, &answer_rc);
+
+	if (answer_rc != EOK) {
+		rc = (int) answer_rc;
+		goto leave;
+	}
+
+	/*
+	 * If the buffer is not NULL, we must accept some data.
+	 */
+	if ((transfer->buffer != NULL) && (transfer->size > 0)) {
+		/*
+		 * The buffer hash identifies the data on the server
+		 * side.
+		 * We will use it when actually reading-in the data.
+		 */
+		ipcarg_t buffer_hash = IPC_GET_ARG1(transfer->reply);
+		if (buffer_hash == 0) {
+			rc = ENOENT;
+			goto leave;
+		}
+
+		size_t actual_size;
+		rc = read_buffer_in(transfer->phone, buffer_hash,
+		    transfer->buffer, transfer->size, &actual_size);
+
+		if (rc != EOK) {
+			goto leave;
+		}
+
+		if (transfer->size_transferred) {
+			*(transfer->size_transferred) = actual_size;
+		}
+	}
+
+leave:
+	free(transfer);
+
+	return rc;
+}
+
+/** Send interrupt data to device. */
+int usb_drv_async_interrupt_out(int phone, usb_endpoint_t endpoint,
+    void *buffer, size_t size,
+    usb_handle_t *handle)
+{
+	return async_send_buffer(phone,
+	    IPC_M_USB_INTERRUPT_OUT,
+	    endpoint,
+	    buffer, size,
+	    handle);
+}
+
+/** Request interrupt data from device. */
+int usb_drv_async_interrupt_in(int phone, usb_endpoint_t endpoint,
+    void *buffer, size_t size, size_t *actual_size,
+    usb_handle_t *handle)
+{
+	return async_recv_buffer(phone,
+	    IPC_M_USB_INTERRUPT_IN,
+	    endpoint,
+	    buffer, size, actual_size,
+	    handle);
+}
 
 /**
Index: uspace/lib/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/usbdrv.h	(revision 3f0a7971b0a7536c06012fdd2835873631dfa824)
+++ uspace/lib/usb/usbdrv.h	(revision 91db50ac4a0d8739daf1220f83a40c68c562e4cd)
@@ -41,19 +41,10 @@
 int usb_drv_hc_connect(device_t *, unsigned int);
 
-/** Set endpoint properties (direction, type). */
-int usb_drv_set_endpoint_properties(device_t *, usb_endpoint_t,
-    usb_transfer_type_t, usb_direction_t);
+int usb_drv_async_interrupt_out(int, usb_endpoint_t,
+    void *, size_t, usb_handle_t *);
+int usb_drv_async_interrupt_in(int, usb_endpoint_t,
+    void *, size_t, size_t *, usb_handle_t *);
 
-/* First variant - repeat transfer type. */
-int usb_drv_interrupt_out(device_t *, usb_endpoint_t,
-    void *, size_t, usb_handle_t *);
-
-/* Second variant - let the HC determine transfer type by endpoint number. */
-int usb_drv_transfer_out(device_t *, usb_endpoint_t,
-    void *, size_t, usb_handle_t *);
-
-
-/** Wait for usb_drv_transfer_* to complete. */
-int usb_drv_wait_for(usb_handle_t);
+int usb_drv_async_wait_for(usb_handle_t);
 
 #endif
