Commit 162d7753 authored by Kevin Barnett's avatar Kevin Barnett Committed by Martin K. Petersen

scsi: smartpqi: ensure controller is in SIS mode at init

put in SIS mode during initialization.
support kexec/kdump
Reviewed-by: default avatarScott Benesh <scott.benesh@microsemi.com>
Reviewed-by: default avatarScott Teel <scott.teel@microsemi.com>
Signed-off-by: default avatarKevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5b0fba0f
...@@ -964,7 +964,7 @@ struct pqi_ctrl_info { ...@@ -964,7 +964,7 @@ struct pqi_ctrl_info {
}; };
enum pqi_ctrl_mode { enum pqi_ctrl_mode {
UNKNOWN, SIS_MODE = 0,
PQI_MODE PQI_MODE
}; };
......
...@@ -5245,38 +5245,50 @@ static int pqi_get_ctrl_firmware_version(struct pqi_ctrl_info *ctrl_info) ...@@ -5245,38 +5245,50 @@ static int pqi_get_ctrl_firmware_version(struct pqi_ctrl_info *ctrl_info)
return rc; return rc;
} }
static int pqi_kdump_init(struct pqi_ctrl_info *ctrl_info) /* Switches the controller from PQI mode back into SIS mode. */
static int pqi_revert_to_sis_mode(struct pqi_ctrl_info *ctrl_info)
{
int rc;
sis_disable_msix(ctrl_info);
rc = pqi_reset(ctrl_info);
if (rc)
return rc;
sis_reenable_sis_mode(ctrl_info);
pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
return 0;
}
/*
* If the controller isn't already in SIS mode, this function forces it into
* SIS mode.
*/
static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info)
{ {
if (!sis_is_firmware_running(ctrl_info)) if (!sis_is_firmware_running(ctrl_info))
return -ENXIO; return -ENXIO;
if (pqi_get_ctrl_mode(ctrl_info) == PQI_MODE) { if (pqi_get_ctrl_mode(ctrl_info) == SIS_MODE)
sis_disable_msix(ctrl_info); return 0;
if (pqi_reset(ctrl_info) == 0)
sis_reenable_sis_mode(ctrl_info); if (sis_is_kernel_up(ctrl_info)) {
pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
return 0;
} }
return 0; return pqi_revert_to_sis_mode(ctrl_info);
} }
static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
{ {
int rc; int rc;
if (reset_devices) { rc = pqi_force_sis_mode(ctrl_info);
rc = pqi_kdump_init(ctrl_info); if (rc)
if (rc) return rc;
return rc;
}
/*
* When the controller comes out of reset, it is always running
* in legacy SIS mode. This is so that it can be compatible
* with legacy drivers shipped with OSes. So we have to talk
* to it using SIS commands at first. Once we are satisified
* that the controller supports PQI, we transition it into PQI
* mode.
*/
/* /*
* Wait until the controller is ready to start accepting SIS * Wait until the controller is ready to start accepting SIS
...@@ -5594,12 +5606,8 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info) ...@@ -5594,12 +5606,8 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info)
cancel_delayed_work_sync(&ctrl_info->update_time_work); cancel_delayed_work_sync(&ctrl_info->update_time_work);
pqi_remove_all_scsi_devices(ctrl_info); pqi_remove_all_scsi_devices(ctrl_info);
pqi_unregister_scsi(ctrl_info); pqi_unregister_scsi(ctrl_info);
if (ctrl_info->pqi_mode_enabled)
if (ctrl_info->pqi_mode_enabled) { pqi_revert_to_sis_mode(ctrl_info);
sis_disable_msix(ctrl_info);
if (pqi_reset(ctrl_info) == 0)
sis_reenable_sis_mode(ctrl_info);
}
pqi_free_ctrl_resources(ctrl_info); pqi_free_ctrl_resources(ctrl_info);
} }
......
...@@ -127,6 +127,12 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info) ...@@ -127,6 +127,12 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
return running; return running;
} }
bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info)
{
return readl(&ctrl_info->registers->sis_firmware_status) &
SIS_CTRL_KERNEL_UP;
}
/* used for passing command parameters/results when issuing SIS commands */ /* used for passing command parameters/results when issuing SIS commands */
struct sis_sync_cmd_params { struct sis_sync_cmd_params {
u32 mailbox[6]; /* mailboxes 0-5 */ u32 mailbox[6]; /* mailboxes 0-5 */
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info); int sis_wait_for_ctrl_ready(struct pqi_ctrl_info *ctrl_info);
bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info); bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info);
bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info);
int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info); int sis_get_ctrl_properties(struct pqi_ctrl_info *ctrl_info);
int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info); int sis_get_pqi_capabilities(struct pqi_ctrl_info *ctrl_info);
int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info); int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info);
......
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