Index: uspace/app/usbinfo/dump.c
===================================================================
--- uspace/app/usbinfo/dump.c	(revision f5e394756565d0500e7b8cb5a54f743aba77d7db)
+++ uspace/app/usbinfo/dump.c	(revision 2c5cefa897b181e123f9677daf6fc62cb602cd82)
@@ -47,4 +47,5 @@
 
 #define INDENT "  "
+#define BYTES_PER_LINE 12
 
 #define BCD_INT(a) (((unsigned int)(a)) / 256)
@@ -53,4 +54,18 @@
 #define BCD_FMT "%x.%x"
 #define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
+
+void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
+{
+	printf("%s\n", msg);
+
+	size_t i;
+	for (i = 0; i < length; i++) {
+		printf("  0x%02X", buffer[i]);
+		if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
+		    || (i + 1 == length)) {
+			printf("\n");
+		}
+	}
+}
 
 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *d)
@@ -75,4 +90,27 @@
 }
 
+void dump_standard_configuration_descriptor(
+    int index, usb_standard_configuration_descriptor_t *d)
+{
+	bool self_powered = d->attributes & 64;
+	bool remote_wakeup = d->attributes & 32;
+	
+	printf("Standard configuration descriptor #%d\n", index);
+	printf(INDENT "bLength = %d\n", d->length);
+	printf(INDENT "bDescriptorType = 0x%02x\n", d->descriptor_type);
+	printf(INDENT "wTotalLength = %d\n", d->total_length);
+	printf(INDENT "bNumInterfaces = %d\n", d->interface_count);
+	printf(INDENT "bConfigurationValue = %d\n", d->configuration_number);
+	printf(INDENT "iConfiguration = %d\n", d->str_configuration);
+	printf(INDENT "bmAttributes = %d [%s%s%s]\n", d->attributes,
+	    self_powered ? "self-powered" : "",
+	    (self_powered & remote_wakeup) ? ", " : "",
+	    remote_wakeup ? "remote-wakeup" : "");
+	printf(INDENT "MaxPower = %d (%dmA)\n", d->max_power,
+	    2 * d->max_power);
+	// printf(INDENT " = %d\n", d->);
+}
+
+
 /** @}
  */
Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision f5e394756565d0500e7b8cb5a54f743aba77d7db)
+++ uspace/app/usbinfo/main.c	(revision 2c5cefa897b181e123f9677daf6fc62cb602cd82)
@@ -107,5 +107,5 @@
 	 */
 	usb_standard_device_descriptor_t device_descriptor;
