lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20231017131851.8299-8-quic_kriskura@quicinc.com>
Date:   Tue, 17 Oct 2023 18:48:51 +0530
From:   Krishna Kurapati <quic_kriskura@...cinc.com>
To:     Thinh Nguyen <Thinh.Nguyen@...opsys.com>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Philipp Zabel <p.zabel@...gutronix.de>,
        "Andy Gross" <agross@...nel.org>,
        Bjorn Andersson <andersson@...nel.org>,
        "Konrad Dybcio" <konrad.dybcio@...aro.org>,
        Rob Herring <robh+dt@...nel.org>,
        Krzysztof Kozlowski <krzysztof.kozlowski+dt@...aro.org>,
        Conor Dooley <conor+dt@...nel.org>, <quic_wcheng@...cinc.com>
CC:     <linux-usb@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <linux-arm-msm@...r.kernel.org>, <devicetree@...r.kernel.org>,
        <quic_ppratap@...cinc.com>, <quic_jackp@...cinc.com>,
        Krishna Kurapati <quic_kriskura@...cinc.com>
Subject: [RFC 8/8] usb: dwc3: core: Skip set_mode notification if cable is disconnected

In device mode use cases, the following sequence of actions are observed:

1. Cable disconnect happens and clears qscratch HS_PHY_CTRL_REG properly
2. Disconnect event is generated and "connected" flag turns false.
3. Then the setmode notification from core goes to glue
4. Glue will set back the qscratch HS_PHY_CTRL_REG bits again.

At this point, since the cable is removed, setting qscratch bits shouldn't
affect anything. But it is observed that after setting this bits, the
controller generated Event-0x101 and Event-0x30601 (bus reset and suspend)
in order. In bus reset, we set back the "connected" flag and this blocks
suspend again.

So send set_mode call only if the cable is connected, else skip it.

Signed-off-by: Krishna Kurapati <quic_kriskura@...cinc.com>
---
 drivers/usb/dwc3/core.c | 3 ++-
 drivers/usb/dwc3/core.h | 2 ++
 drivers/usb/dwc3/drd.c  | 6 +++++-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index b4d1d1c98dd5..6ef1e3558384 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -137,7 +137,8 @@ static void __dwc3_set_mode(struct work_struct *work)
 	if (!desired_dr_role)
 		goto out;
 
-	dwc3_notify_set_mode(dwc, desired_dr_role);
+	if (dwc->cable_disconnected == false)
+		dwc3_notify_set_mode(dwc, desired_dr_role);
 
 	if (desired_dr_role == dwc->current_dr_role)
 		goto out;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 5ed7fd5eb776..1b79c407a798 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1365,6 +1365,8 @@ struct dwc3 {
 
 	void			*glue_data;
 	const struct dwc3_glue_ops *glue_ops;
+
+	bool			cable_disconnected;
 };
 
 #define INCRX_BURST_MODE 0
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index 947faeef0e4d..b3a87c40c4f1 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -446,6 +446,8 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
 	struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
 	u32 mode;
 
+	dwc->cable_disconnected = false;
+
 	switch (role) {
 	case USB_ROLE_HOST:
 		mode = DWC3_GCTL_PRTCAP_HOST;
@@ -467,8 +469,10 @@ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
 	 * glue needs to know that we are disconnected. It must not notify
 	 * the change of mode to default mode.
 	 */
-	if (role == USB_ROLE_NONE)
+	if (role == USB_ROLE_NONE) {
+		dwc->cable_disconnected = true;
 		dwc3_notify_cable_disconnect(dwc);
+	}
 
 	dwc3_set_mode(dwc, mode);
 	return 0;
-- 
2.42.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