diff --git a/linux_5.10/drivers/usb/gadget/composite.c b/linux_5.10/drivers/usb/gadget/composite.c index b080f7c5c..00510729f 100644 --- a/linux_5.10/drivers/usb/gadget/composite.c +++ b/linux_5.10/drivers/usb/gadget/composite.c @@ -7,6 +7,7 @@ /* #define VERBOSE_DEBUG */ +#include "linux/types.h" #include #include #include @@ -664,6 +665,58 @@ static int bos_desc(struct usb_composite_dev *cdev) struct usb_ext_cap_descriptor *usb_ext; struct usb_dcd_config_params dcd_config_params; struct usb_bos_descriptor *bos = cdev->req->buf; +#if defined (CONFIG_GAOYANG) +#if defined (CONFIG_GAOYANG_WCID20) + /* WCID20 device capability descriptor */ + #define USB_CAP_TYPE_WCID 5 + #define USB_CAP_WCID_SIZE 0x1C + #define WINUSB20_WCID_VENDOR_CODE 0x00 + #define WINUSB20_WCID_DESC_SET_SIZE 162 + + struct usb_cap_wcid20_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDevCapabilityType; + __u8 bReserved ; + __u8 bPlatformCapabilityUUID_16[16]; + __u32 dwWindowsVersion; + __le32 wDescriptorSetTotalLength; + __u8 bVendorCode; + __u8 bAltEnumCode; + } __attribute__((packed)); + + char winusb20_wcidbos_uuid[] = { + 0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c, + 0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, 0x9f, + }; + + uint32_t winusb20_wcidbos_version = 0x06030000; + + struct usb_cap_wcid20_descriptor *usb_cap_wcid; +#endif // !defined (CONFIG_GAOYANG_WCID20) + /* WCID10 device capability descriptor */ + #define USB_OS_SIZE 0x12 + #define USB_DT_OS USB_DT_STRING + #define WCID_VENDOR_CODE 0x00 + + struct usb_cap_wcid10_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u16 MicrosoftString[7]; + __u8 bVendorCode; + union { + __u8 bPad; + __u8 bFlags; + }; + } __attribute__((packed)); + + uint8_t os_string[] = { + 0x4D, 0x00, 0x53, 0x00, 0x46, 0x00, 0x54, + 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00 + }; + + struct usb_cap_wcid10_descriptor *usb_os = cdev->req->buf; +#endif // defined (CONFIG_GAOYANG) unsigned int besl = 0; bos->bLength = USB_DT_BOS_SIZE; @@ -671,6 +724,15 @@ static int bos_desc(struct usb_composite_dev *cdev) bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE); bos->bNumDeviceCaps = 0; +#if defined (CONFIG_GAOYANG) + usb_os->bLength = USB_OS_SIZE; + usb_os->bDescriptorType = USB_DT_OS; + usb_os->bVendorCode = WCID_VENDOR_CODE; + memcpy(usb_os->MicrosoftString, os_string, sizeof(os_string)); + + bos->wTotalLength = cpu_to_le16(USB_OS_SIZE); + bos->bNumDeviceCaps = 0; +#endif // defined (CONFIG_GAOYANG_WCID20) /* Get Controller configuration */ if (cdev->gadget->ops->get_config_params) { @@ -694,7 +756,6 @@ static int bos_desc(struct usb_composite_dev *cdev) if (dcd_config_params.besl_deep != USB_DEFAULT_BESL_UNSPECIFIED) besl |= USB_BESL_DEEP_VALID | USB_SET_BESL_DEEP(dcd_config_params.besl_deep); - /* * A SuperSpeed device shall include the USB2.0 extension descriptor * and shall support LPM when operating in USB2.0 HS mode. @@ -708,6 +769,21 @@ static int bos_desc(struct usb_composite_dev *cdev) usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | USB_BESL_SUPPORT | besl); +#if defined (CONFIG_GAOYANG) +#if defined (CONFIG_GAOYANG_WCID20) + usb_cap_wcid = cdev->req->buf + le16_to_cpu(bos->wTotalLength); + le16_add_cpu(&bos->wTotalLength, USB_CAP_WCID_SIZE); + bos->bNumDeviceCaps++; + + usb_cap_wcid->bLength = USB_CAP_WCID_SIZE; + usb_cap_wcid->bDescriptorType = USB_DT_DEVICE_CAPABILITY; + usb_cap_wcid->bDevCapabilityType = USB_CAP_TYPE_WCID; + usb_cap_wcid->dwWindowsVersion = winusb20_wcidbos_version; + usb_cap_wcid->wDescriptorSetTotalLength = cpu_to_le32(WINUSB20_WCID_DESC_SET_SIZE); + usb_cap_wcid->bVendorCode = WINUSB20_WCID_VENDOR_CODE; + memcpy(usb_cap_wcid->bPlatformCapabilityUUID_16, winusb20_wcidbos_uuid, sizeof(winusb20_wcidbos_uuid)); +#endif // !defined (CONFIG_GAOYANG_WCID20) +#endif // defined (CONFIG_GAOYANG) /* * The Superspeed USB Capability descriptor shall be implemented by all * SuperSpeed devices.