Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 365e29e2bf360b7a6db5a954e90836d5f9a109d5)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision bdd8ad2f03530c2b59a0b35c7fdd0147223e5682)
@@ -230,4 +230,5 @@
 ipc_callid_t callid, ipc_call_t *call)
 {
+	assert(false);
 	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
 	assert(usb_iface != NULL);
@@ -291,4 +292,5 @@
 ipc_callid_t callid, ipc_call_t *call)
 {
+	assert(false);
 	usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
 	assert(usb_iface != NULL);
@@ -388,7 +390,6 @@
 #undef _INIT_FROM_LOW_DATA3
 
-	int rc = usb_iface->register_endpoint(fun, target.address,
-	    speed, target.endpoint,
-	    transfer_type, direction, max_packet_size, interval);
+	int rc = usb_iface->register_endpoint(fun, target.address, speed,
+	    target.endpoint, transfer_type, direction, max_packet_size, interval);
 
 	async_answer_0(callid, rc);
@@ -431,4 +432,7 @@
 
 	const usb_target_t target = { .packed = 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);
@@ -451,5 +455,5 @@
 
 	const int rc = hc_iface->read(
-	    fun, target, 0, trans->buffer, trans->size, callback_in, trans);
+	    fun, target, setup, trans->buffer, trans->size, callback_in, trans);
 
 	if (rc != EOK) {
@@ -475,4 +479,8 @@
 
 	const usb_target_t target = { .packed = 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);
@@ -482,16 +490,18 @@
 	}
 
-	int rc = async_data_write_accept(&trans->buffer, false,
-	    1, USB_MAX_PAYLOAD_SIZE,
-	    0, &trans->size);
-
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	rc = hc_iface->write(
-	    fun, target, 0, trans->buffer, trans->size, callback_out, trans);
+	if (data_buffer_len > 0) {
+		int rc = async_data_write_accept(&trans->buffer, false,
+		    1, USB_MAX_PAYLOAD_SIZE,
+		    0, &trans->size);
+
+		if (rc != EOK) {
+			async_answer_0(callid, rc);
+			async_transaction_destroy(trans);
+			return;
+		}
+	}
+
+	int rc = hc_iface->write(
+	    fun, target, setup, trans->buffer, trans->size, callback_out, trans);
 
 	if (rc != EOK) {
Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision 365e29e2bf360b7a6db5a954e90836d5f9a109d5)
+++ uspace/lib/usbdev/src/pipesio.c	(revision bdd8ad2f03530c2b59a0b35c7fdd0147223e5682)
@@ -219,6 +219,6 @@
 	 * Make call identifying target USB device and type of transfer.
 	 */
-	aid_t opening_request = async_send_2(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_DATA_WRITE, target.packed, NULL);
+	aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_DATA_WRITE, target.packed, size, NULL);
 	
 	if (opening_request == 0) {
@@ -337,27 +337,20 @@
 	    {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
 
+	assert(setup_buffer_size == 8);
+	uint64_t setup_packet;
+	memcpy(&setup_packet, setup_buffer, 8);
 	/*
 	 * Make call identifying target USB device and control transfer type.
 	 */
 	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
-	aid_t opening_request = async_send_2(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_CONTROL_READ, target.packed, NULL);
-	
+	aid_t opening_request = async_send_4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_DATA_READ, target.packed,
+	    (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL);
+
 	if (opening_request == 0) {
 		async_exchange_end(exch);
 		return ENOMEM;
 	}
-	
-	/*
-	 * Send the setup packet.
-	 */
-	int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		pipe_end_transaction(pipe);
-		async_wait_for(opening_request, NULL);
-		return rc;
-	}
-	
+
 	/*
 	 * Retrieve the data.
@@ -484,4 +477,7 @@
 	const usb_target_t target =
 	    {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
+	assert(setup_buffer_size == 8);
+	uint64_t setup_packet;
+	memcpy(&setup_packet, setup_buffer, 8);
 
 	/*
@@ -489,7 +485,7 @@
 	 */
 	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
-	aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_CONTROL_WRITE, target.packed,
-	    data_buffer_size, NULL);
+	aid_t opening_request = async_send_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
+	    IPC_M_USBHC_DATA_WRITE, target.packed, data_buffer_size,
+	    (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL);
 	
 	if (opening_request == 0) {
@@ -498,21 +494,10 @@
 		return ENOMEM;
 	}
-	
-	/*
-	 * Send the setup packet.
-	 */
-	int rc = async_data_write_start(exch, setup_buffer, setup_buffer_size);
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		pipe_end_transaction(pipe);
-		async_wait_for(opening_request, NULL);
-		return rc;
-	}
-	
+
 	/*
 	 * Send the data (if any).
 	 */
 	if (data_buffer_size > 0) {
-		rc = async_data_write_start(exch, data_buffer, data_buffer_size);
+		int rc = async_data_write_start(exch, data_buffer, data_buffer_size);
 		
 		/* All data sent, pipe can be released. */
