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

Commit 13630b1f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: dwc3: gadget: properly increment dequeue pointer on ep_dequeue"

parents 29544fd9 d1c93aa1
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -1436,6 +1436,48 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
		if (r == req) {
			/* wait until it is processed */
			dwc3_stop_active_transfer(dwc, dep->number, true);

			/*
			 * If request was already started, this means we had to
			 * stop the transfer. With that we also need to ignore
			 * all TRBs used by the request, however TRBs can only
			 * be modified after completion of END_TRANSFER
			 * command. So what we do here is that we wait for
			 * END_TRANSFER completion and only after that, we jump
			 * over TRBs by clearing HWO and incrementing dequeue
			 * pointer.
			 *
			 * Note that we have 2 possible types of transfers here:
			 *
			 * i) Linear buffer request
			 * ii) SG-list based request
			 *
			 * SG-list based requests will have r->num_pending_sgs
			 * set to a valid number (> 0). Linear requests,
			 * normally use a single TRB.
			 *
			 * All of these cases need to be taken into
			 * consideration so we don't mess up our TRB ring
			 * pointers.
			 */
			if (!r->trb)
				goto out1;

			if (r->num_pending_sgs) {
				struct dwc3_trb *trb;
				int i = 0;

				for (i = 0; i < r->num_pending_sgs; i++) {
					trb = r->trb + i;
					trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
					dwc3_ep_inc_deq(dep);
				}
			} else {
				struct dwc3_trb *trb = r->trb;

				trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
				dwc3_ep_inc_deq(dep);
			}
			goto out1;
		}
		dev_err(dwc->dev, "request %pK was not queued to %s\n",
@@ -1447,6 +1489,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
out1:
	dbg_event(dep->number, "DEQUEUE", 0);
	/* giveback the request */
	dep->queued_requests--;
	dwc3_gadget_giveback(dep, req, -ECONNRESET);

out0: