netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* ISDN: use irqsave() in URB completion + usb_fill_int_urb
@ 2018-06-20 10:40 Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 1/4] isdn: gigaset: use usb_fill_int_urb() Sebastian Andrzej Siewior
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2018-06-20 10:40 UTC (permalink / raw)
  To: netdev; +Cc: Karsten Keil, linux-usb, tglx

This series is mostly about using _irqsave() primitives in the
completion callback in order to get rid of local_irq_save() in
__usb_hcd_giveback_urb(). While at it, I also tried to move drivers to
use usb_fill_int_urb() otherwise it is hard find users of a certain API.

Sebastian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] isdn: gigaset: use usb_fill_int_urb()
  2018-06-20 10:40 ISDN: use irqsave() in URB completion + usb_fill_int_urb Sebastian Andrzej Siewior
@ 2018-06-20 10:40 ` Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 2/4] isdn: hisax: hfc_usb: " Sebastian Andrzej Siewior
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2018-06-20 10:40 UTC (permalink / raw)
  To: netdev
  Cc: Karsten Keil, linux-usb, tglx, Sebastian Andrzej Siewior,
	Paul Bolle, gigaset307x-common

Using usb_fill_int_urb() helps to find code which initializes an
URB. A grep for members of the struct (like ->complete) reveal lots
of other things, too.

Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: gigaset307x-common@lists.sourceforge.net
Cc: netdev@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/isdn/gigaset/bas-gigaset.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 20d0a080a2b0..40c141163f0f 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -972,16 +972,14 @@ static int starturbs(struct bc_state *bcs)
 			rc = -EFAULT;
 			goto error;
 		}
+		usb_fill_int_urb(urb, bcs->cs->hw.bas->udev,
+				 usb_rcvisocpipe(urb->dev, 3 + 2 * bcs->channel),
+				 ubc->isoinbuf + k * BAS_INBUFSIZE,
+				 BAS_INBUFSIZE, read_iso_callback, bcs,
+				 BAS_FRAMETIME);
 
-		urb->dev = bcs->cs->hw.bas->udev;
-		urb->pipe = usb_rcvisocpipe(urb->dev, 3 + 2 * bcs->channel);
 		urb->transfer_flags = URB_ISO_ASAP;
-		urb->transfer_buffer = ubc->isoinbuf + k * BAS_INBUFSIZE;
-		urb->transfer_buffer_length = BAS_INBUFSIZE;
 		urb->number_of_packets = BAS_NUMFRAMES;
-		urb->interval = BAS_FRAMETIME;
-		urb->complete = read_iso_callback;
-		urb->context = bcs;
 		for (j = 0; j < BAS_NUMFRAMES; j++) {
 			urb->iso_frame_desc[j].offset = j * BAS_MAXFRAME;
 			urb->iso_frame_desc[j].length = BAS_MAXFRAME;
@@ -1005,15 +1003,15 @@ static int starturbs(struct bc_state *bcs)
 			rc = -EFAULT;
 			goto error;
 		}
-		urb->dev = bcs->cs->hw.bas->udev;
-		urb->pipe = usb_sndisocpipe(urb->dev, 4 + 2 * bcs->channel);
+		usb_fill_int_urb(urb, bcs->cs->hw.bas->udev,
+				 usb_sndisocpipe(urb->dev, 4 + 2 * bcs->channel),
+				 ubc->isooutbuf->data,
+				 sizeof(ubc->isooutbuf->data),
+				 write_iso_callback, &ubc->isoouturbs[k],
+				 BAS_FRAMETIME);
+
 		urb->transfer_flags = URB_ISO_ASAP;
-		urb->transfer_buffer = ubc->isooutbuf->data;
-		urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data);
 		urb->number_of_packets = BAS_NUMFRAMES;
-		urb->interval = BAS_FRAMETIME;
-		urb->complete = write_iso_callback;
-		urb->context = &ubc->isoouturbs[k];
 		for (j = 0; j < BAS_NUMFRAMES; ++j) {
 			urb->iso_frame_desc[j].offset = BAS_OUTBUFSIZE;
 			urb->iso_frame_desc[j].length = BAS_NORMFRAME;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] isdn: hisax: hfc_usb: use usb_fill_int_urb()
  2018-06-20 10:40 ISDN: use irqsave() in URB completion + usb_fill_int_urb Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 1/4] isdn: gigaset: use usb_fill_int_urb() Sebastian Andrzej Siewior
@ 2018-06-20 10:40 ` Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 3/4] isdn: hisax: st5481_usb: " Sebastian Andrzej Siewior
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2018-06-20 10:40 UTC (permalink / raw)
  To: netdev; +Cc: Karsten Keil, linux-usb, tglx, Sebastian Andrzej Siewior

Using usb_fill_int_urb() helps to find code which initializes an
URB. A grep for members of the struct (like ->complete) reveal lots
of other things, too.

