On Thu, Apr 24 2014, Andrzej Pietrasiewicz wrote: > There is a custom (non-USB IF) extension to the USB standard: > > http://msdn.microsoft.com/library/windows/hardware/gg463182 > > 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 String" under index 0xEE of language 0. > The contents of the string is generated based on the qw_sign > array and b_vendor_code. > > Interested gadgets need to set the cdev->use_os_string flag, > fill cdev->qw_sign with appropriate values and fill cdev->b_vendor_code > with a value of their choice. > > This patch does not however implement responding to any vendor-specific > USB requests. > > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> > --- > drivers/usb/gadget/composite.c | 16 ++++++++++++++++ > include/linux/usb/composite.h | 14 ++++++++++++++ > 2 files changed, 30 insertions(+) > > diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c > index fab9064..0bfdb14 100644 > --- a/drivers/usb/gadget/composite.c > +++ b/drivers/usb/gadget/composite.c > @@ -960,6 +960,22 @@ static int get_string(struct usb_composite_dev *cdev, > return s->bLength; > } > > + if (cdev->use_os_string && language == 0 && id == OS_STRING_IDX) { > + /* > + * bLength|bDescriptorType|qwSignature|bMS_VendorCode|bPad > + * --------------------------------------------------------- > + * 1 Byte |1 Byte |14 Bytes |1 Byte |1 Byte > + * --------------------------------------------------------- > + */ It would be better to have a structure defined for this. > + u8 *b = buf; > + b[0] = 0x12; > + b[1] = USB_DT_STRING; > + memcpy(&b[2], cdev->qw_sign, OS_STRING_QW_SIGN_LEN); > + b[2 + OS_STRING_QW_SIGN_LEN] = cdev->b_vendor_code; > + b[3 + OS_STRING_QW_SIGN_LEN] = 0; > + return 0x12; > + } > + > list_for_each_entry(uc, &cdev->gstrings, list) { > struct usb_gadget_strings **sp; > > diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h > index d3ca3b5..28e3b5d 100644 > --- a/include/linux/usb/composite.h > +++ b/include/linux/usb/composite.h > @@ -335,11 +335,17 @@ 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 > * @config: the currently active configuration > + * @use_os_string: false by default, interested gadgets set it > + * @qw_sign: qwSignature part of the OS string > + * @b_vendor_code: bMS_VendorCode part of the OS string > * > * One of these devices is allocated and initialized before the > * associated device driver's bind() is called. > @@ -372,6 +378,14 @@ struct usb_composite_dev { > > struct usb_configuration *config; > > + /* > + * OS String is a custom (yet popular) extension to the USB standard. > + * > + */ > + unsigned int use_os_string:1; I'd move this with the rest of the bit fields. Otherwise, this likely ends up taking 4 bytes. > + u8 qw_sign[OS_STRING_QW_SIGN_LEN]; > + u8 b_vendor_code; > + > /* private: */ > /* internals */ > unsigned int suspended:1; > -- > 1.8.3.2 > -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz (o o) ooo +--<mpn@xxxxxxxxxx>--<xmpp:mina86@xxxxxxxxxx>--ooO--(_)--Ooo--
Attachment:
signature.asc
Description: PGP signature