usb: dwc3: gadget: re-factor dwc3_prepare_trbs()
authorFelipe Balbi <balbi@ti.com>
Tue, 22 Nov 2011 09:37:34 +0000 (11:37 +0200)
committerFelipe Balbi <balbi@ti.com>
Wed, 21 Dec 2011 11:24:45 +0000 (13:24 +0200)
In order to make it easier to add SG support,
let's split the big loop out to its own function.

Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc3/gadget.c

index 5802720..317fc7d 100644 (file)
@@ -539,6 +539,78 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
        kfree(req);
 }
 
+/**
+ * dwc3_prepare_one_trb - setup one TRB from one request
+ * @dep: endpoint for which this request is prepared
+ * @req: dwc3_request pointer
+ */
+static int dwc3_prepare_one_trb(struct dwc3_ep *dep,
+               struct dwc3_request *req, unsigned last)
+{
+       struct dwc3_trb_hw      *trb_hw;
+       struct dwc3_trb         trb;
+
+       unsigned int            cur_slot;
+
+       trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+       cur_slot = dep->free_slot;
+       dep->free_slot++;
+
+       /* Skip the LINK-TRB on ISOC */
+       if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
+                       usb_endpoint_xfer_isoc(dep->desc))
+               return 0;
+
+       dwc3_gadget_move_request_queued(req);
+       memset(&trb, 0, sizeof(trb));
+
+       req->trb = trb_hw;
+
+       if (usb_endpoint_xfer_isoc(dep->desc)) {
+               trb.isp_imi = true;
+               trb.csp = true;
+       } else {
+               trb.lst = last;
+       }
+
+       if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
+               trb.sid_sofn = req->request.stream_id;
+
+       switch (usb_endpoint_type(dep->desc)) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
+               break;
+
+       case USB_ENDPOINT_XFER_ISOC:
+               trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+
+               /* IOC every DWC3_TRB_NUM / 4 so we can refill */
+               if (!(cur_slot % (DWC3_TRB_NUM / 4)))
+                       trb.ioc = last;
+               break;
+
+       case USB_ENDPOINT_XFER_BULK:
+       case USB_ENDPOINT_XFER_INT:
+               trb.trbctl = DWC3_TRBCTL_NORMAL;
+               break;
+       default:
+               /*
+                * This is only possible with faulty memory because we
+                * checked it already :)
+                */
+               BUG();
+       }
+
+       trb.length      = req->request.length;
+       trb.bplh        = req->request.dma;
+       trb.hwo         = true;
+
+       dwc3_trb_to_hw(&trb, trb_hw);
+       req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);
+
+       return 0;
+}
+
 /*
  * dwc3_prepare_trbs - setup TRBs from requests
  * @dep: endpoint for which requests are being prepared
@@ -552,14 +624,14 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
                bool starting)
 {
        struct dwc3_request     *req, *n, *ret = NULL;
-       struct dwc3_trb_hw      *trb_hw;
-       struct dwc3_trb         trb;
        u32                     trbs_left;
+       unsigned int            last_one = 0;
 
        BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
 
        /* the first request must not be queued */
        trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
+
        /*
         * if busy & slot are equal than it is either full or empty. If we are
         * starting to proceed requests then we are empty. Otherwise we ar
@@ -594,25 +666,11 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
                return NULL;
 
        list_for_each_entry_safe(req, n, &dep->request_list, list) {
-               unsigned int last_one = 0;
-               unsigned int cur_slot;
-
-               trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
-               cur_slot = dep->free_slot;
-               dep->free_slot++;
-
-               /* Skip the LINK-TRB on ISOC */
-               if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
-                               usb_endpoint_xfer_isoc(dep->desc))
-                       continue;
-
-               dwc3_gadget_move_request_queued(req);
-               memset(&trb, 0, sizeof(trb));
                trbs_left--;
 
-               /* Is our TRB pool empty? */
                if (!trbs_left)
                        last_one = 1;
+
                /* Is this the last request? */
                if (list_empty(&dep->request_list))
                        last_one = 1;
@@ -625,57 +683,9 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
                 * While we're debugging the problem, as a workaround to
                 * multiple TRBs handling, use only one TRB at a time.
                 */
-               last_one = 1;
-
-               req->trb = trb_hw;
-               if (!ret)
-                       ret = req;
-
-               trb.bplh = req->request.dma;
-
-               if (usb_endpoint_xfer_isoc(dep->desc)) {
-                       trb.isp_imi = true;
-                       trb.csp = true;
-               } else {
-                       trb.lst = last_one;
-               }
-
-               if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
-                       trb.sid_sofn = req->request.stream_id;
-
-               switch (usb_endpoint_type(dep->desc)) {
-               case USB_ENDPOINT_XFER_CONTROL:
-                       trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
-                       break;
-
-               case USB_ENDPOINT_XFER_ISOC:
-                       trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
-
-                       /* IOC every DWC3_TRB_NUM / 4 so we can refill */
-                       if (!(cur_slot % (DWC3_TRB_NUM / 4)))
-                               trb.ioc = last_one;
-                       break;
-
-               case USB_ENDPOINT_XFER_BULK:
-               case USB_ENDPOINT_XFER_INT:
-                       trb.trbctl = DWC3_TRBCTL_NORMAL;
-                       break;
-               default:
-                       /*
-                        * This is only possible with faulty memory because we
-                        * checked it already :)
-                        */
-                       BUG();
-               }
-
-               trb.length      = req->request.length;
-               trb.hwo = true;
-
-               dwc3_trb_to_hw(&trb, trb_hw);
-               req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);
-
-               if (last_one)
-                       break;
+               dwc3_prepare_one_trb(dep, req, true);
+               ret = req;
+               break;
        }
 
        return ret;