summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorBen McCauley <ben.mccauley@garmin.com>2015-11-16 10:47:24 -0600
committerLuis Henriques <luis.henriques@canonical.com>2015-12-14 10:17:09 +0000
commit16c99134073c09f6bd40dc8452b137b8068889c8 (patch)
tree14630676d76350fed88cd9855fc1b3f98b861023 /drivers/usb/dwc3/gadget.c
parente920ac8f55d520200814f9563b2f980d7ebb9848 (diff)
downloadlinux-stable-16c99134073c09f6bd40dc8452b137b8068889c8.tar.gz
linux-stable-16c99134073c09f6bd40dc8452b137b8068889c8.tar.bz2
linux-stable-16c99134073c09f6bd40dc8452b137b8068889c8.zip
usb: dwc3: gadget: let us set lower max_speed
commit b9e51b2b1fda19143f48d182ed7a2943f21e1ae4 upstream. In some SoCs, dwc3 is implemented as a USB2.0 only core, meaning that it can't ever achieve SuperSpeed. Currect driver always sets gadget.max_speed to USB_SPEED_SUPER unconditionally. This can causes issues to some Host stacks where the host will issue a GetBOS() request and we will reply with a BOS containing Superspeed Capability Descriptor. At least Windows seems to be upset by this fact and prints a warning that we should connect $this device to another port. [ balbi@ti.com : rewrote entire commit, including source code comment to make a lot clearer what the problem is ] Signed-off-by: Ben McCauley <ben.mccauley@garmin.com> Signed-off-by: Felipe Balbi <balbi@ti.com> [ luis: backported to 3.16: - used dev_vdbg() instead of dwc3_trace() ] Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 8946e34cef63..186a79d43250 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2786,12 +2786,33 @@ int dwc3_gadget_init(struct dwc3 *dwc)
}
dwc->gadget.ops = &dwc3_gadget_ops;
- dwc->gadget.max_speed = USB_SPEED_SUPER;
dwc->gadget.speed = USB_SPEED_UNKNOWN;
dwc->gadget.sg_supported = true;
dwc->gadget.name = "dwc3-gadget";
/*
+ * FIXME We might be setting max_speed to <SUPER, however versions
+ * <2.20a of dwc3 have an issue with metastability (documented
+ * elsewhere in this driver) which tells us we can't set max speed to
+ * anything lower than SUPER.
+ *
+ * Because gadget.max_speed is only used by composite.c and function
+ * drivers (i.e. it won't go into dwc3's registers) we are allowing this
+ * to happen so we avoid sending SuperSpeed Capability descriptor
+ * together with our BOS descriptor as that could confuse host into
+ * thinking we can handle super speed.
+ *
+ * Note that, in fact, we won't even support GetBOS requests when speed
+ * is less than super speed because we don't have means, yet, to tell
+ * composite.c that we are USB 2.0 + LPM ECN.
+ */
+ if (dwc->revision < DWC3_REVISION_220A)
+ dev_vdbg(dwc->dev, "Changing max_speed on rev %08x\n",
+ dwc->revision);
+
+ dwc->gadget.max_speed = dwc->maximum_speed;
+
+ /*
* Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
* on ep out.
*/