diff options
author | Michael Buesch <mb@bu3sch.de> | 2006-06-05 14:24:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-06-15 15:48:13 -0400 |
commit | 78ff56a06edc3407996173daf63e48f6b90c7062 (patch) | |
tree | 93ddfccd648ee84faeb95bcf8f5183ac91d873f7 /drivers/net/wireless/bcm43xx/bcm43xx_main.c | |
parent | 74f4903363579d3336c294ebb11f02c8f35845ca (diff) |
[PATCH] bcm43xx: redesign locking
Redesign the bcm43xx locking.
This is pre-work to get a preemptible periodic work handler.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/bcm43xx/bcm43xx_main.c')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 113 |
1 files changed, 54 insertions, 59 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 736dde96c4a3..835a2df1fe30 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -504,14 +504,14 @@ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *old | |||
504 | u32 old; | 504 | u32 old; |
505 | unsigned long flags; | 505 | unsigned long flags; |
506 | 506 | ||
507 | bcm43xx_lock_mmio(bcm, flags); | 507 | bcm43xx_lock_irqonly(bcm, flags); |
508 | if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { | 508 | if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { |
509 | bcm43xx_unlock_mmio(bcm, flags); | 509 | bcm43xx_unlock_irqonly(bcm, flags); |
510 | return -EBUSY; | 510 | return -EBUSY; |
511 | } | 511 | } |
512 | old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 512 | old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
513 | tasklet_disable(&bcm->isr_tasklet); | 513 | tasklet_disable(&bcm->isr_tasklet); |
514 | bcm43xx_unlock_mmio(bcm, flags); | 514 | bcm43xx_unlock_irqonly(bcm, flags); |
515 | if (oldstate) | 515 | if (oldstate) |
516 | *oldstate = old; | 516 | *oldstate = old; |
517 | 517 | ||
@@ -1389,7 +1389,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy) | |||
1389 | bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); | 1389 | bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); |
1390 | #endif | 1390 | #endif |
1391 | } | 1391 | } |
1392 | if (bcm->shutting_down) { | 1392 | if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { |
1393 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, | 1393 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, |
1394 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) | 1394 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) |
1395 | & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); | 1395 | & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); |
@@ -1709,7 +1709,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1709 | # define bcmirq_handled(irq) do { /* nothing */ } while (0) | 1709 | # define bcmirq_handled(irq) do { /* nothing */ } while (0) |
1710 | #endif /* CONFIG_BCM43XX_DEBUG*/ | 1710 | #endif /* CONFIG_BCM43XX_DEBUG*/ |
1711 | 1711 | ||
1712 | bcm43xx_lock_mmio(bcm, flags); | 1712 | bcm43xx_lock_irqonly(bcm, flags); |
1713 | reason = bcm->irq_reason; | 1713 | reason = bcm->irq_reason; |
1714 | dma_reason[0] = bcm->dma_reason[0]; | 1714 | dma_reason[0] = bcm->dma_reason[0]; |
1715 | dma_reason[1] = bcm->dma_reason[1]; | 1715 | dma_reason[1] = bcm->dma_reason[1]; |
@@ -1734,7 +1734,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1734 | dma_reason[0], dma_reason[1], | 1734 | dma_reason[0], dma_reason[1], |
1735 | dma_reason[2], dma_reason[3]); | 1735 | dma_reason[2], dma_reason[3]); |
1736 | bcm43xx_controller_restart(bcm, "DMA error"); | 1736 | bcm43xx_controller_restart(bcm, "DMA error"); |
1737 | bcm43xx_unlock_mmio(bcm, flags); | 1737 | mmiowb(); |
1738 | bcm43xx_unlock_irqonly(bcm, flags); | ||
1738 | return; | 1739 | return; |
1739 | } | 1740 | } |
1740 | if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | | 1741 | if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | |
@@ -1821,7 +1822,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) | |||
1821 | if (!modparam_noleds) | 1822 | if (!modparam_noleds) |
1822 | bcm43xx_leds_update(bcm, activity); | 1823 | bcm43xx_leds_update(bcm, activity); |
1823 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); | 1824 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); |
1824 | bcm43xx_unlock_mmio(bcm, flags); | 1825 | mmiowb(); |
1826 | bcm43xx_unlock_irqonly(bcm, flags); | ||
1825 | } | 1827 | } |
1826 | 1828 | ||
1827 | static void pio_irq_workaround(struct bcm43xx_private *bcm, | 1829 | static void pio_irq_workaround(struct bcm43xx_private *bcm, |
@@ -1870,7 +1872,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
1870 | if (!bcm) | 1872 | if (!bcm) |
1871 | return IRQ_NONE; | 1873 | return IRQ_NONE; |
1872 | 1874 | ||
1873 | spin_lock(&bcm->_lock); | 1875 | spin_lock(&bcm->irq_lock); |
1874 | 1876 | ||
1875 | reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); | 1877 | reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); |
1876 | if (reason == 0xffffffff) { | 1878 | if (reason == 0xffffffff) { |
@@ -1899,7 +1901,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
1899 | * completely, but some careful work is needed to fix this. I think it | 1901 | * completely, but some careful work is needed to fix this. I think it |
1900 | * is best to stay with this cheap workaround for now... . | 1902 | * is best to stay with this cheap workaround for now... . |
1901 | */ | 1903 | */ |
1902 | if (likely(bcm->initialized)) { | 1904 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { |
1903 | /* disable all IRQs. They are enabled again in the bottom half. */ | 1905 | /* disable all IRQs. They are enabled again in the bottom half. */ |
1904 | bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 1906 | bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
1905 | /* save the reason code and call our bottom half. */ | 1907 | /* save the reason code and call our bottom half. */ |
@@ -1909,7 +1911,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
1909 | 1911 | ||
1910 | out: | 1912 | out: |
1911 | mmiowb(); | 1913 | mmiowb(); |
1912 | spin_unlock(&bcm->_lock); | 1914 | spin_unlock(&bcm->irq_lock); |
1913 | 1915 | ||
1914 | return ret; | 1916 | return ret; |
1915 | } | 1917 | } |
@@ -3106,15 +3108,14 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) | |||
3106 | //TODO for APHY (temperature?) | 3108 | //TODO for APHY (temperature?) |
3107 | } | 3109 | } |
3108 | 3110 | ||
3109 | static void bcm43xx_periodic_task_handler(unsigned long d) | 3111 | static void bcm43xx_periodic_work_handler(void *d) |
3110 | { | 3112 | { |
3111 | struct bcm43xx_private *bcm = (struct bcm43xx_private *)d; | 3113 | struct bcm43xx_private *bcm = d; |
3112 | unsigned long flags; | 3114 | unsigned long flags; |
3113 | unsigned int state; | 3115 | unsigned int state; |
3114 | 3116 | ||
3115 | bcm43xx_lock_mmio(bcm, flags); | 3117 | bcm43xx_lock_irqsafe(bcm, flags); |
3116 | 3118 | ||
3117 | assert(bcm->initialized); | ||
3118 | state = bcm->periodic_state; | 3119 | state = bcm->periodic_state; |
3119 | if (state % 8 == 0) | 3120 | if (state % 8 == 0) |
3120 | bcm43xx_periodic_every120sec(bcm); | 3121 | bcm43xx_periodic_every120sec(bcm); |
@@ -3125,26 +3126,24 @@ static void bcm43xx_periodic_task_handler(unsigned long d) | |||
3125 | bcm43xx_periodic_every15sec(bcm); | 3126 | bcm43xx_periodic_every15sec(bcm); |
3126 | bcm->periodic_state = state + 1; | 3127 | bcm->periodic_state = state + 1; |
3127 | 3128 | ||
3128 | mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); | 3129 | schedule_delayed_work(&bcm->periodic_work, HZ * 15); |
3129 | 3130 | ||
3130 | bcm43xx_unlock_mmio(bcm, flags); | 3131 | mmiowb(); |
3132 | bcm43xx_unlock_irqsafe(bcm, flags); | ||
3131 | } | 3133 | } |
3132 | 3134 | ||
3133 | static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) | 3135 | static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) |
3134 | { | 3136 | { |
3135 | del_timer_sync(&bcm->periodic_tasks); | 3137 | cancel_rearming_delayed_work(&bcm->periodic_work); |
3136 | } | 3138 | } |
3137 | 3139 | ||
3138 | static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) | 3140 | static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) |
3139 | { | 3141 | { |
3140 | struct timer_list *timer = &(bcm->periodic_tasks); | 3142 | struct work_struct *work = &(bcm->periodic_work); |
3141 | 3143 | ||
3142 | assert(bcm->initialized); | 3144 | assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); |
3143 | setup_timer(timer, | 3145 | INIT_WORK(work, bcm43xx_periodic_work_handler, bcm); |
3144 | bcm43xx_periodic_task_handler, | 3146 | schedule_work(work); |
3145 | (unsigned long)bcm); | ||
3146 | timer->expires = jiffies; | ||
3147 | add_timer(timer); | ||
3148 | } | 3147 | } |
3149 | 3148 | ||
3150 | static void bcm43xx_security_init(struct bcm43xx_private *bcm) | 3149 | static void bcm43xx_security_init(struct bcm43xx_private *bcm) |
@@ -3158,16 +3157,12 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm) | |||
3158 | static void bcm43xx_free_board(struct bcm43xx_private *bcm) | 3157 | static void bcm43xx_free_board(struct bcm43xx_private *bcm) |
3159 | { | 3158 | { |
3160 | int i, err; | 3159 | int i, err; |
3161 | unsigned long flags; | ||
3162 | 3160 | ||
3161 | bcm43xx_lock_noirq(bcm); | ||
3163 | bcm43xx_sysfs_unregister(bcm); | 3162 | bcm43xx_sysfs_unregister(bcm); |
3164 | |||
3165 | bcm43xx_periodic_tasks_delete(bcm); | 3163 | bcm43xx_periodic_tasks_delete(bcm); |
3166 | 3164 | ||
3167 | bcm43xx_lock(bcm, flags); | 3165 | bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); |
3168 | bcm->initialized = 0; | ||
3169 | bcm->shutting_down = 1; | ||
3170 | bcm43xx_unlock(bcm, flags); | ||
3171 | 3166 | ||
3172 | for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { | 3167 | for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { |
3173 | if (!bcm->core_80211[i].available) | 3168 | if (!bcm->core_80211[i].available) |
@@ -3182,23 +3177,19 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) | |||
3182 | 3177 | ||
3183 | bcm43xx_pctl_set_crystal(bcm, 0); | 3178 | bcm43xx_pctl_set_crystal(bcm, 0); |
3184 | 3179 | ||
3185 | bcm43xx_lock(bcm, flags); | 3180 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); |
3186 | bcm->shutting_down = 0; | 3181 | bcm43xx_unlock_noirq(bcm); |
3187 | bcm43xx_unlock(bcm, flags); | ||
3188 | } | 3182 | } |
3189 | 3183 | ||
3190 | static int bcm43xx_init_board(struct bcm43xx_private *bcm) | 3184 | static int bcm43xx_init_board(struct bcm43xx_private *bcm) |
3191 | { | 3185 | { |
3192 | int i, err; | 3186 | int i, err; |
3193 | int connect_phy; | 3187 | int connect_phy; |
3194 | unsigned long flags; | ||
3195 | 3188 | ||
3196 | might_sleep(); | 3189 | might_sleep(); |
3197 | 3190 | ||
3198 | bcm43xx_lock(bcm, flags); | 3191 | bcm43xx_lock_noirq(bcm); |
3199 | bcm->initialized = 0; | 3192 | bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); |
3200 | bcm->shutting_down = 0; | ||
3201 | bcm43xx_unlock(bcm, flags); | ||
3202 | 3193 | ||
3203 | err = bcm43xx_pctl_set_crystal(bcm, 1); | 3194 | err = bcm43xx_pctl_set_crystal(bcm, 1); |
3204 | if (err) | 3195 | if (err) |
@@ -3265,9 +3256,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3265 | } | 3256 | } |
3266 | 3257 | ||
3267 | /* Initialization of the board is done. Flag it as such. */ | 3258 | /* Initialization of the board is done. Flag it as such. */ |
3268 | bcm43xx_lock(bcm, flags); | 3259 | bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED); |
3269 | bcm->initialized = 1; | ||
3270 | bcm43xx_unlock(bcm, flags); | ||
3271 | 3260 | ||
3272 | bcm43xx_periodic_tasks_setup(bcm); | 3261 | bcm43xx_periodic_tasks_setup(bcm); |
3273 | bcm43xx_sysfs_register(bcm); | 3262 | bcm43xx_sysfs_register(bcm); |
@@ -3278,6 +3267,8 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3278 | 3267 | ||
3279 | assert(err == 0); | 3268 | assert(err == 0); |
3280 | out: | 3269 | out: |
3270 | bcm43xx_unlock_noirq(bcm); | ||
3271 | |||
3281 | return err; | 3272 | return err; |
3282 | 3273 | ||
3283 | err_80211_unwind: | 3274 | err_80211_unwind: |
@@ -3534,8 +3525,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, | |||
3534 | struct bcm43xx_radioinfo *radio; | 3525 | struct bcm43xx_radioinfo *radio; |
3535 | unsigned long flags; | 3526 | unsigned long flags; |
3536 | 3527 | ||
3537 | bcm43xx_lock_mmio(bcm, flags); | 3528 | bcm43xx_lock_irqsafe(bcm, flags); |
3538 | if (bcm->initialized) { | 3529 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { |
3539 | bcm43xx_mac_suspend(bcm); | 3530 | bcm43xx_mac_suspend(bcm); |
3540 | bcm43xx_radio_selectchannel(bcm, channel, 0); | 3531 | bcm43xx_radio_selectchannel(bcm, channel, 0); |
3541 | bcm43xx_mac_enable(bcm); | 3532 | bcm43xx_mac_enable(bcm); |
@@ -3543,7 +3534,7 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, | |||
3543 | radio = bcm43xx_current_radio(bcm); | 3534 | radio = bcm43xx_current_radio(bcm); |
3544 | radio->initial_channel = channel; | 3535 | radio->initial_channel = channel; |
3545 | } | 3536 | } |
3546 | bcm43xx_unlock_mmio(bcm, flags); | 3537 | bcm43xx_unlock_irqsafe(bcm, flags); |
3547 | } | 3538 | } |
3548 | 3539 | ||
3549 | /* set_security() callback in struct ieee80211_device */ | 3540 | /* set_security() callback in struct ieee80211_device */ |
@@ -3557,7 +3548,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3557 | 3548 | ||
3558 | dprintk(KERN_INFO PFX "set security called"); | 3549 | dprintk(KERN_INFO PFX "set security called"); |
3559 | 3550 | ||
3560 | bcm43xx_lock_mmio(bcm, flags); | 3551 | bcm43xx_lock_irqsafe(bcm, flags); |
3561 | 3552 | ||
3562 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) | 3553 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) |
3563 | if (sec->flags & (1<<keyidx)) { | 3554 | if (sec->flags & (1<<keyidx)) { |
@@ -3587,7 +3578,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3587 | dprintk(", .encrypt = %d", sec->encrypt); | 3578 | dprintk(", .encrypt = %d", sec->encrypt); |
3588 | } | 3579 | } |
3589 | dprintk("\n"); | 3580 | dprintk("\n"); |
3590 | if (bcm->initialized && !bcm->ieee->host_encrypt) { | 3581 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && |
3582 | !bcm->ieee->host_encrypt) { | ||
3591 | if (secinfo->enabled) { | 3583 | if (secinfo->enabled) { |
3592 | /* upload WEP keys to hardware */ | 3584 | /* upload WEP keys to hardware */ |
3593 | char null_address[6] = { 0 }; | 3585 | char null_address[6] = { 0 }; |
@@ -3621,7 +3613,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3621 | } else | 3613 | } else |
3622 | bcm43xx_clear_keys(bcm); | 3614 | bcm43xx_clear_keys(bcm); |
3623 | } | 3615 | } |
3624 | bcm43xx_unlock_mmio(bcm, flags); | 3616 | bcm43xx_unlock_irqsafe(bcm, flags); |
3625 | } | 3617 | } |
3626 | 3618 | ||
3627 | /* hard_start_xmit() callback in struct ieee80211_device */ | 3619 | /* hard_start_xmit() callback in struct ieee80211_device */ |
@@ -3633,10 +3625,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, | |||
3633 | int err = -ENODEV; | 3625 | int err = -ENODEV; |
3634 | unsigned long flags; | 3626 | unsigned long flags; |
3635 | 3627 | ||
3636 | bcm43xx_lock_mmio(bcm, flags); | 3628 | bcm43xx_lock_irqonly(bcm, flags); |
3637 | if (likely(bcm->initialized)) | 3629 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) |
3638 | err = bcm43xx_tx(bcm, txb); | 3630 | err = bcm43xx_tx(bcm, txb); |
3639 | bcm43xx_unlock_mmio(bcm, flags); | 3631 | bcm43xx_unlock_irqonly(bcm, flags); |
3640 | 3632 | ||
3641 | return err; | 3633 | return err; |
3642 | } | 3634 | } |
@@ -3651,9 +3643,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev) | |||
3651 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); | 3643 | struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); |
3652 | unsigned long flags; | 3644 | unsigned long flags; |
3653 | 3645 | ||
3654 | bcm43xx_lock_mmio(bcm, flags); | 3646 | bcm43xx_lock_irqonly(bcm, flags); |
3655 | bcm43xx_controller_restart(bcm, "TX timeout"); | 3647 | bcm43xx_controller_restart(bcm, "TX timeout"); |
3656 | bcm43xx_unlock_mmio(bcm, flags); | 3648 | bcm43xx_unlock_irqonly(bcm, flags); |
3657 | } | 3649 | } |
3658 | 3650 | ||
3659 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3651 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -3692,6 +3684,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
3692 | { | 3684 | { |
3693 | int err; | 3685 | int err; |
3694 | 3686 | ||
3687 | bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); | ||
3695 | bcm->ieee = netdev_priv(net_dev); | 3688 | bcm->ieee = netdev_priv(net_dev); |
3696 | bcm->softmac = ieee80211_priv(net_dev); | 3689 | bcm->softmac = ieee80211_priv(net_dev); |
3697 | bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; | 3690 | bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; |
@@ -3700,7 +3693,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, | |||
3700 | bcm->pci_dev = pci_dev; | 3693 | bcm->pci_dev = pci_dev; |
3701 | bcm->net_dev = net_dev; | 3694 | bcm->net_dev = net_dev; |
3702 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; | 3695 | bcm->bad_frames_preempt = modparam_bad_frames_preempt; |
3703 | spin_lock_init(&bcm->_lock); | 3696 | spin_lock_init(&bcm->irq_lock); |
3697 | mutex_init(&bcm->mutex); | ||
3704 | tasklet_init(&bcm->isr_tasklet, | 3698 | tasklet_init(&bcm->isr_tasklet, |
3705 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, | 3699 | (void (*)(unsigned long))bcm43xx_interrupt_tasklet, |
3706 | (unsigned long)bcm); | 3700 | (unsigned long)bcm); |
@@ -3831,7 +3825,7 @@ static void bcm43xx_chip_reset(void *_bcm) | |||
3831 | struct net_device *net_dev = bcm->net_dev; | 3825 | struct net_device *net_dev = bcm->net_dev; |
3832 | struct pci_dev *pci_dev = bcm->pci_dev; | 3826 | struct pci_dev *pci_dev = bcm->pci_dev; |
3833 | int err; | 3827 | int err; |
3834 | int was_initialized = bcm->initialized; | 3828 | int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); |
3835 | 3829 | ||
3836 | netif_stop_queue(bcm->net_dev); | 3830 | netif_stop_queue(bcm->net_dev); |
3837 | tasklet_disable(&bcm->isr_tasklet); | 3831 | tasklet_disable(&bcm->isr_tasklet); |
@@ -3866,6 +3860,7 @@ failure: | |||
3866 | */ | 3860 | */ |
3867 | void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) | 3861 | void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) |
3868 | { | 3862 | { |
3863 | bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING); | ||
3869 | bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | 3864 | bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
3870 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ | 3865 | bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ |
3871 | printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); | 3866 | printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); |
@@ -3884,11 +3879,11 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3884 | 3879 | ||
3885 | dprintk(KERN_INFO PFX "Suspending...\n"); | 3880 | dprintk(KERN_INFO PFX "Suspending...\n"); |
3886 | 3881 | ||
3887 | bcm43xx_lock(bcm, flags); | 3882 | bcm43xx_lock_irqsafe(bcm, flags); |
3888 | bcm->was_initialized = bcm->initialized; | 3883 | bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); |
3889 | if (bcm->initialized) | 3884 | if (bcm->was_initialized) |
3890 | try_to_shutdown = 1; | 3885 | try_to_shutdown = 1; |
3891 | bcm43xx_unlock(bcm, flags); | 3886 | bcm43xx_unlock_irqsafe(bcm, flags); |
3892 | 3887 | ||
3893 | netif_device_detach(net_dev); | 3888 | netif_device_detach(net_dev); |
3894 | if (try_to_shutdown) { | 3889 | if (try_to_shutdown) { |