Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b00c55ec authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa
Browse files

USB: dwc3: gadget: Queue data for 16 micro frames ahead in future



While starting transfer for isochrnous endpoints, make sure first
request is queued for 16 microframes ahead in future. Also set
PENDING_REQUEST flag before giving back usb request if started_list
is empty to avoid queuing in same context. Else it leads to request
getting queued for micro frame interval which might have expired and
resulting USB HW retiring TRB without sending data to host.

Change-Id: Ia5e4512fa2a3ae6637f2be7ef2f102c26d56213c
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
parent 42a7d6b2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -722,6 +722,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
@@ -752,6 +753,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)
+3 −2
Original line number Diff line number Diff line
@@ -149,10 +149,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);
	}
}

+19 −4
Original line number Diff line number Diff line
@@ -319,6 +319,12 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,

	dwc3_gadget_del_and_unmap_request(dep, req, status);

	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);
@@ -1054,6 +1060,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);
	pm_runtime_mark_last_busy(dwc->sysdev);
	pm_runtime_put_sync_autosuspend(dwc->sysdev);
@@ -1628,7 +1636,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
		wraparound_bits += BIT(14);

	dep->frame_number = __dwc3_gadget_get_frame(dep->dwc) +
				2 * dep->interval;
				max_t(u32, 16, 2 * dep->interval);

	/* align uf to ep interval */
	dep->frame_number = (wraparound_bits | dep->frame_number) &
@@ -1687,8 +1695,9 @@ 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)) {
				__dwc3_gadget_start_isoc(dep);
				return 0;
				dep->flags &= ~DWC3_EP_PENDING_REQUEST;
			}
			return 0;
		}
	}

@@ -3181,12 +3190,18 @@ static void dwc3_gadget_endpoint_transfer_in_progress(struct dwc3_ep *dep,
	if (event->status & DEPEVT_STATUS_MISSED_ISOC) {
		status = -EXDEV;

		if (list_empty(&dep->started_list))
			stop = true;
		dep->missed_isoc_packets++;
		dbg_event(dep->number, "MISSEDISOC", 0);
	}

	dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);

	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
					(list_empty(&dep->started_list))) {
		stop = true;
		dbg_event(dep->number, "STOPXFER", dep->frame_number);
	}

	if (stop)
		dwc3_stop_active_transfer(dwc, dep->number, true);
	/*