Hi John,
please apply to wireless-dev.
--
Port of the "opencoded locking" patch from bcm43xx-softmac
to bcm43xx-d80211.
Signed-off-by: Michael Buesch <[EMAIL PROTECTED]>
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
2006-07-09 01:56:07.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
2006-07-09 02:31:45.000000000 +0200
@@ -660,6 +660,19 @@
#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat))
+/* *** THEORY OF LOCKING ***
+ *
+ * We have two different locks in the bcm43xx driver.
+ * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
+ * and the device registers. This mutex does _not_ protect
+ * against concurrency from the IRQ handler.
+ * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
+ *
+ * Please note that, if you only take the irq_lock, you are not protected
+ * against concurrency from the periodic work handlers.
+ * Most times you want to take _both_ locks.
+ */
+
struct bcm43xx_private {
struct ieee80211_hw *ieee;
struct ieee80211_low_level_stats ieee_stats;
@@ -670,7 +683,6 @@
void __iomem *mmio_addr;
- /* Locking, see "theory of locking" text below. */
spinlock_t irq_lock;
struct mutex mutex;
@@ -710,6 +722,7 @@
struct bcm43xx_sprominfo sprom;
#define BCM43xx_NR_LEDS 4
struct bcm43xx_led leds[BCM43xx_NR_LEDS];
+ spinlock_t leds_lock;
/* The currently active core. */
struct bcm43xx_coreinfo *current_core;
@@ -779,55 +792,6 @@
};
-/* *** THEORY OF LOCKING ***
- *
- * We have two different locks in the bcm43xx driver.
- * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
- * and the device registers.
- * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
- *
- * We have three types of helper function pairs to utilize these locks.
- * (Always use the helper functions.)
- * 1) bcm43xx_{un}lock_noirq():
- * Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
- * so it is almost always unsafe, if device IRQs are enabled.
- * So only use this, if device IRQs are masked.
- * Locking may sleep.
- * You can sleep within the critical section.
- * 2) bcm43xx_{un}lock_irqonly():
- * Takes bcm->irq_lock. Does _not_ protect against
- * bcm43xx_lock_noirq() critical sections.
- * Does only protect against the IRQ handler path and other
- * irqonly() critical sections.
- * Locking does not sleep.
- * You must not sleep within the critical section.
- * 3) bcm43xx_{un}lock_irqsafe():
- * This is the cummulative lock and takes both, mutex and irq_lock.
- * Protects against noirq() and irqonly() critical sections (and
- * the IRQ handler path).
- * Locking may sleep.
- * You must not sleep within the critical section.
- */
-
-/* Lock type 1 */
-#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex)
-#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex)
-/* Lock type 2 */
-#define bcm43xx_lock_irqonly(bcm, flags) \
- spin_lock_irqsave(&(bcm)->irq_lock, flags)
-#define bcm43xx_unlock_irqonly(bcm, flags) \
- spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
-/* Lock type 3 */
-#define bcm43xx_lock_irqsafe(bcm, flags) do { \
- bcm43xx_lock_noirq(bcm); \
- bcm43xx_lock_irqonly(bcm, flags); \
- } while (0)
-#define bcm43xx_unlock_irqsafe(bcm, flags) do { \
- bcm43xx_unlock_irqonly(bcm, flags); \
- bcm43xx_unlock_noirq(bcm); \
- } while (0)
-
-
static inline
struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
{
Index:
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c
===================================================================
---
wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c
2006-06-17 21:26:10.000000000 +0200
+++
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_debugfs.c
2006-07-09 02:31:45.000000000 +0200
@@ -77,7 +77,8 @@
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
@@ -121,7 +122,8 @@
fappend("\n");
out:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
@@ -159,7 +161,8 @@
unsigned long flags;
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
@@ -169,7 +172,8 @@
fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
out:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
@@ -188,7 +192,8 @@
u64 tsf;
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
@@ -199,7 +204,8 @@
(unsigned int)(tsf & 0xFFFFFFFFULL));
out:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
@@ -221,7 +227,8 @@
res = -EFAULT;
goto out_up;
}
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
res = -EFAULT;
@@ -237,7 +244,8 @@
res = buf_size;
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
out_up:
up(&big_buffer_sem);
return res;
@@ -258,7 +266,8 @@
int i, cnt, j = 0;
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -294,14 +303,15 @@
i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
- bcm43xx_lock_irqsafe(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (*ppos == pos) {
/* Done. Drop the copied data. */
e->xmitstatus_printing = 0;
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
up(&big_buffer_sem);
return res;
}
Index:
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
===================================================================
---
wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
2006-06-17 21:26:10.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
2006-07-09 02:31:45.000000000 +0200
@@ -51,12 +51,12 @@
struct bcm43xx_private *bcm = led->bcm;
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->leds_lock, flags);
if (led->blink_interval) {
bcm43xx_led_changestate(led);
mod_timer(&led->blink_timer, jiffies + led->blink_interval);
}
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
@@ -177,7 +177,9 @@
int i, turn_on;
unsigned long interval = 0;
u16 ledctl;
+ unsigned long flags;
+ spin_lock_irqsave(&bcm->leds_lock, flags);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
@@ -266,6 +268,7 @@
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
+ spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
@@ -274,7 +277,9 @@
u16 ledctl;
int i;
int bit_on;
+ unsigned long flags;
+ spin_lock_irqsave(&bcm->leds_lock, flags);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
@@ -290,4 +295,5 @@
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
+ spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
Index:
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
===================================================================
---
wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
2006-07-09 02:08:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
2006-07-09 02:50:15.000000000 +0200
@@ -386,7 +386,7 @@
* Time is measured in microseconds.
*/
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
radio = bcm43xx_current_radio(bcm);
oldchan = radio->channel;
testchan = (oldchan == 6) ? 7 : 6;
@@ -394,7 +394,7 @@
bcm43xx_radio_selectchannel(bcm, testchan, 0);
bcm43xx_tsf_read(bcm, &stop);
bcm43xx_radio_selectchannel(bcm, oldchan, 0);
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
assert(stop > start);
bcm->ieee->channel_change_time = stop - start;
@@ -521,13 +521,13 @@
unsigned long flags;
u32 old;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return -EBUSY;
}
old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
bcm43xx_synchronize_irq(bcm);
if (oldstate)
@@ -1843,7 +1843,7 @@
# define bcmirq_handled(irq) do { /* nothing */ } while (0)
#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
reason = bcm->irq_reason;
dma_reason[0] = bcm->dma_reason[0];
dma_reason[1] = bcm->dma_reason[1];
@@ -1869,7 +1869,7 @@
dma_reason[2], dma_reason[3]);
bcm43xx_controller_restart(bcm, "DMA error");
mmiowb();
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return;
}
if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
@@ -1957,7 +1957,7 @@
bcm43xx_leds_update(bcm, activity);
bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
mmiowb();
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
}
static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -3264,25 +3264,26 @@
*/
netif_stop_queue(bcm->net_dev);
synchronize_net();
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm43xx_mac_suspend(bcm);
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_freeze_txqueues(bcm);
savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_unlock_irqonly(bcm, flags);
- bcm43xx_lock_noirq(bcm);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_lock(&bcm->mutex);
bcm43xx_synchronize_irq(bcm);
} else {
/* Periodic work should take short time, so we want low
* locking overhead.
*/
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
}
do_periodic_work(bcm);
if (badness > BADNESS_LIMIT) {
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
tasklet_enable(&bcm->isr_tasklet);
bcm43xx_interrupt_enable(bcm, savedirqs);
@@ -3291,13 +3292,10 @@
bcm43xx_mac_enable(bcm);
}
netif_wake_queue(bcm->net_dev);
- mmiowb();
- bcm43xx_unlock_irqonly(bcm, flags);
- bcm43xx_unlock_noirq(bcm);
- } else {
- mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
}
+ mmiowb();
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
}
static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
@@ -3962,7 +3960,7 @@
{
int i, err;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
bcm43xx_sysfs_unregister(bcm);
bcm43xx_periodic_tasks_delete(bcm);
@@ -3983,7 +3981,7 @@
bcm43xx_free_modes(bcm);
bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&bcm->mutex);
}
static int bcm43xx_init_board(struct bcm43xx_private *bcm)
@@ -3993,7 +3991,7 @@
might_sleep();
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
err = bcm43xx_pctl_set_crystal(bcm, 1);
@@ -4073,7 +4071,7 @@
assert(err == 0);
out:
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&bcm->mutex);
return err;
@@ -4299,14 +4297,14 @@
int err = -ENODEV;
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
if (bcm43xx_using_pio(bcm))
err = bcm43xx_pio_tx(bcm, skb, ctl);
else
err = bcm43xx_dma_tx(bcm, skb, ctl);
}
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return err;
}
@@ -4316,9 +4314,9 @@
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm43xx_controller_restart(bcm, "IEEE reset");
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return 0;
}
@@ -4331,11 +4329,9 @@
struct bcm43xx_phyinfo *phy;
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
- bcm43xx_unlock_irqonly(bcm, flags);
- return 0;
- }
+ spin_lock_irqsave(&bcm->irq_lock, flags);
+ if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
+ goto out_unlock;
radio = bcm43xx_current_radio(bcm);
phy = bcm43xx_current_phy(bcm);
@@ -4384,7 +4380,8 @@
bcm43xx_refresh_templates(bcm);
}
- bcm43xx_unlock_irqonly(bcm, flags);
+out_unlock:
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return 0;
}
@@ -4424,7 +4421,9 @@
index = (u8)(key->keyidx);
if (index >= ARRAY_SIZE(bcm->key))
goto out;
- bcm43xx_lock_irqsafe(bcm, flags);
+
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
switch (cmd) {
case SET_KEY:
err = bcm43xx_key_write(bcm, index, algorithm,
@@ -4452,7 +4451,8 @@
break;
}
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
out:
return err;
}
@@ -4471,7 +4471,7 @@
unsigned long flags;
int err = -ENODEV;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_get_tx_stats(bcm, stats);
@@ -4479,7 +4479,7 @@
bcm43xx_dma_get_tx_stats(bcm, stats);
err = 0;
}
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return err;
}
@@ -4490,9 +4490,9 @@
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- bcm43xx_lock_irqsafe(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
memcpy(stats, &bcm->ieee_stats, sizeof(*stats));
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return 0;
}
@@ -4537,7 +4537,8 @@
unsigned long flags;
int err = -EOPNOTSUPP;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (conf->type == IEEE80211_IF_TYPE_MNTR) {
bcm->interface.monitor++;
@@ -4563,7 +4564,8 @@
BCM43xx_MACARG(conf->mac_addr));
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -4574,7 +4576,8 @@
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (conf->type == IEEE80211_IF_TYPE_MNTR) {
bcm->interface.monitor--;
assert(bcm->interface.monitor >= 0);
@@ -4582,7 +4585,8 @@
bcm->interface.operating = 0;
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
bcm43xx_select_opmode(bcm);
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
dprintk(KERN_INFO PFX "Virtual interface removed "
"(type: 0x%08X, ID: %d, MAC: "
@@ -4598,7 +4602,8 @@
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (conf->type != IEEE80211_IF_TYPE_MNTR) {
assert(bcm->interface.if_id == if_id);
bcm->interface.bssid = conf->bssid;
@@ -4608,7 +4613,8 @@
bcm43xx_refresh_templates(bcm);
}
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -4620,13 +4626,13 @@
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm->interface.promisc != !!(netflags & IFF_PROMISC)) {
bcm->interface.promisc = !!(netflags & IFF_PROMISC);
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
bcm43xx_select_opmode(bcm);
}
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
}
/* Initialization of struct net_device, just after allocation. */
@@ -4652,6 +4658,7 @@
bcm->net_dev = net_dev;
bcm->bad_frames_preempt = modparam_bad_frames_preempt;
spin_lock_init(&bcm->irq_lock);
+ spin_lock_init(&bcm->leds_lock);
mutex_init(&bcm->mutex);
tasklet_init(&bcm->isr_tasklet,
(void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -4838,16 +4845,13 @@
{
struct net_device *net_dev = pci_get_drvdata(pdev);
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
int try_to_shutdown = 0, err;
dprintk(KERN_INFO PFX "Suspending...\n");
- bcm43xx_lock_irqsafe(bcm, flags);
bcm->was_initialized = (bcm43xx_status(bcm) ==
BCM43xx_STAT_INITIALIZED);
if (bcm->was_initialized)
try_to_shutdown = 1;
- bcm43xx_unlock_irqsafe(bcm, flags);
ieee80211_netif_oper(bcm->net_dev, NETIF_DETACH);
if (try_to_shutdown) {
Index:
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_pio.c
===================================================================
---
wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_pio.c
2006-06-17 21:26:10.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_pio.c
2006-07-09 02:33:14.000000000 +0200
@@ -263,7 +263,7 @@
int err;
u16 txctl;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (queue->tx_frozen)
goto out_unlock;
txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
@@ -283,7 +283,7 @@
break;
}
out_unlock:
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
}
static void setup_txqueues(struct bcm43xx_pioqueue *queue)
Index:
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_sysfs.c
===================================================================
---
wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_sysfs.c
2006-06-17 21:26:10.000000000 +0200
+++
wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_sysfs.c
2006-07-09 02:31:45.000000000 +0200
@@ -120,12 +120,14 @@
GFP_KERNEL);
if (!sprom)
return -ENOMEM;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
err = bcm43xx_sprom_read(bcm, sprom);
if (!err)
err = sprom2hex(sprom, buf, PAGE_SIZE);
mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
kfree(sprom);
return err;
@@ -150,10 +152,14 @@
err = hex2sprom(sprom, buf, count);
if (err)
goto out_kfree;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
+ spin_lock(&bcm->leds_lock);
err = bcm43xx_sprom_write(bcm, sprom);
mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock(&bcm->leds_lock);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
out_kfree:
kfree(sprom);
@@ -176,7 +182,7 @@
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
switch (bcm43xx_current_radio(bcm)->interfmode) {
case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -193,7 +199,7 @@
}
err = 0;
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&bcm->mutex);
return err ? err : count;
@@ -229,7 +235,8 @@
return -EINVAL;
}
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
if (err) {
@@ -237,7 +244,8 @@
"supported by device\n");
}
mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err ? err : count;
}
@@ -257,7 +265,7 @@
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
if (bcm->short_preamble)
count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble
enabled)\n");
@@ -265,7 +273,7 @@
count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble
disabled)\n");
err = 0;
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&bcm->mutex);
return err ? err : count;
}
@@ -285,12 +293,14 @@
value = get_boolean(buf, count);
if (value < 0)
return value;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm->short_preamble = !!value;
err = 0;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err ? err : count;
}
--
Greetings Michael.
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html