]> git.karo-electronics.de Git - linux-beck.git/commitdiff
staging: dwc2: don't issue traffic to LS devices in FS mode
authorNick Hudson <skrll@netbsd.org>
Fri, 6 Dec 2013 22:01:44 +0000 (14:01 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Dec 2013 01:25:14 +0000 (17:25 -0800)
I fell over the problem reported in
https://github.com/raspberrypi/linux/pull/390:

"Issuing low-speed packets when the root port is in full-speed mode
 causes the root port to stop responding. Explicitly fail when
 enqueuing URBs to a LS endpoint on a FS bus."

with my dwc2 testing in NetBSD, so I adapted the change to dwc2.

Signed-off-by: Nick Hudson <skrll@netbsd.org>
[paulz: fixed up the patch to compile under Linux, and tested it]
Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Tested-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/dwc2/hcd.c

index 24b57d7952c514b21dd7efdf3b1cb304b26fc626..07dfe855dc203d8c69eed6533847807f192e52d7 100644 (file)
@@ -355,6 +355,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
        unsigned long flags;
        u32 intr_mask;
        int retval;
+       int dev_speed;
 
        if (!hsotg->flags.b.port_connect_status) {
                /* No longer connected */
@@ -362,6 +363,19 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
                return -ENODEV;
        }
 
+       dev_speed = dwc2_host_get_speed(hsotg, urb->priv);
+
+       /* Some configurations cannot support LS traffic on a FS root port */
+       if ((dev_speed == USB_SPEED_LOW) &&
+           (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) &&
+           (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) {
+               u32 hprt0 = readl(hsotg->regs + HPRT0);
+               u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
+
+               if (prtspd == HPRT0_SPD_FULL_SPEED)
+                       return -ENODEV;
+       }
+
        qtd = kzalloc(sizeof(*qtd), mem_flags);
        if (!qtd)
                return -ENOMEM;