]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
scsi: mpi3mr: Handling of fault code for insufficient power
authorRanjan Kumar <ranjan.kumar@broadcom.com>
Sun, 10 Nov 2024 19:44:04 +0000 (01:14 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 4 Dec 2024 17:21:05 +0000 (12:21 -0500)
Before retrying initialization, check and abort if the fault code
indicates insufficient power. Also mark the controller as unrecoverable
instead of issuing reset in the watch dog timer if the fault code
indicates insufficient power.

Signed-off-by: Prayas Patel <prayas.patel@broadcom.com>
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
Link: https://lore.kernel.org/r/20241110194405.10108-5-ranjan.kumar@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr_fw.c

index 2e6245bd4282e4ce39bc6a8a8e7dfc47f06de75c..5ed31fe57474a3f62b4316140b1ced5eab957f29 100644 (file)
@@ -1035,6 +1035,36 @@ static const char *mpi3mr_reset_type_name(u16 reset_type)
        return name;
 }
 
+/**
+ * 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: