Index: uspace/lib/drv/generic/private/remote_usbhc.h
===================================================================
--- uspace/lib/drv/generic/private/remote_usbhc.h	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/drv/generic/private/remote_usbhc.h	(revision e76c0ea8f951c2e63efa8e948fc849e59dec918b)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2010 Vojtech Horky
+ * Copyright (c) 2017 Ondrej Hlavaty
  * All rights reserved.
  *
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/drv/generic/remote_usb.c	(revision e76c0ea8f951c2e63efa8e948fc849e59dec918b)
@@ -63,12 +63,4 @@
 	IPC_M_USB_GET_MY_INTERFACE,
 	IPC_M_USB_GET_MY_DEVICE_HANDLE,
-	IPC_M_USB_RESERVE_DEFAULT_ADDRESS,
-	IPC_M_USB_RELEASE_DEFAULT_ADDRESS,
-	IPC_M_USB_DEVICE_ENUMERATE,
-	IPC_M_USB_DEVICE_REMOVE,
-	IPC_M_USB_REGISTER_ENDPOINT,
-	IPC_M_USB_UNREGISTER_ENDPOINT,
-	IPC_M_USB_READ,
-	IPC_M_USB_WRITE,
 } usb_iface_funcs_t;
 
@@ -109,192 +101,6 @@
 }
 
-/** Reserve default USB address.
- * @param[in] exch IPC communication exchange
- * @param[in] speed Communication speed of the newly attached device
- * @return Error code.
- */
-int usb_reserve_default_address(async_exch_t *exch, usb_speed_t speed)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed);
-}
-
-/** Release default USB address.
- *
- * @param[in] exch IPC communication exchange
- *
- * @return Error code.
- *
- */
-int usb_release_default_address(async_exch_t *exch)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_1_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
-}
-
-/** Trigger USB device enumeration
- *
- * @param[in]  exch   IPC communication exchange
- * @param[out] handle Identifier of the newly added device (if successful)
- *
- * @return Error code.
- *
- */
-int usb_device_enumerate(async_exch_t *exch, unsigned port)
-{
-	if (!exch)
-		return EBADMEM;
-	const int ret = async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_DEVICE_ENUMERATE, port);
-	return ret;
-}
-
-/** Trigger USB device enumeration
- *
- * @param[in] exch   IPC communication exchange
- * @param[in] handle Identifier of the device
- *
- * @return Error code.
- *
- */
-int usb_device_remove(async_exch_t *exch, unsigned port)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_2_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_DEVICE_REMOVE, port);
-}
-
-static_assert(sizeof(sysarg_t) >= 4);
-
-typedef union {
-	uint8_t arr[sizeof(sysarg_t)];
-	sysarg_t arg;
-} pack8_t;
-
-int usb_register_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
-    usb_transfer_type_t type, usb_direction_t direction,
-    size_t mps, unsigned packets, unsigned interval)
-{
-	if (!exch)
-		return EBADMEM;
-	pack8_t pack;
-	pack.arr[0] = type;
-	pack.arr[1] = direction;
-	pack.arr[2] = interval;
-	pack.arr[3] = packets;
-
-	return async_req_4_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_REGISTER_ENDPOINT, endpoint, pack.arg, mps);
-
-}
-
-int usb_unregister_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
-    usb_direction_t direction)
-{
-	if (!exch)
-		return EBADMEM;
-	return async_req_3_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
-	    IPC_M_USB_UNREGISTER_ENDPOINT, endpoint, direction);
-}
-
-int usb_read(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup,
-    void *data, size_t size, size_t *rec_size)
-{
-	if (!exch)
-		return EBADMEM;
-
-	if (size == 0 && setup == 0)
-		return EOK;
-
-	/* Make call identifying target USB device and type of transfer. */
-	aid_t opening_request = async_send_4(exch,
-	    DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_READ, endpoint,
-	    (setup & UINT32_MAX), (setup >> 32), NULL);
-
-	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-	/* Retrieve the data. */
-	ipc_call_t data_request_call;
-	aid_t data_request =
-	    async_data_read(exch, data, size, &data_request_call);
-
-	if (data_request == 0) {
-		// FIXME: How to let the other side know that we want to abort?
-		async_forget(opening_request);
-		return ENOMEM;
-	}
-
-	/* Wait for the answer. */
-	sysarg_t data_request_rc;
-	sysarg_t opening_request_rc;
-	async_wait_for(data_request, &data_request_rc);
-	async_wait_for(opening_request, &opening_request_rc);
-
-	if (data_request_rc != EOK) {
-		/* Prefer the return code of the opening request. */
-		if (opening_request_rc != EOK) {
-			return (int) opening_request_rc;
-		} else {
-			return (int) data_request_rc;
-		}
-	}
-	if (opening_request_rc != EOK) {
-		return (int) opening_request_rc;
-	}
-
-	*rec_size = IPC_GET_ARG2(data_request_call);
-	return EOK;
-}
-
-int usb_write(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup,
-    const void *data, size_t size)
-{
-	if (!exch)
-		return EBADMEM;
-
-	if (size == 0 && setup == 0)
-		return EOK;
-
-	aid_t opening_request = async_send_5(exch,
-	    DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_WRITE, endpoint, size,
-	    (setup & UINT32_MAX), (setup >> 32), NULL);
-
-	if (opening_request == 0) {
-		return ENOMEM;
-	}
-
-	/* Send the data if any. */
-	if (size > 0) {
-		const int ret = async_data_write_start(exch, data, size);
-		if (ret != EOK) {
-			async_forget(opening_request);
-			return ret;
-		}
-	}
-
-	/* Wait for the answer. */
-	sysarg_t opening_request_rc;
-	async_wait_for(opening_request, &opening_request_rc);
-
-	return (int) opening_request_rc;
-}
-
 static void remote_usb_get_my_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usb_get_my_device_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_read(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call);
