Commit a68077de authored by Ulrich Kunitz's avatar Ulrich Kunitz Committed by John W. Linville

[PATCH] zd1211rw: Fix of a locking bug

This patch fixes the bug as reported in the kernel bug tracker
under the id 7244. The bug was simply that the interrupt lock has
been locked outside an interrupt without blocking the interrupt.
Signed-off-by: default avatarUlrich Kunitz <kune@deine-taler.de>
Signed-off-by: default avatarDaniel Drake <dsd@gentoo.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a3df3b6f
...@@ -366,15 +366,6 @@ static int upload_firmware(struct usb_device *udev, u8 device_type) ...@@ -366,15 +366,6 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
return r; return r;
} }
static void disable_read_regs_int(struct zd_usb *usb)
{
struct zd_usb_interrupt *intr = &usb->intr;
spin_lock(&intr->lock);
intr->read_regs_enabled = 0;
spin_unlock(&intr->lock);
}
#define urb_dev(urb) (&(urb)->dev->dev) #define urb_dev(urb) (&(urb)->dev->dev)
static inline void handle_regs_int(struct urb *urb) static inline void handle_regs_int(struct urb *urb)
...@@ -1156,10 +1147,19 @@ static void prepare_read_regs_int(struct zd_usb *usb) ...@@ -1156,10 +1147,19 @@ static void prepare_read_regs_int(struct zd_usb *usb)
{ {
struct zd_usb_interrupt *intr = &usb->intr; struct zd_usb_interrupt *intr = &usb->intr;
spin_lock(&intr->lock); spin_lock_irq(&intr->lock);
intr->read_regs_enabled = 1; intr->read_regs_enabled = 1;
INIT_COMPLETION(intr->read_regs.completion); INIT_COMPLETION(intr->read_regs.completion);
spin_unlock(&intr->lock); spin_unlock_irq(&intr->lock);
}
static void disable_read_regs_int(struct zd_usb *usb)
{
struct zd_usb_interrupt *intr = &usb->intr;
spin_lock_irq(&intr->lock);
intr->read_regs_enabled = 0;
spin_unlock_irq(&intr->lock);
} }
static int get_results(struct zd_usb *usb, u16 *values, static int get_results(struct zd_usb *usb, u16 *values,
...@@ -1171,7 +1171,7 @@ static int get_results(struct zd_usb *usb, u16 *values, ...@@ -1171,7 +1171,7 @@ static int get_results(struct zd_usb *usb, u16 *values,
struct read_regs_int *rr = &intr->read_regs; struct read_regs_int *rr = &intr->read_regs;
struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer;
spin_lock(&intr->lock); spin_lock_irq(&intr->lock);
r = -EIO; r = -EIO;
/* The created block size seems to be larger than expected. /* The created block size seems to be larger than expected.
...@@ -1204,7 +1204,7 @@ static int get_results(struct zd_usb *usb, u16 *values, ...@@ -1204,7 +1204,7 @@ static int get_results(struct zd_usb *usb, u16 *values,
r = 0; r = 0;
error_unlock: error_unlock:
spin_unlock(&intr->lock); spin_unlock_irq(&intr->lock);
return r; return r;
} }
......
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