[PATCH] usb/dwc3: Correct DEPCFG for Config Action "Modify"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Pratyush ANAND <pratyush.anand@xxxxxx>

We need to issue DEPCFG (with Config Action Set to "Modify") as per
specification. Even if we do not respect this , it works in normal
cases.  But, I have observed one failure in very peculiar situation.

If cpu clock is very slow and execution of connection done ISR takes
long time (may be around 150 mS), then one will never be able to
complete even first setup request. Setup bytes is received, but IN data
for get device descriptor is never observed on wire. dwc3 always keeps
on waiting for first data transfer complete event.

It can easily be reproduced even when working with high cpu clock by
deliberately putting delay around 150-200 mS at the start of connection
done handler.

Current patch corrects the error.

Signed-off-by: Pratyush Anand <pratyush.anand@xxxxxx>
---
 drivers/usb/dwc3/core.h   |    1 +
 drivers/usb/dwc3/gadget.c |    9 +++++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 133ed5a..e5b6496 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -489,6 +489,7 @@ enum dwc3_link_state {
 };
 
 enum dwc3_device_state {
+	DWC3_ATTACHED_STATE,
 	DWC3_DEFAULT_STATE,
 	DWC3_ADDRESS_STATE,
 	DWC3_CONFIGURED_STATE,
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f6ba644..3926095 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -473,6 +473,9 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
 		dep->interval = 1 << (desc->bInterval - 1);
 	}
 
+	if (dwc->dev_state != DWC3_ATTACHED_STATE)
+		params.param0 |= DWC3_DEPCFG_ACTION_MODIFY;
+
 	return dwc3_send_gadget_ep_cmd(dwc, dep->number,
 			DWC3_DEPCMD_SETEPCONFIG, &params);
 }
@@ -1551,6 +1554,9 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 	/* Start with SuperSpeed Default */
 	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 
+	/* At Start -> Attached State */
+	dwc->dev_state = DWC3_ATTACHED_STATE;
+
 	dep = dwc->eps[0];
 	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL);
 	if (ret) {
@@ -1976,6 +1982,9 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
 
 	dwc->gadget.speed = USB_SPEED_UNKNOWN;
 	dwc->setup_packet_pending = false;
+
+	/* At Disconnect -> Attached State */
+	dwc->dev_state = DWC3_ATTACHED_STATE;
 }
 
 static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux