Commit 0a91efa2 authored by Pavankumar Kondeti's avatar Pavankumar Kondeti Committed by Greg Kroah-Hartman

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: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 409a15da
...@@ -1626,7 +1626,7 @@ __acquires(udc->lock) ...@@ -1626,7 +1626,7 @@ __acquires(udc->lock)
spin_unlock(udc->lock); spin_unlock(udc->lock);
retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc);
if (!retval) { 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) { if (mEp->status == NULL) {
usb_ep_disable(&mEp->ep); usb_ep_disable(&mEp->ep);
retval = -ENOMEM; retval = -ENOMEM;
...@@ -2055,7 +2055,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) ...@@ -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_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
struct ci13xxx_req *mReq = NULL; struct ci13xxx_req *mReq = NULL;
unsigned long flags;
trace("%p, %i", ep, gfp_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) ...@@ -2064,8 +2063,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
return NULL; return NULL;
} }
spin_lock_irqsave(mEp->lock, flags);
mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
if (mReq != NULL) { if (mReq != NULL) {
INIT_LIST_HEAD(&mReq->queue); 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,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); dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
spin_unlock_irqrestore(mEp->lock, flags);
return (mReq == NULL) ? NULL : &mReq->req; return (mReq == NULL) ? NULL : &mReq->req;
} }
...@@ -2404,9 +2399,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, ...@@ -2404,9 +2399,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
/* this allocation cannot be random */ /* this allocation cannot be random */
for (k = RX; k <= TX; k++) { for (k = RX; k <= TX; k++) {
INIT_LIST_HEAD(&mEp->qh[k].queue); INIT_LIST_HEAD(&mEp->qh[k].queue);
spin_unlock_irqrestore(udc->lock, flags);
mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool,
GFP_KERNEL, GFP_KERNEL,
&mEp->qh[k].dma); &mEp->qh[k].dma);
spin_lock_irqsave(udc->lock, flags);
if (mEp->qh[k].ptr == NULL) if (mEp->qh[k].ptr == NULL)
retval = -ENOMEM; retval = -ENOMEM;
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment