usb: gadget: fsl_udc: Fix dTDs allocation gfp flags
authorBenoit Goby <benoit@android.com>
Tue, 21 Sep 2010 04:19:37 +0000 (21:19 -0700)
committerBenoit Goby <benoit@android.com>
Wed, 13 Oct 2010 23:37:08 +0000 (16:37 -0700)
fsl_build_dtd may be called from atomic context. Don't hardcode the gfp
flag to GFP_KERNEL. Pass down to dma_pool_alloc the flag used by the
function driver to enqueue the request.

Change-Id: Iba1ccf73bbcd648b8c13228157431d2ce52979ef
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/usb/gadget/fsl_udc_core.c

index fe66989232b9ffa18424004ef997227de62ba3ef..0619c4f7be24183da91ebbfec543fccfd1018241 100644 (file)
@@ -730,7 +730,7 @@ out:
  * @is_last: return flag if it is the last dTD of the request
  * return: pointer to the built dTD */
 static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
-               dma_addr_t *dma, int *is_last)
+               dma_addr_t *dma, int *is_last, gfp_t gfp_flags)
 {
        u32 swap_temp;
        struct ep_td_struct *dtd;
@@ -739,7 +739,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
        *length = min(req->req.length - req->req.actual,
                        (unsigned)EP_MAX_LENGTH_TRANSFER);
 
-       dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma);
+       dtd = dma_pool_alloc(udc_controller->td_pool, gfp_flags, dma);
        if (dtd == NULL)
                return dtd;
 
@@ -789,7 +789,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
 }
 
 /* Generate dtd chain for a request */
-static int fsl_req_to_dtd(struct fsl_req *req)
+static int fsl_req_to_dtd(struct fsl_req *req, gfp_t gfp_flags)
 {
        unsigned        count;
        int             is_last;
@@ -798,7 +798,7 @@ static int fsl_req_to_dtd(struct fsl_req *req)
        dma_addr_t dma;
 
        do {
-               dtd = fsl_build_dtd(req, &count, &dma, &is_last);
+               dtd = fsl_build_dtd(req, &count, &dma, &is_last, gfp_flags);
                if (dtd == NULL)
                        return -ENOMEM;
 
@@ -874,15 +874,13 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
        req->req.actual = 0;
        req->dtd_count = 0;
 
-       spin_lock_irqsave(&udc->lock, flags);
 
        /* build dtds and push them to device queue */
-       if (!fsl_req_to_dtd(req)) {
-               fsl_queue_td(ep, req);
-       } else {
-               spin_unlock_irqrestore(&udc->lock, flags);
+       if (fsl_req_to_dtd(req, gfp_flags))
                return -ENOMEM;
-       }
+
+       spin_lock_irqsave(&udc->lock, flags);
+       fsl_queue_td(ep, req);
 
        /* Update ep0 state */
        if ((ep_index(ep) == 0))
@@ -1254,7 +1252,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
        req->req.complete = NULL;
        req->dtd_count = 0;
 
-       if (fsl_req_to_dtd(req) == 0)
+       if (fsl_req_to_dtd(req, GFP_ATOMIC) == 0)
                fsl_queue_td(ep, req);
        else
                return -ENOMEM;
@@ -1332,7 +1330,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
        req->dtd_count = 0;
 
        /* prime the data phase */
-       if ((fsl_req_to_dtd(req) == 0))
+       if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
                fsl_queue_td(ep, req);
        else                    /* no mem */
                goto stall;