diff options
author | James Smart <james.smart@emulex.com> | 2011-10-10 21:33:49 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-16 12:32:17 -0400 |
commit | 5350d872c19a59ef8eadab1e70db83064c134cfa (patch) | |
tree | 4a34c698b36f0874ca808a76583a1d69b122437d /drivers/scsi/lpfc/lpfc_sli.c | |
parent | cd1c8301db15ee52bfc5a0e5bc16b52bab8475aa (diff) |
[SCSI] lpfc 8.3.27: Fix queue allocation failure recovery
Fix queue allocation failure recovery
- Move the allocation of the Queues closer to the creation of the queues.
- If there is a problem with creation, or if the HBA is reset, the queues
will be completely freed and re allocated.
- Only allocate fcp_eq_hdl if cfg_fcp_eq_count is non-zero.
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index b9edfebf5091..c430aada02be 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -6127,12 +6127,20 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6127 | goto out_free_mbox; | 6127 | goto out_free_mbox; |
6128 | } | 6128 | } |
6129 | 6129 | ||
6130 | /* Create all the SLI4 queues */ | ||
6131 | rc = lpfc_sli4_queue_create(phba); | ||
6132 | if (rc) { | ||
6133 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
6134 | "3089 Failed to allocate queues\n"); | ||
6135 | rc = -ENODEV; | ||
6136 | goto out_stop_timers; | ||
6137 | } | ||
6130 | /* Set up all the queues to the device */ | 6138 | /* Set up all the queues to the device */ |
6131 | rc = lpfc_sli4_queue_setup(phba); | 6139 | rc = lpfc_sli4_queue_setup(phba); |
6132 | if (unlikely(rc)) { | 6140 | if (unlikely(rc)) { |
6133 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 6141 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
6134 | "0381 Error %d during queue setup.\n ", rc); | 6142 | "0381 Error %d during queue setup.\n ", rc); |
6135 | goto out_stop_timers; | 6143 | goto out_destroy_queue; |
6136 | } | 6144 | } |
6137 | 6145 | ||
6138 | /* Arm the CQs and then EQs on device */ | 6146 | /* Arm the CQs and then EQs on device */ |
@@ -6205,15 +6213,20 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6205 | spin_lock_irq(&phba->hbalock); | 6213 | spin_lock_irq(&phba->hbalock); |
6206 | phba->link_state = LPFC_LINK_DOWN; | 6214 | phba->link_state = LPFC_LINK_DOWN; |
6207 | spin_unlock_irq(&phba->hbalock); | 6215 | spin_unlock_irq(&phba->hbalock); |
6208 | if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) | 6216 | if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { |
6209 | rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT); | 6217 | rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT); |
6218 | if (rc) | ||
6219 | goto out_unset_queue; | ||
6220 | } | ||
6221 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
6222 | return rc; | ||
6210 | out_unset_queue: | 6223 | out_unset_queue: |
6211 | /* Unset all the queues set up in this routine when error out */ | 6224 | /* Unset all the queues set up in this routine when error out */ |
6212 | if (rc) | 6225 | lpfc_sli4_queue_unset(phba); |
6213 | lpfc_sli4_queue_unset(phba); | 6226 | out_destroy_queue: |
6227 | lpfc_sli4_queue_destroy(phba); | ||
6214 | out_stop_timers: | 6228 | out_stop_timers: |
6215 | if (rc) | 6229 | lpfc_stop_hba_timers(phba); |
6216 | lpfc_stop_hba_timers(phba); | ||
6217 | out_free_mbox: | 6230 | out_free_mbox: |
6218 | mempool_free(mboxq, phba->mbox_mem_pool); | 6231 | mempool_free(mboxq, phba->mbox_mem_pool); |
6219 | return rc; | 6232 | return rc; |
@@ -9562,7 +9575,6 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, | |||
9562 | 9575 | ||
9563 | /* now issue the command */ | 9576 | /* now issue the command */ |
9564 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | 9577 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); |
9565 | |||
9566 | if (retval == MBX_BUSY || retval == MBX_SUCCESS) { | 9578 | if (retval == MBX_BUSY || retval == MBX_SUCCESS) { |
9567 | wait_event_interruptible_timeout(done_q, | 9579 | wait_event_interruptible_timeout(done_q, |
9568 | pmboxq->mbox_flag & LPFC_MBX_WAKE, | 9580 | pmboxq->mbox_flag & LPFC_MBX_WAKE, |
@@ -11319,6 +11331,8 @@ lpfc_sli4_sp_intr_handler(int irq, void *dev_id) | |||
11319 | 11331 | ||
11320 | /* Get to the EQ struct associated with this vector */ | 11332 | /* Get to the EQ struct associated with this vector */ |
11321 | speq = phba->sli4_hba.sp_eq; | 11333 | speq = phba->sli4_hba.sp_eq; |
11334 | if (unlikely(!speq)) | ||
11335 | return IRQ_NONE; | ||
11322 | 11336 | ||
11323 | /* Check device state for handling interrupt */ | 11337 | /* Check device state for handling interrupt */ |
11324 | if (unlikely(lpfc_intr_state_check(phba))) { | 11338 | if (unlikely(lpfc_intr_state_check(phba))) { |
@@ -11396,6 +11410,8 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id) | |||
11396 | 11410 | ||
11397 | if (unlikely(!phba)) | 11411 | if (unlikely(!phba)) |
11398 | return IRQ_NONE; | 11412 | return IRQ_NONE; |
11413 | if (unlikely(!phba->sli4_hba.fp_eq)) | ||
11414 | return IRQ_NONE; | ||
11399 | 11415 | ||
11400 | /* Get to the EQ struct associated with this vector */ | 11416 | /* Get to the EQ struct associated with this vector */ |
11401 | fpeq = phba->sli4_hba.fp_eq[fcp_eqidx]; | 11417 | fpeq = phba->sli4_hba.fp_eq[fcp_eqidx]; |