Skip to content

Commit

Permalink
usb: dwc3: gadget: extract dwc3_gadget_ep_skip_trbs()
Browse files Browse the repository at this point in the history
Extract the logic for skipping over TRBs to its own function. This
makes the code slightly more readable and makes it easier to move this
call to its final resting place as a following patch.

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
  • Loading branch information
Felipe Balbi committed Nov 26, 2018
1 parent c3acd59 commit 7746a8d
Showing 1 changed file with 24 additions and 37 deletions.
61 changes: 24 additions & 37 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,29 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
return ret;
}

static void dwc3_gadget_ep_skip_trbs(struct dwc3_ep *dep, struct dwc3_request *req)
{
int i;

/*
* If request was already started, this means we had to
* stop the transfer. With that we also need to ignore
* all TRBs used by the request, however TRBs can only
* be modified after completion of END_TRANSFER
* command. So what we do here is that we wait for
* END_TRANSFER completion and only after that, we jump
* over TRBs by clearing HWO and incrementing dequeue
* pointer.
*/
for (i = 0; i < req->num_trbs; i++) {
struct dwc3_trb *trb;

trb = req->trb + i;
trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
dwc3_ep_inc_deq(dep);
}
}

static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
struct usb_request *request)
{
Expand Down Expand Up @@ -1502,52 +1525,16 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
break;
}
if (r == req) {
int i;

/* wait until it is processed */
dwc3_stop_active_transfer(dep, true);

/*
* If request was already started, this means we had to
* stop the transfer. With that we also need to ignore
* all TRBs used by the request, however TRBs can only
* be modified after completion of END_TRANSFER
* command. So what we do here is that we wait for
* END_TRANSFER completion and only after that, we jump
* over TRBs by clearing HWO and incrementing dequeue
* pointer.
*
* Note that we have 2 possible types of transfers here:
*
* i) Linear buffer request
* ii) SG-list based request
*
* SG-list based requests will have r->num_pending_sgs
* set to a valid number (> 0). Linear requests,
* normally use a single TRB.
*
* For each of these two cases, if r->unaligned flag is
* set, one extra TRB has been used to align transfer
* size to wMaxPacketSize.
*
* All of these cases need to be taken into
* consideration so we don't mess up our TRB ring
* pointers.
*/
wait_event_lock_irq(dep->wait_end_transfer,
!(dep->flags & DWC3_EP_END_TRANSFER_PENDING),
dwc->lock);

if (!r->trb)
goto out0;

for (i = 0; i < r->num_trbs; i++) {
struct dwc3_trb *trb;

trb = r->trb + i;
trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
dwc3_ep_inc_deq(dep);
}
dwc3_gadget_ep_skip_trbs(dep, r);
goto out1;
}
dev_err(dwc->dev, "request %pK was not queued to %s\n",
Expand Down

0 comments on commit 7746a8d

Please sign in to comment.