Commit fae21608 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen

scsi: mpt3sas: Transition IOC to Ready state during shutdown

The IOC firmware assumes that the host driver is still alive after shutdown
and continues to post events to host memory (due to faulty expander phy
links, etc). This leads to 0x2666 (a bus fault occurred during a host-IOC
memory access).

Perform an IOC soft reset as part of shutdown to disable event posting.

Link: https://lore.kernel.org/r/20210705145951.32258-1-sreekanth.reddy@broadcom.comSigned-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 6d8e7e7c
...@@ -2983,13 +2983,13 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc) ...@@ -2983,13 +2983,13 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc)
} }
/** /**
* _base_free_irq - free irq * mpt3sas_base_free_irq - free irq
* @ioc: per adapter object * @ioc: per adapter object
* *
* Freeing respective reply_queue from the list. * Freeing respective reply_queue from the list.
*/ */
static void void
_base_free_irq(struct MPT3SAS_ADAPTER *ioc) mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc)
{ {
struct adapter_reply_queue *reply_q, *next; struct adapter_reply_queue *reply_q, *next;
...@@ -3191,12 +3191,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc, ...@@ -3191,12 +3191,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc,
} }
/** /**
* _base_disable_msix - disables msix * mpt3sas_base_disable_msix - disables msix
* @ioc: per adapter object * @ioc: per adapter object
* *
*/ */
static void void
_base_disable_msix(struct MPT3SAS_ADAPTER *ioc) mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc)
{ {
if (!ioc->msix_enable) if (!ioc->msix_enable)
return; return;
...@@ -3304,8 +3304,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ...@@ -3304,8 +3304,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
for (i = 0; i < ioc->reply_queue_count; i++) { for (i = 0; i < ioc->reply_queue_count; i++) {
r = _base_request_irq(ioc, i); r = _base_request_irq(ioc, i);
if (r) { if (r) {
_base_free_irq(ioc); mpt3sas_base_free_irq(ioc);
_base_disable_msix(ioc); mpt3sas_base_disable_msix(ioc);
goto try_ioapic; goto try_ioapic;
} }
} }
...@@ -3342,8 +3342,8 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) ...@@ -3342,8 +3342,8 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc)
dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); dexitprintk(ioc, ioc_info(ioc, "%s\n", __func__));
_base_free_irq(ioc); mpt3sas_base_free_irq(ioc);
_base_disable_msix(ioc); mpt3sas_base_disable_msix(ioc);
kfree(ioc->replyPostRegisterIndex); kfree(ioc->replyPostRegisterIndex);
ioc->replyPostRegisterIndex = NULL; ioc->replyPostRegisterIndex = NULL;
...@@ -7613,14 +7613,14 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) ...@@ -7613,14 +7613,14 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc)
} }
/** /**
* _base_make_ioc_ready - put controller in READY state * mpt3sas_base_make_ioc_ready - put controller in READY state
* @ioc: per adapter object * @ioc: per adapter object
* @type: FORCE_BIG_HAMMER or SOFT_RESET * @type: FORCE_BIG_HAMMER or SOFT_RESET
* *
* Return: 0 for success, non-zero for failure. * Return: 0 for success, non-zero for failure.
*/ */
static int int
_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type) mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type)
{ {
u32 ioc_state; u32 ioc_state;
int rc; int rc;
...@@ -7897,7 +7897,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) ...@@ -7897,7 +7897,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
if (ioc->chip_phys && ioc->chip) { if (ioc->chip_phys && ioc->chip) {
mpt3sas_base_mask_interrupts(ioc); mpt3sas_base_mask_interrupts(ioc);
ioc->shost_recovery = 1; ioc->shost_recovery = 1;
_base_make_ioc_ready(ioc, SOFT_RESET); mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
ioc->shost_recovery = 0; ioc->shost_recovery = 0;
} }
...@@ -8017,7 +8017,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ...@@ -8017,7 +8017,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
ioc->build_sg_mpi = &_base_build_sg; ioc->build_sg_mpi = &_base_build_sg;
ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge; ioc->build_zero_len_sge_mpi = &_base_build_zero_len_sge;
r = _base_make_ioc_ready(ioc, SOFT_RESET); r = mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
if (r) if (r)
goto out_free_resources; goto out_free_resources;
...@@ -8471,7 +8471,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, ...@@ -8471,7 +8471,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
_base_pre_reset_handler(ioc); _base_pre_reset_handler(ioc);
mpt3sas_wait_for_commands_to_complete(ioc); mpt3sas_wait_for_commands_to_complete(ioc);
mpt3sas_base_mask_interrupts(ioc); mpt3sas_base_mask_interrupts(ioc);
r = _base_make_ioc_ready(ioc, type); r = mpt3sas_base_make_ioc_ready(ioc, type);
if (r) if (r)
goto out; goto out;
_base_clear_outstanding_commands(ioc); _base_clear_outstanding_commands(ioc);
......
...@@ -1730,6 +1730,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \ ...@@ -1730,6 +1730,10 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \
status, mpi_request, sz); } while (0) status, mpi_request, sz); } while (0)
int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count); int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count);
int
mpt3sas_base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, enum reset_type type);
void mpt3sas_base_free_irq(struct MPT3SAS_ADAPTER *ioc);
void mpt3sas_base_disable_msix(struct MPT3SAS_ADAPTER *ioc);
/* scsih shared API */ /* scsih shared API */
struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc,
......
...@@ -11295,7 +11295,12 @@ scsih_shutdown(struct pci_dev *pdev) ...@@ -11295,7 +11295,12 @@ scsih_shutdown(struct pci_dev *pdev)
_scsih_ir_shutdown(ioc); _scsih_ir_shutdown(ioc);
_scsih_nvme_shutdown(ioc); _scsih_nvme_shutdown(ioc);
mpt3sas_base_detach(ioc); mpt3sas_base_mask_interrupts(ioc);
ioc->shost_recovery = 1;
mpt3sas_base_make_ioc_ready(ioc, SOFT_RESET);
ioc->shost_recovery = 0;
mpt3sas_base_free_irq(ioc);
mpt3sas_base_disable_msix(ioc);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment