Index: uspace/lib/usb/include/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/include/usb/usbdrv.h	(revision 947d78839aee48678e3102bf15a647260383d50d)
+++ uspace/lib/usb/include/usb/usbdrv.h	(revision 9501cced4832feaa69f1ecd479985c509812797d)
@@ -38,4 +38,6 @@
 #include <usb/usb.h>
 #include <driver.h>
+#include <usb/devreq.h>
+#include <usb/descriptor.h>
 
 int usb_drv_hc_connect(device_t *, unsigned int);
@@ -72,4 +74,6 @@
 
 int usb_drv_req_set_address(int, usb_address_t, usb_address_t);
+int usb_drv_req_get_device_descriptor(int, usb_address_t,
+    usb_standard_device_descriptor_t *);
 
 #endif
Index: uspace/lib/usb/src/usbdrvreq.c
===================================================================
--- uspace/lib/usb/src/usbdrvreq.c	(revision 947d78839aee48678e3102bf15a647260383d50d)
+++ uspace/lib/usb/src/usbdrvreq.c	(revision 9501cced4832feaa69f1ecd479985c509812797d)
@@ -34,5 +34,4 @@
  */
 #include <usb/usbdrv.h>
-#include <usb/devreq.h>
 #include <errno.h>
 
@@ -95,4 +94,88 @@
 }
 
+/** Retrieve device descriptor of connected USB device.
+ *
+ * @param[in] phone Open phone to HC driver.
+ * @param[in] address Device USB address.
+ * @param[out] descriptor Storage for the device descriptor.
+ * @return Error code.
+ * @retval EBADMEM @p descriptor is NULL.
+ */
+int usb_drv_req_get_device_descriptor(int phone, usb_address_t address,
+    usb_standard_device_descriptor_t *descriptor)
+{
+	if (descriptor == NULL) {
+		return EBADMEM;
+	}
+
+	/* Prepare the target. */
+	usb_target_t target = {
+		.address = address,
+		.endpoint = 0
+	};
+
+	/* Prepare the setup packet. */
+	usb_device_request_setup_packet_t setup_packet = {
+		.request_type = 0,
+		.request = USB_DEVREQ_GET_DESCRIPTOR,
+		.index = 0,
+		.length = sizeof(usb_standard_device_descriptor_t)
+	};
+	setup_packet.value_high = USB_DESCTYPE_DEVICE;
+	setup_packet.value_low = 0;
+
+	usb_handle_t handle;
+	int rc;
+
+	/* Start the control read transfer. */
+	rc = usb_drv_async_control_read_setup(phone, target,
+	    &setup_packet, sizeof(setup_packet), &handle);
+	if (rc != EOK) {
+		return rc;
+	}
+	rc = usb_drv_async_wait_for(handle);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Retrieve the descriptor. */
+	size_t actually_transferred = 0;
+	usb_standard_device_descriptor_t descriptor_tmp;
+	rc = usb_drv_async_control_read_data(phone, target,
+	    &descriptor_tmp, sizeof(usb_standard_device_descriptor_t),
+	    &actually_transferred, &handle);
+	if (rc != EOK) {
+		return rc;
+	}
+	rc = usb_drv_async_wait_for(handle);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Finish the control read transfer. */
+	rc = usb_drv_async_control_read_status(phone, target, &handle);
+	if (rc != EOK) {
+		return rc;
+	}
+	rc = usb_drv_async_wait_for(handle);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	if (actually_transferred < sizeof(usb_standard_device_descriptor_t)) {
+		return ELIMIT;
+	}
+
+	/*
+	 * Everything is okay, copy the descriptor.
+	 */
+	memcpy(descriptor, &descriptor_tmp,
+	    sizeof(usb_standard_device_descriptor_t));
+
+	return EOK;
+}
+
+
+
 /**
  * @}
