Commit 16630f54 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by David S. Miller

isdn: mISDN: use irqsave() in USB's complete callback

The USB completion callback does not disable interrupts while acquiring
the ->lock. We want to remove the local_irq_disable() invocation from
__usb_hcd_giveback_urb() and therefore it is required for the callback
handler to disable the interrupts while acquiring the lock.
The callback may be invoked either in IRQ or BH context depending on the
USB host controller.
Use the _irqsave() variant of the locking primitives.

Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: netdev@vger.kernel.org
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e112ce43
...@@ -819,6 +819,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -819,6 +819,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
int fifon = fifo->fifonum; int fifon = fifo->fifonum;
int i; int i;
int hdlc = 0; int hdlc = 0;
unsigned long flags;
if (debug & DBG_HFC_CALL_TRACE) if (debug & DBG_HFC_CALL_TRACE)
printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) " printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "
...@@ -835,7 +836,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -835,7 +836,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
return; return;
} }
spin_lock(&hw->lock); spin_lock_irqsave(&hw->lock, flags);
if (fifo->dch) { if (fifo->dch) {
rx_skb = fifo->dch->rx_skb; rx_skb = fifo->dch->rx_skb;
maxlen = fifo->dch->maxlen; maxlen = fifo->dch->maxlen;
...@@ -844,7 +845,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -844,7 +845,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
if (fifo->bch) { if (fifo->bch) {
if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) { if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
fifo->bch->dropcnt += len; fifo->bch->dropcnt += len;
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
maxlen = bchannel_get_rxbuf(fifo->bch, len); maxlen = bchannel_get_rxbuf(fifo->bch, len);
...@@ -854,7 +855,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -854,7 +855,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
skb_trim(rx_skb, 0); skb_trim(rx_skb, 0);
pr_warning("%s.B%d: No bufferspace for %d bytes\n", pr_warning("%s.B%d: No bufferspace for %d bytes\n",
hw->name, fifo->bch->nr, len); hw->name, fifo->bch->nr, len);
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
maxlen = fifo->bch->maxlen; maxlen = fifo->bch->maxlen;
...@@ -878,7 +879,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -878,7 +879,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
} else { } else {
printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n", printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
hw->name, __func__); hw->name, __func__);
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
} }
...@@ -888,7 +889,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -888,7 +889,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
"for fifo(%d) HFCUSB_D_RX\n", "for fifo(%d) HFCUSB_D_RX\n",
hw->name, __func__, fifon); hw->name, __func__, fifon);
skb_trim(rx_skb, 0); skb_trim(rx_skb, 0);
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
} }
...@@ -942,7 +943,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, ...@@ -942,7 +943,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
/* deliver transparent data to layer2 */ /* deliver transparent data to layer2 */
recv_Bchannel(fifo->bch, MISDN_ID_ANY, false); recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
} }
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
} }
static void static void
...@@ -979,18 +980,19 @@ rx_iso_complete(struct urb *urb) ...@@ -979,18 +980,19 @@ rx_iso_complete(struct urb *urb)
__u8 *buf; __u8 *buf;
static __u8 eof[8]; static __u8 eof[8];
__u8 s0_state; __u8 s0_state;
unsigned long flags;
fifon = fifo->fifonum; fifon = fifo->fifonum;
status = urb->status; status = urb->status;
spin_lock(&hw->lock); spin_lock_irqsave(&hw->lock, flags);
if (fifo->stop_gracefull) { if (fifo->stop_gracefull) {
fifo->stop_gracefull = 0; fifo->stop_gracefull = 0;
fifo->active = 0; fifo->active = 0;
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
/* /*
* ISO transfer only partially completed, * ISO transfer only partially completed,
...@@ -1096,15 +1098,16 @@ rx_int_complete(struct urb *urb) ...@@ -1096,15 +1098,16 @@ rx_int_complete(struct urb *urb)
struct usb_fifo *fifo = (struct usb_fifo *) urb->context; struct usb_fifo *fifo = (struct usb_fifo *) urb->context;
struct hfcsusb *hw = fifo->hw; struct hfcsusb *hw = fifo->hw;
static __u8 eof[8]; static __u8 eof[8];
unsigned long flags;
spin_lock(&hw->lock); spin_lock_irqsave(&hw->lock, flags);
if (fifo->stop_gracefull) { if (fifo->stop_gracefull) {
fifo->stop_gracefull = 0; fifo->stop_gracefull = 0;
fifo->active = 0; fifo->active = 0;
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
fifon = fifo->fifonum; fifon = fifo->fifonum;
if ((!fifo->active) || (urb->status)) { if ((!fifo->active) || (urb->status)) {
...@@ -1172,12 +1175,13 @@ tx_iso_complete(struct urb *urb) ...@@ -1172,12 +1175,13 @@ tx_iso_complete(struct urb *urb)
int *tx_idx; int *tx_idx;
int frame_complete, fifon, status, fillempty = 0; int frame_complete, fifon, status, fillempty = 0;
__u8 threshbit, *p; __u8 threshbit, *p;
unsigned long flags;
spin_lock(&hw->lock); spin_lock_irqsave(&hw->lock, flags);
if (fifo->stop_gracefull) { if (fifo->stop_gracefull) {
fifo->stop_gracefull = 0; fifo->stop_gracefull = 0;
fifo->active = 0; fifo->active = 0;
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
...@@ -1195,7 +1199,7 @@ tx_iso_complete(struct urb *urb) ...@@ -1195,7 +1199,7 @@ tx_iso_complete(struct urb *urb)
} else { } else {
printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n", printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
hw->name, __func__); hw->name, __func__);
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
return; return;
} }
...@@ -1375,7 +1379,7 @@ tx_iso_complete(struct urb *urb) ...@@ -1375,7 +1379,7 @@ tx_iso_complete(struct urb *urb)
hw->name, __func__, hw->name, __func__,
symbolic(urb_errlist, status), status, fifon); symbolic(urb_errlist, status), status, fifon);
} }
spin_unlock(&hw->lock); spin_unlock_irqrestore(&hw->lock, flags);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment