summaryrefslogtreecommitdiff
path: root/drivers/scsi/mpi3mr
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpi3mr')
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr_fw.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 2e6245bd4282..5ed31fe57474 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -1036,6 +1036,36 @@ static const char *mpi3mr_reset_type_name(u16 reset_type)
}
/**
+ * mpi3mr_is_fault_recoverable - Read fault code and decide
+ * whether the controller can be recoverable
+ * @mrioc: Adapter instance reference
+ * Return: true if fault is recoverable, false otherwise.
+ */
+static inline bool mpi3mr_is_fault_recoverable(struct mpi3mr_ioc *mrioc)
+{
+ u32 fault;
+
+ fault = (readl(&mrioc->sysif_regs->fault) &
+ MPI3_SYSIF_FAULT_CODE_MASK);
+
+ switch (fault) {
+ case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
+ case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED:
+ ioc_warn(mrioc,
+ "controller requires system power cycle, marking controller as unrecoverable\n");
+ return false;
+ case MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER:
+ ioc_warn(mrioc,
+ "controller faulted due to insufficient power,\n"
+ " try by connecting it to a different slot\n");
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+/**
* mpi3mr_print_fault_info - Display fault information
* @mrioc: Adapter instance reference
*
@@ -1373,6 +1403,11 @@ retry_bring_ioc_ready:
ioc_info(mrioc, "ioc_status(0x%08x), ioc_config(0x%08x), ioc_info(0x%016llx) at the bringup\n",
ioc_status, ioc_config, base_info);
+ if (!mpi3mr_is_fault_recoverable(mrioc)) {
+ mrioc->unrecoverable = 1;
+ goto out_device_not_present;
+ }
+
/*The timeout value is in 2sec unit, changing it to seconds*/
mrioc->ready_timeout =
((base_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK) >>
@@ -2734,6 +2769,11 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
mpi3mr_print_fault_info(mrioc);
mrioc->diagsave_timeout = 0;
+ if (!mpi3mr_is_fault_recoverable(mrioc)) {
+ mrioc->unrecoverable = 1;
+ goto schedule_work;
+ }
+
switch (trigger_data.fault) {
case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED: