spinlock_t req_lock; /* guard {rx,tx}_reqs */
struct list_head tx_reqs, rx_reqs;
- unsigned tx_qlen;
+ atomic_t tx_qlen;
/* Minimum number of TX USB request queued to UDC */
#define TX_REQ_THRESHOLD 5
int no_tx_req_used;
dev_kfree_skb_any(skb);
}
+ atomic_dec(&dev->tx_qlen);
if (netif_carrier_ok(dev->net))
netif_wake_queue(dev->net);
}
req->length = length;
- /* throttle highspeed IRQ rate back slightly */
- if (gadget_is_dualspeed(dev->gadget) &&
- (dev->gadget->speed == USB_SPEED_HIGH) &&
- !list_empty(&dev->tx_reqs)) {
- dev->tx_qlen++;
- if (dev->tx_qlen == (dev->qmult/2)) {
- req->no_interrupt = 0;
- dev->tx_qlen = 0;
- } else {
- req->no_interrupt = 1;
- }
- } else {
- req->no_interrupt = 0;
- }
+ /* 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)) &&
+ !list_empty(&dev->tx_reqs))
+ ? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0)
+ : 0;
retval = usb_ep_queue(in, req, GFP_ATOMIC);
switch (retval) {
break;
case 0:
net->trans_start = jiffies;
+ atomic_inc(&dev->tx_qlen);
}
if (retval) {
rx_fill(dev, gfp_flags);
/* and open the tx floodgates */
- dev->tx_qlen = 0;
+ atomic_set(&dev->tx_qlen, 0);
netif_wake_queue(dev->net);
}