diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-03 10:18:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-03 10:18:21 -0700 |
commit | 4f9faaace217b854ae1e1746ee4ac44688ddadbd (patch) | |
tree | 34122d9e84349a394988d6bfc480115e4809776a /drivers/bluetooth | |
parent | bf640be423d60d954b9673527e106a461a129eb8 (diff) | |
parent | f37f2c62a28e848e06399ea2f9be1e098212625c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (47 commits)
rose: Wrong list_lock argument in rose_node seqops
netns: Fix reassembly timer to use the right namespace
netns: Fix device renaming for sysfs
bnx2: Update version to 1.7.5.
bnx2: Update RV2P firmware for 5709.
bnx2: Zero out context memory for 5709.
bnx2: Fix register test on 5709.
bnx2: Fix remote PHY initial link state.
bnx2: Refine remote PHY locking.
bridge: forwarding table information for >256 devices
tg3: Update version to 3.92
tg3: Add link state reporting to UMP firmware
tg3: Fix ethtool loopback test for 5761 BX devices
tg3: Fix 5761 NVRAM sizes
tg3: Use constant 500KHz MI clock on adapters with a CPMU
hci_usb.h: fix hard-to-trigger race
dccp: ccid2.c, ccid3.c use clamp(), clamp_t()
net: remove NR_CPUS arrays in net/core/dev.c
net: use get/put_unaligned_* helpers
bluetooth: use get/put_unaligned_* helpers
...
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/hci_usb.h | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h index 414080a4e8ff..1790cc8e431e 100644 --- a/drivers/bluetooth/hci_usb.h +++ b/drivers/bluetooth/hci_usb.h @@ -70,7 +70,8 @@ static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb) { unsigned long flags; spin_lock_irqsave(&q->lock, flags); - list_add(&_urb->list, &q->head); _urb->queue = q; + /* _urb_unlink needs to know which spinlock to use, thus mb(). */ + _urb->queue = q; mb(); list_add(&_urb->list, &q->head); spin_unlock_irqrestore(&q->lock, flags); } @@ -78,19 +79,23 @@ static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb) { unsigned long flags; spin_lock_irqsave(&q->lock, flags); - list_add_tail(&_urb->list, &q->head); _urb->queue = q; + /* _urb_unlink needs to know which spinlock to use, thus mb(). */ + _urb->queue = q; mb(); list_add_tail(&_urb->list, &q->head); spin_unlock_irqrestore(&q->lock, flags); } static inline void _urb_unlink(struct _urb *_urb) { - struct _urb_queue *q = _urb->queue; + struct _urb_queue *q; unsigned long flags; - if (q) { - spin_lock_irqsave(&q->lock, flags); - list_del(&_urb->list); _urb->queue = NULL; - spin_unlock_irqrestore(&q->lock, flags); - } + + mb(); + q = _urb->queue; + /* If q is NULL, it will die at easy-to-debug NULL pointer dereference. + No need to BUG(). */ + spin_lock_irqsave(&q->lock, flags); + list_del(&_urb->list); _urb->queue = NULL; + spin_unlock_irqrestore(&q->lock, flags); } struct hci_usb { |