Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision 56bdd9a4306c6d99a59c72a07fe62501b10576c1)
+++ uspace/lib/usbdev/src/hub.c	(revision 02fc5c403d52648f5ee6dcf5158ad19197c73795)
@@ -76,17 +76,14 @@
 {
 	CHECK_CONNECTION(connection);
-	
+
 	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
-	
-	sysarg_t address;
-	int rc = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REQUEST_ADDRESS, preferred, strict, speed, &address);
-	
+	if (!exch)
+		return (usb_address_t)ENOMEM;
+
+	usb_address_t address = preferred;
+	const int ret = usbhc_request_address(exch, &address, strict, speed);
+
 	async_exchange_end(exch);
-	
-	if (rc != EOK)
-		return (usb_address_t) rc;
-	
-	return (usb_address_t) address;
+	return ret == EOK ? address : ret;
 }
 
@@ -97,19 +94,19 @@
  * @return Error code.
  */
-int usb_hc_register_device(usb_hc_connection_t * connection,
+int usb_hc_register_device(usb_hc_connection_t *connection,
     const usb_hub_attached_device_t *attached_device)
 {
 	CHECK_CONNECTION(connection);
-	
-	if (attached_device == NULL)
-		return EBADMEM;
-	
+	if (attached_device == NULL || attached_device->fun == NULL)
+		return EINVAL;
+
 	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
-	int rc = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_BIND_ADDRESS,
+	if (!exch)
+		return ENOMEM;
+	const int ret = usbhc_bind_address(exch,
 	    attached_device->address, attached_device->fun->handle);
 	async_exchange_end(exch);
-	
-	return rc;
+
+	return ret;
 }
 
@@ -124,11 +121,12 @@
 {
 	CHECK_CONNECTION(connection);
-	
+
 	async_exch_t *exch = async_exchange_begin(connection->hc_sess);
-	int rc = async_req_2_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_RELEASE_ADDRESS, address);
+	if (!exch)
+		return ENOMEM;
+	const int ret = usbhc_release_address(exch, address);
 	async_exchange_end(exch);
-	
-	return rc;
+
+	return ret;
 }
 
Index: uspace/lib/usbdev/src/pipesinit.c
===================================================================
--- uspace/lib/usbdev/src/pipesinit.c	(revision 56bdd9a4306c6d99a59c72a07fe62501b10576c1)
+++ uspace/lib/usbdev/src/pipesinit.c	(revision 02fc5c403d52648f5ee6dcf5158ad19197c73795)
@@ -405,9 +405,4 @@
 	}
 
-#define TRY_LOOP(attempt_var) \
-	for (attempt_var = 0; attempt_var < 3; attempt_var++)
-
-	size_t failed_attempts;
-	int rc;
 
 	usb_pipe_start_long_transfer(pipe);
@@ -415,5 +410,6 @@
 	uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
 	size_t transferred_size;
-	TRY_LOOP(failed_attempts) {
+	int rc;
+	for (size_t attempt_var = 0; attempt_var < 3; ++attempt_var) {
 		rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
 		    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
@@ -450,22 +446,18 @@
 {
 	assert(pipe);
+	assert(pipe->wire);
 	assert(hc_connection);
 
 	if (!usb_hc_connection_is_opened(hc_connection))
 		return EBADF;
-
-	const usb_target_t target =
-	    {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
-#define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
-
 	async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,
-	    _PACK2(pipe->transfer_type, pipe->direction),
-	    _PACK2(pipe->max_packet_size, interval));
+	if (!exch)
+		return ENOMEM;
+	const int ret = usbhc_register_endpoint(exch,
+	    pipe->wire->address, pipe->endpoint_no, pipe->transfer_type,
+	    pipe->direction, pipe->max_packet_size, interval);
+
 	async_exchange_end(exch);
-
-#undef _PACK2
-	return rc;
+	return ret;
 }
 
@@ -482,15 +474,16 @@
 	assert(pipe->wire);
 	assert(hc_connection);
-	
+
 	if (!usb_hc_connection_is_opened(hc_connection))
 		return EBADF;
-	
+
 	async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
-	int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_UNREGISTER_ENDPOINT,
+	if (!exch)
+		return ENOMEM;
+	const int ret = usbhc_unregister_endpoint(exch,
 	    pipe->wire->address, pipe->endpoint_no, pipe->direction);
 	async_exchange_end(exch);
-	
-	return rc;
+
+	return ret;
 }
 
Index: uspace/lib/usbdev/src/pipesio.c
===================================================================
--- uspace/lib/usbdev/src/pipesio.c	(revision 56bdd9a4306c6d99a59c72a07fe62501b10576c1)
+++ uspace/lib/usbdev/src/pipesio.c	(revision 02fc5c403d52648f5ee6dcf5158ad19197c73795)
@@ -70,69 +70,17 @@
 	    return ENOTSUP;
 
-	const usb_target_t target =
-	    {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
-	
 	/* Ensure serialization over the phone. */
 	pipe_start_transaction(pipe);
 	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
-	
-	/*
-	 * 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_READ, target.packed, NULL);
-	
-	if (opening_request == 0) {
-		async_exchange_end(exch);
+	if (!exch) {
 		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
-	
-	/*
-	 * Retrieve the data.
-	 */
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, buffer, size,
-	    &data_request_call);
-	
-	/*
-	 * Since now on, someone else might access the backing phone
-	 * without breaking the transfer IPC protocol.
-	 */
+
+	const int ret = usbhc_read(exch, pipe->wire->address, pipe->endpoint_no,
+	    0, buffer, size, size_transfered);
 	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
-	
-	if (data_request == 0) {
-		/*
-		 * FIXME:
-		 * How to let the other side know that we want to abort?
-		 */
-		async_wait_for(opening_request, NULL);
-		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;
-	}
-	
-	*size_transfered = IPC_GET_ARG2(data_request_call);
-	
-	return EOK;
+	return ret;
 }
 
