Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision 02fc5c403d52648f5ee6dcf5158ad19197c73795)
+++ uspace/lib/usbdev/src/pipesio.c	(revision b4292e70f7c60b7e20817809c5eb17d45ca63f15)
@@ -62,10 +62,11 @@
  * @return Error code.
  */
-static int usb_pipe_read_no_checks(usb_pipe_t *pipe,
+static int usb_pipe_read_no_check(usb_pipe_t *pipe, uint64_t setup,
     void *buffer, size_t size, size_t *size_transfered)
 {
 	/* Only interrupt and bulk transfers are supported */
 	if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
-	    pipe->transfer_type != USB_TRANSFER_BULK)
+	    pipe->transfer_type != USB_TRANSFER_BULK &&
+	    pipe->transfer_type != USB_TRANSFER_CONTROL)
 	    return ENOTSUP;
 
@@ -79,5 +80,5 @@
 
 	const int ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no,
-	    0, buffer, size, size_transfered);
+	    setup, buffer, size, size_transfered);
 	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
@@ -85,5 +86,4 @@
 }
 
-
 /** Request a read (in) transfer on an endpoint pipe.
  *
@@ -124,5 +124,5 @@
 	size_t act_size = 0;
 
-	rc = usb_pipe_read_no_checks(pipe, buffer, size, &act_size);
+	rc = usb_pipe_read_no_check(pipe, 0, buffer, size, &act_size);
 
 	pipe_drop_ref(pipe);
@@ -139,7 +139,4 @@
 }
 
-
-
-
 /** Request an out transfer, no checking of input parameters.
  *
@@ -149,10 +146,11 @@
  * @return Error code.
  */
-static int usb_pipe_write_no_check(usb_pipe_t *pipe,
-    void *buffer, size_t size)
+static int usb_pipe_write_no_check(usb_pipe_t *pipe, uint64_t setup,
+    const void *buffer, size_t size)
 {
 	/* Only interrupt and bulk transfers are supported */
 	if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
-	    pipe->transfer_type != USB_TRANSFER_BULK)
+	    pipe->transfer_type != USB_TRANSFER_BULK &&
+	    pipe->transfer_type != USB_TRANSFER_CONTROL)
 	    return ENOTSUP;
 
@@ -166,5 +164,5 @@
 	const int ret =
 	    usbhc_write(exch, pipe->wire->address, pipe->endpoint_no,
-	    0, buffer, size);
+	    setup, buffer, size);
 	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
@@ -179,14 +177,9 @@
  * @return Error code.
  */
