![Hal Emmerich](/assets/img/avatar_default.png)
Add backported patched from 5.x from usb related fixes Up kernel version to most recent lts
112 lines
3.8 KiB
Diff
112 lines
3.8 KiB
Diff
From b4c53b4ac66a75a93672abf08aafac64dfb08d00 Mon Sep 17 00:00:00 2001
|
|
From: Minas Harutyunyan <minas.harutyunyan@synopsys.com>
|
|
Date: Tue, 12 Mar 2019 11:45:12 +0400
|
|
Subject: [PATCH 38/53] usb: dwc2: Delayed status support
|
|
|
|
Added delayed status support for Control transfers.
|
|
|
|
Tested in all 3 modes: Slave, BDMA and DDMA.
|
|
Performed tests: USB CV (Ch9 and MSC), Control Read/Write tests
|
|
using Synopsys USB test environment function driver.
|
|
|
|
Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
|
|
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
|
|
---
|
|
drivers/usb/dwc2/core.h | 2 ++
|
|
drivers/usb/dwc2/gadget.c | 31 +++++++++++++++++++++++++++----
|
|
2 files changed, 29 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
|
|
index 9f3fc8e18277..152ac41dfb2d 100644
|
|
--- a/drivers/usb/dwc2/core.h
|
|
+++ b/drivers/usb/dwc2/core.h
|
|
@@ -993,6 +993,7 @@ struct dwc2_hregs_backup {
|
|
* @ctrl_buff: Buffer for EP0 control requests.
|
|
* @ctrl_req: Request for EP0 control packets.
|
|
* @ep0_state: EP0 control transfers state
|
|
+ * @delayed_status: true when gadget driver asks for delayed status
|
|
* @test_mode: USB test mode requested by the host
|
|
* @remote_wakeup_allowed: True if device is allowed to wake-up host by
|
|
* remote-wakeup signalling
|
|
@@ -1175,6 +1176,7 @@ struct dwc2_hsotg {
|
|
void *ep0_buff;
|
|
void *ctrl_buff;
|
|
enum dwc2_ep0_state ep0_state;
|
|
+ unsigned delayed_status : 1;
|
|
u8 test_mode;
|
|
|
|
dma_addr_t setup_desc_dma[2];
|
|
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
|
|
index 2e2f9cbf6a3d..5f314a10a116 100644
|
|
--- a/drivers/usb/dwc2/gadget.c
|
|
+++ b/drivers/usb/dwc2/gadget.c
|
|
@@ -27,6 +27,8 @@
|
|
#include <linux/usb/ch9.h>
|
|
#include <linux/usb/gadget.h>
|
|
#include <linux/usb/phy.h>
|
|
+#include <linux/usb/composite.h>
|
|
+
|
|
|
|
#include "core.h"
|
|
#include "hw.h"
|
|
@@ -1446,6 +1448,11 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
|
|
return 0;
|
|
}
|
|
|
|
+ /* Change EP direction if status phase request is after data out */
|
|
+ if (!hs_ep->index && !req->length && !hs_ep->dir_in &&
|
|
+ hs->ep0_state == DWC2_EP0_DATA_OUT)
|
|
+ hs_ep->dir_in = 1;
|
|
+
|
|
if (first) {
|
|
if (!hs_ep->isochronous) {
|
|
dwc2_hsotg_start_req(hs, hs_ep, hs_req, false);
|
|
@@ -1938,6 +1945,10 @@ static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg,
|
|
dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret);
|
|
}
|
|
|
|
+ hsotg->delayed_status = false;
|
|
+ if (ret == USB_GADGET_DELAYED_STATUS)
|
|
+ hsotg->delayed_status = true;
|
|
+
|
|
/*
|
|
* the request is either unhandlable, or is not formatted correctly
|
|
* so respond with a STALL for the status stage to indicate failure.
|
|
@@ -2387,8 +2398,8 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
|
|
if (!using_desc_dma(hsotg) && epnum == 0 &&
|
|
hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
|
|
/* Move to STATUS IN */
|
|
- dwc2_hsotg_ep0_zlp(hsotg, true);
|
|
- return;
|
|
+ if (!hsotg->delayed_status)
|
|
+ dwc2_hsotg_ep0_zlp(hsotg, true);
|
|
}
|
|
|
|
/*
|
|
@@ -3053,8 +3064,20 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
|
|
/* Safety check EP0 state when STSPHSERCVD asserted */
|
|
if (hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
|
|
/* Move to STATUS IN for DDMA */
|
|
- if (using_desc_dma(hsotg))
|
|
- dwc2_hsotg_ep0_zlp(hsotg, true);
|
|
+ if (using_desc_dma(hsotg)) {
|
|
+ if (!hsotg->delayed_status)
|
|
+ dwc2_hsotg_ep0_zlp(hsotg, true);
|
|
+ else
|
|
+ /* In case of 3 stage Control Write with delayed
|
|
+ * status, when Status IN transfer started
|
|
+ * before STSPHSERCVD asserted, NAKSTS bit not
|
|
+ * cleared by CNAK in dwc2_hsotg_start_req()
|
|
+ * function. Clear now NAKSTS to allow complete
|
|
+ * transfer.
|
|
+ */
|
|
+ dwc2_set_bit(hsotg, DIEPCTL(0),
|
|
+ DXEPCTL_CNAK);
|
|
+ }
|
|
}
|
|
|
|
}
|
|
--
|
|
2.11.0
|
|
|