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

Commit f6caffbf 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: Add support for sending zero length packets"

parents 71c6e79e e8244d86
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -648,6 +648,7 @@ struct dwc3_request {

	u8			epnum;
	struct dwc3_trb		*trb;
	struct dwc3_trb		*ztrb;
	dma_addr_t		trb_dma;

	unsigned		direction:1;
+54 −3
Original line number Diff line number Diff line
@@ -294,6 +294,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
				dep->busy_slot++;
		} while(++i < req->request.num_mapped_sgs);
		req->queued = false;

		if (req->request.zero && req->ztrb) {
			dep->busy_slot++;
			req->ztrb = NULL;
			if (((dep->busy_slot & DWC3_TRB_MASK) ==
				DWC3_TRB_NUM - 1) &&
				usb_endpoint_xfer_isoc(dep->endpoint.desc))
				dep->busy_slot++;
		}
	}
	list_del(&req->list);
	req->trb = NULL;
@@ -863,6 +872,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,

	dep->free_slot++;

update_trb:
	trb->size = DWC3_TRB_SIZE_LENGTH(length);
	trb->bpl = lower_32_bits(dma);
	trb->bph = upper_32_bits(dma);
@@ -897,8 +907,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
	if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
		trb->ctrl |= DWC3_TRB_CTRL_CSP;
	} else if (last) {
		trb->ctrl |= DWC3_TRB_CTRL_LST;
	}

	if (chain)
@@ -908,6 +916,25 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
		trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);

	trb->ctrl |= DWC3_TRB_CTRL_HWO;

	if (req->request.zero && length &&
			(length % usb_endpoint_maxp(dep->endpoint.desc) == 0)) {
		/* Skip the LINK-TRB on ISOC */
		if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
			usb_endpoint_xfer_isoc(dep->endpoint.desc))
			dep->free_slot++;

		trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
		dep->free_slot++;

		req->ztrb = trb;
		length = 0;

		goto update_trb;
	}

	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && last)
		trb->ctrl |= DWC3_TRB_CTRL_LST;
}

/*
@@ -1011,12 +1038,25 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
			}
			dbg_queue(dep->number, &req->request, 0);
		} else {
			struct dwc3_request	*req1;
			int maxpkt_size = usb_endpoint_maxp(dep->endpoint.desc);

			dma = req->request.dma;
			length = req->request.length;
			trbs_left--;

			if (!trbs_left)
			if (req->request.zero && length &&
						(length % maxpkt_size == 0))
				trbs_left--;

			if (!trbs_left) {
				last_one = 1;
			} else if (dep->direction && (trbs_left <= 1)) {
				req1 = next_request(&req->list);
				if (req1->request.zero && req1->request.length
				 && (req1->request.length % maxpkt_size == 0))
					last_one = 1;
			}

			/* Is this the last request? */
			if (list_is_last(&req->list, &dep->request_list))
@@ -2201,6 +2241,17 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
				break;
		}while (++i < req->request.num_mapped_sgs);

		if (req->ztrb) {
			trb = req->ztrb;
			if ((event->status & DEPEVT_STATUS_LST) &&
				(trb->ctrl & (DWC3_TRB_CTRL_LST |
					DWC3_TRB_CTRL_HWO)))
				ret = 1;

			if ((event->status & DEPEVT_STATUS_IOC) &&
					(trb->ctrl & DWC3_TRB_CTRL_IOC))
				ret = 1;
		}
		dwc3_gadget_giveback(dep, req, status);

		if (ret)