usb:langwell_udc: fix NULL pointer in langwell_ep_dequeue
authorjzhuan5 <jin.can.zhuang@intel.com>
Mon, 9 Jan 2012 17:17:00 +0000 (12:17 -0500)
committerbuildbot <buildbot@intel.com>
Thu, 12 Jan 2012 13:59:39 +0000 (05:59 -0800)
BZ: 19244

langwell_ep_dequeue calls is_in(ep) which dereferences ep->desc. But ep->desc may be set to NULL due to race condition.
Therefore, need to check ep->desc after seizing the lock again.

Change-Id: I0472fea0de1261c94877d7158ee876760c2686ce
Signed-off-by: jzhuan5 <jin.can.zhuang@intel.com>
Reviewed-on: http://android.intel.com:8080/31511
Reviewed-by: Tang, Richard <richard.tang@intel.com>
Reviewed-by: Kuppuswamy, Sathyanarayanan <sathyanarayanan.kuppuswamy@intel.com>
Tested-by: Sun, Jianhua <jianhua.sun@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/usb/gadget/langwell_udc.c

index c2e5c29..8a1cb97 100644 (file)
@@ -956,12 +956,14 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
        ep_num = ep->ep_num;
 
        /* disable endpoint control register */
-       endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-       if (is_in(ep))
-               endptctrl &= ~EPCTRL_TXE;
-       else
-               endptctrl &= ~EPCTRL_RXE;
-       writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
+       if (ep->desc) {
+               endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
+               if (is_in(ep))
+                       endptctrl &= ~EPCTRL_TXE;
+               else
+                       endptctrl &= ~EPCTRL_RXE;
+               writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
+       }
 
        /* make sure it's still queued on this endpoint */
        list_for_each_entry(req, &ep->queue, queue) {
@@ -1005,12 +1007,14 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 
 done:
        /* enable endpoint again */
-       endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-       if (is_in(ep))
-               endptctrl |= EPCTRL_TXE;
-       else
-               endptctrl |= EPCTRL_RXE;
-       writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
+       if (ep->desc) {
+               endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
+               if (is_in(ep))
+                       endptctrl |= EPCTRL_TXE;
+               else
+                       endptctrl |= EPCTRL_RXE;
+               writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
+       }
 
        ep->stopped = stopped;
        spin_unlock_irqrestore(&dev->lock, flags);