Skip to content

Commit fb6eb98

Browse files
Ranjan Kumarmartinkpetersen
authored andcommitted
scsi: mpi3mr: Handling of fault code for insufficient power
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 <[email protected]> Signed-off-by: Ranjan Kumar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 0d32014 commit fb6eb98

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

drivers/scsi/mpi3mr/mpi3mr_fw.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,36 @@ static const char *mpi3mr_reset_type_name(u16 reset_type)
10351035
return name;
10361036
}
10371037

1038+
/**
1039+
* mpi3mr_is_fault_recoverable - Read fault code and decide
1040+
* whether the controller can be recoverable
1041+
* @mrioc: Adapter instance reference
1042+
* Return: true if fault is recoverable, false otherwise.
1043+
*/
1044+
static inline bool mpi3mr_is_fault_recoverable(struct mpi3mr_ioc *mrioc)
1045+
{
1046+
u32 fault;
1047+
1048+
fault = (readl(&mrioc->sysif_regs->fault) &
1049+
MPI3_SYSIF_FAULT_CODE_MASK);
1050+
1051+
switch (fault) {
1052+
case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
1053+
case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED:
1054+
ioc_warn(mrioc,
1055+
"controller requires system power cycle, marking controller as unrecoverable\n");
1056+
return false;
1057+
case MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER:
1058+
ioc_warn(mrioc,
1059+
"controller faulted due to insufficient power,\n"
1060+
" try by connecting it to a different slot\n");
1061+
return false;
1062+
default:
1063+
break;
1064+
}
1065+
return true;
1066+
}
1067+
10381068
/**
10391069
* mpi3mr_print_fault_info - Display fault information
10401070
* @mrioc: Adapter instance reference
@@ -1373,6 +1403,11 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc)
13731403
ioc_info(mrioc, "ioc_status(0x%08x), ioc_config(0x%08x), ioc_info(0x%016llx) at the bringup\n",
13741404
ioc_status, ioc_config, base_info);
13751405

1406+
if (!mpi3mr_is_fault_recoverable(mrioc)) {
1407+
mrioc->unrecoverable = 1;
1408+
goto out_device_not_present;
1409+
}
1410+
13761411
/*The timeout value is in 2sec unit, changing it to seconds*/
13771412
mrioc->ready_timeout =
13781413
((base_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK) >>
@@ -2734,6 +2769,11 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
27342769
mpi3mr_print_fault_info(mrioc);
27352770
mrioc->diagsave_timeout = 0;
27362771

2772+
if (!mpi3mr_is_fault_recoverable(mrioc)) {
2773+
mrioc->unrecoverable = 1;
2774+
goto schedule_work;
2775+
}
2776+
27372777
switch (trigger_data.fault) {
27382778
case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
27392779
case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED:

0 commit comments

Comments
 (0)