usb:langwell_ude: Check ep desc to guarantee it is not disabled
authorfeng wang <feng.a.wang@intel.com>
Fri, 3 Feb 2012 06:07:57 +0000 (14:07 +0800)
committerbuildbot <buildbot@intel.com>
Fri, 10 Feb 2012 04:41:48 +0000 (20:41 -0800)
BZ: 20895

A panic is raised in langwell_irq as ep->desc is set to NULL.
In langwell_ep_disable, ep is disabled and spin_lock get unlocked
in langwell_irq to handle the trans complete. In function done,
ep->desc is accessed and we meet NULL pointer. Function done will
be skipped as it is called in nuke to release resources. So no leakage.

Change-Id: I0c72ad83e12b6e61e04128dbafb492417eb1de01
Signed-off-by: feng wang <feng.a.wang@intel.com>
Reviewed-on: http://android.intel.com:8080/33821
Reviewed-by: Zhuang, Jin Can <jin.can.zhuang@intel.com>
Reviewed-by: Tang, Richard <richard.tang@intel.com>
Reviewed-by: Meng, Zhe <zhe.meng@intel.com>
Tested-by: Meng, Zhe <zhe.meng@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/usb/gadget/langwell_udc.c

index 972fdb4..d56dfcb 100644 (file)
@@ -529,6 +529,13 @@ static int langwell_ep_disable(struct usb_ep *_ep)
 
        spin_lock_irqsave(&dev->lock, flags);
 
+       if (!ep->desc) {
+               spin_unlock_irqrestore(&dev->lock, flags);
+               pm_runtime_put(&dev->pdev->dev);
+               dev_err(&dev->pdev->dev, "ep has already disabled\n");
+               return -EINVAL;
+       }
+
        /* disable endpoint control register */
        ep_num = ep->ep_num;
        endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
@@ -2866,6 +2873,12 @@ static void handle_trans_complete(struct langwell_udc *dev)
                                ep0_req_complete(dev, epn, curr_req);
                                break;
                        } else {
+                               /* Check to guarantee ep is enabled */
+                               if (!epn->desc) {
+                                       dev_err(&dev->pdev->dev,
+                                       "epn is disabled, break in handle trans complete\n");
+                                       break;
+                               }
                                done(epn, curr_req, status);
                        }
                }