-static void remote_usb_write(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call);
 
 /** Remote USB interface operations. */
@@ -302,12 +108,4 @@
 	[IPC_M_USB_GET_MY_INTERFACE] = remote_usb_get_my_interface,
 	[IPC_M_USB_GET_MY_DEVICE_HANDLE] = remote_usb_get_my_device_handle,
-	[IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usb_reserve_default_address,
-	[IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usb_release_default_address,
-	[IPC_M_USB_DEVICE_ENUMERATE] = remote_usb_device_enumerate,
-	[IPC_M_USB_DEVICE_REMOVE] = remote_usb_device_remove,
-	[IPC_M_USB_REGISTER_ENDPOINT] = remote_usb_register_endpoint,
-	[IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usb_unregister_endpoint,
-	[IPC_M_USB_READ] = remote_usb_read,
-	[IPC_M_USB_WRITE] = remote_usb_write,
 };
 
@@ -357,266 +155,4 @@
 }
 
-void remote_usb_reserve_default_address(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
-
-	if (usb_iface->reserve_default_address == NULL) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
-	const int ret = usb_iface->reserve_default_address(fun, speed);
-	async_answer_0(callid, ret);
-}
-
-void remote_usb_release_default_address(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
-
-	if (usb_iface->release_default_address == NULL) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const int ret = usb_iface->release_default_address(fun);
-	async_answer_0(callid, ret);
-}
-
-static void remote_usb_device_enumerate(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
-
-	if (usb_iface->device_enumerate == NULL) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const unsigned port = DEV_IPC_GET_ARG1(*call);
-	const int ret = usb_iface->device_enumerate(fun, port);
-	async_answer_0(callid, ret);
-}
-
-static void remote_usb_device_remove(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	const usb_iface_t *usb_iface = (usb_iface_t *) iface;
-
-	if (usb_iface->device_remove == NULL) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const unsigned port = DEV_IPC_GET_ARG1(*call);
-	const int ret = usb_iface->device_remove(fun, port);
-	async_answer_0(callid, ret);
-}
-
-static void remote_usb_register_endpoint(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	usb_iface_t *usb_iface = (usb_iface_t *) iface;
-
-	if (!usb_iface->register_endpoint) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_endpoint_t endpoint = DEV_IPC_GET_ARG1(*call);
-	const pack8_t pack = { .arg = DEV_IPC_GET_ARG2(*call)};
-	const size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
-
-	const usb_transfer_type_t transfer_type = pack.arr[0];
-	const usb_direction_t direction = pack.arr[1];
-	unsigned packets = pack.arr[2];
-	unsigned interval = pack.arr[3];
-
-	const int ret = usb_iface->register_endpoint(fun, endpoint,
-	    transfer_type, direction, max_packet_size, packets, interval);
-
-	async_answer_0(callid, ret);
-}
-
-static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	usb_iface_t *usb_iface = (usb_iface_t *) iface;
-
-	if (!usb_iface->unregister_endpoint) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG1(*call);
-	usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG2(*call);
-
-	int rc = usb_iface->unregister_endpoint(fun, endpoint, direction);
-
-	async_answer_0(callid, rc);
-}
-
-typedef struct {
-	ipc_callid_t caller;
-	ipc_callid_t data_caller;
-	void *buffer;
-} async_transaction_t;
-
-static void async_transaction_destroy(async_transaction_t *trans)
-{
-	if (trans == NULL) {
-		return;
-	}
-	if (trans->buffer != NULL) {
-		free(trans->buffer);
-	}
-
-	free(trans);
-}
-
-static async_transaction_t *async_transaction_create(ipc_callid_t caller)
-{
-	async_transaction_t *trans = malloc(sizeof(async_transaction_t));
-	if (trans == NULL) {
-		return NULL;
-	}
-
-	trans->caller = caller;
-	trans->data_caller = 0;
-	trans->buffer = NULL;
-
-	return trans;
-}
-
-static void callback_out(int outcome, void *arg)
-{
-	async_transaction_t *trans = arg;
-
-	async_answer_0(trans->caller, outcome);
-
-	async_transaction_destroy(trans);
-}
-
-static void callback_in(int outcome, size_t actual_size, void *arg)
-{
-	async_transaction_t *trans = (async_transaction_t *)arg;
-
-	if (outcome != EOK) {
-		async_answer_0(trans->caller, outcome);
-		if (trans->data_caller) {
-			async_answer_0(trans->data_caller, EINTR);
-		}
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	if (trans->data_caller) {
-		async_data_read_finalize(trans->data_caller,
-		    trans->buffer, actual_size);
-	}
-
-	async_answer_0(trans->caller, EOK);
-
-	async_transaction_destroy(trans);
-}
-
-void remote_usb_read(
-    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
-{
-	assert(fun);
-	assert(iface);
-	assert(call);
-
-	const usb_iface_t *usb_iface = iface;
-
-	if (!usb_iface->read) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call);
-	const uint64_t setup =
-	    ((uint64_t)DEV_IPC_GET_ARG2(*call)) |
-	    (((uint64_t)DEV_IPC_GET_ARG3(*call)) << 32);
-
-	async_transaction_t *trans = async_transaction_create(callid);
-	if (trans == NULL) {
-		async_answer_0(callid, ENOMEM);
-		return;
-	}
-
-	size_t size = 0;
-	if (!async_data_read_receive(&trans->data_caller, &size)) {
-		async_answer_0(callid, EPARTY);
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	trans->buffer = malloc(size);
-	if (trans->buffer == NULL) {
-		async_answer_0(trans->data_caller, ENOMEM);
-		async_answer_0(callid, ENOMEM);
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	const int rc = usb_iface->read(
-	    fun, ep, setup, trans->buffer, size, callback_in, trans);
-
-	if (rc != EOK) {
-		async_answer_0(trans->data_caller, rc);
-		async_answer_0(callid, rc);
-		async_transaction_destroy(trans);
-	}
-}
-
-void remote_usb_write(
-    ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
-{
-	assert(fun);
-	assert(iface);
-	assert(call);
-
-	const usb_iface_t *usb_iface = iface;
-
-	if (!usb_iface->write) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call);
-	const size_t data_buffer_len = DEV_IPC_GET_ARG2(*call);
-	const uint64_t setup =
-	    ((uint64_t)DEV_IPC_GET_ARG3(*call)) |
-	    (((uint64_t)DEV_IPC_GET_ARG4(*call)) << 32);
-
-	async_transaction_t *trans = async_transaction_create(callid);
-	if (trans == NULL) {
-		async_answer_0(callid, ENOMEM);
-		return;
-	}
-
-	size_t size = 0;
-	if (data_buffer_len > 0) {
-		const int rc = async_data_write_accept(&trans->buffer, false,
-		    1, data_buffer_len, 0, &size);
-
-		if (rc != EOK) {
-			async_answer_0(callid, rc);
-			async_transaction_destroy(trans);
-			return;
-		}
-	}
-
-	const int rc = usb_iface->write(
-	    fun, ep, setup, trans->buffer, size, callback_out, trans);
-
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_transaction_destroy(trans);
-	}
-}
 /**
  * @}
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision e76c0ea8f951c2e63efa8e948fc849e59dec918b)
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2010-2011 Vojtech Horky
+ * Copyright (c) 2010 Vojtech Horky
  * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2017 Ondrej Hlavaty
  * All rights reserved.
  *
@@ -35,68 +36,147 @@
 
 #include <async.h>
+#include <macros.h>
 #include <errno.h>
-#include <assert.h>
-#include <macros.h>
+#include <devman.h>
 
 #include "usbhc_iface.h"
 #include "ddf/driver.h"
 
-#define USB_MAX_PAYLOAD_SIZE 1020
-
-/** 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_USBHC_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 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
- *   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_USBHC_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
- * - this call is immediately followed by IPC data read (async version)
- * - the call is not answered until the device returns some data (or until
- *   error occurs)
- *
- * 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.
- **
- * 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 {
-	/** Get data from device.
-	 * See explanation at usb_iface_funcs_t (IN transaction).
-	 */
-	IPC_M_USBHC_READ,
-
-	/** Send data to device.
-	 * See explanation at usb_iface_funcs_t (OUT transaction).
-	 */
-	IPC_M_USBHC_WRITE,
+	IPC_M_USB_RESERVE_DEFAULT_ADDRESS,
+	IPC_M_USB_RELEASE_DEFAULT_ADDRESS,
+	IPC_M_USB_DEVICE_ENUMERATE,
+	IPC_M_USB_DEVICE_REMOVE,
+	IPC_M_USB_REGISTER_ENDPOINT,
+	IPC_M_USB_UNREGISTER_ENDPOINT,
+	IPC_M_USB_READ,
+	IPC_M_USB_WRITE,
 } usbhc_iface_funcs_t;
 
-int usbhc_read(async_exch_t *exch, usb_address_t address,
-    usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size,
-    size_t *rec_size)
+/** Reserve default USB address.
+ * @param[in] exch IPC communication exchange
+ * @param[in] speed Communication speed of the newly attached device
+ * @return Error code.
+ */
+int usbhc_reserve_default_address(async_exch_t *exch, usb_speed_t speed)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USB_RESERVE_DEFAULT_ADDRESS, speed);
+}
+
+/** Release default USB address.
+ *
+ * @param[in] exch IPC communication exchange
+ *
+ * @return Error code.
+ *
+ */
+int usbhc_release_default_address(async_exch_t *exch)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_1_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USB_RELEASE_DEFAULT_ADDRESS);
+}
+
+/** Trigger USB device enumeration
+ *
+ * @param[in]  exch   IPC communication exchange
+ * @param[out] handle Identifier of the newly added device (if successful)
+ *
+ * @return Error code.
+ *
+ */
+int usbhc_device_enumerate(async_exch_t *exch, unsigned port)
+{
+	if (!exch)
+		return EBADMEM;
+	const int ret = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USB_DEVICE_ENUMERATE, port);
+	return ret;
+}
+
+/** Trigger USB device enumeration
+ *
+ * @param[in] exch   IPC communication exchange
+ * @param[in] handle Identifier of the device
+ *
+ * @return Error code.
+ *
+ */
+int usbhc_device_remove(async_exch_t *exch, unsigned port)
+{
+	if (!exch)
+		return EBADMEM;
+	return async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USB_DEVICE_REMOVE, port);
+}
+
+int static_assert[sizeof(sysarg_t) >= 4 ? 1 : -1];
+typedef union {
+	uint8_t arr[sizeof(sysarg_t)];
+	sysarg_t arg;
+} pack8_t;
+
+int usbhc_register_endpoint(async_exch_t *exch,
+	usb_endpoint_desc_t *endpoint_desc)
+{
+	if (!exch)
+		return EBADMEM;
+
+	aid_t opening_request = async_send_1(exch,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_REGISTER_ENDPOINT, NULL);
+
+	if (opening_request == 0) {
+		return ENOMEM;
+	}
+
+	const int ret = async_data_write_start(exch, (void *) endpoint_desc,
+		sizeof(usb_endpoint_desc_t));
+
+	if (ret != EOK) {
+		async_forget(opening_request);
+		return ret;
+	}
+
+	/* Wait for the answer. */
+	sysarg_t opening_request_rc;
+	async_wait_for(opening_request, &opening_request_rc);
+
+	return (int) opening_request_rc;
+}
+
+int usbhc_unregister_endpoint(async_exch_t *exch,
+	usb_endpoint_desc_t *endpoint_desc)
+{
+	if (!exch)
+		return EBADMEM;
+
+	aid_t opening_request = async_send_1(exch,
+		DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_UNREGISTER_ENDPOINT, NULL);
+
+	if (opening_request == 0) {
+		return ENOMEM;
+	}
+
+	const int ret = async_data_write_start(exch, endpoint_desc,
+		sizeof(usb_endpoint_desc_t));
+	if (ret != EOK) {
+		async_forget(opening_request);
+		return ret;
+	}
+
+	/* Wait for the answer. */
+	sysarg_t opening_request_rc;
+	async_wait_for(opening_request, &opening_request_rc);
+
+	return (int) opening_request_rc;
+}
+
+int usbhc_read(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup,
+    void *data, size_t size, size_t *rec_size)
 {
 	if (!exch)
@@ -106,11 +186,7 @@
 		return EOK;
 
-	const usb_target_t target =
-	    {{ .address = address, .endpoint = endpoint }};
-
 	/* Make call identifying target USB device and type of transfer. */
 	aid_t opening_request = async_send_4(exch,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_READ, target.packed,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_READ, endpoint,
 	    (setup & UINT32_MAX), (setup >> 32), NULL);
 
@@ -152,6 +228,6 @@
 }
 
