Michael Buesch wrote:
> On Tuesday 04 September 2007, Larry Finger wrote:
>> A crash upon booting that is caused by bcm43xx has been reported [1] and
>> found to be due to a work queue being reinitialized while work on that
>> queue is still pending. This fix modifies the shutdown of work queues and
>> prevents periodic work from being requeued during shutdown. With this patch,
>> no more crashes on reboot were observed by the original reporter. I do not
>> get that particular failure on my system; however, when running a large
>> number of ifdown/ifup sequences, my system would occasionally hang with the
>> 'caps lock' light blinking at roughly a 1 Hz rate. In addition, there were
>> infrequent failures in the firmware that resulted in 'IRQ READY TIMEOUT'
>> errors. With this patch, no more of the first type of failure occur, and
>> incidence of the second type is greatly reduced.
>>
>> [1] http://bugzilla.kernel.org/show_bug.cgi?id=8937
>>
>> Signed-off-by: Larry Finger <[EMAIL PROTECTED]>
>> ---
>>
>> Michael,
>>
>> The version I sent as 'RFC V2' had even more problems than the one you noted
>> as it suffered from the total crash with the blinking caps lock light. This
>> patch is a lot more solid.
>>
>> Larry
>>
>>
>>  drivers/net/wireless/bcm43xx/bcm43xx_main.c  |   28 
>> +++++++++++++++++++--------
>>  drivers/net/wireless/bcm43xx/bcm43xx_main.h  |    2 -
>>  drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c |    3 +-
>>  3 files changed, 23 insertions(+), 10 deletions(-)
>>
>> Index: linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.c
>> ===================================================================
>> --- linux-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
>> +++ linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.c
>> @@ -3197,6 +3197,9 @@ static void bcm43xx_periodic_work_handle
>>      unsigned long orig_trans_start = 0;
>>  
>>      mutex_lock(&bcm->mutex);
>> +    /* keep from doing and rearming periodic work if shutting down */
>> +    if (bcm43xx_status(bcm) == BCM43xx_STAT_UNINIT)
>> +            goto unlock_mutex;
>>      if (unlikely(bcm->periodic_state % 60 == 0)) {
>>              /* Periodic work will take a long time, so we want it to
>>               * be preemtible.
>> @@ -3242,14 +3245,10 @@ static void bcm43xx_periodic_work_handle
>>      mmiowb();
>>      bcm->periodic_state++;
>>      spin_unlock_irqrestore(&bcm->irq_lock, flags);
>> +unlock_mutex:
>>      mutex_unlock(&bcm->mutex);
>>  }
>>  
>> -void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
>> -{
>> -    cancel_rearming_delayed_work(&bcm->periodic_work);
>> -}
>> -
>>  void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
>>  {
>>      struct delayed_work *work = &bcm->periodic_work;
>> @@ -3299,6 +3298,14 @@ static int bcm43xx_rng_init(struct bcm43
>>      return err;
>>  }
>>  
>> +void bcm43xx_cancel_work(struct bcm43xx_private *bcm)
>> +{
>> +    /* The system must be unlocked when this routine is entered.
>> +     * If not, the next 2 steps may deadlock */
>> +    cancel_work_sync(&bcm->restart_work);
>> +    cancel_delayed_work_sync(&bcm->periodic_work);
>> +}
>> +
>>  static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
>>  {
>>      int ret = 0;
>> @@ -3335,7 +3342,12 @@ static void bcm43xx_free_board(struct bc
>>  {
>>      bcm43xx_rng_exit(bcm);
>>      bcm43xx_sysfs_unregister(bcm);
>> -    bcm43xx_periodic_tasks_delete(bcm);
>> +
>> +    mutex_lock(&(bcm)->mutex);
>> +    bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
>> +    mutex_unlock(&(bcm)->mutex);
>> +
>> +    bcm43xx_cancel_work(bcm);
>>  
>>      mutex_lock(&(bcm)->mutex);
>>      bcm43xx_shutdown_all_wireless_cores(bcm);
>> @@ -4030,7 +4042,7 @@ static int bcm43xx_net_stop(struct net_d
>>      err = bcm43xx_disable_interrupts_sync(bcm);
>>      assert(!err);
>>      bcm43xx_free_board(bcm);
>> -    flush_scheduled_work();
>> +    bcm43xx_cancel_work(bcm);
>>  
>>      return 0;
>>  }
>> @@ -4162,9 +4174,9 @@ static void bcm43xx_chip_reset(struct wo
>>      struct bcm43xx_phyinfo *phy;
>>      int err = -ENODEV;
>>  
>> +    bcm43xx_cancel_work(bcm);
>>      mutex_lock(&(bcm)->mutex);
>>      if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
>> -            bcm43xx_periodic_tasks_delete(bcm);
>>              phy = bcm43xx_current_phy(bcm);
>>              err = bcm43xx_select_wireless_core(bcm, phy->type);
>>              if (!err)
>> Index: linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.h
>> ===================================================================
>> --- linux-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.h
>> +++ linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_main.h
>> @@ -122,7 +122,7 @@ void bcm43xx_wireless_core_reset(struct 
>>  void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
>>  void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
>>  
>> -void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm);
>> +void bcm43xx_cancel_work(struct bcm43xx_private *bcm);
>>  void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
>>  
>>  void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char 
>> *reason);
>> Index: linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
>> ===================================================================
>> --- linux-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
>> +++ linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
>> @@ -327,8 +327,9 @@ static ssize_t bcm43xx_attr_phymode_stor
>>              goto out;
>>      }
>>  
>> -    bcm43xx_periodic_tasks_delete(bcm);
>> +    bcm43xx_cancel_work(bcm);
>>      mutex_lock(&(bcm)->mutex);
>> +    bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
> 
> No, Don't change the status.
> 
I doubt that two many people are changing phy modes anyway. I certainly have 
not tested this code. 
As the BCM4306/2 devices are having a problem with OFDM rates, would writing a 
'b' to this file 
limit those cards to CCCK rates? I'll have to try this one later.

Larry
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev

Reply via email to