It might happen that dwc3_remove_requests is called when req_queued list is not empty but end transfer command was issued. It will occur if dwc3_remove_requests is called again before interrupt for end transfer command is received. This situation can be reproduced when cable is physically disconnected after some isoc in transfer (testusb case 16). Signed-off-by: Pratyush Anand <pratyush.anand@xxxxxx> --- drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/gadget.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 1210dae..5c6cd18 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -357,6 +357,7 @@ struct dwc3_event_buffer { * @name: a human readable name e.g. ep1out-bulk * @direction: true for TX, false for RX * @stream_capable: true when streams are enabled + * @end_xfer_issued: true when EndTransfer command has been issued */ struct dwc3_ep { struct usb_ep endpoint; @@ -394,6 +395,7 @@ struct dwc3_ep { unsigned direction:1; unsigned stream_capable:1; + unsigned end_xfer_issued:1; }; enum dwc3_phy { diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 322b62e..fe2f4f9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -530,7 +530,7 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) { struct dwc3_request *req; - if (!list_empty(&dep->req_queued)) + if (!list_empty(&dep->req_queued) && !dep->end_xfer_issued) dwc3_stop_active_transfer(dwc, dep->number); while (!list_empty(&dep->request_list)) { @@ -1762,6 +1762,7 @@ static void dwc3_ep_cmd_compl(struct dwc3_ep *dep, switch (cmd_type) { case DWC3_DEPCMD_ENDTRANSFER: + dep->end_xfer_issued = false; dwc3_process_ep_cmd_complete(dep, event); break; case DWC3_DEPCMD_STARTTRANSFER: @@ -1885,6 +1886,8 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); memset(¶ms, 0, sizeof(params)); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); + if (!ret) + dep->end_xfer_issued = true; WARN_ON_ONCE(ret); dep->res_trans_idx = 0; } -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html