usb: dwc3: gadget: Issue soft reset as part of composition switch

As part of composition switch, the device initiates
disconnect from the host by clearing the run/stop
bit of DCTL and initiates a connect by setting the run/stop bit.
But during this entire scenario the core is not reset
and there is a possibility of core caching the SETUP packets
from the previous session and giving this to the driver once the
run/stop bit is set leading to unintnented SETUP packets further
leading to stall on endpoint 0. This caused the endpoint 0 to
go into a bad state leading to enumeration failures.

Also, the databook clearly mentions that the soft reset has
to be issued before setting the run/stop bit to initialize a
conenct after a disconnect.
So, issue soft reset as part of composition switch to fix this
issue.

Change-Id: Id93bef710e7cdb67a6820cb4c9defecc5ad2a34e
Signed-off-by: Sriharsha Allenki <sallenki@codeaurora.org>
Signed-off-by: Yaroslav Furman <yaro330@gmail.com>
Signed-off-by: Forenche <prahul2003@gmail.com>
Signed-off-by: azrim <mirzaspc@gmail.com>
This commit is contained in:
Sriharsha Allenki 2020-03-11 12:43:06 +05:30 committed by azrim
parent 9c9056f434
commit 940cd6e121
No known key found for this signature in database
GPG Key ID: 497F8FB059B45D1C

View File

@ -2165,6 +2165,12 @@ done:
/* phy sync delay as per data book */
msleep(50);
/*
* Soft reset clears the block on the doorbell,
* set it back to prevent unwanted writes to the doorbell.
*/
dwc3_notify_event(dwc, DWC3_CONTROLLER_NOTIFY_CLEAR_DB, 0);
return 0;
}
@ -2330,6 +2336,9 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
/* prevent pending bh to run later */
flush_work(&dwc->bh_work);
if (is_on)
dwc3_device_core_soft_reset(dwc);
spin_lock_irqsave(&dwc->lock, flags);
if (dwc->ep0state != EP0_SETUP_PHASE)
dbg_event(0xFF, "EP0 is not in SETUP phase\n", 0);