scsi: smartpqi: ensure controller is in SIS mode at init
put in SIS mode during initialization. support kexec/kdump Reviewed-by: Scott Benesh <scott.benesh@microsemi.com> Reviewed-by: Scott Teel <scott.teel@microsemi.com> Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com> Signed-off-by: Don Brace <don.brace@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
5b0fba0f40
commit
162d7753fc
|
@ -964,7 +964,7 @@ struct pqi_ctrl_info {
|
|||
};
|
||||
|
||||
enum pqi_ctrl_mode {
|
||||
UNKNOWN,
|
||||
SIS_MODE = 0,
|
||||
PQI_MODE
|
||||
};
|
||||
|
||||
|
|
|
@ -5245,38 +5245,50 @@ out:
|
|||
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))
|
||||
return -ENXIO;
|
||||
|
||||
if (pqi_get_ctrl_mode(ctrl_info) == PQI_MODE) {
|
||||
sis_disable_msix(ctrl_info);
|
||||
if (pqi_reset(ctrl_info) == 0)
|
||||
sis_reenable_sis_mode(ctrl_info);
|
||||
if (pqi_get_ctrl_mode(ctrl_info) == SIS_MODE)
|
||||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (reset_devices) {
|
||||
rc = pqi_kdump_init(ctrl_info);
|
||||
if (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.
|
||||
*/
|
||||
rc = pqi_force_sis_mode(ctrl_info);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* 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)
|
|||
cancel_delayed_work_sync(&ctrl_info->update_time_work);
|
||||
pqi_remove_all_scsi_devices(ctrl_info);
|
||||
pqi_unregister_scsi(ctrl_info);
|
||||
|
||||
if (ctrl_info->pqi_mode_enabled) {
|
||||
sis_disable_msix(ctrl_info);
|
||||
if (pqi_reset(ctrl_info) == 0)
|
||||
sis_reenable_sis_mode(ctrl_info);
|
||||
}
|
||||
if (ctrl_info->pqi_mode_enabled)
|
||||
pqi_revert_to_sis_mode(ctrl_info);
|
||||
pqi_free_ctrl_resources(ctrl_info);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,12 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info)
|
|||
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 */
|
||||
struct sis_sync_cmd_params {
|
||||
u32 mailbox[6]; /* mailboxes 0-5 */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
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_kernel_up(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_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info);
|
||||
|
|
Loading…
Reference in a new issue