Index: uspace/lib/usbdev/src/pipepriv.c
===================================================================
--- uspace/lib/usbdev/src/pipepriv.c	(revision b4292e70f7c60b7e20817809c5eb17d45ca63f15)
+++ uspace/lib/usbdev/src/pipepriv.c	(revision 8969f46521c752673b4f66d59e0481fe70513ca3)
@@ -87,4 +87,5 @@
 	
 	if (pipe->refcount == 0) {
+		assert(pipe->hc_sess == NULL);
 		/* Need to open the phone by ourselves. */
 		async_sess_t *sess =
Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision b4292e70f7c60b7e20817809c5eb17d45ca63f15)
+++ uspace/lib/usbdev/src/pipesio.c	(revision 8969f46521c752673b4f66d59e0481fe70513ca3)
@@ -65,4 +65,82 @@
     void *buffer, size_t size, size_t *size_transfered)
 {
+	/* Isochronous transfer are not supported (yet) */
+	if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
+	    pipe->transfer_type != USB_TRANSFER_BULK &&
+	    pipe->transfer_type != USB_TRANSFER_CONTROL)
+	    return ENOTSUP;
+
+	int ret = pipe_add_ref(pipe, false);
+	if (ret != EOK) {
+		return ret;
+	}
+
+	/* Ensure serialization over the phone. */
+	pipe_start_transaction(pipe);
+	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
+	if (!exch) {
+		pipe_end_transaction(pipe);
+		pipe_drop_ref(pipe);
+		return ENOMEM;
+	}
+
+	ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no,
+	    setup, buffer, size, size_transfered);
+	async_exchange_end(exch);
+	pipe_end_transaction(pipe);
+	pipe_drop_ref(pipe);
+	return ret;
+}
+
+/** Request a read (in) transfer on an endpoint pipe.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[out] buffer Buffer where to store the data.
+ * @param[in] size Size of the buffer (in bytes).
+ * @param[out] size_transfered Number of bytes that were actually transfered.
+ * @return Error code.
+ */
+int usb_pipe_read(usb_pipe_t *pipe,
+    void *buffer, size_t size, size_t *size_transfered)
+{
+	assert(pipe);
+
+	if (buffer == NULL) {
+		return EINVAL;
+	}
+
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	if (pipe->direction != USB_DIRECTION_IN) {
+		return EBADF;
+	}
+
+	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
+		return EBADF;
+	}
+
+	size_t act_size = 0;
+	const int rc = usb_pipe_read_no_check(pipe, 0, buffer, size, &act_size);
+
+
+	if (rc == EOK && size_transfered != NULL) {
+		*size_transfered = act_size;
+	}
+
+	return rc;
+}
+
+/** Request an out transfer, no checking of input parameters.
+ *
+ * @param[in] pipe Pipe used for the transfer.
+ * @param[in] buffer Buffer with data to transfer.
+ * @param[in] size Size of the buffer (in bytes).
+ * @return Error code.
+ */
+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 &&
@@ -71,4 +149,9 @@
 	    return ENOTSUP;
 
+	int ret = pipe_add_ref(pipe, false);
+	if (ret != EOK) {
+		return ret;
+	}
+
 	/* Ensure serialization over the phone. */
 	pipe_start_transaction(pipe);
@@ -76,95 +159,12 @@
 	if (!exch) {
 		pipe_end_transaction(pipe);
+		pipe_drop_ref(pipe);
 		return ENOMEM;
 	}
-
-	const int ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no,
-	    setup, buffer, size, size_transfered);
-	async_exchange_end(exch);
-	pipe_end_transaction(pipe);
-	return ret;
-}
-
-/** Request a read (in) transfer on an endpoint pipe.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[out] buffer Buffer where to store the data.
- * @param[in] size Size of the buffer (in bytes).
- * @param[out] size_transfered Number of bytes that were actually transfered.
- * @return Error code.
- */
-int usb_pipe_read(usb_pipe_t *pipe,
-    void *buffer, size_t size, size_t *size_transfered)
-{
-	assert(pipe);
-
-	if (buffer == NULL) {
-		return EINVAL;
-	}
-
-	if (size == 0) {
-		return EINVAL;
-	}
-
-	if (pipe->direction != USB_DIRECTION_IN) {
-		return EBADF;
-	}
-
-	if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
-		return EBADF;
-	}
-
-	int rc;
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-
-	size_t act_size = 0;
-
-	rc = usb_pipe_read_no_check(pipe, 0, buffer, size, &act_size);
-
-	pipe_drop_ref(pipe);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	if (size_transfered != NULL) {
-		*size_transfered = act_size;
-	}
-
-	return EOK;
-}
-
-/** Request an out transfer, no checking of input parameters.
- *
- * @param[in] pipe Pipe used for the transfer.
- * @param[in] buffer Buffer with data to transfer.
- * @param[in] size Size of the buffer (in bytes).
- * @return Error code.
- */
-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_CONTROL)
-	    return ENOTSUP;
-
-	/* Ensure serialization over the phone. */
-	pipe_start_transaction(pipe);
-	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,
+	ret = usbhc_write(exch, pipe->wire->address, pipe->endpoint_no,
 	    setup, buffer, size);
 	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
+	pipe_drop_ref(pipe);
 	return ret;
 }
@@ -193,15 +193,5 @@
 	}
 
-	int rc;
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	rc = usb_pipe_write_no_check(pipe, 0, buffer, size);
-
-	pipe_drop_ref(pipe);
-
-	return rc;
+	return usb_pipe_write_no_check(pipe, 0, buffer, size);
 }
 
@@ -260,13 +250,6 @@
 	memcpy(&setup_packet, setup_buffer, 8);
 
-	int rc;
-
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
 	size_t act_size = 0;
-	rc = usb_pipe_read_no_check(pipe, setup_packet,
+	const int rc = usb_pipe_read_no_check(pipe, setup_packet,
 	    data_buffer, data_buffer_size, &act_size);
 
@@ -275,15 +258,9 @@
 	}
 
-	pipe_drop_ref(pipe);
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	if (data_transfered_size != NULL) {
+	if (rc == EOK && data_transfered_size != NULL) {
 		*data_transfered_size = act_size;
 	}
 
-	return EOK;
+	return rc;
 }
 
@@ -325,11 +302,5 @@
 	memcpy(&setup_packet, setup_buffer, 8);
 
-	int rc;
-	rc = pipe_add_ref(pipe, false);
-	if (rc != EOK) {
-		return rc;
-	}
-
-	rc = usb_pipe_write_no_check(pipe, setup_packet,
+	const int rc = usb_pipe_write_no_check(pipe, setup_packet,
 	    data_buffer, data_buffer_size);
 
@@ -338,10 +309,6 @@
 	}
 
-	pipe_drop_ref(pipe);
-
 	return rc;
 }
-
-
 /**
  * @}
