diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:53:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 20:53:36 -0400 |
commit | 39695224bd84dc4be29abad93a0ec232a16fc519 (patch) | |
tree | 2bfa5cb50788a4c8be9f2e9f4412e47a565f4508 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | a9bbd210a44102cc50b30a5f3d111dbf5f2f9cd4 (diff) | |
parent | ea038f63ac52439e7816295fa6064fe95e6c1f51 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (209 commits)
[SCSI] fix oops during scsi scanning
[SCSI] libsrp: fix memory leak in srp_ring_free()
[SCSI] libiscsi, bnx2i: make bound ep check common
[SCSI] libiscsi: add completion function for drivers that do not need pdu processing
[SCSI] scsi_dh_rdac: changes for rdac debug logging
[SCSI] scsi_dh_rdac: changes to collect the rdac debug information during the initialization
[SCSI] scsi_dh_rdac: move the init code from rdac_activate to rdac_bus_attach
[SCSI] sg: fix oops in the error path in sg_build_indirect()
[SCSI] mptsas : Bump version to 3.04.12
[SCSI] mptsas : FW event thread and scsi mid layer deadlock in SYNCHRONIZE CACHE command
[SCSI] mptsas : Send DID_NO_CONNECT for pending IOs of removed device
[SCSI] mptsas : PAE Kernel more than 4 GB kernel panic
[SCSI] mptsas : NULL pointer on big endian systems causing Expander not to tear off
[SCSI] mptsas : Sanity check for phyinfo is added
[SCSI] scsi_dh_rdac: Add support for Sun StorageTek ST2500, ST2510 and ST2530
[SCSI] pmcraid: PMC-Sierra MaxRAID driver to support 6Gb/s SAS RAID controller
[SCSI] qla2xxx: Update version number to 8.03.01-k6.
[SCSI] qla2xxx: Properly delete rports attached to a vport.
[SCSI] qla2xxx: Correct various NPIV issues.
[SCSI] qla2xxx: Correct qla2x00_eh_wait_on_command() to wait correctly.
...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 263 |
1 files changed, 207 insertions, 56 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index acc43b061ba1..43cbe336f1f8 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4139,7 +4139,7 @@ lpfc_sli4_read_fcoe_params(struct lpfc_hba *phba, | |||
4139 | return -EIO; | 4139 | return -EIO; |
4140 | } | 4140 | } |
4141 | data_length = mqe->un.mb_words[5]; | 4141 | data_length = mqe->un.mb_words[5]; |
4142 | if (data_length > DMP_FCOEPARAM_RGN_SIZE) { | 4142 | if (data_length > DMP_RGN23_SIZE) { |
4143 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 4143 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
4144 | kfree(mp); | 4144 | kfree(mp); |
4145 | return -EIO; | 4145 | return -EIO; |
@@ -4304,7 +4304,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4304 | */ | 4304 | */ |
4305 | if (lpfc_sli4_read_fcoe_params(phba, mboxq)) | 4305 | if (lpfc_sli4_read_fcoe_params(phba, mboxq)) |
4306 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT, | 4306 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT, |
4307 | "2570 Failed to read FCoE parameters \n"); | 4307 | "2570 Failed to read FCoE parameters\n"); |
4308 | 4308 | ||
4309 | /* Issue READ_REV to collect vpd and FW information. */ | 4309 | /* Issue READ_REV to collect vpd and FW information. */ |
4310 | vpd_size = PAGE_SIZE; | 4310 | vpd_size = PAGE_SIZE; |
@@ -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, |
@@ -4706,13 +4702,13 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, | |||
4706 | 4702 | ||
4707 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | 4703 | spin_lock_irqsave(&phba->hbalock, drvr_flag); |
4708 | if (!pmbox) { | 4704 | if (!pmbox) { |
4705 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
4709 | /* processing mbox queue from intr_handler */ | 4706 | /* processing mbox queue from intr_handler */ |
4710 | if (unlikely(psli->sli_flag & LPFC_SLI_ASYNC_MBX_BLK)) { | 4707 | if (unlikely(psli->sli_flag & LPFC_SLI_ASYNC_MBX_BLK)) { |
4711 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 4708 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
4712 | return MBX_SUCCESS; | 4709 | return MBX_SUCCESS; |
4713 | } | 4710 | } |
4714 | processing_queue = 1; | 4711 | processing_queue = 1; |
4715 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
4716 | pmbox = lpfc_mbox_get(phba); | 4712 | pmbox = lpfc_mbox_get(phba); |
4717 | if (!pmbox) { | 4713 | if (!pmbox) { |
4718 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 4714 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
@@ -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 { |
@@ -6327,7 +6326,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba, | |||
6327 | KERN_ERR, | 6326 | KERN_ERR, |
6328 | LOG_SLI, | 6327 | LOG_SLI, |
6329 | "0346 Ring %d handler: unexpected ASYNC_STATUS" | 6328 | "0346 Ring %d handler: unexpected ASYNC_STATUS" |
6330 | " evt_code 0x%x \n" | 6329 | " evt_code 0x%x\n" |
6331 | "W0 0x%08x W1 0x%08x W2 0x%08x W3 0x%08x\n" | 6330 | "W0 0x%08x W1 0x%08x W2 0x%08x W3 0x%08x\n" |
6332 | "W4 0x%08x W5 0x%08x W6 0x%08x W7 0x%08x\n" | 6331 | "W4 0x%08x W5 0x%08x W6 0x%08x W7 0x%08x\n" |
6333 | "W8 0x%08x W9 0x%08x W10 0x%08x W11 0x%08x\n" | 6332 | "W8 0x%08x W9 0x%08x W10 0x%08x W11 0x%08x\n" |
@@ -6790,6 +6789,33 @@ lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt) | |||
6790 | 6789 | ||
6791 | 6790 | ||
6792 | /** | 6791 | /** |
6792 | * lpfc_sli_bemem_bcopy - SLI memory copy function | ||
6793 | * @srcp: Source memory pointer. | ||
6794 | * @destp: Destination memory pointer. | ||
6795 | * @cnt: Number of words required to be copied. | ||
6796 | * | ||
6797 | * This function is used for copying data between a data structure | ||
6798 | * with big endian representation to local endianness. | ||
6799 | * This function can be called with or without lock. | ||
6800 | **/ | ||
6801 | void | ||
6802 | lpfc_sli_bemem_bcopy(void *srcp, void *destp, uint32_t cnt) | ||
6803 | { | ||
6804 | uint32_t *src = srcp; | ||
6805 | uint32_t *dest = destp; | ||
6806 | uint32_t ldata; | ||
6807 | int i; | ||
6808 | |||
6809 | for (i = 0; i < (int)cnt; i += sizeof(uint32_t)) { | ||
6810 | ldata = *src; | ||
6811 | ldata = be32_to_cpu(ldata); | ||
6812 | *dest = ldata; | ||
6813 | src++; | ||
6814 | dest++; | ||
6815 | } | ||
6816 | } | ||
6817 | |||
6818 | /** | ||
6793 | * lpfc_sli_ringpostbuf_put - Function to add a buffer to postbufq | 6819 | * lpfc_sli_ringpostbuf_put - Function to add a buffer to postbufq |
6794 | * @phba: Pointer to HBA context object. | 6820 | * @phba: Pointer to HBA context object. |
6795 | * @pring: Pointer to driver SLI ring object. | 6821 | * @pring: Pointer to driver SLI ring object. |
@@ -7678,12 +7704,6 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) | |||
7678 | "online0_reg=0x%x, online1_reg=0x%x\n", | 7704 | "online0_reg=0x%x, online1_reg=0x%x\n", |
7679 | uerr_sta_lo, uerr_sta_hi, | 7705 | uerr_sta_lo, uerr_sta_hi, |
7680 | onlnreg0, onlnreg1); | 7706 | 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; | 7707 | phba->work_status[0] = uerr_sta_lo; |
7688 | phba->work_status[1] = uerr_sta_hi; | 7708 | phba->work_status[1] = uerr_sta_hi; |
7689 | /* Set the driver HA work bitmap */ | 7709 | /* Set the driver HA work bitmap */ |
@@ -9499,8 +9519,7 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax) | |||
9499 | eq->host_index = 0; | 9519 | eq->host_index = 0; |
9500 | eq->hba_index = 0; | 9520 | eq->hba_index = 0; |
9501 | 9521 | ||
9502 | if (rc != MBX_TIMEOUT) | 9522 | mempool_free(mbox, phba->mbox_mem_pool); |
9503 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9504 | return status; | 9523 | return status; |
9505 | } | 9524 | } |
9506 | 9525 | ||
@@ -9604,10 +9623,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); | 9623 | cq->queue_id = bf_get(lpfc_mbx_cq_create_q_id, &cq_create->u.response); |
9605 | cq->host_index = 0; | 9624 | cq->host_index = 0; |
9606 | cq->hba_index = 0; | 9625 | cq->hba_index = 0; |
9607 | out: | ||
9608 | 9626 | ||
9609 | if (rc != MBX_TIMEOUT) | 9627 | out: |
9610 | mempool_free(mbox, phba->mbox_mem_pool); | 9628 | mempool_free(mbox, phba->mbox_mem_pool); |
9611 | return status; | 9629 | return status; |
9612 | } | 9630 | } |
9613 | 9631 | ||
@@ -9712,8 +9730,7 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq, | |||
9712 | /* link the mq onto the parent cq child list */ | 9730 | /* link the mq onto the parent cq child list */ |
9713 | list_add_tail(&mq->list, &cq->child_list); | 9731 | list_add_tail(&mq->list, &cq->child_list); |
9714 | out: | 9732 | out: |
9715 | if (rc != MBX_TIMEOUT) | 9733 | mempool_free(mbox, phba->mbox_mem_pool); |
9716 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9717 | return status; | 9734 | return status; |
9718 | } | 9735 | } |
9719 | 9736 | ||
@@ -9795,8 +9812,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
9795 | /* link the wq onto the parent cq child list */ | 9812 | /* link the wq onto the parent cq child list */ |
9796 | list_add_tail(&wq->list, &cq->child_list); | 9813 | list_add_tail(&wq->list, &cq->child_list); |
9797 | out: | 9814 | out: |
9798 | if (rc != MBX_TIMEOUT) | 9815 | mempool_free(mbox, phba->mbox_mem_pool); |
9799 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9800 | return status; | 9816 | return status; |
9801 | } | 9817 | } |
9802 | 9818 | ||
@@ -9970,8 +9986,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
9970 | list_add_tail(&drq->list, &cq->child_list); | 9986 | list_add_tail(&drq->list, &cq->child_list); |
9971 | 9987 | ||
9972 | out: | 9988 | out: |
9973 | if (rc != MBX_TIMEOUT) | 9989 | mempool_free(mbox, phba->mbox_mem_pool); |
9974 | mempool_free(mbox, phba->mbox_mem_pool); | ||
9975 | return status; | 9990 | return status; |
9976 | } | 9991 | } |
9977 | 9992 | ||
@@ -10026,8 +10041,7 @@ lpfc_eq_destroy(struct lpfc_hba *phba, struct lpfc_queue *eq) | |||
10026 | 10041 | ||
10027 | /* Remove eq from any list */ | 10042 | /* Remove eq from any list */ |
10028 | list_del_init(&eq->list); | 10043 | list_del_init(&eq->list); |
10029 | if (rc != MBX_TIMEOUT) | 10044 | mempool_free(mbox, eq->phba->mbox_mem_pool); |
10030 | mempool_free(mbox, eq->phba->mbox_mem_pool); | ||
10031 | return status; | 10045 | return status; |
10032 | } | 10046 | } |
10033 | 10047 | ||
@@ -10080,8 +10094,7 @@ lpfc_cq_destroy(struct lpfc_hba *phba, struct lpfc_queue *cq) | |||
10080 | } | 10094 | } |
10081 | /* Remove cq from any list */ | 10095 | /* Remove cq from any list */ |
10082 | list_del_init(&cq->list); | 10096 | list_del_init(&cq->list); |
10083 | if (rc != MBX_TIMEOUT) | 10097 | mempool_free(mbox, cq->phba->mbox_mem_pool); |
10084 | mempool_free(mbox, cq->phba->mbox_mem_pool); | ||
10085 | return status; | 10098 | return status; |
10086 | } | 10099 | } |
10087 | 10100 | ||
@@ -10134,8 +10147,7 @@ lpfc_mq_destroy(struct lpfc_hba *phba, struct lpfc_queue *mq) | |||
10134 | } | 10147 | } |
10135 | /* Remove mq from any list */ | 10148 | /* Remove mq from any list */ |
10136 | list_del_init(&mq->list); | 10149 | list_del_init(&mq->list); |
10137 | if (rc != MBX_TIMEOUT) | 10150 | mempool_free(mbox, mq->phba->mbox_mem_pool); |
10138 | mempool_free(mbox, mq->phba->mbox_mem_pool); | ||
10139 | return status; | 10151 | return status; |
10140 | } | 10152 | } |
10141 | 10153 | ||
@@ -10187,8 +10199,7 @@ lpfc_wq_destroy(struct lpfc_hba *phba, struct lpfc_queue *wq) | |||
10187 | } | 10199 | } |
10188 | /* Remove wq from any list */ | 10200 | /* Remove wq from any list */ |
10189 | list_del_init(&wq->list); | 10201 | list_del_init(&wq->list); |
10190 | if (rc != MBX_TIMEOUT) | 10202 | mempool_free(mbox, wq->phba->mbox_mem_pool); |
10191 | mempool_free(mbox, wq->phba->mbox_mem_pool); | ||
10192 | return status; | 10203 | return status; |
10193 | } | 10204 | } |
10194 | 10205 | ||
@@ -10258,8 +10269,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
10258 | } | 10269 | } |
10259 | list_del_init(&hrq->list); | 10270 | list_del_init(&hrq->list); |
10260 | list_del_init(&drq->list); | 10271 | list_del_init(&drq->list); |
10261 | if (rc != MBX_TIMEOUT) | 10272 | mempool_free(mbox, hrq->phba->mbox_mem_pool); |
10262 | mempool_free(mbox, hrq->phba->mbox_mem_pool); | ||
10263 | return status; | 10273 | return status; |
10264 | } | 10274 | } |
10265 | 10275 | ||
@@ -10933,6 +10943,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10933 | first_iocbq = lpfc_sli_get_iocbq(vport->phba); | 10943 | first_iocbq = lpfc_sli_get_iocbq(vport->phba); |
10934 | if (first_iocbq) { | 10944 | if (first_iocbq) { |
10935 | /* Initialize the first IOCB. */ | 10945 | /* Initialize the first IOCB. */ |
10946 | first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0; | ||
10936 | first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; | 10947 | first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; |
10937 | first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; | 10948 | first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; |
10938 | first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); | 10949 | first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id); |
@@ -10945,6 +10956,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10945 | first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = | 10956 | first_iocbq->iocb.un.cont64[0].tus.f.bdeSize = |
10946 | LPFC_DATA_BUF_SIZE; | 10957 | LPFC_DATA_BUF_SIZE; |
10947 | first_iocbq->iocb.un.rcvels.remoteID = sid; | 10958 | first_iocbq->iocb.un.rcvels.remoteID = sid; |
10959 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | ||
10960 | bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe); | ||
10948 | } | 10961 | } |
10949 | iocbq = first_iocbq; | 10962 | iocbq = first_iocbq; |
10950 | /* | 10963 | /* |
@@ -10961,6 +10974,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10961 | iocbq->iocb.ulpBdeCount++; | 10974 | iocbq->iocb.ulpBdeCount++; |
10962 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = | 10975 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = |
10963 | LPFC_DATA_BUF_SIZE; | 10976 | LPFC_DATA_BUF_SIZE; |
10977 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | ||
10978 | bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe); | ||
10964 | } else { | 10979 | } else { |
10965 | iocbq = lpfc_sli_get_iocbq(vport->phba); | 10980 | iocbq = lpfc_sli_get_iocbq(vport->phba); |
10966 | if (!iocbq) { | 10981 | if (!iocbq) { |
@@ -10978,6 +10993,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
10978 | iocbq->iocb.ulpBdeCount = 1; | 10993 | iocbq->iocb.ulpBdeCount = 1; |
10979 | iocbq->iocb.un.cont64[0].tus.f.bdeSize = | 10994 | iocbq->iocb.un.cont64[0].tus.f.bdeSize = |
10980 | LPFC_DATA_BUF_SIZE; | 10995 | LPFC_DATA_BUF_SIZE; |
10996 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | ||
10997 | bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe); | ||
10981 | iocbq->iocb.un.rcvels.remoteID = sid; | 10998 | iocbq->iocb.un.rcvels.remoteID = sid; |
10982 | list_add_tail(&iocbq->list, &first_iocbq->list); | 10999 | list_add_tail(&iocbq->list, &first_iocbq->list); |
10983 | } | 11000 | } |
@@ -11324,7 +11341,7 @@ lpfc_sli4_init_vpi(struct lpfc_hba *phba, uint16_t vpi) | |||
11324 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 11341 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
11325 | if (!mboxq) | 11342 | if (!mboxq) |
11326 | return -ENOMEM; | 11343 | return -ENOMEM; |
11327 | lpfc_init_vpi(mboxq, vpi); | 11344 | lpfc_init_vpi(phba, mboxq, vpi); |
11328 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI); | 11345 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI); |
11329 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | 11346 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); |
11330 | if (rc != MBX_TIMEOUT) | 11347 | if (rc != MBX_TIMEOUT) |
@@ -11519,6 +11536,7 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11519 | uint32_t alloc_len, req_len; | 11536 | uint32_t alloc_len, req_len; |
11520 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | 11537 | struct lpfc_mbx_read_fcf_tbl *read_fcf; |
11521 | 11538 | ||
11539 | phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag; | ||
11522 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 11540 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
11523 | if (!mboxq) { | 11541 | if (!mboxq) { |
11524 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 11542 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -11570,7 +11588,140 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | |||
11570 | if (rc == MBX_NOT_FINISHED) { | 11588 | if (rc == MBX_NOT_FINISHED) { |
11571 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | 11589 | lpfc_sli4_mbox_cmd_free(phba, mboxq); |
11572 | error = -EIO; | 11590 | error = -EIO; |
11573 | } else | 11591 | } else { |
11592 | spin_lock_irq(&phba->hbalock); | ||
11593 | phba->hba_flag |= FCF_DISC_INPROGRESS; | ||
11594 | spin_unlock_irq(&phba->hbalock); | ||
11574 | error = 0; | 11595 | error = 0; |
11596 | } | ||
11575 | return error; | 11597 | return error; |
11576 | } | 11598 | } |
11599 | |||
11600 | /** | ||
11601 | * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. | ||
11602 | * @phba: pointer to lpfc hba data structure. | ||
11603 | * | ||
11604 | * This function read region 23 and parse TLV for port status to | ||
11605 | * decide if the user disaled the port. If the TLV indicates the | ||
11606 | * port is disabled, the hba_flag is set accordingly. | ||
11607 | **/ | ||
11608 | void | ||
11609 | lpfc_sli_read_link_ste(struct lpfc_hba *phba) | ||
11610 | { | ||
11611 | LPFC_MBOXQ_t *pmb = NULL; | ||
11612 | MAILBOX_t *mb; | ||
11613 | uint8_t *rgn23_data = NULL; | ||
11614 | uint32_t offset = 0, data_size, sub_tlv_len, tlv_offset; | ||
11615 | int rc; | ||
11616 | |||
11617 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
11618 | if (!pmb) { | ||
11619 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11620 | "2600 lpfc_sli_read_serdes_param failed to" | ||
11621 | " allocate mailbox memory\n"); | ||
11622 | goto out; | ||
11623 | } | ||
11624 | mb = &pmb->u.mb; | ||
11625 | |||
11626 | /* Get adapter Region 23 data */ | ||
11627 | rgn23_data = kzalloc(DMP_RGN23_SIZE, GFP_KERNEL); | ||
11628 | if (!rgn23_data) | ||
11629 | goto out; | ||
11630 | |||
11631 | do { | ||
11632 | lpfc_dump_mem(phba, pmb, offset, DMP_REGION_23); | ||
11633 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | ||
11634 | |||
11635 | if (rc != MBX_SUCCESS) { | ||
11636 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
11637 | "2601 lpfc_sli_read_link_ste failed to" | ||
11638 | " read config region 23 rc 0x%x Status 0x%x\n", | ||
11639 | rc, mb->mbxStatus); | ||
11640 | mb->un.varDmp.word_cnt = 0; | ||
11641 | } | ||
11642 | /* | ||
11643 | * dump mem may return a zero when finished or we got a | ||
11644 | * mailbox error, either way we are done. | ||
11645 | */ | ||
11646 | if (mb->un.varDmp.word_cnt == 0) | ||
11647 | break; | ||
11648 | if (mb->un.varDmp.word_cnt > DMP_RGN23_SIZE - offset) | ||
11649 | mb->un.varDmp.word_cnt = DMP_RGN23_SIZE - offset; | ||
11650 | |||
11651 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, | ||
11652 | rgn23_data + offset, | ||
11653 | mb->un.varDmp.word_cnt); | ||
11654 | offset += mb->un.varDmp.word_cnt; | ||
11655 | } while (mb->un.varDmp.word_cnt && offset < DMP_RGN23_SIZE); | ||
11656 | |||
11657 | data_size = offset; | ||
11658 | offset = 0; | ||
11659 | |||
11660 | if (!data_size) | ||
11661 | goto out; | ||
11662 | |||
11663 | /* Check the region signature first */ | ||
11664 | if (memcmp(&rgn23_data[offset], LPFC_REGION23_SIGNATURE, 4)) { | ||
11665 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11666 | "2619 Config region 23 has bad signature\n"); | ||
11667 | goto out; | ||
11668 | } | ||
11669 | offset += 4; | ||
11670 | |||
11671 | /* Check the data structure version */ | ||
11672 | if (rgn23_data[offset] != LPFC_REGION23_VERSION) { | ||
11673 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11674 | "2620 Config region 23 has bad version\n"); | ||
11675 | goto out; | ||
11676 | } | ||
11677 | offset += 4; | ||
11678 | |||
11679 | /* Parse TLV entries in the region */ | ||
11680 | while (offset < data_size) { | ||
11681 | if (rgn23_data[offset] == LPFC_REGION23_LAST_REC) | ||
11682 | break; | ||
11683 | /* | ||
11684 | * If the TLV is not driver specific TLV or driver id is | ||
11685 | * not linux driver id, skip the record. | ||
11686 | */ | ||
11687 | if ((rgn23_data[offset] != DRIVER_SPECIFIC_TYPE) || | ||
11688 | (rgn23_data[offset + 2] != LINUX_DRIVER_ID) || | ||
11689 | (rgn23_data[offset + 3] != 0)) { | ||
11690 | offset += rgn23_data[offset + 1] * 4 + 4; | ||
11691 | continue; | ||
11692 | } | ||
11693 | |||
11694 | /* Driver found a driver specific TLV in the config region */ | ||
11695 | sub_tlv_len = rgn23_data[offset + 1] * 4; | ||
11696 | offset += 4; | ||
11697 | tlv_offset = 0; | ||
11698 | |||
11699 | /* | ||
11700 | * Search for configured port state sub-TLV. | ||
11701 | */ | ||
11702 | while ((offset < data_size) && | ||
11703 | (tlv_offset < sub_tlv_len)) { | ||
11704 | if (rgn23_data[offset] == LPFC_REGION23_LAST_REC) { | ||
11705 | offset += 4; | ||
11706 | tlv_offset += 4; | ||
11707 | break; | ||
11708 | } | ||
11709 | if (rgn23_data[offset] != PORT_STE_TYPE) { | ||
11710 | offset += rgn23_data[offset + 1] * 4 + 4; | ||
11711 | tlv_offset += rgn23_data[offset + 1] * 4 + 4; | ||
11712 | continue; | ||
11713 | } | ||
11714 | |||
11715 | /* This HBA contains PORT_STE configured */ | ||
11716 | if (!rgn23_data[offset + 2]) | ||
11717 | phba->hba_flag |= LINK_DISABLED; | ||
11718 | |||
11719 | goto out; | ||
11720 | } | ||
11721 | } | ||
11722 | out: | ||
11723 | if (pmb) | ||
11724 | mempool_free(pmb, phba->mbox_mem_pool); | ||
11725 | kfree(rgn23_data); | ||
11726 | return; | ||
11727 | } | ||