@@ -209,47 +157,17 @@
 	    return ENOTSUP;
 
-	const usb_target_t target =
-	    {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
-
 	/* Ensure serialization over the phone. */
 	pipe_start_transaction(pipe);
 	async_exch_t *exch = async_exchange_begin(pipe->hc_sess);
-	
-	/*
-	 * Make call identifying target USB device and type of transfer.
-	 */
-	aid_t opening_request = async_send_3(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_WRITE, target.packed, size, NULL);
-	
-	if (opening_request == 0) {
-		async_exchange_end(exch);
+	if (!exch) {
 		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
-	
-	/*
-	 * Send the data.
-	 */
-	int rc = async_data_write_start(exch, buffer, size);
-	
-	/*
-	 * Since now on, someone else might access the backing phone
-	 * without breaking the transfer IPC protocol.
-	 */
+	const int ret =
+	    usbhc_write(exch, pipe->wire->address, pipe->endpoint_no,
+	    0, buffer, size);
 	async_exchange_end(exch);
 	pipe_end_transaction(pipe);
-	
-	if (rc != EOK) {
-		async_wait_for(opening_request, NULL);
-		return rc;
-	}
-	
-	/*
-	 * Wait for the answer.
-	 */
-	sysarg_t opening_request_rc;
-	async_wait_for(opening_request, &opening_request_rc);
-	
-	return (int) opening_request_rc;
+	return ret;
 }
 
@@ -334,65 +252,19 @@
 	pipe_start_transaction(pipe);
 
-	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);
-	/*
-	 * 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_4(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_READ, target.packed,
-	    (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL);
-
-	if (opening_request == 0) {
-		async_exchange_end(exch);
+	if (!exch) {
+		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
 
-	/*
-	 * Retrieve the data.
-	 */
-	ipc_call_t data_request_call;
-	aid_t data_request = async_data_read(exch, data_buffer,
-	    data_buffer_size, &data_request_call);
-	
-	/*
-	 * Since now on, someone else might access the backing phone
-	 * without breaking the transfer IPC protocol.
-	 */
+	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);
-	
-	if (data_request == 0) {
-		async_wait_for(opening_request, NULL);
-		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;
-	}
-
-	*data_transfered_size = IPC_GET_ARG2(data_request_call);
-
-	return EOK;
+	return ret;
 }
 
@@ -475,51 +347,20 @@
 	pipe_start_transaction(pipe);
 
-	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);
 
-	/*
-	 * Make call identifying target USB device and control transfer type.
-	 */
+	/* 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_5(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_WRITE, target.packed, data_buffer_size,
-	    (setup_packet & UINT32_MAX), (setup_packet >> 32), NULL);
-	
-	if (opening_request == 0) {
-		async_exchange_end(exch);
+	if (!exch) {
 		pipe_end_transaction(pipe);
 		return ENOMEM;
 	}
-
-	/*
-	 * Send the data (if any).
-	 */
-	if (data_buffer_size > 0) {
-		int rc = async_data_write_start(exch, data_buffer, data_buffer_size);
-		
-		/* All data sent, pipe can be released. */
-		async_exchange_end(exch);
-		pipe_end_transaction(pipe);
-	
-		if (rc != EOK) {
-			async_wait_for(opening_request, NULL);
-			return rc;
-		}
-	} else {
-		/* No data to send, we can release the pipe for others. */
-		async_exchange_end(exch);
-		pipe_end_transaction(pipe);
-	}
-	
-	/*
-	 * Wait for the answer.
-	 */
-	sysarg_t opening_request_rc;
-	async_wait_for(opening_request, &opening_request_rc);
-
-	return (int) opening_request_rc;
+	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;
 }
 
