Unverified Commit 10076de3 authored by Pawel Laszczak's avatar Pawel Laszczak Committed by Peter Chen
Browse files

usb: cdnsp: Fixes issue with Configure Endpoint command



Patch adds flag EP_UNCONFIGURED to detect whether endpoint was
unconfigured. This flag is set in cdnsp_reset_device after Reset Device
command. Among others this command disables all non control endpoints.
Flag is used in cdnsp_gadget_ep_disable to protect controller against
invoking Configure Endpoint command on disabled endpoint. Lack of this
protection in some cases caused that Configure Endpoint command completed
with Context State Error code completion.

Fixes: 3d829045 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
Signed-off-by: default avatarPawel Laszczak <pawell@cadence.com>
Signed-off-by: default avatarPeter Chen <peter.chen@kernel.org>
parent 9ecc3eb0
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -727,7 +727,7 @@ int cdnsp_reset_device(struct cdnsp_device *pdev)
	 * are in Disabled state.
	 */
	for (i = 1; i < CDNSP_ENDPOINTS_NUM; ++i)
		pdev->eps[i].ep_state |= EP_STOPPED;
		pdev->eps[i].ep_state |= EP_STOPPED | EP_UNCONFIGURED;

	trace_cdnsp_handle_cmd_reset_dev(slot_ctx);

@@ -942,6 +942,7 @@ static int cdnsp_gadget_ep_enable(struct usb_ep *ep,

	pep = to_cdnsp_ep(ep);
	pdev = pep->pdev;
	pep->ep_state &= ~EP_UNCONFIGURED;

	if (dev_WARN_ONCE(pdev->dev, pep->ep_state & EP_ENABLED,
			  "%s is already enabled\n", pep->name))
@@ -1023,9 +1024,13 @@ static int cdnsp_gadget_ep_disable(struct usb_ep *ep)
		goto finish;
	}

	cdnsp_cmd_stop_ep(pdev, pep);
	pep->ep_state |= EP_DIS_IN_RROGRESS;

	/* Endpoint was unconfigured by Reset Device command. */
	if (!(pep->ep_state & EP_UNCONFIGURED)) {
		cdnsp_cmd_stop_ep(pdev, pep);
		cdnsp_cmd_flush_ep(pdev, pep);
	}

	/* Remove all queued USB requests. */
	while (!list_empty(&pep->pending_list)) {
@@ -1043,10 +1048,12 @@ static int cdnsp_gadget_ep_disable(struct usb_ep *ep)

	cdnsp_endpoint_zero(pdev, pep);

	if (!(pep->ep_state & EP_UNCONFIGURED))
		ret = cdnsp_update_eps_configuration(pdev, pep);

	cdnsp_free_endpoint_rings(pdev, pep);

	pep->ep_state &= ~EP_ENABLED;
	pep->ep_state &= ~(EP_ENABLED | EP_UNCONFIGURED);
	pep->ep_state |= EP_STOPPED;

finish:
+1 −0
Original line number Diff line number Diff line
@@ -835,6 +835,7 @@ struct cdnsp_ep {
#define EP_WEDGE		BIT(4)
#define EP0_HALTED_STATUS	BIT(5)
#define EP_HAS_STREAMS		BIT(6)
#define EP_UNCONFIGURED		BIT(7)

	bool skip;
};