Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: adutux: 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.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Sebastian Andrzej Siewior and committed by
Greg Kroah-Hartman
957ada71 7375fc9f

+6 -4
+6 -4
drivers/usb/misc/adutux.c
··· 155 155 { 156 156 struct adu_device *dev = urb->context; 157 157 int status = urb->status; 158 + unsigned long flags; 158 159 159 160 adu_debug_data(&dev->udev->dev, __func__, 160 161 urb->actual_length, urb->transfer_buffer); 161 162 162 - spin_lock(&dev->buflock); 163 + spin_lock_irqsave(&dev->buflock, flags); 163 164 164 165 if (status != 0) { 165 166 if ((status != -ENOENT) && (status != -ECONNRESET) && ··· 191 190 192 191 exit: 193 192 dev->read_urb_finished = 1; 194 - spin_unlock(&dev->buflock); 193 + spin_unlock_irqrestore(&dev->buflock, flags); 195 194 /* always wake up so we recover from errors */ 196 195 wake_up_interruptible(&dev->read_wait); 197 196 } ··· 200 199 { 201 200 struct adu_device *dev = urb->context; 202 201 int status = urb->status; 202 + unsigned long flags; 203 203 204 204 adu_debug_data(&dev->udev->dev, __func__, 205 205 urb->actual_length, urb->transfer_buffer); ··· 215 213 return; 216 214 } 217 215 218 - spin_lock(&dev->buflock); 216 + spin_lock_irqsave(&dev->buflock, flags); 219 217 dev->out_urb_finished = 1; 220 218 wake_up(&dev->write_wait); 221 - spin_unlock(&dev->buflock); 219 + spin_unlock_irqrestore(&dev->buflock, flags); 222 220 } 223 221 224 222 static int adu_open(struct inode *inode, struct file *file)