summaryrefslogtreecommitdiffstats
path: root/include/linux/usb
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2014-05-08 14:06:23 +0200
committerFelipe Balbi <balbi@ti.com>2014-05-14 09:38:16 -0500
commit37a3a533429ef9b3cc9f15a656c19623f0e88df7 (patch)
tree93746c1babf3172e5d705b6a72fe19e84f7d3362 /include/linux/usb
parent19824d5eeecedfb46639961da1b7a21ba3179930 (diff)
usb: gadget: OS Feature Descriptors support
There is a custom (non-USB IF) extension to the USB standard: http://msdn.microsoft.com/library/windows/hardware/gg463182 They grant permission to use the specification - there is "Microsoft OS Descriptor Specification License Agreement" under the link mentioned above, and its Section 2 "Grant of License", letter (b) reads: "Patent license. Microsoft hereby grants to You a nonexclusive, royalty-free, nontransferable, worldwide license under Microsoft’s patents embodied solely within the Specification and that are owned or licensable by Microsoft to make, use, import, offer to sell, sell and distribute directly or indirectly to Your Licensees Your Implementation. You may sublicense this patent license to Your Licensees under the same terms and conditions." The said extension is maintained by Microsoft for Microsoft. Yet it is fairly common for various devices to use it, and a popular proprietary operating system expects devices to provide "OS descriptors", so Linux-based USB gadgets whishing to be able to talk to a variety of operating systems should be able to provide the "OS descriptors". This patch adds optional support for gadgets whishing to expose the so called "OS Feature Descriptors", that is "Extended Compatibility ID" and "Extended Properties". Hosts which do request "OS descriptors" from gadgets do so during the enumeration phase and before the configuration is set with SET_CONFIGURATION. What is more, those hosts never ask for configurations at indices other than 0. Therefore, gadgets whishing to provide "OS descriptors" must designate one configuration to be used with this kind of hosts - this is what os_desc_config is added for in struct usb_composite_dev. There is an additional advantage to it: if a gadget provides "OS descriptors" and designates one configuration to be used with such non-USB-compliant hosts it can invoke "usb_add_config" in any order because the designated configuration will be reported to be at index 0 anyway. This patch also adds handling vendor-specific requests addressed at device or interface and related to handling "OS descriptors". Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'include/linux/usb')
-rw-r--r--include/linux/usb/composite.h58
1 files changed, 58 insertions, 0 deletions
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 7d29ee9363e..549f5382b01 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -57,6 +57,53 @@
struct usb_configuration;
/**
+ * struct usb_os_desc_ext_prop - describes one "Extended Property"
+ * @entry: used to keep a list of extended properties
+ * @type: Extended Property type
+ * @name_len: Extended Property unicode name length, including terminating '\0'
+ * @name: Extended Property name
+ * @data_len: Length of Extended Property blob (for unicode store double len)
+ * @data: Extended Property blob
+ */
+struct usb_os_desc_ext_prop {
+ struct list_head entry;
+ u8 type;
+ int name_len;
+ char *name;
+ int data_len;
+ char *data;
+};
+
+/**
+ * struct usb_os_desc - describes OS descriptors associated with one interface
+ * @ext_compat_id: 16 bytes of "Compatible ID" and "Subcompatible ID"
+ * @ext_prop: Extended Properties list
+ * @ext_prop_len: Total length of Extended Properties blobs
+ * @ext_prop_count: Number of Extended Properties
+ */
+struct usb_os_desc {
+ char *ext_compat_id;
+ struct list_head ext_prop;
+ int ext_prop_len;
+ int ext_prop_count;
+};
+
+/**
+ * struct usb_os_desc_table - describes OS descriptors associated with one
+ * interface of a usb_function
+ * @if_id: Interface id
+ * @os_desc: "Extended Compatibility ID" and "Extended Properties" of the
+ * interface
+ *
+ * Each interface can have at most one "Extended Compatibility ID" and a
+ * number of "Extended Properties".
+ */
+struct usb_os_desc_table {
+ int if_id;
+ struct usb_os_desc *os_desc;
+};
+
+/**
* struct usb_function - describes one function of a configuration
* @name: For diagnostics, identifies the function.
* @strings: tables of strings, keyed by identifiers assigned during bind()
@@ -73,6 +120,10 @@ struct usb_configuration;
* be available at super speed.
* @config: assigned when @usb_add_function() is called; this is the
* configuration with which this function is associated.
+ * @os_desc_table: Table of (interface id, os descriptors) pairs. The function
+ * can expose more than one interface. If an interface is a member of
+ * an IAD, only the first interface of IAD has its entry in the table.
+ * @os_desc_n: Number of entries in os_desc_table
* @bind: Before the gadget can register, all of its functions bind() to the
* available resources including string and interface identifiers used
* in interface or class descriptors; endpoints; I/O buffers; and so on.
@@ -129,6 +180,9 @@ struct usb_function {
struct usb_configuration *config;
+ struct usb_os_desc_table *os_desc_table;
+ unsigned os_desc_n;
+
/* REVISIT: bind() functions can be marked __init, which
* makes trouble for section mismatch analysis. See if
* we can't restructure things to avoid mismatching.
@@ -342,10 +396,12 @@ static inline struct usb_composite_driver *to_cdriver(
* struct usb_composite_device - represents one composite usb gadget
* @gadget: read-only, abstracts the gadget's usb peripheral controller
* @req: used for control responses; buffer is pre-allocated
+ * @os_desc_req: used for OS descriptors responses; buffer is pre-allocated
* @config: the currently active configuration
* @qw_sign: qwSignature part of the OS string
* @b_vendor_code: bMS_VendorCode part of the OS string
* @use_os_string: false by default, interested gadgets set it
+ * @os_desc_config: the configuration to be used with OS descriptors
*
* One of these devices is allocated and initialized before the
* associated device driver's bind() is called.
@@ -375,12 +431,14 @@ static inline struct usb_composite_driver *to_cdriver(
struct usb_composite_dev {
struct usb_gadget *gadget;
struct usb_request *req;
+ struct usb_request *os_desc_req;
struct usb_configuration *config;
/* OS String is a custom (yet popular) extension to the USB standard. */
u8 qw_sign[OS_STRING_QW_SIGN_LEN];
u8 b_vendor_code;
+ struct usb_configuration *os_desc_config;
unsigned int use_os_string:1;
/* private: */