From: Kevin Barnett <kevin.barnett@xxxxxxxxxxxxx> Allow user to override the default driver timeout for controller ready. There are some rare configurations which require the driver to wait longer than the normal 3 minutes for the controller to complete its bootup sequence and be ready to accept commands from the driver. The module parameter is: ctrl_ready_timeout= { 0 | 30-1800 } and specifies the timeout in seconds for the driver to wait for controller ready. The valid range is 0 or 30-1800. The default value is 0, which causes the driver to use a timeout of 180 seconds (3 minutes). Reviewed-by: Scott Teel <scott.teel@xxxxxxxxxxxxx> Reviewed-by: Mike McGowen <mike.mcgowen@xxxxxxxxxxxxx> Signed-off-by: Kevin Barnett <kevin.barnett@xxxxxxxxxxxxx> Signed-off-by: Don Brace <don.brace@xxxxxxxxxxxxx> --- drivers/scsi/smartpqi/smartpqi_init.c | 28 ++++++++++++++++++++++++++++ drivers/scsi/smartpqi/smartpqi_sis.c | 4 +++- drivers/scsi/smartpqi/smartpqi_sis.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 122772628a2f..f18b63637d0b 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -181,6 +181,12 @@ module_param_named(disable_managed_interrupts, MODULE_PARM_DESC(disable_managed_interrupts, "Disable the kernel automatically assigning SMP affinity to IRQs."); +static unsigned int pqi_ctrl_ready_timeout_secs; +module_param_named(ctrl_ready_timeout, + pqi_ctrl_ready_timeout_secs, uint, 0644); +MODULE_PARM_DESC(ctrl_ready_timeout, + "Timeout in seconds for driver to wait for controller ready."); + static char *raid_levels[] = { "RAID-0", "RAID-4", @@ -9089,9 +9095,31 @@ static void pqi_process_lockup_action_param(void) DRIVER_NAME_SHORT, pqi_lockup_action_param); } +#define PQI_CTRL_READY_TIMEOUT_PARAM_MIN_SECS 30 +#define PQI_CTRL_READY_TIMEOUT_PARAM_MAX_SECS (30 * 60) + +static void pqi_process_ctrl_ready_timeout_param(void) +{ + if (pqi_ctrl_ready_timeout_secs == 0) + return; + + if (pqi_ctrl_ready_timeout_secs < PQI_CTRL_READY_TIMEOUT_PARAM_MIN_SECS) { + pr_warn("%s: ctrl_ready_timeout parm of %u second(s) is less than minimum timeout of %d seconds - setting timeout to %d seconds\n", + DRIVER_NAME_SHORT, pqi_ctrl_ready_timeout_secs, PQI_CTRL_READY_TIMEOUT_PARAM_MIN_SECS, PQI_CTRL_READY_TIMEOUT_PARAM_MIN_SECS); + pqi_ctrl_ready_timeout_secs = PQI_CTRL_READY_TIMEOUT_PARAM_MIN_SECS; + } else if (pqi_ctrl_ready_timeout_secs > PQI_CTRL_READY_TIMEOUT_PARAM_MAX_SECS) { + pr_warn("%s: ctrl_ready_timeout parm of %u seconds is greater than maximum timeout of %d seconds - setting timeout to %d seconds\n", + DRIVER_NAME_SHORT, pqi_ctrl_ready_timeout_secs, PQI_CTRL_READY_TIMEOUT_PARAM_MAX_SECS, PQI_CTRL_READY_TIMEOUT_PARAM_MAX_SECS); + pqi_ctrl_ready_timeout_secs = PQI_CTRL_READY_TIMEOUT_PARAM_MAX_SECS; + } + + sis_ctrl_ready_timeout_secs = pqi_ctrl_ready_timeout_secs; +} + static void pqi_process_module_params(void) { pqi_process_lockup_action_param(); + pqi_process_ctrl_ready_timeout_param(); } #if defined(CONFIG_PM) diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index 59d9c2792371..12b575f2bcef 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -86,6 +86,8 @@ struct sis_base_struct { #pragma pack() +unsigned int sis_ctrl_ready_timeout_secs = SIS_CTRL_READY_TIMEOUT_SECS; + static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info, unsigned int timeout_secs) { @@ -122,7 +124,7 @@ static int sis_wait_for_ctrl_ready_with_timeout(struct pqi_ctrl_info *ctrl_info, int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info) { return sis_wait_for_ctrl_ready_with_timeout(ctrl_info, - SIS_CTRL_READY_TIMEOUT_SECS); + sis_ctrl_ready_timeout_secs); } int sis_wait_for_ctrl_ready_resume(struct pqi_ctrl_info *ctrl_info) diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index 5f3575261a8e..2f825d31a47e 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -32,4 +32,6 @@ void sis_soft_reset(struct pqi_ctrl_info *ctrl_info); u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info); int sis_wait_for_fw_triage_completion(struct pqi_ctrl_info *ctrl_info); +extern unsigned int sis_ctrl_ready_timeout_secs; + #endif /* _SMARTPQI_SIS_H */