From 0a91efa2f951d790969dec96fb675ca7869eca83 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 7 Dec 2010 17:54:00 +0530 Subject: [PATCH] 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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ci13xxx_udc.c | 9 +++------ 1 file 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) spin_unlock(udc->lock); retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); if (!retval) { - mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_KERNEL); + mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC); if (mEp->status == NULL) { usb_ep_disable(&mEp->ep); retval = -ENOMEM; @@ -2055,7 +2055,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); struct ci13xxx_req *mReq = NULL; - unsigned long flags; trace("%p, %i", ep, gfp_flags); @@ -2064,8 +2063,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) return NULL; } - spin_lock_irqsave(mEp->lock, flags); - mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); if (mReq != NULL) { INIT_LIST_HEAD(&mReq->queue); @@ -2080,8 +2077,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); - spin_unlock_irqrestore(mEp->lock, flags); - return (mReq == NULL) ? NULL : &mReq->req; } @@ -2404,9 +2399,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, /* this allocation cannot be random */ for (k = RX; k <= TX; k++) { INIT_LIST_HEAD(&mEp->qh[k].queue); + spin_unlock_irqrestore(udc->lock, flags); mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL, &mEp->qh[k].dma); + spin_lock_irqsave(udc->lock, flags); if (mEp->qh[k].ptr == NULL) retval = -ENOMEM; else -- 2.39.5