From 5390d438e6f4aaf3555acc72aff155660a48cd28 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:25 +0200 Subject: [PATCH] usb: dwc2: gadget: kill ep0 requests before reinitializing core Make sure there are no requests pending on ep0 before reinitializing core. Otherwise, dwc2_hsotg_enqueue_setup will fail afterwards. Also, take hsotg->lock before calling dwc2_hsotg_core_init_disconnected() from dwc2_conn_id_status_change() as dwc2_hsotg_complete_request() expect lock to be held. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 8 +++----- drivers/usb/dwc2/hcd.c | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 38c29a8bdd11..2d81fc5f39e9 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2287,6 +2287,9 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, { u32 val; + /* Kill any ep0 requests as controller will be reinitialized */ + kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); + if (!is_usb_reset) if (dwc2_hsotg_corereset(hsotg)) return; @@ -2515,9 +2518,6 @@ irq_retry: if (time_after(jiffies, hsotg->last_rst + msecs_to_jiffies(200))) { - kill_all_requests(hsotg, hsotg->eps_out[0], - -ECONNRESET); - dwc2_hsotg_core_init_disconnected(hsotg, true); } } @@ -3296,8 +3296,6 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) if (hsotg->lx_state == DWC2_L2) dwc2_exit_hibernation(hsotg, false); - /* Kill any ep0 requests as controller will be reinitialized */ - kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); dwc2_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) dwc2_hsotg_core_connect(hsotg); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 15a1e62ac902..af4e4a27126f 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) wf_otg); u32 count = 0; u32 gotgctl; + unsigned long flags; dev_dbg(hsotg->dev, "%s()\n", __func__); @@ -1382,7 +1383,9 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + spin_lock_irqsave(&hsotg->lock, flags); dwc2_hsotg_core_init_disconnected(hsotg, false); + spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_hsotg_core_connect(hsotg); } else { /* A-Device connector (Host Mode) */