diff options
Diffstat (limited to 'drivers/usb/gadget/dummy_hcd.c')
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b799106027ad..afdbb1cbf5d9 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1916,6 +1916,27 @@ done: | |||
1916 | return retval; | 1916 | return retval; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | /* usb 3.0 root hub device descriptor */ | ||
1920 | struct { | ||
1921 | struct usb_bos_descriptor bos; | ||
1922 | struct usb_ss_cap_descriptor ss_cap; | ||
1923 | } __packed usb3_bos_desc = { | ||
1924 | |||
1925 | .bos = { | ||
1926 | .bLength = USB_DT_BOS_SIZE, | ||
1927 | .bDescriptorType = USB_DT_BOS, | ||
1928 | .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), | ||
1929 | .bNumDeviceCaps = 1, | ||
1930 | }, | ||
1931 | .ss_cap = { | ||
1932 | .bLength = USB_DT_USB_SS_CAP_SIZE, | ||
1933 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
1934 | .bDevCapabilityType = USB_SS_CAP_TYPE, | ||
1935 | .wSpeedSupported = cpu_to_le16(USB_5GBPS_OPERATION), | ||
1936 | .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), | ||
1937 | }, | ||
1938 | }; | ||
1939 | |||
1919 | static inline void | 1940 | static inline void |
1920 | ss_hub_descriptor(struct usb_hub_descriptor *desc) | 1941 | ss_hub_descriptor(struct usb_hub_descriptor *desc) |
1921 | { | 1942 | { |
@@ -2006,6 +2027,18 @@ static int dummy_hub_control( | |||
2006 | else | 2027 | else |
2007 | hub_descriptor((struct usb_hub_descriptor *) buf); | 2028 | hub_descriptor((struct usb_hub_descriptor *) buf); |
2008 | break; | 2029 | break; |
2030 | |||
2031 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | ||
2032 | if (hcd->speed != HCD_USB3) | ||
2033 | goto error; | ||
2034 | |||
2035 | if ((wValue >> 8) != USB_DT_BOS) | ||
2036 | goto error; | ||
2037 | |||
2038 | memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); | ||
2039 | retval = sizeof(usb3_bos_desc); | ||
2040 | break; | ||
2041 | |||
2009 | case GetHubStatus: | 2042 | case GetHubStatus: |
2010 | *(__le32 *) buf = cpu_to_le32(0); | 2043 | *(__le32 *) buf = cpu_to_le32(0); |
2011 | break; | 2044 | break; |
@@ -2503,10 +2536,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2503 | hs_hcd->has_tt = 1; | 2536 | hs_hcd->has_tt = 1; |
2504 | 2537 | ||
2505 | retval = usb_add_hcd(hs_hcd, 0, 0); | 2538 | retval = usb_add_hcd(hs_hcd, 0, 0); |
2506 | if (retval != 0) { | 2539 | if (retval) |
2507 | usb_put_hcd(hs_hcd); | 2540 | goto put_usb2_hcd; |
2508 | return retval; | ||
2509 | } | ||
2510 | 2541 | ||
2511 | if (mod_data.is_super_speed) { | 2542 | if (mod_data.is_super_speed) { |
2512 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, | 2543 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, |
@@ -2525,6 +2556,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2525 | put_usb3_hcd: | 2556 | put_usb3_hcd: |
2526 | usb_put_hcd(ss_hcd); | 2557 | usb_put_hcd(ss_hcd); |
2527 | dealloc_usb2_hcd: | 2558 | dealloc_usb2_hcd: |
2559 | usb_remove_hcd(hs_hcd); | ||
2560 | put_usb2_hcd: | ||
2528 | usb_put_hcd(hs_hcd); | 2561 | usb_put_hcd(hs_hcd); |
2529 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; | 2562 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; |
2530 | return retval; | 2563 | return retval; |