| From 9b96e1f65add95b5332ba53832a942f7a393db6a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 20 Aug 2025 14:11:34 +0530 |
| Subject: scsi: mpi3mr: Fix controller init failure on fault during queue |
| creation |
| |
| From: Chandrakanth Patil <chandrakanth.patil@broadcom.com> |
| |
| [ Upstream commit 829fa1582b6ff607b0e2fe41ba1c45c77f686618 ] |
| |
| Firmware can enter a transient fault while creating operational queues. |
| The driver fails the load immediately. |
| |
| Add a retry loop that checks controller status and history bit after |
| queue creation. If either indicates a fault, retry init up to a set |
| limit before failing. |
| |
| Signed-off-by: Chandrakanth Patil <chandrakanth.patil@broadcom.com> |
| Link: https://lore.kernel.org/r/20250820084138.228471-3-chandrakanth.patil@broadcom.com |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/mpi3mr/mpi3mr_fw.c | 10 ++++++++++ |
| 1 file changed, 10 insertions(+) |
| |
| diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c |
| index 82cbe98e8a044..acb2f7b04fb8f 100644 |
| --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c |
| +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c |
| @@ -2337,6 +2337,8 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc) |
| { |
| int retval = 0; |
| u16 num_queues = 0, i = 0, msix_count_op_q = 1; |
| + u32 ioc_status; |
| + enum mpi3mr_iocstate ioc_state; |
| |
| num_queues = min_t(int, mrioc->facts.max_op_reply_q, |
| mrioc->facts.max_op_req_q); |
| @@ -2392,6 +2394,14 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc) |
| retval = -1; |
| goto out_failed; |
| } |
| + ioc_status = readl(&mrioc->sysif_regs->ioc_status); |
| + ioc_state = mpi3mr_get_iocstate(mrioc); |
| + if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) || |
| + ioc_state != MRIOC_STATE_READY) { |
| + mpi3mr_print_fault_info(mrioc); |
| + retval = -1; |
| + goto out_failed; |
| + } |
| mrioc->num_op_reply_q = mrioc->num_op_req_q = i; |
| ioc_info(mrioc, |
| "successfully created %d operational queue pairs(default/polled) queue = (%d/%d)\n", |
| -- |
| 2.51.0 |
| |