-int usb_pipe_write(usb_pipe_t *pipe,
-    void *buffer, size_t size)
+int usb_pipe_write(usb_pipe_t *pipe, const void *buffer, size_t size)
 {
 	assert(pipe);
 
-	if (buffer == NULL) {
-		return EINVAL;
-	}
-
-	if (size == 0) {
+	if (buffer == NULL || size == 0) {
 		return EINVAL;
 	}
@@ -201,5 +194,4 @@
 
 	int rc;
-
 	rc = pipe_add_ref(pipe, false);
 	if (rc != EOK) {
@@ -207,5 +199,5 @@
 	}
 
-	rc = usb_pipe_write_no_check(pipe, buffer, size);
+	rc = usb_pipe_write_no_check(pipe, 0, buffer, size);
 
 	pipe_drop_ref(pipe);
@@ -227,5 +219,5 @@
 
 
-	/* Prevent indefinite recursion. */
+	/* Prevent infinite recursion. */
 	pipe->auto_reset_halt = false;
 	usb_request_clear_endpoint_halt(pipe, 0);
@@ -233,6 +225,7 @@
 }
 
-
-/** Request a control read transfer, no checking of input parameters.
+/** Request a control read transfer on an endpoint pipe.
+ *
+ * This function encapsulates all three stages of a control transfer.
  *
  * @param[in] pipe Pipe used for the transfer.
@@ -245,41 +238,4 @@
  * @return Error code.
  */
-static int usb_pipe_control_read_no_check(usb_pipe_t *pipe,
-    const void *setup_buffer, size_t setup_buffer_size,
-    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
-{
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-
-	assert(setup_buffer_size == 8);
-	uint64_t setup_packet;
-	memcpy(&setup_packet, setup_buffer, 8);
-
-	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
-	if (!exch) {
-		pipe_end_transaction(pipe);
-		return ENOMEM;
-	}
-
-	const int ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no,
-	    setup_packet, data_buffer, data_buffer_size, data_transfered_size);
-	async_exchange_end(exch);
-	pipe_end_transaction(pipe);
-	return ret;
-}
-
-/** Request a control read transfer on an endpoint pipe.
- *
- * This function encapsulates all three stages of a control transfer.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] setup_buffer Buffer with the setup packet.
- * @param[in] setup_buffer_size Size of the setup packet (in bytes).
- * @param[out] data_buffer Buffer for incoming data.
- * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes).
- * @param[out] data_transfered_size Number of bytes that were actually
- *                                  transfered during the DATA stage.
- * @return Error code.
- */
 int usb_pipe_control_read(usb_pipe_t *pipe,
     const void *setup_buffer, size_t setup_buffer_size,
@@ -288,5 +244,5 @@
 	assert(pipe);
 
-	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
+	if ((setup_buffer == NULL) || (setup_buffer_size != 8)) {
 		return EINVAL;
 	}
@@ -301,4 +257,7 @@
 	}
 
+	uint64_t setup_packet;
+	memcpy(&setup_packet, setup_buffer, 8);
+
 	int rc;
 
@@ -309,6 +268,5 @@
 
 	size_t act_size = 0;
-	rc = usb_pipe_control_read_no_check(pipe,
-	    setup_buffer, setup_buffer_size,
+	rc = usb_pipe_read_no_check(pipe, setup_packet,
 	    data_buffer, data_buffer_size, &act_size);
 
@@ -330,6 +288,7 @@
 }
 
-
-/** Request a control write transfer, no checking of input parameters.
+/** Request a control write transfer on an endpoint pipe.
+ *
+ * This function encapsulates all three stages of a control transfer.
  *
  * @param[in] pipe Pipe used for the transfer.
@@ -340,40 +299,4 @@
  * @return Error code.
  */
-static int usb_pipe_control_write_no_check(usb_pipe_t *pipe,
-    const void *setup_buffer, size_t setup_buffer_size,
-    const void *data_buffer, size_t data_buffer_size)
-{
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-
-	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);
-	if (!exch) {
-		pipe_end_transaction(pipe);
-		return ENOMEM;
-	}
-	const int ret =
-	    usbhc_write(exch, pipe->wire->address, pipe->endpoint_no,
-	    setup_packet, data_buffer, data_buffer_size);
-	async_exchange_end(exch);
-	pipe_end_transaction(pipe);
-	return ret;
-}
-
-/** Request a control write transfer on an endpoint pipe.
- *
- * This function encapsulates all three stages of a control transfer.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] setup_buffer Buffer with the setup packet.
- * @param[in] setup_buffer_size Size of the setup packet (in bytes).
- * @param[in] data_buffer Buffer with data to be sent.
- * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes).
- * @return Error code.
- */
 int usb_pipe_control_write(usb_pipe_t *pipe,
     const void *setup_buffer, size_t setup_buffer_size,
@@ -382,5 +305,5 @@
 	assert(pipe);
 
-	if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
+	if ((setup_buffer == NULL) || (setup_buffer_size != 8)) {
 		return EINVAL;
 	}
@@ -399,6 +322,8 @@
 	}
 
+	uint64_t setup_packet;
+	memcpy(&setup_packet, setup_buffer, 8);
+
 	int rc;
-
 	rc = pipe_add_ref(pipe, false);
 	if (rc != EOK) {
@@ -406,6 +331,6 @@
 	}
 
-	rc = usb_pipe_control_write_no_check(pipe,
-	    setup_buffer, setup_buffer_size, data_buffer, data_buffer_size);
+	rc = usb_pipe_write_no_check(pipe, setup_packet,
+	    data_buffer, data_buffer_size);
 
 	if (rc == ESTALL) {
