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

Reply via email to