The `interval' parameter is now set differently on HS and SS. The
argument is fed from bInterval so it should be the right thing to do.

Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: netdev@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/isdn/hisax/hfc_usb.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 97ecb3073045..1d4cd01d4685 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -432,16 +432,12 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
 {
 	int k;
 
-	urb->dev = dev;
-	urb->pipe = pipe;
-	urb->complete = complete;
+	usb_fill_int_urb(urb, dev, pipe, buf, packet_size * num_packets,
+			 complete, context, interval);
+
 	urb->number_of_packets = num_packets;
-	urb->transfer_buffer_length = packet_size * num_packets;
-	urb->context = context;
-	urb->transfer_buffer = buf;
 	urb->transfer_flags = URB_ISO_ASAP;
 	urb->actual_length = 0;
-	urb->interval = interval;
 	for (k = 0; k < num_packets; k++) {
 		urb->iso_frame_desc[k].offset = packet_size * k;
 		urb->iso_frame_desc[k].length = packet_size;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] isdn: hisax: st5481_usb: use usb_fill_int_urb()
  2018-06-20 10:40 ISDN: use irqsave() in URB completion + usb_fill_int_urb Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 1/4] isdn: gigaset: use usb_fill_int_urb() Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 2/4] isdn: hisax: hfc_usb: " Sebastian Andrzej Siewior
@ 2018-06-20 10:40 ` Sebastian Andrzej Siewior
  2018-06-20 10:40 ` [PATCH 4/4] isdn: mISDN: use irqsave() in USB's complete callback Sebastian Andrzej Siewior
  2018-06-22  4:54 ` ISDN: use irqsave() in URB completion + usb_fill_int_urb David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2018-06-20 10:40 UTC (permalink / raw)
  To: netdev; +Cc: Karsten Keil, linux-usb, tglx, Sebastian Andrzej Siewior

Using usb_fill_int_urb() helps to find code which initializes an
URB. A grep for members of the struct (like ->complete) reveal lots
of other things, too.

Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: netdev@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/isdn/hisax/st5481_usb.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 1cb9930d5e24..f207fda691c7 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -408,15 +408,10 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev,
 {
 	int k;
 
-	urb->dev = dev;
-	urb->pipe = pipe;
-	urb->interval = 1;
-	urb->transfer_buffer = buf;
+	usb_fill_int_urb(urb, dev, pipe, buf, num_packets * packet_size,
+			 complete, context, 1);
+
 	urb->number_of_packets = num_packets;
-	urb->transfer_buffer_length = num_packets * packet_size;
-	urb->actual_length = 0;
-	urb->complete = complete;
-	urb->context = context;
 	urb->transfer_flags = URB_ISO_ASAP;
 	for (k = 0; k < num_packets; k++) {
 		urb->iso_frame_desc[k].offset = packet_size * k;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] isdn: mISDN: use irqsave() in USB's complete callback
  2018-06-20 10:40 ISDN: use irqsave() in URB completion + usb_fill_int_urb Sebastian Andrzej Siewior
                   ` (2 preceding siblings ...)
  2018-06-20 10:40 ` [PATCH 3/4] isdn: hisax: st5481_usb: " Sebastian Andrzej Siewior
@ 2018-06-20 10:40 ` Sebastian Andrzej Siewior
  2018-06-22  4:54 ` ISDN: use irqsave() in URB completion + usb_fill_int_urb David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2018-06-20 10:40 UTC (permalink / raw)
  To: netdev; +Cc: Karsten Keil, linux-usb, tglx, Sebastian Andrzej Siewior

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: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/isdn/hardware/mISDN/hfcsusb.c | 36 +++++++++++++++------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 17cc879ad2bb..6d05946b445e 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -819,6 +819,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 	int		fifon = fifo->fifonum;
 	int		i;
 	int		hdlc = 0;
+	unsigned long	flags;
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		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,
 		return;
 	}
 
-	spin_lock(&hw->lock);
+	spin_lock_irqsave(&hw->lock, flags);
 	if (fifo->dch) {
 		rx_skb = fifo->dch->rx_skb;
 		maxlen = fifo->dch->maxlen;
@@ -844,7 +845,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 	if (fifo->bch) {
 		if (test_bit(FLG_RX_OFF, &fifo->bch->Flags)) {
 			fifo->bch->dropcnt += len;
-			spin_unlock(&hw->lock);
+			spin_unlock_irqrestore(&hw->lock, flags);
 			return;
 		}
 		maxlen = bchannel_get_rxbuf(fifo->bch, len);
@@ -854,7 +855,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 				skb_trim(rx_skb, 0);
 			pr_warning("%s.B%d: No bufferspace for %d bytes\n",
 				   hw->name, fifo->bch->nr, len);
-			spin_unlock(&hw->lock);
+			spin_unlock_irqrestore(&hw->lock, flags);
 			return;
 		}
 		maxlen = fifo->bch->maxlen;
@@ -878,7 +879,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 			} else {
 				printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
 				       hw->name, __func__);
-				spin_unlock(&hw->lock);
+				spin_unlock_irqrestore(&hw->lock, flags);
 				return;
 			}
 		}
@@ -888,7 +889,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 			       "for fifo(%d) HFCUSB_D_RX\n",
 			       hw->name, __func__, fifon);
 			skb_trim(rx_skb, 0);