-int usbhc_write(async_exch_t *exch, usb_address_t address,
-    usb_endpoint_t endpoint, uint64_t setup, const void *data, size_t size)
+int usbhc_write(async_exch_t *exch, usb_endpoint_t endpoint, uint64_t setup,
+    const void *data, size_t size)
 {
 	if (!exch)
@@ -161,9 +237,6 @@
 		return EOK;
 
-	const usb_target_t target =
-	    {{ .address = address, .endpoint = endpoint }};
-
-	aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_WRITE, target.packed, size,
+	aid_t opening_request = async_send_5(exch,
+	    DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USB_WRITE, endpoint, size,
 	    (setup & UINT32_MAX), (setup >> 32), NULL);
 
@@ -188,18 +261,30 @@
 }
 
-static void remote_usbhc_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
-
-/** Remote USB host controller interface operations. */
-static const remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
-	[IPC_M_USBHC_READ] = remote_usbhc_read,
-	[IPC_M_USBHC_WRITE] = remote_usbhc_write,
+static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_device_enumerate(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_device_remove(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_read(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call);
+static void remote_usbhc_write(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call);
+
+/** Remote USB interface operations. */
+static const remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
+	[IPC_M_USB_RESERVE_DEFAULT_ADDRESS] = remote_usbhc_reserve_default_address,
+	[IPC_M_USB_RELEASE_DEFAULT_ADDRESS] = remote_usbhc_release_default_address,
+	[IPC_M_USB_DEVICE_ENUMERATE] = remote_usbhc_device_enumerate,
+	[IPC_M_USB_DEVICE_REMOVE] = remote_usbhc_device_remove,
+	[IPC_M_USB_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint,
+	[IPC_M_USB_UNREGISTER_ENDPOINT] = remote_usbhc_unregister_endpoint,
+	[IPC_M_USB_READ] = remote_usbhc_read,
+	[IPC_M_USB_WRITE] = remote_usbhc_write,
 };
 
-/** Remote USB host controller interface structure.
+/** Remote USB interface structure.
  */
 const remote_iface_t remote_usbhc_iface = {
 	.method_count = ARRAY_SIZE(remote_usbhc_iface_ops),
-	.methods = remote_usbhc_iface_ops
+	.methods = remote_usbhc_iface_ops,
 };
 
@@ -210,12 +295,136 @@
 } async_transaction_t;
 
+void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface;
+
+	if (usbhc_iface->reserve_default_address == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
+	const int ret = usbhc_iface->reserve_default_address(fun, speed);
+	async_answer_0(callid, ret);
+}
+
+void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface;
+
+	if (usbhc_iface->release_default_address == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	const int ret = usbhc_iface->release_default_address(fun);
+	async_answer_0(callid, ret);
+}
+
+static void remote_usbhc_device_enumerate(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface;
+
+	if (usbhc_iface->device_enumerate == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	const unsigned port = DEV_IPC_GET_ARG1(*call);
+	const int ret = usbhc_iface->device_enumerate(fun, port);
+	async_answer_0(callid, ret);
+}
+
+static void remote_usbhc_device_remove(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	const usbhc_iface_t *usbhc_iface = (usbhc_iface_t *) iface;
+
+	if (usbhc_iface->device_remove == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	const unsigned port = DEV_IPC_GET_ARG1(*call);
+	const int ret = usbhc_iface->device_remove(fun, port);
+	async_answer_0(callid, ret);
+}
+
+static void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(fun);
+	assert(iface);
+	assert(call);
+
+	const usbhc_iface_t *usbhc_iface = iface;
+
+	if (!usbhc_iface->register_endpoint) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	void *buffer = NULL;
+	size_t size = 0;
+	int rc = async_data_write_accept(&buffer, false,
+		sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size);
+
+	if (rc != EOK) {
+		free(buffer);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer;
+	rc = usbhc_iface->register_endpoint(fun, endpoint_desc);
+
+	free(buffer);
+	async_answer_0(callid, rc);
+}
+
+static void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	assert(fun);
+	assert(iface);
+	assert(call);
+
+	const usbhc_iface_t *usbhc_iface = iface;
+
+	if (!usbhc_iface->unregister_endpoint) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	void *buffer = NULL;
+	size_t size = 0;
+	int rc = async_data_write_accept(&buffer, false,
+		sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size);
+
+	if (rc != EOK) {
+		free(buffer);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer;
+	usbhc_iface->unregister_endpoint(fun, endpoint_desc);
+
+	free(buffer);
+	async_answer_0(callid, rc);
+}
+
 static void async_transaction_destroy(async_transaction_t *trans)
 {
-	if (trans == NULL)
-		return;
-	
-	if (trans->buffer != NULL)
+	if (trans == NULL) {
+		return;
+	}
+	if (trans->buffer != NULL) {
 		free(trans->buffer);
-	
+	}
+
 	free(trans);
 }
@@ -235,34 +444,31 @@
 }
 
-static void callback_out(int outcome, void *arg)
+static int callback_out(void *arg, int error, size_t transfered_size)
 {
 	async_transaction_t *trans = arg;
 
-	async_answer_0(trans->caller, outcome);
+	const int err = async_answer_0(trans->caller, error);
 
 	async_transaction_destroy(trans);
-}
-
-static void callback_in(int outcome, size_t actual_size, void *arg)
-{
-	async_transaction_t *trans = (async_transaction_t *)arg;
-
-	if (outcome != EOK) {
-		async_answer_0(trans->caller, outcome);
-		if (trans->data_caller) {
+
+	return err;
+}
+
+static int callback_in(void *arg, int error, size_t transfered_size)
+{
+	async_transaction_t *trans = arg;
+
+	if (trans->data_caller) {
+		if (error == EOK) {
+			error = async_data_read_finalize(trans->data_caller,
+			    trans->buffer, transfered_size);
+		} else {
 			async_answer_0(trans->data_caller, EINTR);
 		}
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	if (trans->data_caller) {
-		async_data_read_finalize(trans->data_caller,
-		    trans->buffer, actual_size);
-	}
-
-	async_answer_0(trans->caller, EOK);
-
+	}
+
+	const int err = async_answer_0(trans->caller, error);
 	async_transaction_destroy(trans);
+	return err;
 }
 
@@ -274,12 +480,12 @@
 	assert(call);
 
-	const usbhc_iface_t *hc_iface = iface;
-
-	if (!hc_iface->read) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };
+	const usbhc_iface_t *usbhc_iface = iface;
+
+	if (!usbhc_iface->read) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call);
 	const uint64_t setup =
 	    ((uint64_t)DEV_IPC_GET_ARG2(*call)) |
@@ -295,4 +501,5 @@
 	if (!async_data_read_receive(&trans->data_caller, &size)) {
 		async_answer_0(callid, EPARTY);
+		async_transaction_destroy(trans);
 		return;
 	}
@@ -306,5 +513,10 @@
 	}
 
-	const int rc = hc_iface->read(
+	const usb_target_t target = {{
+		/* .address is initialized by read itself */
+		.endpoint = ep,
+	}};
+
+	const int rc = usbhc_iface->read(
 	    fun, target, setup, trans->buffer, size, callback_in, trans);
 
@@ -323,12 +535,12 @@
 	assert(call);
 
-	const usbhc_iface_t *hc_iface = iface;
-
-	if (!hc_iface->write) {
-		async_answer_0(callid, ENOTSUP);
-		return;
-	}
-
-	const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };
+	const usbhc_iface_t *usbhc_iface = iface;
+
+	if (!usbhc_iface->write) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+
+	const usb_endpoint_t ep = DEV_IPC_GET_ARG1(*call);
 	const size_t data_buffer_len = DEV_IPC_GET_ARG2(*call);
 	const uint64_t setup =
@@ -345,6 +557,5 @@
 	if (data_buffer_len > 0) {
 		const int rc = async_data_write_accept(&trans->buffer, false,
-		    1, USB_MAX_PAYLOAD_SIZE,
-		    0, &size);
+		    1, data_buffer_len, 0, &size);
 
 		if (rc != EOK) {
@@ -355,5 +566,10 @@
 	}
 
-	const int rc = hc_iface->write(
+	const usb_target_t target = {{
+		/* .address is initialized by write itself */
+		.endpoint = ep,
+	}};
+
+	const int rc = usbhc_iface->write(
 	    fun, target, setup, trans->buffer, size, callback_out, trans);
 
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/drv/include/usb_iface.h	(revision e76c0ea8f951c2e63efa8e948fc849e59dec918b)
@@ -32,5 +32,5 @@
  */
 /** @file
- * @brief USB interface definition.
+ * @brief USB device interface definition.
  */
 
@@ -51,4 +51,6 @@
 	/** USB 2.0 high speed (480Mbits/s). */
 	USB_SPEED_HIGH,
+	/** USB 3.0 super speed (5Gbits/s). */
+	USB_SPEED_SUPER,
 	/** Psuedo-speed serving as a boundary. */
 	USB_SPEED_MAX
@@ -64,4 +66,11 @@
  */
 typedef int16_t usb_address_t;
+
+/** USB address for the purposes of Transaction Translation.
+ */
+typedef struct {
+	usb_address_t address;
+	unsigned port;
+} usb_tt_address_t;
 
 /** USB transfer type. */
@@ -91,4 +100,34 @@
 } usb_target_t;
 
+/** Description of usb endpoint.
+ */
+typedef struct {
+	/** Endpoint number. */
+	usb_endpoint_t endpoint_no;
+
+	/** Endpoint transfer type. */
+	usb_transfer_type_t transfer_type;
+
+	/** Endpoint direction. */
+	usb_direction_t direction;
+
+	/** Maximum packet size for the endpoint. */
+	size_t max_packet_size;
+
+	/** Number of packets per frame/uframe.
+	 * Only valid for HS INT and ISO transfers. All others should set to 1*/
+	unsigned packets;
+
+	struct {
+		unsigned polling_interval;
+	} usb2;
+
+	struct {
+		unsigned max_burst;
+		unsigned max_streams;
+	} usb3;
+} usb_endpoint_desc_t;
+
+
 extern usb_dev_session_t *usb_dev_connect(devman_handle_t);
 extern usb_dev_session_t *usb_dev_connect_to_self(ddf_dev_t *);
@@ -98,45 +137,8 @@
 extern int usb_get_my_device_handle(async_exch_t *, devman_handle_t *);
 
-extern int usb_reserve_default_address(async_exch_t *, usb_speed_t);
-extern int usb_release_default_address(async_exch_t *);
-
-extern int usb_device_enumerate(async_exch_t *, unsigned port);
-extern int usb_device_remove(async_exch_t *, unsigned port);
-
-extern int usb_register_endpoint(async_exch_t *, usb_endpoint_t,
-    usb_transfer_type_t, usb_direction_t, size_t, unsigned, unsigned);
-extern int usb_unregister_endpoint(async_exch_t *, usb_endpoint_t,
-    usb_direction_t);
-extern int usb_read(async_exch_t *, usb_endpoint_t, uint64_t, void *, size_t,
-    size_t *);
-extern int usb_write(async_exch_t *, usb_endpoint_t, uint64_t, const void *,
-    size_t);
-
-/** Callback for outgoing transfer. */
-typedef void (*usb_iface_transfer_out_callback_t)(int, void *);
-
-/** Callback for incoming transfer. */
-typedef void (*usb_iface_transfer_in_callback_t)(int, size_t, void *);
-
 /** USB device communication interface. */
 typedef struct {
 	int (*get_my_interface)(ddf_fun_t *, int *);
 	int (*get_my_device_handle)(ddf_fun_t *, devman_handle_t *);
-
-	int (*reserve_default_address)(ddf_fun_t *, usb_speed_t);
-	int (*release_default_address)(ddf_fun_t *);
-
-	int (*device_enumerate)(ddf_fun_t *, unsigned);
-	int (*device_remove)(ddf_fun_t *, unsigned);
-
-	int (*register_endpoint)(ddf_fun_t *, usb_endpoint_t,
-	    usb_transfer_type_t, usb_direction_t, size_t, unsigned, unsigned);
-	int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_t,
-	    usb_direction_t);
-
-	int (*read)(ddf_fun_t *, usb_endpoint_t, uint64_t, uint8_t *, size_t,
-	    usb_iface_transfer_in_callback_t, void *);
-	int (*write)(ddf_fun_t *, usb_endpoint_t, uint64_t, const uint8_t *,
-	    size_t, usb_iface_transfer_out_callback_t, void *);
 } usb_iface_t;
 
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision cecba66ea48d60cfa59865e98aeda663808e42c7)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision e76c0ea8f951c2e63efa8e948fc849e59dec918b)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2010 Vojtech Horky
- * Copyright (c) 2011 Jan Vesely
+ * Copyright (c) 2017 Ondrej Hlavaty
  * All rights reserved.
  *
