Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -964,7 +964,7 @@ struct pqi_ctrl_info {
};

enum pqi_ctrl_mode {
	UNKNOWN,
	SIS_MODE = 0,
	PQI_MODE
};

+34 −26
Original line number Diff line number Diff line
@@ -5245,38 +5245,50 @@ static int pqi_get_ctrl_firmware_version(struct pqi_ctrl_info *ctrl_info)
	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)
{
	if (!sis_is_firmware_running(ctrl_info))
		return -ENXIO;
	int rc;

	if (pqi_get_ctrl_mode(ctrl_info) == PQI_MODE) {
	sis_disable_msix(ctrl_info);
		if (pqi_reset(ctrl_info) == 0)
	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) == SIS_MODE)
		return 0;

	if (sis_is_kernel_up(ctrl_info)) {
		pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
		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);
	rc = pqi_force_sis_mode(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.
	 */

	/*
	 * 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);
}

+6 −0
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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);