aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2017-09-26 15:15:22 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2017-09-28 05:30:51 -0400
commitfe659bcc9b173bcfdd958ce2aec75e47651e74e1 (patch)
tree11d1e48c6e3a7857719a906c8154dff13471a90c
parent8fec9355a968ad240f3a2e9ad55b823cf1cc52ff (diff)
USB: dummy-hcd: fix connection failures (wrong speed)
The dummy-hcd UDC driver is not careful about the way it handles connection speeds. It ignores the module parameter that is supposed to govern the maximum connection speed and it doesn't set the HCD flags properly for the case where it ends up running at full speed. The result is that in many cases, gadget enumeration over dummy-hcd fails because the bMaxPacketSize byte in the device descriptor is set incorrectly. For example, the default settings call for a high-speed connection, but the maxpacket value for ep0 ends up being set for a Super-Speed connection. This patch fixes the problem by initializing the gadget's max_speed and the HCD flags correctly. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> CC: <stable@vger.kernel.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index b1e21b3be6e1..d515ec31afe4 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -1036,7 +1036,12 @@ static int dummy_udc_probe(struct platform_device *pdev)
1036 memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); 1036 memzero_explicit(&dum->gadget, sizeof(struct usb_gadget));
1037 dum->gadget.name = gadget_name; 1037 dum->gadget.name = gadget_name;
1038 dum->gadget.ops = &dummy_ops; 1038 dum->gadget.ops = &dummy_ops;
1039 dum->gadget.max_speed = USB_SPEED_SUPER; 1039 if (mod_data.is_super_speed)
1040 dum->gadget.max_speed = USB_SPEED_SUPER;
1041 else if (mod_data.is_high_speed)
1042 dum->gadget.max_speed = USB_SPEED_HIGH;
1043 else
1044 dum->gadget.max_speed = USB_SPEED_FULL;
1040 1045
1041 dum->gadget.dev.parent = &pdev->dev; 1046 dum->gadget.dev.parent = &pdev->dev;
1042 init_dummy_udc_hw(dum); 1047 init_dummy_udc_hw(dum);
@@ -2560,8 +2565,6 @@ static struct hc_driver dummy_hcd = {
2560 .product_desc = "Dummy host controller", 2565 .product_desc = "Dummy host controller",
2561 .hcd_priv_size = sizeof(struct dummy_hcd), 2566 .hcd_priv_size = sizeof(struct dummy_hcd),
2562 2567
2563 .flags = HCD_USB3 | HCD_SHARED,
2564
2565 .reset = dummy_setup, 2568 .reset = dummy_setup,
2566 .start = dummy_start, 2569 .start = dummy_start,
2567 .stop = dummy_stop, 2570 .stop = dummy_stop,
@@ -2590,8 +2593,12 @@ static int dummy_hcd_probe(struct platform_device *pdev)
2590 dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); 2593 dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
2591 dum = *((void **)dev_get_platdata(&pdev->dev)); 2594 dum = *((void **)dev_get_platdata(&pdev->dev));
2592 2595
2593 if (!mod_data.is_super_speed) 2596 if (mod_data.is_super_speed)
2597 dummy_hcd.flags = HCD_USB3 | HCD_SHARED;
2598 else if (mod_data.is_high_speed)
2594 dummy_hcd.flags = HCD_USB2; 2599 dummy_hcd.flags = HCD_USB2;
2600 else
2601 dummy_hcd.flags = HCD_USB11;
2595 hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); 2602 hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev));
2596 if (!hs_hcd) 2603 if (!hs_hcd)
2597 return -ENOMEM; 2604 return -ENOMEM;