@@ -32,7 +32,7 @@
  * @{
  */
-
 /** @file
- * @brief USB host controller interface definition.
+ * @brief USB host controler interface definition. This is the interface of
+ * USB host controller function, which can be used by usb device drivers.
  */
 
@@ -41,26 +41,41 @@
 
 #include "ddf/driver.h"
-#include <usb_iface.h>
-#include <stdbool.h>
+#include "usb_iface.h"
+#include <async.h>
 
-extern int usbhc_read(async_exch_t *, usb_address_t, usb_endpoint_t,
-    uint64_t, void *, size_t, size_t *);
-extern int usbhc_write(async_exch_t *, usb_address_t, usb_endpoint_t,
-    uint64_t, const void *, size_t);
+extern int usbhc_reserve_default_address(async_exch_t *, usb_speed_t);
+extern int usbhc_release_default_address(async_exch_t *);
 
-/** Callback for outgoing transfer. */
-typedef void (*usbhc_iface_transfer_out_callback_t)(int, void *);
+extern int usbhc_device_enumerate(async_exch_t *, unsigned port);
+extern int usbhc_device_remove(async_exch_t *, unsigned port);
 
-/** Callback for incoming transfer. */
-typedef void (*usbhc_iface_transfer_in_callback_t)(int, size_t, void *);
+extern int usbhc_register_endpoint(async_exch_t *, usb_endpoint_desc_t *);
+extern int usbhc_unregister_endpoint(async_exch_t *, usb_endpoint_desc_t *);
+extern int usbhc_read(async_exch_t *, usb_endpoint_t, uint64_t, void *, size_t,
+    size_t *);
+extern int usbhc_write(async_exch_t *, usb_endpoint_t, uint64_t, const void *,
+    size_t);
 
-/** USB host controller communication interface. */
+/** Callback for outgoing transfer */
+typedef int (*usbhc_iface_transfer_callback_t)(void *, int, size_t);
+
+/** USB device communication interface. */
 typedef struct {
-	int (*read)(ddf_fun_t *, usb_target_t, uint64_t, uint8_t *, size_t,
-	    usbhc_iface_transfer_in_callback_t, void *);
-	int (*write)(ddf_fun_t *, usb_target_t, uint64_t, const uint8_t *,
-	    size_t, usbhc_iface_transfer_out_callback_t, void *);
+	int (*reserve_default_address)(ddf_fun_t *, usb_speed_t);
+	int (*release_default_address)(ddf_fun_t *);
+
+	int (*device_enumerate)(ddf_fun_t *, unsigned);
+	int (*device_remove)(ddf_fun_t *, unsigned);
+
+	int (*register_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
+	int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
+
+	int (*read)(ddf_fun_t *, usb_target_t,
+		uint64_t, char *, size_t,
+		usbhc_iface_transfer_callback_t, void *);
+	int (*write)(ddf_fun_t *, usb_target_t,
+		uint64_t, const char *, size_t,
+		usbhc_iface_transfer_callback_t, void *);
 } usbhc_iface_t;
-
 
 #endif
