Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/app/usbinfo/main.c	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -81,4 +81,8 @@
 {
 	int rc;
+
+	if (str_cmp(path, "uhci") == 0) {
+		path = "/hw/pci0/00:01.2";
+	}
 
 	devman_handle_t handle;
Index: uspace/drv/usbhid/hid.h
===================================================================
--- uspace/drv/usbhid/hid.h	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/drv/usbhid/hid.h	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -69,8 +69,8 @@
 	device_t *device;
 	usb_hid_configuration_t *conf;
-	usb_address_t address;
 	usb_hid_report_parser_t *parser;
 
 	usb_device_connection_t wire;
+	usb_endpoint_pipe_t ctrl_pipe;
 	usb_endpoint_pipe_t poll_pipe;
 } usb_hid_dev_kbd_t;
Index: uspace/drv/usbhid/main.c
===================================================================
--- uspace/drv/usbhid/main.c	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/drv/usbhid/main.c	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -47,5 +47,5 @@
 #include <usb/classes/hid.h>
 #include <usb/classes/hidparser.h>
-#include <usb/devreq.h>
+#include <usb/request.h>
 #include <usb/descriptor.h>
 #include <io/console.h>
@@ -262,5 +262,4 @@
 }
 
-# if 0
 /*
  * Kbd functions
@@ -281,7 +280,8 @@
 		
 		// get the descriptor from the device
-		int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone,
-		    kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 
-		    0, i, kbd_dev->conf->interfaces[i].report_desc, length, 
+		int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
+		    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
+		    i, 0,
+		    kbd_dev->conf->interfaces[i].report_desc, length,
 		    &actual_size);
 
@@ -303,6 +303,7 @@
 	usb_standard_configuration_descriptor_t config_desc;
 	
-	int rc = usb_drv_req_get_bare_configuration_descriptor(
-	    kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
+	int rc;
+	rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
+	    0, &config_desc);
 	
 	if (rc != EOK) {
@@ -318,6 +319,6 @@
 	size_t transferred = 0;
 	// get full configuration descriptor
-	rc = usb_drv_req_get_full_configuration_descriptor(
-	    kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
+	rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
+	    0, descriptors,
 	    config_desc.total_length, &transferred);
 	
@@ -363,7 +364,9 @@
 	return EOK;
 }
-#endif
+
 static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
 {
+	int rc;
+
 	usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 
 	    sizeof(usb_hid_dev_kbd_t));
@@ -376,40 +379,4 @@
 	kbd_dev->device = dev;
 
-	// get phone to my HC and save it as my parent's phone
-	// TODO: maybe not a good idea if DDF will use parent_phone
-	int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
-	if (rc < 0) {
-		printf("Problem setting phone to HC.\n");
-		goto error_leave;
-	}
-
-	rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev);
-	if (rc < 0) {
-		printf("Problem getting address of the device.\n");
-		goto error_leave;
-	}
-
-	// doesn't matter now that we have no address
-//	if (kbd_dev->address < 0) {
-//		fprintf(stderr, NAME ": No device address!\n");
-//		free(kbd_dev);
-//		return NULL;
-//	}
-
-	/*
-	 * will need all descriptors:
-	 * 1) choose one configuration from configuration descriptors 
-	 *    (set it to the device)
-	 * 2) set endpoints from endpoint descriptors
-	 */
-
-
-	// TODO: get descriptors, parse descriptors and save endpoints
-	//usbkbd_process_descriptors(kbd_dev);
-	usb_drv_req_set_configuration(
-	  kbd_dev->device->parent_phone, kbd_dev->address, 1);
-
-
-
 	/*
 	 * Initialize the backing connection to the host controller.
@@ -425,4 +392,12 @@
 	 * Initialize device pipes.
 	 */
+	rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,
+	    &kbd_dev->wire);
+	if (rc != EOK) {
+		printf("Failed to initialize default control pipe: %s.\n",
+		    str_error(rc));
+		goto error_leave;
+	}
+
 	rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire,
 	    GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, USB_DIRECTION_IN);
@@ -433,4 +408,16 @@
 	}
 
+	/*
+	 * will need all descriptors:
+	 * 1) choose one configuration from configuration descriptors
+	 *    (set it to the device)
+	 * 2) set endpoints from endpoint descriptors
+	 */
+
+	// TODO: get descriptors, parse descriptors and save endpoints
+	usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
+	//usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);
+	usbkbd_process_descriptors(kbd_dev);
+	usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
 
 	return kbd_dev;
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/lib/c/generic/async.c	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -1567,4 +1567,18 @@
 }
 
