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

Commit e49d3cf4 authored by Felipe Balbi's avatar Felipe Balbi
Browse files

usb: dwc3: gadget: extract __dwc3_prepare_one_trb()



This new internal function will be used to solve a minor issue with dwc3
which exists in regards to short packets with OUT endpoints. Currently
we're asking gadget driver to *always* send us aligned requests; however
if we have enough TRBs we can easily append one extra TRB chained to the
previous and keep a throw away 1024 byte buffer around for that.

The actual fix will come in a separate patch, this is merely in
preparation for such fix.

Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 84305309
Loading
Loading
Loading
Loading
+36 −22
Original line number Diff line number Diff line
@@ -833,29 +833,13 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,

static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep);

/**
 * dwc3_prepare_one_trb - setup one TRB from one request
 * @dep: endpoint for which this request is prepared
 * @req: dwc3_request pointer
 */
static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
		struct dwc3_request *req, unsigned chain, unsigned node)
static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
		dma_addr_t dma, unsigned length, unsigned chain, unsigned node,
		unsigned stream_id, unsigned short_not_ok, unsigned no_interrupt)
{
	struct dwc3_trb		*trb;
	struct dwc3		*dwc = dep->dwc;
	struct usb_gadget	*gadget = &dwc->gadget;
	enum usb_device_speed	speed = gadget->speed;
	unsigned		length = req->request.length;
	dma_addr_t		dma = req->request.dma;

	trb = &dep->trb_pool[dep->trb_enqueue];

	if (!req->trb) {
		dwc3_gadget_move_started_request(req);
		req->trb = trb;
		req->trb_dma = dwc3_trb_dma_offset(dep, trb);
		dep->queued_requests++;
	}

	dwc3_ep_inc_enq(dep);

@@ -901,11 +885,11 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
	if (usb_endpoint_dir_out(dep->endpoint.desc)) {
		trb->ctrl |= DWC3_TRB_CTRL_CSP;

		if (req->request.short_not_ok)
		if (short_not_ok)
			trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
	}

	if ((!req->request.no_interrupt && !chain) ||
	if ((!no_interrupt && !chain) ||
			(dwc3_calc_trbs_left(dep) == 0))
		trb->ctrl |= DWC3_TRB_CTRL_IOC;

@@ -913,13 +897,43 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
		trb->ctrl |= DWC3_TRB_CTRL_CHN;

	if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
		trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);
		trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(stream_id);

	trb->ctrl |= DWC3_TRB_CTRL_HWO;

	trace_dwc3_prepare_trb(dep, trb);
}

/**
 * dwc3_prepare_one_trb - setup one TRB from one request
 * @dep: endpoint for which this request is prepared
 * @req: dwc3_request pointer
 * @chain: should this TRB be chained to the next?
 * @node: only for isochronous endpoints. First TRB needs different type.
 */
static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
		struct dwc3_request *req, unsigned chain, unsigned node)
{
	struct dwc3_trb		*trb;
	unsigned		length = req->request.length;
	unsigned		stream_id = req->request.stream_id;
	unsigned		short_not_ok = req->request.short_not_ok;
	unsigned		no_interrupt = req->request.no_interrupt;
	dma_addr_t		dma = req->request.dma;

	trb = &dep->trb_pool[dep->trb_enqueue];

	if (!req->trb) {
		dwc3_gadget_move_started_request(req);
		req->trb = trb;
		req->trb_dma = dwc3_trb_dma_offset(dep, trb);
		dep->queued_requests++;
	}

	__dwc3_prepare_one_trb(dep, trb, dma, length, chain, node,
			stream_id, short_not_ok, no_interrupt);
}

/**
 * dwc3_ep_prev_trb() - Returns the previous TRB in the ring
 * @dep: The endpoint with the TRB ring