Index: uspace/lib/usb/Makefile
===================================================================
--- uspace/lib/usb/Makefile	(revision c7137738c048f4d114777abf95ab228e771e4627)
+++ 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 c7137738c048f4d114777abf95ab228e771e4627)
+++ 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 c7137738c048f4d114777abf95ab228e771e4627)
+++ 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 c7137738c048f4d114777abf95ab228e771e4627)
+++ 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 c7137738c048f4d114777abf95ab228e771e4627)
+++ 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 c7137738c048f4d114777abf95ab228e771e4627)
+++ 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 c7137738c048f4d114777abf95ab228e771e4627)
+++ 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
