diff mbox series

[3/5] usb: dwc3: gadget: Adjust IRQ management during soft disconnect/connect

Message ID 20220708185007.21743-4-quic_wcheng@quicinc.com (mailing list archive)
State Superseded
Headers show
Series Fix controller halt and endxfer timeout issues | expand

Commit Message

Wesley Cheng July 8, 2022, 6:50 p.m. UTC
Local interrupts are currently being disabled as part of aquiring the
spin lock before issuing the endxfer command.  Leave interrupts enabled, so
that EP0 events can continue to be processed.  Also, ensure that there are
no pending interrupts before attempting to handle any soft
connect/disconnect.

Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
---
 drivers/usb/dwc3/gadget.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

Comments

kernel test robot July 9, 2022, 2:26 a.m. UTC | #1
Hi Wesley,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on linus/master v5.19-rc5 next-20220708]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wesley-Cheng/Fix-controller-halt-and-endxfer-timeout-issues/20220709-025241
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-randconfig-a002 (https://download.01.org/0day-ci/archive/20220709/202207091054.eGEUvBXn-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-3) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/457fe4752b0f6dcc5c1b329f91003b7ffc518b44
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Wesley-Cheng/Fix-controller-halt-and-endxfer-timeout-issues/20220709-025241
        git checkout 457fe4752b0f6dcc5c1b329f91003b7ffc518b44
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/usb/dwc3/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/usb/dwc3/gadget.c: In function 'dwc3_gadget_ep_dequeue':
>> drivers/usb/dwc3/gadget.c:2032:41: warning: unused variable 'flags' [-Wunused-variable]
    2032 |         unsigned long                   flags;
         |                                         ^~~~~


vim +/flags +2032 drivers/usb/dwc3/gadget.c

d4f1afe5e896c1 Felipe Balbi 2018-08-01  2022  
72246da40f3719 Felipe Balbi 2011-08-19  2023  static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
72246da40f3719 Felipe Balbi 2011-08-19  2024  		struct usb_request *request)
72246da40f3719 Felipe Balbi 2011-08-19  2025  {
72246da40f3719 Felipe Balbi 2011-08-19  2026  	struct dwc3_request		*req = to_dwc3_request(request);
72246da40f3719 Felipe Balbi 2011-08-19  2027  	struct dwc3_request		*r = NULL;
72246da40f3719 Felipe Balbi 2011-08-19  2028  
72246da40f3719 Felipe Balbi 2011-08-19  2029  	struct dwc3_ep			*dep = to_dwc3_ep(ep);
72246da40f3719 Felipe Balbi 2011-08-19  2030  	struct dwc3			*dwc = dep->dwc;
72246da40f3719 Felipe Balbi 2011-08-19  2031  
72246da40f3719 Felipe Balbi 2011-08-19 @2032  	unsigned long			flags;
72246da40f3719 Felipe Balbi 2011-08-19  2033  	int				ret = 0;
72246da40f3719 Felipe Balbi 2011-08-19  2034  
2c4cbe6e5a9c71 Felipe Balbi 2014-04-30  2035  	trace_dwc3_ep_dequeue(req);
2c4cbe6e5a9c71 Felipe Balbi 2014-04-30  2036  
457fe4752b0f6d Wesley Cheng 2022-07-08  2037  	spin_lock(&dwc->lock);
72246da40f3719 Felipe Balbi 2011-08-19  2038  
a7027ca69d82ae Thinh Nguyen 2020-03-05  2039  	list_for_each_entry(r, &dep->cancelled_list, list) {
72246da40f3719 Felipe Balbi 2011-08-19  2040  		if (r == req)
fcd2def6639293 Thinh Nguyen 2020-03-05  2041  			goto out;
72246da40f3719 Felipe Balbi 2011-08-19  2042  	}
72246da40f3719 Felipe Balbi 2011-08-19  2043  
aa3342c8bb618a Felipe Balbi 2016-03-14  2044  	list_for_each_entry(r, &dep->pending_list, list) {
fcd2def6639293 Thinh Nguyen 2020-03-05  2045  		if (r == req) {
fcd2def6639293 Thinh Nguyen 2020-03-05  2046  			dwc3_gadget_giveback(dep, req, -ECONNRESET);
fcd2def6639293 Thinh Nguyen 2020-03-05  2047  			goto out;
fcd2def6639293 Thinh Nguyen 2020-03-05  2048  		}
72246da40f3719 Felipe Balbi 2011-08-19  2049  	}
72246da40f3719 Felipe Balbi 2011-08-19  2050  
aa3342c8bb618a Felipe Balbi 2016-03-14  2051  	list_for_each_entry(r, &dep->started_list, list) {
72246da40f3719 Felipe Balbi 2011-08-19  2052  		if (r == req) {
a7027ca69d82ae Thinh Nguyen 2020-03-05  2053  			struct dwc3_request *t;
a7027ca69d82ae Thinh Nguyen 2020-03-05  2054  
72246da40f3719 Felipe Balbi 2011-08-19  2055  			/* wait until it is processed */
c5353b225df9b2 Felipe Balbi 2019-02-13  2056  			dwc3_stop_active_transfer(dep, true, true);
cf3113d893d442 Felipe Balbi 2017-02-17  2057  
a7027ca69d82ae Thinh Nguyen 2020-03-05  2058  			/*
a7027ca69d82ae Thinh Nguyen 2020-03-05  2059  			 * Remove any started request if the transfer is
a7027ca69d82ae Thinh Nguyen 2020-03-05  2060  			 * cancelled.
a7027ca69d82ae Thinh Nguyen 2020-03-05  2061  			 */
a7027ca69d82ae Thinh Nguyen 2020-03-05  2062  			list_for_each_entry_safe(r, t, &dep->started_list, list)
04dd6e76b22889 Ray Chi      2021-03-28  2063  				dwc3_gadget_move_cancelled_request(r,
04dd6e76b22889 Ray Chi      2021-03-28  2064  						DWC3_REQUEST_STATUS_DEQUEUED);
cf3113d893d442 Felipe Balbi 2017-02-17  2065  
a5c7682aaaa10e Thinh Nguyen 2021-01-04  2066  			dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
a5c7682aaaa10e Thinh Nguyen 2021-01-04  2067  
fcd2def6639293 Thinh Nguyen 2020-03-05  2068  			goto out;
72246da40f3719 Felipe Balbi 2011-08-19  2069  		}
72246da40f3719 Felipe Balbi 2011-08-19  2070  	}
fcd2def6639293 Thinh Nguyen 2020-03-05  2071  
04fb365c453e14 Felipe Balbi 2017-05-17  2072  	dev_err(dwc->dev, "request %pK was not queued to %s\n",
72246da40f3719 Felipe Balbi 2011-08-19  2073  		request, ep->name);
72246da40f3719 Felipe Balbi 2011-08-19  2074  	ret = -EINVAL;
fcd2def6639293 Thinh Nguyen 2020-03-05  2075  out:
457fe4752b0f6d Wesley Cheng 2022-07-08  2076  	spin_unlock(&dwc->lock);
72246da40f3719 Felipe Balbi 2011-08-19  2077  
72246da40f3719 Felipe Balbi 2011-08-19  2078  	return ret;
72246da40f3719 Felipe Balbi 2011-08-19  2079  }
72246da40f3719 Felipe Balbi 2011-08-19  2080
kernel test robot July 9, 2022, 4:47 a.m. UTC | #2
Hi Wesley,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on usb/usb-testing]
[also build test WARNING on linus/master v5.19-rc5 next-20220708]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Wesley-Cheng/Fix-controller-halt-and-endxfer-timeout-issues/20220709-025241
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-randconfig-a012 (https://download.01.org/0day-ci/archive/20220709/202207091200.uLedVxl7-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 562c3467a6738aa89203f72fc1d1343e5baadf3c)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/457fe4752b0f6dcc5c1b329f91003b7ffc518b44
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Wesley-Cheng/Fix-controller-halt-and-endxfer-timeout-issues/20220709-025241
        git checkout 457fe4752b0f6dcc5c1b329f91003b7ffc518b44
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/usb/dwc3/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/usb/dwc3/gadget.c:2032:18: warning: unused variable 'flags' [-Wunused-variable]
           unsigned long                   flags;
                                           ^
   1 warning generated.


vim +/flags +2032 drivers/usb/dwc3/gadget.c

d4f1afe5e896c1 Felipe Balbi 2018-08-01  2022  
72246da40f3719 Felipe Balbi 2011-08-19  2023  static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
72246da40f3719 Felipe Balbi 2011-08-19  2024  		struct usb_request *request)
72246da40f3719 Felipe Balbi 2011-08-19  2025  {
72246da40f3719 Felipe Balbi 2011-08-19  2026  	struct dwc3_request		*req = to_dwc3_request(request);
72246da40f3719 Felipe Balbi 2011-08-19  2027  	struct dwc3_request		*r = NULL;
72246da40f3719 Felipe Balbi 2011-08-19  2028  
72246da40f3719 Felipe Balbi 2011-08-19  2029  	struct dwc3_ep			*dep = to_dwc3_ep(ep);
72246da40f3719 Felipe Balbi 2011-08-19  2030  	struct dwc3			*dwc = dep->dwc;
72246da40f3719 Felipe Balbi 2011-08-19  2031  
72246da40f3719 Felipe Balbi 2011-08-19 @2032  	unsigned long			flags;
72246da40f3719 Felipe Balbi 2011-08-19  2033  	int				ret = 0;
72246da40f3719 Felipe Balbi 2011-08-19  2034  
2c4cbe6e5a9c71 Felipe Balbi 2014-04-30  2035  	trace_dwc3_ep_dequeue(req);
2c4cbe6e5a9c71 Felipe Balbi 2014-04-30  2036  
457fe4752b0f6d Wesley Cheng 2022-07-08  2037  	spin_lock(&dwc->lock);
72246da40f3719 Felipe Balbi 2011-08-19  2038  
a7027ca69d82ae Thinh Nguyen 2020-03-05  2039  	list_for_each_entry(r, &dep->cancelled_list, list) {
72246da40f3719 Felipe Balbi 2011-08-19  2040  		if (r == req)
fcd2def6639293 Thinh Nguyen 2020-03-05  2041  			goto out;
72246da40f3719 Felipe Balbi 2011-08-19  2042  	}
72246da40f3719 Felipe Balbi 2011-08-19  2043  
aa3342c8bb618a Felipe Balbi 2016-03-14  2044  	list_for_each_entry(r, &dep->pending_list, list) {
fcd2def6639293 Thinh Nguyen 2020-03-05  2045  		if (r == req) {
fcd2def6639293 Thinh Nguyen 2020-03-05  2046  			dwc3_gadget_giveback(dep, req, -ECONNRESET);
fcd2def6639293 Thinh Nguyen 2020-03-05  2047  			goto out;
fcd2def6639293 Thinh Nguyen 2020-03-05  2048  		}
72246da40f3719 Felipe Balbi 2011-08-19  2049  	}
72246da40f3719 Felipe Balbi 2011-08-19  2050  
aa3342c8bb618a Felipe Balbi 2016-03-14  2051  	list_for_each_entry(r, &dep->started_list, list) {
72246da40f3719 Felipe Balbi 2011-08-19  2052  		if (r == req) {
a7027ca69d82ae Thinh Nguyen 2020-03-05  2053  			struct dwc3_request *t;
a7027ca69d82ae Thinh Nguyen 2020-03-05  2054  
72246da40f3719 Felipe Balbi 2011-08-19  2055  			/* wait until it is processed */
c5353b225df9b2 Felipe Balbi 2019-02-13  2056  			dwc3_stop_active_transfer(dep, true, true);
cf3113d893d442 Felipe Balbi 2017-02-17  2057  
a7027ca69d82ae Thinh Nguyen 2020-03-05  2058  			/*
a7027ca69d82ae Thinh Nguyen 2020-03-05  2059  			 * Remove any started request if the transfer is
a7027ca69d82ae Thinh Nguyen 2020-03-05  2060  			 * cancelled.
a7027ca69d82ae Thinh Nguyen 2020-03-05  2061  			 */
a7027ca69d82ae Thinh Nguyen 2020-03-05  2062  			list_for_each_entry_safe(r, t, &dep->started_list, list)
04dd6e76b22889 Ray Chi      2021-03-28  2063  				dwc3_gadget_move_cancelled_request(r,
04dd6e76b22889 Ray Chi      2021-03-28  2064  						DWC3_REQUEST_STATUS_DEQUEUED);
cf3113d893d442 Felipe Balbi 2017-02-17  2065  
a5c7682aaaa10e Thinh Nguyen 2021-01-04  2066  			dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
a5c7682aaaa10e Thinh Nguyen 2021-01-04  2067  
fcd2def6639293 Thinh Nguyen 2020-03-05  2068  			goto out;
72246da40f3719 Felipe Balbi 2011-08-19  2069  		}
72246da40f3719 Felipe Balbi 2011-08-19  2070  	}
fcd2def6639293 Thinh Nguyen 2020-03-05  2071  
04fb365c453e14 Felipe Balbi 2017-05-17  2072  	dev_err(dwc->dev, "request %pK was not queued to %s\n",
72246da40f3719 Felipe Balbi 2011-08-19  2073  		request, ep->name);
72246da40f3719 Felipe Balbi 2011-08-19  2074  	ret = -EINVAL;
fcd2def6639293 Thinh Nguyen 2020-03-05  2075  out:
457fe4752b0f6d Wesley Cheng 2022-07-08  2076  	spin_unlock(&dwc->lock);
72246da40f3719 Felipe Balbi 2011-08-19  2077  
72246da40f3719 Felipe Balbi 2011-08-19  2078  	return ret;
72246da40f3719 Felipe Balbi 2011-08-19  2079  }
72246da40f3719 Felipe Balbi 2011-08-19  2080
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 75cbc3f185d0..bd40608b19df 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2046,7 +2046,7 @@  static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 
 	trace_dwc3_ep_dequeue(req);
 
