|
@@ -1063,18 +1063,6 @@ 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)
|
|
@@ -1082,73 +1070,16 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
|
|
|
|
|
|
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",
|