usb: gadget: configfs: OS Extended Properties descriptors support
[firefly-linux-kernel-4.4.55.git] / include / linux / usb / composite.h
index d3ca3b53837c42c85ff2dd7ebcc11764014fe23d..7373203140e7d17e68386f6dfa21ed1fd14c077d 100644 (file)
 #define USB_MS_TO_HS_INTERVAL(x)       (ilog2((x * 1000 / 125)) + 1)
 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
+ * @item: Represents this Extended Property in configfs
+ */
+struct usb_os_desc_ext_prop {
+       struct list_head        entry;
+       u8                      type;
+       int                     name_len;
+       char                    *name;
+       int                     data_len;
+       char                    *data;
+       struct config_item      item;
+};
+
+/**
+ * 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
+ * @opts_mutex: Optional mutex protecting config data of a usb_function_instance
+ * @group: Represents OS descriptors associated with an interface in configfs
+ * @owner: Module associated with this OS descriptor
+ */
+struct usb_os_desc {
+       char                    *ext_compat_id;
+       struct list_head        ext_prop;
+       int                     ext_prop_len;
+       int                     ext_prop_count;
+       struct mutex            *opts_mutex;
+       struct config_group     group;
+       struct module           *owner;
+};
+
+/**
+ * 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.
@@ -73,6 +128,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 +188,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.
@@ -327,6 +389,8 @@ extern void usb_composite_unregister(struct usb_composite_driver *driver);
 extern void usb_composite_setup_continue(struct usb_composite_dev *cdev);
 extern int composite_dev_prepare(struct usb_composite_driver *composite,
                struct usb_composite_dev *cdev);
+extern int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
+                                        struct usb_ep *ep0);
 void composite_dev_cleanup(struct usb_composite_dev *cdev);
 
 static inline struct usb_composite_driver *to_cdriver(
@@ -335,11 +399,19 @@ static inline struct usb_composite_driver *to_cdriver(
        return container_of(gdrv, struct usb_composite_driver, gadget_driver);
 }
 
+#define OS_STRING_QW_SIGN_LEN          14
+#define OS_STRING_IDX                  0xEE
+
 /**
  * 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.
@@ -369,9 +441,16 @@ 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: */
        /* internals */
        unsigned int                    suspended:1;