+/** Start IPC_M_DATA_READ using the async framework.
+ *
+ * @param phoneid Phone that will be used to contact the receiving side.
+ * @param dst Address of the beginning of the destination buffer.
+ * @param size Size of the destination buffer (in bytes).
+ * @param dataptr Storage of call data (arg 2 holds actual data size).
+ * @return Hash of the sent message or 0 on error.
+ */
+aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
+{
+	return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
+	    (sysarg_t) size, dataptr);
+}
+
 /** Wrapper for IPC_M_DATA_READ calls using the async framework.
  *
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/lib/c/include/async.h	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -340,4 +340,5 @@
 	    (arg4), (answer))
 
+extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
 extern int async_data_read_start(int, void *, size_t);
 extern bool async_data_read_receive(ipc_callid_t *, size_t *);
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -42,5 +42,4 @@
 
 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
@@ -64,6 +63,4 @@
 	remote_usbhc_get_address,
 
-	remote_usbhc_get_buffer,
-
 	remote_usbhc_reserve_default_address,
 	remote_usbhc_release_default_address,
@@ -98,4 +95,5 @@
 typedef struct {
 	ipc_callid_t caller;
+	ipc_callid_t data_caller;
 	void *buffer;
 	void *setup_packet;
@@ -127,4 +125,5 @@
 
 	trans->caller = caller;
+	trans->data_caller = 0;
 	trans->buffer = NULL;
 	trans->setup_packet = NULL;
@@ -155,37 +154,4 @@
 }
 
-void remote_usbhc_get_buffer(device_t *device, void *iface,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);
-	async_transaction_t * trans = (async_transaction_t *)buffer_hash;
-	if (trans == NULL) {
-		async_answer_0(callid, ENOENT);
-		return;
-	}
-	if (trans->buffer == NULL) {
-		async_answer_0(callid, EINVAL);
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	ipc_callid_t cid;
-	size_t accepted_size;
-	if (!async_data_read_receive(&cid, &accepted_size)) {
-		async_answer_0(callid, EINVAL);
-		async_transaction_destroy(trans);
-		return;
-	}
-
-	if (accepted_size > trans->size) {
-		accepted_size = trans->size;
-	}
-	async_data_read_finalize(cid, trans->buffer, accepted_size);
-
-	async_answer_1(callid, EOK, accepted_size);
-
-	async_transaction_destroy(trans);
-}
-
 void remote_usbhc_reserve_default_address(device_t *device, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
@@ -290,4 +256,7 @@
 	if (outcome != USB_OUTCOME_OK) {
 		async_answer_0(trans->caller, outcome);
+		if (trans->data_caller) {
+			async_answer_0(trans->data_caller, EINTR);
+		}
 		async_transaction_destroy(trans);
 		return;
@@ -295,5 +264,13 @@
 
 	trans->size = actual_size;
-	async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
+
+	if (trans->data_caller) {
+		async_data_read_finalize(trans->data_caller,
+		    trans->buffer, actual_size);
+	}
+
+	async_answer_0(trans->caller, USB_OUTCOME_OK);
+
+	async_transaction_destroy(trans);
 }
 
@@ -376,4 +353,10 @@
 	};
 
+	ipc_callid_t data_callid;
+	if (!async_data_read_receive(&data_callid, &len)) {
+		async_answer_0(callid, EPARTY);
+		return;
+	}
+
 	async_transaction_t *trans = async_transaction_create(callid);
 	if (trans == NULL) {
@@ -381,4 +364,5 @@
 		return;
 	}
+	trans->data_caller = data_callid;
 	trans->buffer = malloc(len);
 	trans->size = len;
@@ -630,4 +614,11 @@
 	}
 
+	ipc_callid_t data_callid;
+	if (!async_data_read_receive(&data_callid, &data_len)) {
+		async_answer_0(callid, EPARTY);
+		free(setup_packet);
+		return;
+	}
+
 	async_transaction_t *trans = async_transaction_create(callid);
 	if (trans == NULL) {
@@ -636,4 +627,5 @@
 		return;
 	}
+	trans->data_caller = data_callid;
 	trans->setup_packet = setup_packet;
 	trans->size = data_len;
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -66,21 +66,12 @@
  *   - argument #2 is target endpoint
  *   - argument #3 is buffer size
+ * - this call is immediately followed by IPC data read (async version)
  * - the call is not answered until the device returns some data (or until
  *   error occurs)
- * - if the call is answered with EOK, first argument of the answer is buffer
- *   hash that could be used to retrieve the actual data
  *
  * Some special methods (NO-DATA transactions) do not send any data. These
  * might behave as both OUT or IN transactions because communication parts
  * where actual buffers are exchanged are omitted.
- *
- * The mentioned data retrieval can be done any time after receiving EOK
- * answer to IN method.
- * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where
- * the first argument is buffer hash from call answer.
- * This call must be immediately followed by data read-in and after the
- * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER)
- * is answered. Each buffer can be retrieved only once.
- *
+ **
  * For all these methods, wrap functions exists. Important rule: functions
  * for IN transactions have (as parameters) buffers where retrieved data
@@ -104,11 +95,4 @@
 	IPC_M_USBHC_GET_ADDRESS,
 
-	/** Asks for data buffer.
-	 * See explanation at usb_iface_funcs_t.
-	 * This function does not have counter part in functional interface
-	 * as it is handled by the remote part itself.
-	 */
-	IPC_M_USBHC_GET_BUFFER,
-
 
 	/** Reserve usage of default address.
Index: uspace/lib/usb/src/usbdrv.c
===================================================================
--- uspace/lib/usb/src/usbdrv.c	(revision 53338bda98807fedcb5b4a4ee04c9e6e2ee1813d)
+++ uspace/lib/usb/src/usbdrv.c	(revision f6309b65e6fe0aa5377536ac1f12c5eeafc99ac6)
@@ -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;
 
