|
|
@@ -21,6 +21,22 @@
|
|
|
#include <linux/usb/composite.h>
|
|
|
#include <asm/unaligned.h>
|
|
|
|
|
|
+/**
|
|
|
+ * struct usb_os_string - represents OS String to be reported by a gadget
|
|
|
+ * @bLength: total length of the entire descritor, always 0x12
|
|
|
+ * @bDescriptorType: USB_DT_STRING
|
|
|
+ * @qwSignature: the OS String proper
|
|
|
+ * @bMS_VendorCode: code used by the host for subsequent requests
|
|
|
+ * @bPad: not used, must be zero
|
|
|
+ */
|
|
|
+struct usb_os_string {
|
|
|
+ __u8 bLength;
|
|
|
+ __u8 bDescriptorType;
|
|
|
+ __u8 qwSignature[OS_STRING_QW_SIGN_LEN];
|
|
|
+ __u8 bMS_VendorCode;
|
|
|
+ __u8 bPad;
|
|
|
+} __packed;
|
|
|
+
|
|
|
/*
|
|
|
* The code in this file is utility code, used to build a gadget driver
|
|
|
* from one or more "function" drivers, one or more "configuration"
|
|
|
@@ -961,6 +977,19 @@ static int get_string(struct usb_composite_dev *cdev,
|
|
|
return s->bLength;
|
|
|
}
|
|
|
|
|
|
+ if (cdev->use_os_string && language == 0 && id == OS_STRING_IDX) {
|
|
|
+ struct usb_os_string *b = buf;
|
|
|
+ b->bLength = sizeof(*b);
|
|
|
+ b->bDescriptorType = USB_DT_STRING;
|
|
|
+ compiletime_assert(
|
|
|
+ sizeof(b->qwSignature) == sizeof(cdev->qw_sign),
|
|
|
+ "qwSignature size must be equal to qw_sign");
|
|
|
+ memcpy(&b->qwSignature, cdev->qw_sign, sizeof(b->qwSignature));
|
|
|
+ b->bMS_VendorCode = cdev->b_vendor_code;
|
|
|
+ b->bPad = 0;
|
|
|
+ return sizeof(*b);
|
|
|
+ }
|
|
|
+
|
|
|
list_for_each_entry(uc, &cdev->gstrings, list) {
|
|
|
struct usb_gadget_strings **sp;
|
|
|
|