Commit 4244e7fc authored by Shahar S Matityahu's avatar Shahar S Matityahu Committed by Luca Coelho

iwlwifi: dump debug data before stop device

Debug data dump is not working in flows that stop the device is used
in their error handling. During these flows the op mode mutex is
locked until the device stops.  Because of that, any assert generated
from the firmware can be handled only after the device already
stopped.

Since dumping cannot occour after stopping the device, split the the
dump function to two parts, Part that handles locking, and the part
that starts the actual dumping and call the second part in the op mode
stop device function.
Signed-off-by: default avatarShahar S Matityahu <shahar.s.matityahu@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 2ec3ef46
......@@ -1154,14 +1154,14 @@ int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 conf_id)
}
IWL_EXPORT_SYMBOL(iwl_fw_start_dbg_conf);
void iwl_fw_error_dump_wk(struct work_struct *work)
/* this function assumes dump_start was called beforehand and dump_end will be
* called afterwards
*/
void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt)
{
struct iwl_fw_runtime *fwrt =
container_of(work, struct iwl_fw_runtime, dump.wk.work);
struct iwl_fw_dbg_params params = {0};
if (fwrt->ops && fwrt->ops->dump_start &&
fwrt->ops->dump_start(fwrt->ops_ctx))
if (!test_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
return;
if (fwrt->ops && fwrt->ops->fw_running &&
......@@ -1169,7 +1169,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
IWL_ERR(fwrt, "Firmware not running - cannot dump error\n");
iwl_fw_free_dump_desc(fwrt);
clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
goto out;
return;
}
iwl_fw_dbg_stop_recording(fwrt, &params);
......@@ -1183,7 +1183,20 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
udelay(500);
iwl_fw_dbg_restart_recording(fwrt, &params);
}
out:
}
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_sync);
void iwl_fw_error_dump_wk(struct work_struct *work)
{
struct iwl_fw_runtime *fwrt =
container_of(work, struct iwl_fw_runtime, dump.wk.work);
if (fwrt->ops && fwrt->ops->dump_start &&
fwrt->ops->dump_start(fwrt->ops_ctx))
return;
iwl_fw_dbg_collect_sync(fwrt);
if (fwrt->ops && fwrt->ops->dump_end)
fwrt->ops->dump_end(fwrt->ops_ctx);
}
......
......@@ -367,4 +367,5 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
#endif /* CONFIG_IWLWIFI_DEBUGFS */
void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
#endif /* __iwl_fw_dbg_h__ */
......@@ -1906,6 +1906,11 @@ static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
{
lockdep_assert_held(&mvm->mutex);
/* calling this function without using dump_start/end since at this
* point we already hold the op mode mutex
*/
iwl_fw_dbg_collect_sync(&mvm->fwrt);
iwl_fw_cancel_timestamp(&mvm->fwrt);
iwl_free_fw_paging(&mvm->fwrt);
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment