Skip to content

Commit

Permalink
usb: dwc3: gadget: simplify __dwc3_gadget_ep_queue()
Browse files Browse the repository at this point in the history
Many of the comments in that function are really
outdated and don't match what the driver is
doing. Moreover, recent patches combined programming
model for all non-control endpoints, this gives us
an opportunity to get rid of our special cases in
__dwc3_gadget_ep_queue().

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
  • Loading branch information
Felipe Balbi committed Aug 22, 2016
1 parent 45438a0 commit 08a36b5
Showing 1 changed file with 7 additions and 76 deletions.
83 changes: 7 additions & 76 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1063,92 +1063,23 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)

trace_dwc3_ep_queue(req);

/*
* We only add to our list of requests now and
* start consuming the list once we get XferNotReady
* IRQ.
*
* That way, we avoid doing anything that we don't need
* to do now and defer it until the point we receive a
* particular token from the Host side.
*
* This will also avoid Host cancelling URBs due to too
* many NAKs.
*/
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
dep->direction);
if (ret)
return ret;

list_add_tail(&req->list, &dep->pending_list);

/*
* If there are no pending requests and the endpoint isn't already
* busy, we will just start the request straight away.
*
* This will save one IRQ (XFER_NOT_READY) and possibly make it a
* little bit faster.
*/
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
ret = __dwc3_gadget_kick_transfer(dep, 0);
goto out;
}

/*
* There are a few special cases:
*
* 1. XferNotReady with empty list of requests. We need to kick the
* transfer here in that situation, otherwise we will be NAKing
* forever. If we get XferNotReady before gadget driver has a
* chance to queue a request, we will ACK the IRQ but won't be
* able to receive the data until the next request is queued.
* The following code is handling exactly that.
*
*/
if (dep->flags & DWC3_EP_PENDING_REQUEST) {
/*
* If xfernotready is already elapsed and it is a case
* of isoc transfer, then issue END TRANSFER, so that
* you can receive xfernotready again and can have
* notion of current microframe.
*/
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
if (list_empty(&dep->started_list)) {
dwc3_stop_active_transfer(dwc, dep->number, true);
dep->flags = DWC3_EP_ENABLED;
}
return 0;
}

ret = __dwc3_gadget_kick_transfer(dep, 0);
if (!ret)
dep->flags &= ~DWC3_EP_PENDING_REQUEST;

goto out;
}

/*
* 2. XferInProgress on Isoc EP with an active transfer. We need to
* kick the transfer here after queuing a request, otherwise the
* core may not see the modified TRB(s).
*/
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
(dep->flags & DWC3_EP_BUSY) &&
!(dep->flags & DWC3_EP_MISSED_ISOC)) {
WARN_ON_ONCE(!dep->resource_index);
ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index);
goto out;
dep->flags & DWC3_EP_PENDING_REQUEST) {
if (list_empty(&dep->started_list)) {
dwc3_stop_active_transfer(dwc, dep->number, true);
dep->flags = DWC3_EP_ENABLED;
}
return 0;
}

/*
* 4. Stream Capable Bulk Endpoints. We need to start the transfer
* right away, otherwise host will not know we have streams to be
* handled.
*/
if (dep->stream_capable)
ret = __dwc3_gadget_kick_transfer(dep, 0);

out:
ret = __dwc3_gadget_kick_transfer(dep, 0);
if (ret && ret != -EBUSY)
dwc3_trace(trace_dwc3_gadget,
"%s: failed to kick transfers",
Expand Down

0 comments on commit 08a36b5

Please sign in to comment.