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

Commit c7874448 authored by Minas Harutyunyan's avatar Minas Harutyunyan Committed by Greg Kroah-Hartman
Browse files

usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows



commit 9a0d6f7c0a83844baae1d6d85482863d2bf3b7a7 upstream.

SET/CLEAR_FEATURE for Remote Wakeup allowance not handled correctly.
GET_STATUS handling provided not correct data on DATA Stage.
Issue seen when gadget's dr_mode set to "otg" mode and connected
to MacOS.
Both are fixed and tested using USBCV Ch.9 tests.

Signed-off-by: default avatarMinas Harutyunyan <hminas@synopsys.com>
Fixes: fa389a6d ("usb: dwc2: gadget: Add remote_wakeup_allowed flag")
Tested-by: default avatarJack Mitchell <ml@embed.me.uk>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8cfda0c9
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -1542,6 +1542,7 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
	struct dwc2_hsotg_ep *ep;
	__le16 reply;
	u16 status;
	int ret;

	dev_dbg(hsotg->dev, "%s: USB_REQ_GET_STATUS\n", __func__);
@@ -1553,11 +1554,10 @@ static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,

	switch (ctrl->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		/*
		 * bit 0 => self powered
		 * bit 1 => remote wakeup
		 */
		reply = cpu_to_le16(0);
		status = 1 << USB_DEVICE_SELF_POWERED;
		status |= hsotg->remote_wakeup_allowed <<
			  USB_DEVICE_REMOTE_WAKEUP;
		reply = cpu_to_le16(status);
		break;

	case USB_RECIP_INTERFACE:
@@ -1668,7 +1668,10 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
	case USB_RECIP_DEVICE:
		switch (wValue) {
		case USB_DEVICE_REMOTE_WAKEUP:
			if (set)
				hsotg->remote_wakeup_allowed = 1;
			else
				hsotg->remote_wakeup_allowed = 0;
			break;

		case USB_DEVICE_TEST_MODE:
@@ -1678,6 +1681,11 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
				return -EINVAL;

			hsotg->test_mode = wIndex >> 8;
			break;
		default:
			return -ENOENT;
		}

		ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
		if (ret) {
			dev_err(hsotg->dev,
@@ -1685,10 +1693,6 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
			return ret;
		}
		break;
		default:
			return -ENOENT;
		}
		break;

	case USB_RECIP_ENDPOINT:
		ep = ep_from_windex(hsotg, wIndex);