-			spin_unlock(&hw->lock);
+			spin_unlock_irqrestore(&hw->lock, flags);
 			return;
 		}
 	}
@@ -942,7 +943,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 		/* deliver transparent data to layer2 */
 		recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
 	}
-	spin_unlock(&hw->lock);
+	spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 static void
@@ -979,18 +980,19 @@ rx_iso_complete(struct urb *urb)
 	__u8 *buf;
 	static __u8 eof[8];
 	__u8 s0_state;
+	unsigned long flags;
 
 	fifon = fifo->fifonum;
 	status = urb->status;
 
-	spin_lock(&hw->lock);
+	spin_lock_irqsave(&hw->lock, flags);
 	if (fifo->stop_gracefull) {
 		fifo->stop_gracefull = 0;
 		fifo->active = 0;
-		spin_unlock(&hw->lock);
+		spin_unlock_irqrestore(&hw->lock, flags);
 		return;
 	}
-	spin_unlock(&hw->lock);
+	spin_unlock_irqrestore(&hw->lock, flags);
 
 	/*
 	 * ISO transfer only partially completed,
@@ -1096,15 +1098,16 @@ rx_int_complete(struct urb *urb)
 	struct usb_fifo *fifo = (struct usb_fifo *) urb->context;
 	struct hfcsusb *hw = fifo->hw;
 	static __u8 eof[8];
+	unsigned long flags;
 
-	spin_lock(&hw->lock);
+	spin_lock_irqsave(&hw->lock, flags);
 	if (fifo->stop_gracefull) {
 		fifo->stop_gracefull = 0;
 		fifo->active = 0;
-		spin_unlock(&hw->lock);
+		spin_unlock_irqrestore(&hw->lock, flags);
 		return;
 	}
-	spin_unlock(&hw->lock);
+	spin_unlock_irqrestore(&hw->lock, flags);
 
 	fifon = fifo->fifonum;
 	if ((!fifo->active) || (urb->status)) {
@@ -1172,12 +1175,13 @@ tx_iso_complete(struct urb *urb)
 	int *tx_idx;
 	int frame_complete, fifon, status, fillempty = 0;
 	__u8 threshbit, *p;
+	unsigned long flags;
 
-	spin_lock(&hw->lock);
+	spin_lock_irqsave(&hw->lock, flags);
 	if (fifo->stop_gracefull) {
 		fifo->stop_gracefull = 0;
 		fifo->active = 0;
-		spin_unlock(&hw->lock);
+		spin_unlock_irqrestore(&hw->lock, flags);
 		return;
 	}
 
@@ -1195,7 +1199,7 @@ tx_iso_complete(struct urb *urb)
 	} else {
 		printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
 		       hw->name, __func__);
-		spin_unlock(&hw->lock);
+		spin_unlock_irqrestore(&hw->lock, flags);
 		return;
 	}
 
@@ -1375,7 +1379,7 @@ tx_iso_complete(struct urb *urb)
 			       hw->name, __func__,
 			       symbolic(urb_errlist, status), status, fifon);
 	}
-	spin_unlock(&hw->lock);
+	spin_unlock_irqrestore(&hw->lock, flags);
 }
 
 /*
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: ISDN: use irqsave() in URB completion + usb_fill_int_urb
  2018-06-20 10:40 ISDN: use irqsave() in URB completion + usb_fill_int_urb Sebastian Andrzej Siewior
                   ` (3 preceding siblings ...)
  2018-06-20 10:40 ` [PATCH 4/4] isdn: mISDN: use irqsave() in USB's complete callback Sebastian Andrzej Siewior
@ 2018-06-22  4:54 ` David Miller
  4 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2018-06-22  4:54 UTC (permalink / raw)
  To: bigeasy; +Cc: netdev, isdn, linux-usb, tglx

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Wed, 20 Jun 2018 12:40:24 +0200

> This series is mostly about using _irqsave() primitives in the
> completion callback in order to get rid of local_irq_save() in
> __usb_hcd_giveback_urb(). While at it, I also tried to move drivers to
> use usb_fill_int_urb() otherwise it is hard find users of a certain API.

Series applied, thanks Sebastian.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-06-22  4:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-20 10:40 ISDN: use irqsave() in URB completion + usb_fill_int_urb Sebastian Andrzej Siewior
2018-06-20 10:40 ` [PATCH 1/4] isdn: gigaset: use usb_fill_int_urb() Sebastian Andrzej Siewior
2018-06-20 10:40 ` [PATCH 2/4] isdn: hisax: hfc_usb: " Sebastian Andrzej Siewior
2018-06-20 10:40 ` [PATCH 3/4] isdn: hisax: st5481_usb: " Sebastian Andrzej Siewior
2018-06-20 10:40 ` [PATCH 4/4] isdn: mISDN: use irqsave() in USB's complete callback Sebastian Andrzej Siewior
2018-06-22  4:54 ` ISDN: use irqsave() in URB completion + usb_fill_int_urb David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).