aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorPavankumar Kondeti <pkondeti@codeaurora.org>2010-12-07 07:24:00 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-12-10 17:23:33 -0500
commit0a91efa2f951d790969dec96fb675ca7869eca83 (patch)
treead63994806977fbe7b2b64ba7711d5a098ab6237 /drivers/usb
parent409a15da9851b6e6a5e1c5787be31a987184b7cf (diff)
USB: gadget: Fix "scheduling while atomic" bugs in ci13xxx_udc
dma_pool_alloc() require sleeping context when called with GFP_KERNEL argument. Hence release the spin lock before calling dma_pool_alloc(). usb_ep_alloc_request can also be called with non-atomic GFP flags. Hence get rid off spin lock while allocation request memory. Use GFP_ATOMIC flag for allocating request for ep0 in interrupt handler. Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 4e9ec7d256fd..d19537a0613d 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1626,7 +1626,7 @@ __acquires(udc->lock)
1626 spin_unlock(udc->lock); 1626 spin_unlock(udc->lock);
1627 retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); 1627 retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc);
1628 if (!retval) { 1628 if (!retval) {
1629 mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_KERNEL); 1629 mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC);
1630 if (mEp->status == NULL) { 1630 if (mEp->status == NULL) {
1631 usb_ep_disable(&mEp->ep); 1631 usb_ep_disable(&mEp->ep);
1632 retval = -ENOMEM; 1632 retval = -ENOMEM;
@@ -2055,7 +2055,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2055{ 2055{
2056 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); 2056 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2057 struct ci13xxx_req *mReq = NULL; 2057 struct ci13xxx_req *mReq = NULL;
2058 unsigned long flags;
2059 2058
2060 trace("%p, %i", ep, gfp_flags); 2059 trace("%p, %i", ep, gfp_flags);
2061 2060
@@ -2064,8 +2063,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2064 return NULL; 2063 return NULL;
2065 } 2064 }
2066 2065
2067 spin_lock_irqsave(mEp->lock, flags);
2068
2069 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); 2066 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2070 if (mReq != NULL) { 2067 if (mReq != NULL) {
2071 INIT_LIST_HEAD(&mReq->queue); 2068 INIT_LIST_HEAD(&mReq->queue);
@@ -2080,8 +2077,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2080 2077
2081 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); 2078 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2082 2079
2083 spin_unlock_irqrestore(mEp->lock, flags);
2084
2085 return (mReq == NULL) ? NULL : &mReq->req; 2080 return (mReq == NULL) ? NULL : &mReq->req;
2086} 2081}
2087 2082
@@ -2404,9 +2399,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
2404 /* this allocation cannot be random */ 2399 /* this allocation cannot be random */
2405 for (k = RX; k <= TX; k++) { 2400 for (k = RX; k <= TX; k++) {
2406 INIT_LIST_HEAD(&mEp->qh[k].queue); 2401 INIT_LIST_HEAD(&mEp->qh[k].queue);
2402 spin_unlock_irqrestore(udc->lock, flags);
2407 mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, 2403 mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool,
2408 GFP_KERNEL, 2404 GFP_KERNEL,
2409 &mEp->qh[k].dma); 2405 &mEp->qh[k].dma);
2406 spin_lock_irqsave(udc->lock, flags);
2410 if (mEp->qh[k].ptr == NULL) 2407 if (mEp->qh[k].ptr == NULL)
2411 retval = -ENOMEM; 2408 retval = -ENOMEM;
2412 else 2409 else