| From 794b808ce34df15e35da6c5a6454ea674a52948a Mon Sep 17 00:00:00 2001 |
| From: James Smart <jsmart2021@gmail.com> |
| Date: Tue, 12 Mar 2019 16:30:18 -0700 |
| Subject: scsi: lpfc: Fix mailbox hang on adapter init |
| |
| [ Upstream commit e8869f5b0a7273fcf20ef99066fd8129e58ba5b7 ] |
| |
| The adapter initialization sequence enables interrupts, initializes the |
| adapter link_state to LINK_DOWN, then issues commands to initialize the |
| adapter. The interrupt handler on the adapter validates the link_state (has |
| to be at least LINK_DOWN) and if invalid, will discard the interrupting |
| event. |
| |
| In most cases, there is not a command completion, thus an interrupt until |
| the initialization commands have been sent which is post the setting of |
| state to LINK_DOWN. However, in cases of firmware reset, the reset will |
| modify the link_state to an invalid value (indicating a reset of the |
| adapter) and there occasionally are cases where the adapter will generate |
| an asynchronous event which shares the eq/cq used for mailbox commands. In |
| the failure case, an interrupt is generated immediately after enabling them |
| due to the async event. As link_state is invalid, the eq is list and the |
| CQ not serviced. At this point link_state is initialized and the mailbox |
| command sent. As the CQ has not been serviced, it is not armed, so no |
| interrupt event is generated when the mailbox command completes. |
| |
| Modify the initialization sequence so that interrupts are enabled after |
| link_state is properly initialized, which avoids the race condition with |
| the async event. |
| |
| Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> |
| Signed-off-by: James Smart <jsmart2021@gmail.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/lpfc/lpfc_sli.c | 12 ++++++------ |
| 1 file changed, 6 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c |
| index 57b4a463b5892..7d2abb70cf093 100644 |
| --- a/drivers/scsi/lpfc/lpfc_sli.c |
| +++ b/drivers/scsi/lpfc/lpfc_sli.c |
| @@ -7652,12 +7652,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) |
| phba->cfg_xri_rebalancing = 0; |
| } |
| |
| - /* Arm the CQs and then EQs on device */ |
| - lpfc_sli4_arm_cqeq_intr(phba); |
| - |
| - /* Indicate device interrupt mode */ |
| - phba->sli4_hba.intr_enable = 1; |
| - |
| /* Allow asynchronous mailbox command to go through */ |
| spin_lock_irq(&phba->hbalock); |
| phba->sli.sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; |
| @@ -7726,6 +7720,12 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) |
| phba->trunk_link.link3.state = LPFC_LINK_DOWN; |
| spin_unlock_irq(&phba->hbalock); |
| |
| + /* Arm the CQs and then EQs on device */ |
| + lpfc_sli4_arm_cqeq_intr(phba); |
| + |
| + /* Indicate device interrupt mode */ |
| + phba->sli4_hba.intr_enable = 1; |
| + |
| if (!(phba->hba_flag & HBA_FCOE_MODE) && |
| (phba->hba_flag & LINK_DISABLED)) { |
| lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_SLI, |
| -- |
| 2.20.1 |
| |