summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2016-10-04 15:14:43 +0300
committerSasha Levin <alexander.levin@verizon.com>2016-11-01 15:17:22 -0400
commit517052446f36f78b13502ccafc8884b6339643d2 (patch)
tree710b4dbb93e8513fc0a1089fcc216f046ec5a846 /drivers/usb
parent66f38bf99faa0b30d7486906738da66b56fb7d80 (diff)
usb: gadget: function: u_ether: don't starve tx request queue
[ Upstream commit 6c83f77278f17a7679001027e9231291c20f0d8a ] 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. Cc: <stable@vger.kernel.org> Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/function/u_ether.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index f1fd777ef4ec..82e63f73bfd5 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -591,8 +591,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
/* 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;