Index: uspace/lib/usb/src/usbdrv.c
===================================================================
--- uspace/lib/usb/src/usbdrv.c	(revision 687efaa9ee025f3d8c5d59617915bae3b1889ca0)
+++ uspace/lib/usb/src/usbdrv.c	(revision e0df6c2d7a704b8e474264f04947e3eadfc936c2)
@@ -49,8 +49,12 @@
 	/** Storage for actual number of bytes transferred. */
 	size_t *size_transferred;
-	/** Initial call replay data. */
+	/** Initial call reply data. */
 	ipc_call_t reply;
 	/** Initial call identifier. */
 	aid_t request;
+	/** Reply data for data read call. */
+	ipc_call_t read_reply;
+	/** Data read call identifier. */
+	aid_t read_request;
 } transfer_info_t;
 
@@ -140,5 +144,4 @@
 
 	if (rc != EOK) {
-		printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));
 		return rc;
 	}
@@ -250,4 +253,5 @@
 	}
 
+	transfer->read_request = 0;
 	transfer->size_transferred = NULL;
 	transfer->buffer = NULL;
@@ -315,4 +319,5 @@
 	}
 
+	transfer->read_request = 0;
 	transfer->size_transferred = actual_size;
 	transfer->buffer = buffer;
@@ -327,4 +332,9 @@
 	    &transfer->reply);
 
+	if (buffer != NULL) {
+		transfer->read_request = async_data_read(phone, buffer, size,
+		    &transfer->read_reply);
+	}
+
 	*handle = (usb_handle_t) transfer;
 
@@ -332,45 +342,4 @@
 }
 
-/** Read buffer from HCD.
- *
- * @param phone Opened phone to HCD.
- * @param hash Buffer hash (obtained after completing IN transaction).
- * @param buffer Buffer where to store data data.
- * @param size Buffer size.
- * @param actual_size Storage where actual number of bytes transferred will
- * 	be stored.
- * @return Error status.
- */
-static int read_buffer_in(int phone, sysarg_t hash,
-    void *buffer, size_t size, size_t *actual_size)
-{
-	ipc_call_t answer_data;
-	sysarg_t answer_rc;
-	aid_t req;
-	int rc;
-
-	req = async_send_2(phone,
-	    DEV_IFACE_ID(USBHC_DEV_IFACE),
-	    IPC_M_USBHC_GET_BUFFER,
-	    hash,
-	    &answer_data);
-
-	rc = async_data_read_start(phone, buffer, size);
-	if (rc != EOK) {
-		async_wait_for(req, NULL);
-		return EINVAL;
-	}
-
-	async_wait_for(req, &answer_rc);
-	rc = (int)answer_rc;
-
-	if (rc != EOK) {
-		return rc;
-	}
-
-	*actual_size = IPC_GET_ARG1(answer_data);
-
-	return EOK;
-}
 
 /** Blocks caller until given USB transaction is finished.
@@ -395,10 +364,4 @@
 
 	sysarg_t answer_rc;
-	async_wait_for(transfer->request, &answer_rc);
-
-	if (answer_rc != EOK) {
-		rc = (int) answer_rc;
-		goto leave;
-	}
 
 	/*
@@ -406,26 +369,22 @@
 	 */
 	if ((transfer->buffer != NULL) && (transfer->size > 0)) {
-		/*
-		 * The buffer hash identifies the data on the server
-		 * side.
-		 * We will use it when actually reading-in the data.
-		 */
-		sysarg_t buffer_hash = IPC_GET_ARG1(transfer->reply);
-		if (buffer_hash == 0) {
-			rc = ENOENT;
+		async_wait_for(transfer->read_request, &answer_rc);
+
+		if (answer_rc != EOK) {
+			rc = (int) answer_rc;
 			goto leave;
 		}
 
-		size_t actual_size;
-		rc = read_buffer_in(transfer->phone, buffer_hash,
-		    transfer->buffer, transfer->size, &actual_size);
-
-		if (rc != EOK) {
-			goto leave;
+		if (transfer->size_transferred != NULL) {
+			*(transfer->size_transferred)
+			    = IPC_GET_ARG2(transfer->read_reply);
 		}
-
-		if (transfer->size_transferred) {
-			*(transfer->size_transferred) = actual_size;
-		}
+	}
+
+	async_wait_for(transfer->request, &answer_rc);
+
+	if (answer_rc != EOK) {
+		rc = (int) answer_rc;
+		goto leave;
 	}
 
@@ -515,4 +474,5 @@
 	}
 
+	transfer->read_request = 0;
 	transfer->size_transferred = NULL;
 	transfer->buffer = NULL;
@@ -620,4 +580,7 @@
 	}
 
+	transfer->read_request = async_data_read(phone, buffer, buffer_size,
+	    &transfer->read_reply);
+
 	*handle = (usb_handle_t) transfer;
 
