scsi: smartpqi: Add ctrl ready timeout module parameter
authorKevin Barnett <kevin.barnett@microchip.com>
Fri, 8 Jul 2022 18:47:56 +0000 (13:47 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 14 Jul 2022 03:42:04 +0000 (23:42 -0400)
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).

Link: https://lore.kernel.org/r/165730607666.177165.9221211345284471213.stgit@brunhilda
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Reviewed-by: Mike McGowen <mike.mcgowen@microchip.com>
Signed-off-by: Kevin Barnett <kevin.barnett@microchip.com>
Signed-off-by: Don Brace <don.brace@microchip.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/smartpqi/smartpqi_init.c
drivers/scsi/smartpqi/smartpqi_sis.c
drivers/scsi/smartpqi/smartpqi_sis.h

index 122772628a2ff4213c3ca7d96aaa08362edd6b49..f18b63637d0befdfe8ffabe653e092c04a2f5665 100644 (file)
@@ -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)
index 59d9c2792371813cedab5c1bbfd742cef2109f66..12b575f2bcefab61c1f2677624d82393d7daad71 100644 (file)
@@ -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)
index 5f3575261a8ed530dedaebf6fe23fcbfcf1816f4..2f825d31a47e0f58df7e8705326f3132bc738e13 100644 (file)
@@ -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 */