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

Commit 6093862d 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: Fix assignment of EP transfer resources"

parents f58fae55 73e3c176
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -948,7 +948,6 @@ struct dwc3 {
	unsigned		pullups_connected:1;
	unsigned		resize_fifos:1;
	unsigned		setup_packet_pending:1;
	unsigned		start_config_issued:1;
	unsigned		three_stage_setup:1;
	unsigned		is_drd:1;

+0 −1
Original line number Diff line number Diff line
@@ -589,7 +589,6 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
	int ret;
	u32 reg;

	dwc->start_config_issued = false;
	cfg = le16_to_cpu(ctrl->wValue);

	switch (state) {
+52 −21
Original line number Diff line number Diff line
@@ -460,24 +460,66 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
	}
}

static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep);

/**
 * dwc3_gadget_start_config - Configure EP resources
 * @dwc: pointer to our controller context structure
 * @dep: endpoint that is being enabled
 *
 * The assignment of transfer resources cannot perfectly follow the
 * data book due to the fact that the controller driver does not have
 * all knowledge of the configuration in advance. It is given this
 * information piecemeal by the composite gadget framework after every
 * SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook
 * programming model in this scenario can cause errors. For two
 * reasons:
 *
 * 1) The databook says to do DEPSTARTCFG for every SET_CONFIGURATION
 * and SET_INTERFACE (8.1.5). This is incorrect in the scenario of
 * multiple interfaces.
 *
 * 2) The databook does not mention doing more DEPXFERCFG for new
 * endpoint on alt setting (8.1.6).
 *
 * The following simplified method is used instead:
 *
 * All hardware endpoints can be assigned a transfer resource and this
 * setting will stay persistent until either a core reset or
 * hibernation. So whenever we do a DEPSTARTCFG(0) we can go ahead and
 * do DEPXFERCFG for every hardware endpoint as well. We are
 * guaranteed that there are as many transfer resources as endpoints.
 *
 * This function is called for each endpoint when it is being enabled
 * but is triggered only when called for EP0-out, which always happens
 * first, and which should only happen in one of the above conditions.
 */
static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
{
	struct dwc3_gadget_ep_cmd_params params;
	u32			cmd;
	int			i;
	int			ret;

	memset(&params, 0x00, sizeof(params));
	if (dep->number)
		return 0;

	if (dep->number != 1) {
	memset(&params, 0x00, sizeof(params));
	cmd = DWC3_DEPCMD_DEPSTARTCFG;
		/* XferRscIdx == 0 for ep0 and 2 for the remaining */
		if (dep->number > 1) {
			if (dwc->start_config_issued)
				return 0;
			dwc->start_config_issued = true;
			cmd |= DWC3_DEPCMD_PARAM(2);
		}

		return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
	ret = dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
	if (ret)
		return ret;

	for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
		struct dwc3_ep *dep = dwc->eps[i];

		if (!dep)
			continue;

		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
		if (ret)
			return ret;
	}

	return 0;
@@ -603,13 +645,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
		struct dwc3_trb	*trb_st_hw;
		struct dwc3_trb	*trb_link;

		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
		if (ret) {
			dev_err(dwc->dev, "set_xfer_resource() failed for %s\n",
								dep->name);
			return ret;
		}

		dep->endpoint.desc = desc;
		dep->comp_desc = comp_desc;
		dep->type = usb_endpoint_type(desc);
@@ -2175,8 +2210,6 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
		dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg);
	}

	dwc->start_config_issued = false;

	/* Start with SuperSpeed Default */
	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);

@@ -2906,7 +2939,6 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)

	dbg_event(0xFF, "DISCONNECT", 0);
	dwc3_disconnect_gadget(dwc);
	dwc->start_config_issued = false;

	dwc->gadget.speed = USB_SPEED_UNKNOWN;
	dwc->setup_packet_pending = false;
@@ -2985,7 +3017,6 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)

	dwc3_stop_active_transfers(dwc);
	dwc3_clear_stall_all_ep(dwc);
	dwc->start_config_issued = false;

	/* bus reset issued due to missing status stage of a control transfer */
	dwc->resize_fifos = 0;