Skip to content

Commit 16630f5

Browse files
Sebastian Andrzej Siewiordavem330
authored andcommitted
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 <[email protected]> Cc: [email protected] Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e112ce4 commit 16630f5

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

drivers/isdn/hardware/mISDN/hfcsusb.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
819819
int fifon = fifo->fifonum;
820820
int i;
821821
int hdlc = 0;
822+
unsigned long flags;
822823

823824
if (debug & DBG_HFC_CALL_TRACE)
824825
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,
835836
return;
836837
}
837838

838-
spin_lock(&hw->lock);
839+
spin_lock_irqsave(&hw->lock, flags);
839840
if (fifo->dch) {
840841
rx_skb = fifo->dch->rx_skb;
841842
maxlen = fifo->dch->maxlen;
@@ -844,7 +845,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
844845
if (fifo->bch) {
845846
if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
846847
fifo->bch->dropcnt += len;
847-
spin_unlock(&hw->lock);
848+
spin_unlock_irqrestore(&hw->lock, flags);
848849
return;
849850
}
850851
maxlen = bchannel_get_rxbuf(fifo->bch, len);
@@ -854,7 +855,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
854855
skb_trim(rx_skb, 0);
855856
pr_warning("%s.B%d: No bufferspace for %d bytes\n",
856857
hw->name, fifo->bch->nr, len);
857-
spin_unlock(&hw->lock);
858+
spin_unlock_irqrestore(&hw->lock, flags);
858859
return;
859860
}
860861
maxlen = fifo->bch->maxlen;
@@ -878,7 +879,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
878879
} else {
879880
printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
880881
hw->name, __func__);
881-
spin_unlock(&hw->lock);
882+
spin_unlock_irqrestore(&hw->lock, flags);
882883
return;
883884
}
884885
}
@@ -888,7 +889,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
888889
"for fifo(%d) HFCUSB_D_RX\n",
889890
hw->name, __func__, fifon);
890891
skb_trim(rx_skb, 0);
891-
spin_unlock(&hw->lock);
892+
spin_unlock_irqrestore(&hw->lock, flags);
892893
return;
893894
}
894895
}
@@ -942,7 +943,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
942943
/* deliver transparent data to layer2 */
943944
recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
944945
}
945-
spin_unlock(&hw->lock);
946+
spin_unlock_irqrestore(&hw->lock, flags);
946947
}
947948

948949
static void
@@ -979,18 +980,19 @@ rx_iso_complete(struct urb *urb)
979980
__u8 *buf;
980981
static __u8 eof[8];
981982
__u8 s0_state;
983+
unsigned long flags;
982984

983985
fifon = fifo->fifonum;
984986
status = urb->status;
985987

986-
spin_lock(&hw->lock);
988+
spin_lock_irqsave(&hw->lock, flags);
987989
if (fifo->stop_gracefull) {
988990
fifo->stop_gracefull = 0;
989991
fifo->active = 0;
990-
spin_unlock(&hw->lock);
992+
spin_unlock_irqrestore(&hw->lock, flags);
991993
return;
992994
}
993-
spin_unlock(&hw->lock);
995+
spin_unlock_irqrestore(&hw->lock, flags);
994996

995997
/*
996998
* ISO transfer only partially completed,
@@ -1096,15 +1098,16 @@ rx_int_complete(struct urb *urb)
10961098
struct usb_fifo *fifo = (struct usb_fifo *) urb->context;
10971099
struct hfcsusb *hw = fifo->hw;
10981100
static __u8 eof[8];
1101+
unsigned long flags;
10991102

1100-
spin_lock(&hw->lock);
1103+
spin_lock_irqsave(&hw->lock, flags);
11011104
if (fifo->stop_gracefull) {
11021105
fifo->stop_gracefull = 0;
11031106
fifo->active = 0;
1104-
spin_unlock(&hw->lock);
1107+
spin_unlock_irqrestore(&hw->lock, flags);
11051108
return;
11061109
}
1107-
spin_unlock(&hw->lock);
1110+
spin_unlock_irqrestore(&hw->lock, flags);
11081111

11091112
fifon = fifo->fifonum;
11101113
if ((!fifo->active) || (urb->status)) {
@@ -1172,12 +1175,13 @@ tx_iso_complete(struct urb *urb)
11721175
int *tx_idx;
11731176
int frame_complete, fifon, status, fillempty = 0;
11741177
__u8 threshbit, *p;
1178+
unsigned long flags;
11751179

1176-
spin_lock(&hw->lock);
1180+
spin_lock_irqsave(&hw->lock, flags);
11771181
if (fifo->stop_gracefull) {
11781182
fifo->stop_gracefull = 0;
11791183
fifo->active = 0;
1180-
spin_unlock(&hw->lock);
1184+
spin_unlock_irqrestore(&hw->lock, flags);
11811185
return;
11821186
}
11831187

@@ -1195,7 +1199,7 @@ tx_iso_complete(struct urb *urb)
11951199
} else {
11961200
printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
11971201
hw->name, __func__);
1198-
spin_unlock(&hw->lock);
1202+
spin_unlock_irqrestore(&hw->lock, flags);
11991203
return;
12001204
}
12011205

@@ -1375,7 +1379,7 @@ tx_iso_complete(struct urb *urb)
13751379
hw->name, __func__,
13761380
symbolic(urb_errlist, status), status, fifon);
13771381
}
1378-
spin_unlock(&hw->lock);
1382+
spin_unlock_irqrestore(&hw->lock, flags);
13791383
}
13801384

13811385
/*

0 commit comments

Comments
 (0)