| From 6c83f77278f17a7679001027e9231291c20f0d8a Mon Sep 17 00:00:00 2001 |
| From: Felipe Balbi <felipe.balbi@linux.intel.com> |
| Date: Tue, 4 Oct 2016 15:14:43 +0300 |
| Subject: usb: gadget: function: u_ether: don't starve tx request queue |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Felipe Balbi <felipe.balbi@linux.intel.com> |
| |
| commit 6c83f77278f17a7679001027e9231291c20f0d8a upstream. |
| |
| If we don't guarantee that we will always get an |
| interrupt at least when we're queueing our very last |
| request, we could fall into situation where we queue |
| every request with 'no_interrupt' set. This will |
| cause the link to get stuck. |
| |
| The behavior above has been triggered with g_ether |
| and dwc3. |
| |
| Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/gadget/function/u_ether.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/usb/gadget/function/u_ether.c |
| +++ b/drivers/usb/gadget/function/u_ether.c |
| @@ -587,8 +587,9 @@ static netdev_tx_t eth_start_xmit(struct |
| |
| /* throttle high/super speed IRQ rate back slightly */ |
| if (gadget_is_dualspeed(dev->gadget)) |
| - req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH || |
| - dev->gadget->speed == USB_SPEED_SUPER) |
| + req->no_interrupt = (((dev->gadget->speed == USB_SPEED_HIGH || |
| + dev->gadget->speed == USB_SPEED_SUPER)) && |
| + !list_empty(&dev->tx_reqs)) |
| ? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0) |
| : 0; |
| |