aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 9ac4835d7b6b..1c98aee051a5 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1075,17 +1075,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
1075 1075
1076 list_add_tail(&req->list, &dep->request_list); 1076 list_add_tail(&req->list, &dep->request_list);
1077 1077
1078 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
1079 if (dep->flags & DWC3_EP_BUSY) {
1080 dep->flags |= DWC3_EP_PENDING_REQUEST;
1081 } else if (dep->flags & DWC3_EP_MISSED_ISOC) {
1082 __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf);
1083 dep->flags &= ~DWC3_EP_MISSED_ISOC;
1084 }
1085 }
1086
1087 /* 1078 /*
1088 * There are two special cases: 1079 * There are a few special cases:
1089 * 1080 *
1090 * 1. XferNotReady with empty list of requests. We need to kick the 1081 * 1. XferNotReady with empty list of requests. We need to kick the
1091 * transfer here in that situation, otherwise we will be NAKing 1082 * transfer here in that situation, otherwise we will be NAKing
@@ -1094,24 +1085,29 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
1094 * able to receive the data until the next request is queued. 1085 * able to receive the data until the next request is queued.
1095 * The following code is handling exactly that. 1086 * The following code is handling exactly that.
1096 * 1087 *
1097 * 2. XferInProgress on Isoc EP with an active transfer. We need to
1098 * kick the transfer here after queuing a request, otherwise the
1099 * core may not see the modified TRB(s).
1100 */ 1088 */
1101 if (dep->flags & DWC3_EP_PENDING_REQUEST) { 1089 if (dep->flags & DWC3_EP_PENDING_REQUEST) {
1102 int ret; 1090 int ret;
1103 int start_trans = 1;
1104 u8 trans_idx = dep->res_trans_idx;
1105 1091
1106 if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && 1092 ret = __dwc3_gadget_kick_transfer(dep, 0, true);
1107 (dep->flags & DWC3_EP_BUSY)) { 1093 if (ret && ret != -EBUSY) {
1108 start_trans = 0; 1094 struct dwc3 *dwc = dep->dwc;
1109 WARN_ON_ONCE(!trans_idx); 1095
1110 } else { 1096 dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
1111 trans_idx = 0; 1097 dep->name);
1112 } 1098 }
1099 }
1113 1100
1114 ret = __dwc3_gadget_kick_transfer(dep, trans_idx, start_trans); 1101 /*
1102 * 2. XferInProgress on Isoc EP with an active transfer. We need to
1103 * kick the transfer here after queuing a request, otherwise the
1104 * core may not see the modified TRB(s).
1105 */
1106 if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
1107 (dep->flags & DWC3_EP_BUSY)) {
1108 WARN_ON_ONCE(!dep->res_trans_idx);
1109 ret = __dwc3_gadget_kick_transfer(dep, dep->res_trans_idx,
1110 false);
1115 if (ret && ret != -EBUSY) { 1111 if (ret && ret != -EBUSY) {
1116 struct dwc3 *dwc = dep->dwc; 1112 struct dwc3 *dwc = dep->dwc;
1117 1113
@@ -1120,6 +1116,16 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
1120 } 1116 }
1121 } 1117 }
1122 1118
1119 /*
1120 * 3. Missed ISOC Handling. We need to start isoc transfer on the saved
1121 * uframe number.
1122 */
1123 if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
1124 (dep->flags & DWC3_EP_MISSED_ISOC)) {
1125 __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf);
1126 dep->flags &= ~DWC3_EP_MISSED_ISOC;
1127 }
1128
1123 return 0; 1129 return 0;
1124} 1130}
1125 1131