iwlwifi: mvm: allow to collect debug data from non-sleepable context
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 29 Dec 2014 07:42:37 +0000 (09:42 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 22 Jan 2015 15:53:57 +0000 (17:53 +0200)
iwl_mvm_fw_dbg_collect allows to collect debug data from
the firmware. Most of the firmware interaction is done in
non-sleepable context. It makes little sense to force the
caller of iwl_mvm_fw_dbg_collect to sleep.
Defer the actual collection to a worker so that this
function will be able to be called from any context.

Reviewed-by: Eran Harary <eran.harary@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/ops.c

index 534ee3123a63fef57318aae3c374b308fc73715c..52338b73722382b88ab7a730ee6b01fc0e6eac2d 100644 (file)
@@ -402,8 +402,6 @@ out:
 
 void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
 {
-       lockdep_assert_held(&mvm->mutex);
-
        /* stop recording */
        if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
                iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
@@ -412,11 +410,7 @@ void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
                iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
        }
 
-       iwl_mvm_fw_error_dump(mvm);
-
-       /* start recording again */
-       WARN_ON_ONCE(mvm->fw->dbg_dest_tlv &&
-                    iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
+       schedule_work(&mvm->fw_error_dump_wk);
 }
 
 int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
index 12b565a6f1a6b8ee44c094d02de4be5739f48dab..90143aa838bebcc3b6811fbb2c88319a02a4af91 100644 (file)
@@ -825,6 +825,12 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
 
        mutex_lock(&mvm->mutex);
        iwl_mvm_fw_error_dump(mvm);
+
+       /* start recording again if the firmware is not crashed */
+       WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
+                     mvm->fw->dbg_dest_tlv &&
+                     iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
+
        mutex_unlock(&mvm->mutex);
 
        iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);