Index: uspace/lib/usb/src/request.c
===================================================================
--- uspace/lib/usb/src/request.c	(revision 2211125e137c99b013c783e876c6cdf7ab9d4ee6)
+++ uspace/lib/usb/src/request.c	(revision e387d0fad920ec084554d359efa79df35684f3ec)
@@ -157,4 +157,97 @@
 }
 
+/** Retrieve status of a USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] index Recipient index (in native endianness).
+ * @param[in] recipient Recipient of the GET_STATUS request.
+ * @param[out] status Recipient status (in native endianness).
+ * @return Error code.
+ */
+int usb_request_get_status(usb_endpoint_pipe_t *pipe,
+    usb_request_recipient_t recipient, uint16_t index,
+    uint16_t *status)
+{
+	if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0)) {
+		return EINVAL;
+	}
+
+	if (status == NULL) {
+		return EBADMEM;
+	}
+
+	uint16_t status_usb_endianess;
+	size_t data_transfered_size;
+	int rc = usb_control_request_get(pipe, USB_REQUEST_TYPE_STANDARD,
+	    recipient, USB_DEVREQ_GET_STATUS, 0, uint16_host2usb(index),
+	    &status_usb_endianess, 2, &data_transfered_size);
+	if (rc != EOK) {
+		return rc;
+	}
+	if (data_transfered_size != 2) {
+		return ELIMIT;
+	}
+
+	*status = uint16_usb2host(status_usb_endianess);
+
+	return EOK;
+}
+
+/** Clear or disable specific device feature.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Recipient of the CLEAR_FEATURE request.
+ * @param[in] feature_selector Feature selector (in native endianness).
+ * @param[in] index Recipient index (in native endianness).
+ * @return Error code.
+ */
+int usb_request_clear_feature(usb_endpoint_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint16_t feature_selector, uint16_t index)
+{
+	if (request_type == USB_REQUEST_TYPE_STANDARD) {
+		if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
+		    && (index != 0)) {
+			return EINVAL;
+		}
+	}
+
+	int rc = usb_control_request_set(pipe, request_type, recipient,
+	    USB_DEVREQ_CLEAR_FEATURE,
+	    uint16_host2usb(feature_selector), uint16_host2usb(index),
+	    NULL, 0);
+
+	return rc;
+}
+
+/** Set or enable specific device feature.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Recipient of the SET_FEATURE request.
+ * @param[in] feature_selector Feature selector (in native endianness).
+ * @param[in] index Recipient index (in native endianness).
+ * @return Error code.
+ */
+int usb_request_set_feature(usb_endpoint_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint16_t feature_selector, uint16_t index)
+{
+	if (request_type == USB_REQUEST_TYPE_STANDARD) {
+		if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
+		    && (index != 0)) {
+			return EINVAL;
+		}
+	}
+
+	int rc = usb_control_request_set(pipe, request_type, recipient,
+	    USB_DEVREQ_SET_FEATURE,
+	    uint16_host2usb(feature_selector), uint16_host2usb(index),
+	    NULL, 0);
+
+	return rc;
+}
+
 /** Change address of connected device.
  * This function automatically updates the backing connection to point to
@@ -473,4 +566,71 @@
 }
 
+/** Update existing or add new USB descriptor to a USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] request_type Request type (standard/class/vendor).
+ * @param[in] recipient Request recipient (device/interface/endpoint).
+ * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
+ * @param[in] descriptor_index Descriptor index.
+ * @param[in] language Language index (in native endianness).
+ * @param[in] buffer Buffer with the new descriptor (in USB endianness).
+ * @param[in] size Size of the @p buffer in bytes (in native endianness).
+ * @return Error code.
+ */
+int usb_request_set_descriptor(usb_endpoint_pipe_t *pipe,
+    usb_request_type_t request_type, usb_request_recipient_t recipient,
+    uint8_t descriptor_type, uint8_t descriptor_index,
+    uint16_t language,
+    void *buffer, size_t size)
+{
+	if (buffer == NULL) {
+		return EBADMEM;
+	}
+	if (size == 0) {
+		return EINVAL;
+	}
+
+	/* FIXME: proper endianness. */
+	uint16_t wValue = descriptor_index | (descriptor_type << 8);
+
+	return usb_control_request_set(pipe,
+	    request_type, recipient,
+	    USB_DEVREQ_SET_DESCRIPTOR,
+	    wValue, language,
+	    buffer, size);
+}
+
+/** Get current configuration value of USB device.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[out] configuration_value Current configuration value.
+ * @return Error code.
+ */
+int usb_request_get_configuration(usb_endpoint_pipe_t *pipe,
+    uint8_t *configuration_value)
+{
+	uint8_t value;
+	size_t actual_size;
+
+	int rc = usb_control_request_get(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
+	    USB_DEVREQ_GET_CONFIGURATION,
+	    0, 0,
+	    &value, 1, &actual_size);
+
+	if (rc != EOK) {
+		return rc;
+	}
+	if (actual_size != 1) {
+		return ELIMIT;
+	}
+
+	if (configuration_value != NULL) {
+		*configuration_value = value;
+	}
+
+	return EOK;
+}
+
 /** Set configuration of USB device.
  *
@@ -488,4 +648,55 @@
 	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
 	    USB_DEVREQ_SET_CONFIGURATION, config_value, 0,
+	    NULL, 0);
+}
+
+/** Get selected alternate setting for USB interface.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] interface_index Interface index.
+ * @param[out] alternate_setting Alternate setting for the interface.
+ * @return Error code.
+ */
+int usb_request_get_interface(usb_endpoint_pipe_t *pipe,
+    uint8_t interface_index, uint8_t *alternate_setting)
+{
+	uint8_t value;
+	size_t actual_size;
+
+	int rc = usb_control_request_get(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DEVREQ_GET_INTERFACE,
+	    0, uint16_host2usb((uint16_t) interface_index),
+	    &value, 1, &actual_size);
+
+	if (rc != EOK) {
+		return rc;
+	}
+	if (actual_size != 1) {
+		return ELIMIT;
+	}
+
+	if (alternate_setting != NULL) {
+		*alternate_setting = value;
+	}
+
+	return EOK;
+}
+
+/** Select alternate setting for USB interface.
+ *
+ * @param[in] pipe Control endpoint pipe (session must be already started).
+ * @param[in] interface_index Interface index.
+ * @param[in] alternate_setting Alternate setting to select.
+ * @return Error code.
+ */
+int usb_request_set_interface(usb_endpoint_pipe_t *pipe,
+    uint8_t interface_index, uint8_t alternate_setting)
+{
+	return usb_control_request_set(pipe,
+	    USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
+	    USB_DEVREQ_SET_INTERFACE,
+	    uint16_host2usb((uint16_t) alternate_setting),
+	    uint16_host2usb((uint16_t) interface_index),
 	    NULL, 0);
 }
