From a46be992e7c96353d73dbc952615f85577edcda6 Mon Sep 17 00:00:00 2001 From: jzhuan5 Date: Mon, 9 Jan 2012 12:17:00 -0500 Subject: [PATCH] usb:langwell_udc: fix NULL pointer in langwell_ep_dequeue 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 Reviewed-on: http://android.intel.com:8080/31511 Reviewed-by: Tang, Richard Reviewed-by: Kuppuswamy, Sathyanarayanan Tested-by: Sun, Jianhua Reviewed-by: buildbot Tested-by: buildbot --- drivers/usb/gadget/langwell_udc.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index c2e5c29..8a1cb97 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c @@ -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); -- 2.7.4