-	usb_dprintf("usbinfo", 1,
+	usb_dprintf(NAME, 1,
 	    "usb_drv_req_get_device_descriptor(%d, %d, %p)\n",
 	    hc_phone, (int) address, &device_descriptor);
@@ -121,4 +121,41 @@
 	dump_standard_device_descriptor(&device_descriptor);
 
+	/*
+	 * Get first configuration descriptor and dump it.
+	 */
+	usb_standard_configuration_descriptor_t config_descriptor;
+	int config_index = 0;
+	usb_dprintf(NAME, 1,
+	    "usb_drv_req_get_bare_configuration_descriptor(%d, %d, %d, %p)\n",
+	    hc_phone, (int) address, config_index, &config_descriptor);
+
+	rc = usb_drv_req_get_bare_configuration_descriptor(hc_phone, address,
+	    config_index, &config_descriptor );
+	if (rc != EOK) {
+		fprintf(stderr,
+		    NAME ": failed to fetch standard configuration descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	dump_standard_configuration_descriptor(config_index,
+	    &config_descriptor);
+
+	void *full_config_descriptor = malloc(config_descriptor.total_length);
+	usb_dprintf(NAME, 1,
+	    "usb_drv_req_get_full_configuration_descriptor(%d, %d, %d, %p, %zu)\n",
+	    hc_phone, (int) address, config_index,
+	    full_config_descriptor, config_descriptor.total_length);
+
+	rc = usb_drv_req_get_full_configuration_descriptor(hc_phone, address,
+	    config_index,
+	    full_config_descriptor, config_descriptor.total_length, NULL);
+	if (rc != EOK) {
+		fprintf(stderr,
+		    NAME ": failed to fetch full configuration descriptor: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+	dump_buffer("Full configuration descriptor:",
+	    full_config_descriptor, config_descriptor.total_length);
 
 	return EOK;
Index: uspace/app/usbinfo/usbinfo.h
===================================================================
--- uspace/app/usbinfo/usbinfo.h	(revision f5e394756565d0500e7b8cb5a54f743aba77d7db)
+++ uspace/app/usbinfo/usbinfo.h	(revision 2c5cefa897b181e123f9677daf6fc62cb602cd82)
@@ -43,5 +43,8 @@
 #define NAME "usbinfo"
 
+void dump_buffer(const char *, const uint8_t *, size_t);
 void dump_standard_device_descriptor(usb_standard_device_descriptor_t *);
+void dump_standard_configuration_descriptor(int, 
+    usb_standard_configuration_descriptor_t *);
 
 #endif
Index: uspace/lib/usb/include/usb/devreq.h
===================================================================
--- uspace/lib/usb/include/usb/devreq.h	(revision f5e394756565d0500e7b8cb5a54f743aba77d7db)
+++ uspace/lib/usb/include/usb/devreq.h	(revision 2c5cefa897b181e123f9677daf6fc62cb602cd82)
@@ -38,4 +38,6 @@
 #include <ipc/ipc.h>
 #include <async.h>
+#include <usb/usb.h>
+#include <usb/descriptor.h>
 
 /** Standard device request. */
@@ -83,4 +85,13 @@
 } __attribute__ ((packed)) usb_device_request_setup_packet_t;
 
+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 *);
+int usb_drv_req_get_bare_configuration_descriptor(int, usb_address_t, int,
+    usb_standard_configuration_descriptor_t *);
+int usb_drv_req_get_full_configuration_descriptor(int, usb_address_t, int,
+    void *, size_t, size_t *);
+
+
 #endif
 /**
Index: uspace/lib/usb/include/usb/usbdrv.h
===================================================================
--- uspace/lib/usb/include/usb/usbdrv.h	(revision f5e394756565d0500e7b8cb5a54f743aba77d7db)
+++ uspace/lib/usb/include/usb/usbdrv.h	(revision 2c5cefa897b181e123f9677daf6fc62cb602cd82)
@@ -95,8 +95,4 @@
 
 
-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 f5e394756565d0500e7b8cb5a54f743aba77d7db)
+++ uspace/lib/usb/src/usbdrvreq.c	(revision 2c5cefa897b181e123f9677daf6fc62cb602cd82)
@@ -130,4 +130,112 @@
 
 
+/** Retrieve configuration descriptor of connected USB device.
+ *
+ * The function does not retrieve additional data binded with configuration
+ * descriptor (such as its interface and endpoint descriptors) - use
+ * usb_drv_req_get_full_configuration_descriptor() instead.
+ *
+ * @param[in] phone Open phone to HC driver.
+ * @param[in] address Device USB address.
+ * @param[in] index Configuration descriptor index.
+ * @param[out] descriptor Storage for the configuration descriptor.
+ * @return Error code.
+ * @retval EBADMEM @p descriptor is NULL.
+ */
+int usb_drv_req_get_bare_configuration_descriptor(int phone,
+    usb_address_t address, int index,
+    usb_standard_configuration_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 = 128,
+		.request = USB_DEVREQ_GET_DESCRIPTOR,
+		.index = 0,
+		.length = sizeof(usb_standard_device_descriptor_t)
+	};
+	setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
+	setup_packet.value_low = index;
+
+	/* Prepare local descriptor. */
+	size_t actually_transferred = 0;
+	usb_standard_configuration_descriptor_t descriptor_tmp;
+
+	/* Perform the control read transaction. */
+	int rc = usb_drv_psync_control_read(phone, target,
+	    &setup_packet, sizeof(setup_packet),
+	    &descriptor_tmp, sizeof(descriptor_tmp), &actually_transferred);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	/* Verify that all data has been transferred. */
+	if (actually_transferred < sizeof(descriptor_tmp)) {
+		return ELIMIT;
+	}
+
+	/* Everything is okay, copy the descriptor. */
+	memcpy(descriptor, &descriptor_tmp,
+	    sizeof(descriptor_tmp));
+
+	return EOK;
+}
+
+/** Retrieve full configuration descriptor of connected USB device.
+ *
+ * @warning The @p buffer might be touched (i.e. its contents changed)
+ * even when error occurres.
+ *
+ * @param[in] phone Open phone to HC driver.
+ * @param[in] address Device USB address.
+ * @param[in] index Configuration descriptor index.
+ * @param[out] buffer Buffer for the whole configuration descriptor.
+ * @param[in] buffer_size Size of the prepared @p buffer.
+ * @param[out] actual_buffer_size Bytes actually transfered.
+ * @return Error code.
+ * @retval EBADMEM @p descriptor is NULL.
+ */
+int usb_drv_req_get_full_configuration_descriptor(int phone,
+    usb_address_t address, int index,
+    void *buffer, size_t buffer_size, size_t *actual_buffer_size)
+{
+	if (buffer == 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 = 128,
+		.request = USB_DEVREQ_GET_DESCRIPTOR,
+		.index = 0,
+		.length = sizeof(usb_standard_device_descriptor_t)
+	};
+	setup_packet.value_high = USB_DESCTYPE_CONFIGURATION;
+	setup_packet.value_low = index;
+
+	/* Perform the control read transaction. */
+	int rc = usb_drv_psync_control_read(phone, target,
+	    &setup_packet, sizeof(setup_packet),
+	    buffer, buffer_size, actual_buffer_size);
+
+	return rc;
+}
+
 
 /**
