diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-07-19 10:01:03 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-08-22 18:51:56 -0400 |
commit | 8fa38513ddc1076f3e26c651f3567b084c273ba2 (patch) | |
tree | a13d51bd2b2deced5b2209f52118b53ad1f59bbc /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 66d6faec2f874cf6bf9bd4900966584ea9feae3d (diff) |
[SCSI] lpfc 8.3.4: Various SLI4 fixes
Various SLI4 fixes
- Fix switch name not used in the FCF record for FCoE HBAs
- Enabled HBA UE error polling error-condition action code
- Rewrite lpfc_sli4_scmd_to_wqidx_distr() to handle counter rollover cleanly
- Modify resume_rpi mailbox data structure to match current SLI4 spec
- Do not issue mailbox command in MBX_POLL mode when LPFC_HBA_ERROR is set
- Wait for HBA POST completion before checking Online and UE registers
- Fix accumulated total length not being filled in on unsolicited IOCBs
- Use PCI config space register to determine SLI rev of HBA
- Turn on starting ELS tmo function timer during device initialization
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 90 |
1 files changed, 40 insertions, 50 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index acc43b061ba1..04f527ca8f5f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4522,12 +4522,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4522 | lpfc_sli4_rb_setup(phba); | 4522 | lpfc_sli4_rb_setup(phba); |
4523 | 4523 | ||
4524 | /* Start the ELS watchdog timer */ | 4524 | /* Start the ELS watchdog timer */ |
4525 | /* | 4525 | mod_timer(&vport->els_tmofunc, |
4526 | * The driver for SLI4 is not yet ready to process timeouts | 4526 | jiffies + HZ * (phba->fc_ratov * 2)); |
4527 | * or interrupts. Once it is, the comment bars can be removed. | ||
4528 | */ | ||
4529 | /* mod_timer(&vport->els_tmofunc, | ||
4530 | * jiffies + HZ * (phba->fc_ratov*2)); */ | ||
4531 | 4527 | ||
4532 | /* Start heart beat timer */ | 4528 | /* Start heart beat timer */ |
4533 | mod_timer(&phba->hb_tmofunc, | 4529 | mod_timer(&phba->hb_tmofunc, |
@@ -5279,6 +5275,18 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
5279 | unsigned long iflags; | 5275 | unsigned long iflags; |
5280 | int rc; | 5276 | int rc; |
5281 | 5277 | ||
5278 | rc = lpfc_mbox_dev_check(phba); | ||
5279 | if (unlikely(rc)) { | ||
5280 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
5281 | "(%d):2544 Mailbox command x%x (x%x) " | ||
5282 | "cannot issue Data: x%x x%x\n", | ||
5283 | mboxq->vport ? mboxq->vport->vpi : 0, | ||
5284 | mboxq->u.mb.mbxCommand, | ||
5285 | lpfc_sli4_mbox_opcode_get(phba, mboxq), | ||
5286 | psli->sli_flag, flag); | ||
5287 | goto out_not_finished; | ||
5288 | } | ||
5289 | |||
5282 | /* Detect polling mode and jump to a handler */ | 5290 | /* Detect polling mode and jump to a handler */ |
5283 | if (!phba->sli4_hba.intr_enable) { | 5291 | if (!phba->sli4_hba.intr_enable) { |
5284 | if (flag == MBX_POLL) | 5292 | if (flag == MBX_POLL) |
@@ -5338,17 +5346,6 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
5338 | psli->sli_flag, flag); | 5346 | psli->sli_flag, flag); |
5339 | goto out_not_finished; | 5347 | goto out_not_finished; |
5340 | } | 5348 | } |
5341 | rc = lpfc_mbox_dev_check(phba); | ||
5342 | if (unlikely(rc)) { | ||
5343 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
5344 | "(%d):2544 Mailbox command x%x (x%x) " | ||
5345 | "cannot issue Data: x%x x%x\n", | ||
5346 | mboxq->vport ? mboxq->vport->vpi : 0, | ||
5347 | mboxq->u.mb.mbxCommand, | ||
5348 | lpfc_sli4_mbox_opcode_get(phba, mboxq), | ||
5349 | psli->sli_flag, flag); | ||
5350 | goto out_not_finished; | ||
5351 | } | ||
5352 | 5349 | ||
5353 | /* Put the mailbox command to the driver internal FIFO */ | 5350 | /* Put the mailbox command to the driver internal FIFO */ |
5354 | psli->slistat.mbox_busy++; | 5351 | psli->slistat.mbox_busy++; |
@@ -5817,19 +5814,21 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
5817 | /** | 5814 | /** |
5818 | * lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution | 5815 | * lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution |
5819 | * @phba: Pointer to HBA context object. | 5816 | * @phba: Pointer to HBA context object. |
5820 | * @piocb: Pointer to command iocb. | ||
5821 | * | 5817 | * |
5822 | * This routine performs a round robin SCSI command to SLI4 FCP WQ index | 5818 | * This routine performs a round robin SCSI command to SLI4 FCP WQ index |
5823 | * distribution. | 5819 | * distribution. This is called by __lpfc_sli_issue_iocb_s4() with the hbalock |
5820 | * held. | ||
5824 | * | 5821 | * |
5825 | * Return: index into SLI4 fast-path FCP queue index. | 5822 | * Return: index into SLI4 fast-path FCP queue index. |
5826 | **/ | 5823 | **/ |
5827 | static uint32_t | 5824 | static uint32_t |
5828 | lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba, struct lpfc_iocbq *piocb) | 5825 | lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba) |
5829 | { | 5826 | { |
5830 | static uint32_t fcp_qidx; | 5827 | ++phba->fcp_qidx; |
5828 | if (phba->fcp_qidx >= phba->cfg_fcp_wq_count) | ||
5829 | phba->fcp_qidx = 0; | ||
5831 | 5830 | ||
5832 | return fcp_qidx++ % phba->cfg_fcp_wq_count; | 5831 | return phba->fcp_qidx; |
5833 | } | 5832 | } |
5834 | 5833 | ||
5835 | /** | 5834 | /** |
@@ -6156,7 +6155,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6156 | return IOCB_ERROR; | 6155 | return IOCB_ERROR; |
6157 | 6156 | ||
6158 | if (piocb->iocb_flag & LPFC_IO_FCP) { | 6157 | if (piocb->iocb_flag & LPFC_IO_FCP) { |
6159 | fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba, piocb); | 6158 | fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba); |
6160 | if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe)) | 6159 | if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe)) |
6161 | return IOCB_ERROR; | 6160 | return IOCB_ERROR; |
6162 | } else { | 6161 | } else { |
@@ -7678,12 +7677,6 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) | |||
7678 | "online0_reg=0x%x, online1_reg=0x%x\n", | 7677 | "online0_reg=0x%x, online1_reg=0x%x\n", |
7679 | uerr_sta_lo, uerr_sta_hi, | 7678 | uerr_sta_lo, uerr_sta_hi, |
7680 | onlnreg0, onlnreg1); | 7679 | onlnreg0, onlnreg1); |
7681 | /* TEMP: as the driver error recover logic is not | ||
7682 | * fully developed, we just log the error message | ||
7683 | * and the device error attention action is now | ||
7684 | * temporarily disabled. | ||
7685 | */ | ||
7686 | return 0; | ||
7687 | phba->work_status[0] = uerr_sta_lo; | 7680 | phba->work_status[0] = uerr_sta_lo; |
7688 | phba->work_status[1] = uerr_sta_hi; | 7681 | phba->work_status[1] = uerr_sta_hi; |
7689 | /* Set the driver HA work bitmap */ | 7682 | /* Set the driver HA work bitmap */ |
@@ -9499,8 +9492,7 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax) | |||
9499 | eq->host_index = 0; | 9492 | eq->host_index = 0; |
9500 | eq->hba_index = 0; | 9493 | eq->hba_index = 0; |
9501 | 9494 | ||
9502 | if (rc != MBX_TIMEOUT) | 9495 | mempool_free(mbox, phba->mbox_mem_pool); |
9503 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9504 | return status; | 9496 | return status; |
9505 | } | 9497 | } |
9506 | 9498 | ||
@@ -9604,10 +9596,9 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, | |||
9604 | cq->queue_id = bf_get(lpfc_mbx_cq_create_q_id, &cq_create->u.response); | 9596 | cq->queue_id = bf_get(lpfc_mbx_cq_create_q_id, &cq_create->u.response); |
9605 | cq->host_index = 0; | 9597 | cq->host_index = 0; |
9606 | cq->hba_index = 0; | 9598 | cq->hba_index = 0; |
9607 | out: | ||
9608 | 9599 | ||
9609 | if (rc != MBX_TIMEOUT) | 9600 | out: |
9610 | mempool_free(mbox, phba->mbox_mem_pool); | 9601 | mempool_free(mbox, phba->mbox_mem_pool); |
9611 | return status; | 9602 | return status; |
9612 | } | 9603 | } |
9613 | 9604 | ||
@@ -9712,8 +9703,7 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq, | |||
9712 | /* link the mq onto the parent cq child list */ | 9703 | /* link the mq onto the parent cq child list */ |
9713 | list_add_tail(&mq->list, &cq->child_list); | 9704 | list_add_tail(&mq->list, &cq->child_list); |
9714 | out: | 9705 | out: |
9715 | if (rc != MBX_TIMEOUT) | 9706 | mempool_free(mbox, phba->mbox_mem_pool); |
9716 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9717 | return status; | 9707 | return status; |
9718 | } | 9708 | } |
9719 | 9709 | ||
@@ -9795,8 +9785,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
9795 | /* link the wq onto the parent cq child list */ | 9785 | /* link the wq onto the parent cq child list */ |
9796 | list_add_tail(&wq->list, &cq->child_list); | 9786 | list_add_tail(&wq->list, &cq->child_list); |
9797 | out: | 9787 | out: |
9798 | if (rc != MBX_TIMEOUT) | 9788 | mempool_free(mbox, phba->mbox_mem_pool); |
9799 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9800 | return status; | 9789 | return status; |
9801 | } | 9790 | } |
9802 | 9791 | ||
@@ -9970,8 +9959,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
9970 | list_add_tail(&drq->list, &cq->child_list); | 9959 | list_add_tail(&drq->list, &cq->child_list); |
9971 | 9960 | ||
9972 | out: | 9961 | out: |
9973 | if (rc != MBX_TIMEOUT) | 9962 | mempool_free(mbox, phba->mbox_mem_pool); |
9974 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9975 | return status; | 9963 | return status; |
9976 | } | 9964 | } |
9977 | 9965 | ||
@@ -10026,8 +10014,7 @@ lpfc_eq_destroy(struct lpfc_hba *phba, struct lpfc_queue *eq) | |||
10026 | 10014 | ||
10027 | /* Remove eq from any list */ | 10015 | /* Remove eq from any list */ |
10028 | list_del_init(&eq->list); | 10016 | list_del_init(&eq->list); |
10029 | if (rc != MBX_TIMEOUT) | 10017 | mempool_free(mbox, eq->phba->mbox_mem_pool); |
10030 | mempool_free(mbox, eq->phba->mbox_mem_pool); | ||
10031 | return status; | 10018 | return status; |
10032 | } | 10019 | } |
10033 | 10020 | ||
@@ -10080,8 +10067,7 @@ lpfc_cq_destroy(struct lpfc_hba *phba, struct lpfc_queue *cq) | |||
10080 | } | 10067 | } |
10081 | /* Remove cq from any list */ | 10068 | /* Remove cq from any list */ |
10082 | list_del_init(&cq->list); | 10069 | list_del_init(&cq->list); |
10083 | if (rc != MBX_TIMEOUT) | 10070 | mempool_free(mbox, cq->phba->mbox_mem_pool); |
10084 | mempool_free(mbox, cq->phba->mbox_mem_pool); | ||
10085 | return status; | 10071 | return status; |
10086 | } | 10072 | } |
10087 | 10073 | ||
@@ -10134,8 +10120,7 @@ lpfc_mq_destroy(struct lpfc_hba *phba, struct lpfc_queue *mq) | |||
10134 | } | 10120 | } |
10135 | /* Remove mq from any list */ | 10121 | /* Remove mq from any list */ |
10136 | list_del_init(&mq->list); | 10122 | list_del_init(&mq->list); |
10137 | if (rc != MBX_TIMEOUT) | 10123 | mempool_free(mbox, mq->phba->mbox_mem_pool); |
10138 | mempool_free(mbox, mq->phba->mbox_mem_pool); | ||
10139 | return status; | 10124 | return status; |
10140 | } | 10125 | } |
10141 | 10126 | ||
@@ -10187,8 +10172,7 @@ lpfc_wq_destroy(struct lpfc_hba *phba, struct lpfc_queue *wq) | |||
10187 | } | 10172 | } |
10188 | /* Remove wq from any list */ | 10173 | /* Remove wq from any list */ |
10189 | list_del_init(&wq->list); | 10174 | list_del_init(&wq->list); |
10190 | if (rc != MBX_TIMEOUT) | 10175 | mempool_free(mbox, wq->phba->mbox_mem_pool); |
10191 | mempool_free(mbox, wq->phba->mbox_mem_pool); | ||
10192 | return status; | 10176 | return status; |
10193 | } | 10177 | } |
10194 | 10178 | ||
@@ -10258,8 +10242,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
10258 | } | 10242 | } |
10259 | list_del_init(&hrq->list); | 10243 | list_del_init(&hrq->list); |
10260 | list_del_init(&drq->list); | 10244 | list_del_init(&drq->list); |
10261 | if (rc != MBX_TIMEOUT) | 10245 | mempool_free(mbox, hrq->phba->mbox_mem_pool); |
10262 | mempool_free(mbox, hrq->phba->mbox_mem_pool); | ||
10263 | return status; | 10246 | return status; |
10264 | } | 10247 | } |
10265 | 10248 | ||
@@ -10933,6 +10916,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10933 | first_iocbq = lpfc_sli_get_iocbq(vport->phba); | 10916 | first_iocbq = lpfc_sli_get_iocbq(vport->phba); |
10934 | if (first_iocbq) { | 10917 | if (first_iocbq) { |
10935 | /* Initialize the first IOCB. */ | 10918 | /* Initialize the first IOCB. */ |
10919 | first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0; | ||
10936 | first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; | 10920 | first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; |
10937 | first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; | 10921 | first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; |
10938 | first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); | 10922 | first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); |
@@ -10945,6 +10929,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10945 | first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = | 10929 | first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = |
10946 | LPFC_DATA_BUF_SIZE; | 10930 | LPFC_DATA_BUF_SIZE; |
10947 | first_iocbq->iocb.un.rcvels.remoteID = sid; | 10931 | first_iocbq->iocb.un.rcvels.remoteID = sid; |
10932 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | ||
10933 | bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe); | ||
10948 | } | 10934 | } |
10949 | iocbq = first_iocbq; | 10935 | iocbq = first_iocbq; |
10950 | /* | 10936 | /* |
@@ -10961,6 +10947,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10961 | iocbq->iocb.ulpBdeCount++; | 10947 | iocbq->iocb.ulpBdeCount++; |
10962 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = | 10948 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = |
10963 | LPFC_DATA_BUF_SIZE; | 10949 | LPFC_DATA_BUF_SIZE; |
10950 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | ||
10951 | bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe); | ||
10964 | } else { | 10952 | } else { |
10965 | iocbq = lpfc_sli_get_iocbq(vport->phba); | 10953 | iocbq = lpfc_sli_get_iocbq(vport->phba); |
10966 | if (!iocbq) { | 10954 | if (!iocbq) { |
@@ -10978,6 +10966,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10978 | iocbq->iocb.ulpBdeCount = 1; | 10966 | iocbq->iocb.ulpBdeCount = 1; |
10979 | iocbq->iocb.un.cont64[0].tus.f.bdeSize = | 10967 | iocbq->iocb.un.cont64[0].tus.f.bdeSize = |
10980 | LPFC_DATA_BUF_SIZE; | 10968 | LPFC_DATA_BUF_SIZE; |
10969 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | ||
10970 | bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe); | ||
10981 | iocbq->iocb.un.rcvels.remoteID = sid; | 10971 | iocbq->iocb.un.rcvels.remoteID = sid; |
10982 | list_add_tail(&iocbq->list, &first_iocbq->list); | 10972 | list_add_tail(&iocbq->list, &first_iocbq->list); |
10983 | } | 10973 | } |