diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 941a5e0b198f..498da2a0b620 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -735,6 +735,7 @@ struct dwc3_ep_events { * @desc: usb_endpoint_descriptor pointer * @dwc: pointer to DWC controller * @saved_state: ep state saved during hibernation + * @missed_isoc_packets: counter for missed packets sent * @flags: endpoint flags (wedged, stalled, ...) * @number: endpoint number (1 - 15) * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK @@ -768,6 +769,7 @@ struct dwc3_ep { struct dwc3 *dwc; u32 saved_state; + u32 missed_isoc_packets; unsigned flags; #define DWC3_EP_ENABLED BIT(0) #define DWC3_EP_STALL BIT(1) diff --git a/drivers/usb/dwc3/debug_ipc.c b/drivers/usb/dwc3/debug_ipc.c index 4126936aed87..f475b0622edb 100644 --- a/drivers/usb/dwc3/debug_ipc.c +++ b/drivers/usb/dwc3/debug_ipc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. */ #include "debug.h" @@ -150,10 +151,11 @@ void dwc3_dbg_dma_unmap(struct dwc3 *dwc, u8 ep_num, struct dwc3_request *req) req->trb->ctrl & DWC3_TRB_CTRL_HWO); } else { ipc_log_string(dwc->dwc_dma_ipc_log_ctxt, - "%02X-%-3.3s %-25.25s 0x%pK 0x%lx %u 0x%lx %d", + "%02X-%-3.3s %-25.25s 0x%pK 0x%lx %u 0x%lx %d %u", ep_num >> 1, ep_num & 1 ? "IN":"OUT", "UNMAP", &req->request, req->request.dma, req->request.length, - req->trb_dma, req->trb->ctrl & DWC3_TRB_CTRL_HWO); + req->trb_dma, req->trb->ctrl & DWC3_TRB_CTRL_HWO, + req->request.actual); } } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index b405b97f13d1..b4bb218c8b75 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -309,6 +309,12 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, dwc3_gadget_del_and_unmap_request(dep, req, status); req->status = DWC3_REQUEST_STATUS_COMPLETED; + if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && + (list_empty(&dep->started_list))) { + dep->flags |= DWC3_EP_PENDING_REQUEST; + dbg_event(dep->number, "STARTEDLISTEMPTY", 0); + } + spin_unlock(&dwc->lock); usb_gadget_giveback_request(&dep->endpoint, &req->request); spin_lock(&dwc->lock); @@ -984,6 +990,8 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep) spin_lock_irqsave(&dwc->lock, flags); ret = __dwc3_gadget_ep_disable(dep); dbg_event(dep->number, "DISABLE", ret); + dbg_event(dep->number, "MISSEDISOCPKTS", dep->missed_isoc_packets); + dep->missed_isoc_packets = 0; spin_unlock_irqrestore(&dwc->lock, flags); return ret; @@ -1662,6 +1670,7 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) } for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) { + dep->frame_number = __dwc3_gadget_get_frame(dep->dwc) + 16; dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1); ret = __dwc3_gadget_kick_transfer(dep); @@ -1728,8 +1737,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) if ((dep->flags & DWC3_EP_PENDING_REQUEST)) { if (!(dep->flags & DWC3_EP_TRANSFER_STARTED)) { + dep->flags &= ~DWC3_EP_PENDING_REQUEST; return __dwc3_gadget_start_isoc(dep); } + return 0; } } @@ -3399,15 +3410,18 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep, if (event->status & DEPEVT_STATUS_BUSERR) status = -ECONNRESET; + dwc3_gadget_ep_cleanup_completed_requests(dep, event, status); + if (event->status & DEPEVT_STATUS_MISSED_ISOC) { status = -EXDEV; + dep->missed_isoc_packets++; + dbg_event(dep->number, "MISSEDISOC", 0); + if (list_empty(&dep->started_list)) stop = true; } - dwc3_gadget_ep_cleanup_completed_requests(dep, event, status); - if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) goto out;