-	spin_lock_irqsave(&dwc->lock, flags);
+	spin_lock(&dwc->lock);
 
 	list_for_each_entry(r, &dep->cancelled_list, list) {
 		if (r == req)
@@ -2085,7 +2085,7 @@  static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 		request, ep->name);
 	ret = -EINVAL;
 out:
-	spin_unlock_irqrestore(&dwc->lock, flags);
+	spin_unlock(&dwc->lock);
 
 	return ret;
 }
@@ -2501,9 +2501,7 @@  static int __dwc3_gadget_start(struct dwc3 *dwc);
 
 static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
+	spin_lock(&dwc->lock);
 	dwc->connected = false;
 
 	/*
@@ -2518,10 +2516,10 @@  static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
 
 		reinit_completion(&dwc->ep0_in_setup);
 
-		spin_unlock_irqrestore(&dwc->lock, flags);
+		spin_unlock(&dwc->lock);
 		ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
 				msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
-		spin_lock_irqsave(&dwc->lock, flags);
+		spin_lock(&dwc->lock);
 		if (ret == 0)
 			dev_warn(dwc->dev, "timed out waiting for SETUP phase\n");
 	}
@@ -2535,7 +2533,7 @@  static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
 	 */
 	dwc3_stop_active_transfers(dwc);
 	__dwc3_gadget_stop(dwc);
-	spin_unlock_irqrestore(&dwc->lock, flags);
+	spin_unlock(&dwc->lock);
 
 	/*
 	 * Note: if the GEVNTCOUNT indicates events in the event buffer, the
@@ -2581,6 +2579,8 @@  static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
 		return 0;
 	}
 
+	synchronize_irq(dwc->irq_gadget);
+
 	if (!is_on) {
 		ret = dwc3_gadget_soft_disconnect(dwc);
 	} else {
@@ -3740,7 +3740,10 @@  void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
 	 * This mode is NOT available on the DWC_usb31 IP.
 	 */
 
+	spin_unlock(&dwc->lock);
 	__dwc3_stop_active_transfer(dep, force, interrupt);
+	spin_lock(&dwc->lock);
+
 }
 
 static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)