iwlagn: probe would crash with DEBUG_SHIRQ
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 21 Jul 2011 00:51:22 +0000 (17:51 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Thu, 21 Jul 2011 14:41:07 +0000 (07:41 -0700)
This is since my patch:

    iwlagn: introduce transport layer and implement rx_init

The IRQ is requested before the locks are initialized, hence the crash.
Initialize the tasklet before we request the IRQ on the way.

Reported-by: Johannes Berg <johannes.berg@intel.com>
Tested-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-trans.c

index 299acb4..4b666b7 100644 (file)
@@ -3645,10 +3645,6 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
        priv->cfg = cfg;
        priv->inta_mask = CSR_INI_SET_MASK;
 
-       err = iwl_trans_register(&priv->trans, priv);
-       if (err)
-               goto out_free_priv;
-
        /* is antenna coupling more than 35dB ? */
        priv->bt_ant_couple_ok =
                (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
@@ -3682,10 +3678,14 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
        IWL_INFO(priv, "Detected %s, REV=0x%X\n",
                priv->cfg->name, hw_rev);
 
+       err = iwl_trans_register(&priv->trans, priv);
+       if (err)
+               goto out_free_traffic_mem;
+
        if (trans_prepare_card_hw(&priv->trans)) {
                err = -EIO;
                IWL_WARN(priv, "Failed, HW not ready\n");
-               goto out_free_traffic_mem;
+               goto out_free_trans;
        }
 
        /*****************
@@ -3695,7 +3695,7 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg)
        err = iwl_eeprom_init(priv, hw_rev);
        if (err) {
                IWL_ERR(priv, "Unable to init EEPROM\n");
-               goto out_free_traffic_mem;
+               goto out_free_trans;
        }
        err = iwl_eeprom_check_version(priv);
        if (err)
@@ -3778,10 +3778,10 @@ out_destroy_workqueue:
        iwl_uninit_drv(priv);
 out_free_eeprom:
        iwl_eeprom_free(priv);
+out_free_trans:
+       trans_free(&priv->trans);
 out_free_traffic_mem:
        iwl_free_traffic_mem(priv);
-       trans_free(&priv->trans);
-out_free_priv:
        ieee80211_free_hw(priv->hw);
 out:
        return err;
index 582ab1b..41f0de9 100644 (file)
@@ -1153,6 +1153,9 @@ int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv)
        priv->trans.ops = &trans_ops;
        priv->trans.priv = priv;
 
+       tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+               iwl_irq_tasklet, (unsigned long)priv);
+
        iwl_alloc_isr_ict(priv);
 
        err = request_irq(priv->bus->irq, iwl_isr_ict, IRQF_SHARED,
@@ -1163,9 +1166,6 @@ int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv)
                return err;
        }
 
-       tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-               iwl_irq_tasklet, (unsigned long)priv);
-
        INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
 
        return 0;