diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-06-10 17:22:44 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-15 11:09:32 -0400 |
commit | f1126688805d77a4798b694439fa48bba6629388 (patch) | |
tree | 8a6169f70dba7e8644f07c8ca654ebad1786281d /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 43fac4d97a1a30085f1cae61aa565e5e7e5e5d7d (diff) |
[SCSI] lpfc 8.3.3 : Fix various SLI-3 vs SLI-4 differences
Contains the following changes
- Set the CT field of FDISC to 3
- Fixed over allocation of SCSI buffers on SLI4
- Removed unused jump table entries
- Increase LPFC_WQE_DEF_COUNT to 256
- Updated FDISC context to VPI
- Fixed immediate SCSI command for LUN reset translation to WQE
- Extended mailbox handling to allow MBX_POLL commands in between async
MBQ commands
- Fixed SID used for FDISC
- Fix crash when accessing ctlregs from sysfs for SLI4 HBAs
- Fix SLI4 firmware version not being saved or displayed correctly
- Expand CQID field in WQE structure to 16 bits
- Fix post header template mailbox command timing out
- Removed FCoE PCI device ID 0x0705
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 198 |
1 files changed, 151 insertions, 47 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ff04daf18f48..b8cf0a1b1382 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4211,27 +4211,6 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
4211 | return -EIO; | 4211 | return -EIO; |
4212 | } | 4212 | } |
4213 | 4213 | ||
4214 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | ||
4215 | "(%d):0380 Mailbox cmd x%x Status x%x " | ||
4216 | "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x " | ||
4217 | "x%x x%x x%x x%x x%x x%x x%x x%x x%x " | ||
4218 | "CQ: x%x x%x x%x x%x\n", | ||
4219 | mboxq->vport ? mboxq->vport->vpi : 0, | ||
4220 | bf_get(lpfc_mqe_command, mqe), | ||
4221 | bf_get(lpfc_mqe_status, mqe), | ||
4222 | mqe->un.mb_words[0], mqe->un.mb_words[1], | ||
4223 | mqe->un.mb_words[2], mqe->un.mb_words[3], | ||
4224 | mqe->un.mb_words[4], mqe->un.mb_words[5], | ||
4225 | mqe->un.mb_words[6], mqe->un.mb_words[7], | ||
4226 | mqe->un.mb_words[8], mqe->un.mb_words[9], | ||
4227 | mqe->un.mb_words[10], mqe->un.mb_words[11], | ||
4228 | mqe->un.mb_words[12], mqe->un.mb_words[13], | ||
4229 | mqe->un.mb_words[14], mqe->un.mb_words[15], | ||
4230 | mqe->un.mb_words[16], mqe->un.mb_words[50], | ||
4231 | mboxq->mcqe.word0, | ||
4232 | mboxq->mcqe.mcqe_tag0, mboxq->mcqe.mcqe_tag1, | ||
4233 | mboxq->mcqe.trailer); | ||
4234 | |||
4235 | /* | 4214 | /* |
4236 | * The available vpd length cannot be bigger than the | 4215 | * The available vpd length cannot be bigger than the |
4237 | * DMA buffer passed to the port. Catch the less than | 4216 | * DMA buffer passed to the port. Catch the less than |
@@ -4337,21 +4316,18 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4337 | goto out_free_vpd; | 4316 | goto out_free_vpd; |
4338 | 4317 | ||
4339 | mqe = &mboxq->u.mqe; | 4318 | mqe = &mboxq->u.mqe; |
4340 | if ((bf_get(lpfc_mbx_rd_rev_sli_lvl, | 4319 | phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev); |
4341 | &mqe->un.read_rev) != LPFC_SLI_REV4) || | 4320 | if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)) |
4342 | (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev) == 0)) { | 4321 | phba->hba_flag |= HBA_FCOE_SUPPORT; |
4322 | if (phba->sli_rev != LPFC_SLI_REV4 || | ||
4323 | !(phba->hba_flag & HBA_FCOE_SUPPORT)) { | ||
4343 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 4324 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, |
4344 | "0376 READ_REV Error. SLI Level %d " | 4325 | "0376 READ_REV Error. SLI Level %d " |
4345 | "FCoE enabled %d\n", | 4326 | "FCoE enabled %d\n", |
4346 | bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev), | 4327 | phba->sli_rev, phba->hba_flag & HBA_FCOE_SUPPORT); |
4347 | bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)); | ||
4348 | rc = -EIO; | 4328 | rc = -EIO; |
4349 | goto out_free_vpd; | 4329 | goto out_free_vpd; |
4350 | } | 4330 | } |
4351 | /* Single threaded at this point, no need for lock */ | ||
4352 | spin_lock_irq(&phba->hbalock); | ||
4353 | phba->hba_flag |= HBA_FCOE_SUPPORT; | ||
4354 | spin_unlock_irq(&phba->hbalock); | ||
4355 | /* | 4331 | /* |
4356 | * Evaluate the read rev and vpd data. Populate the driver | 4332 | * Evaluate the read rev and vpd data. Populate the driver |
4357 | * state with the results. If this routine fails, the failure | 4333 | * state with the results. If this routine fails, the failure |
@@ -4365,8 +4341,32 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
4365 | rc = 0; | 4341 | rc = 0; |
4366 | } | 4342 | } |
4367 | 4343 | ||
4368 | /* By now, we should determine the SLI revision, hard code for now */ | 4344 | /* Save information as VPD data */ |
4369 | phba->sli_rev = LPFC_SLI_REV4; | 4345 | phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev; |
4346 | phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev; | ||
4347 | phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev; | ||
4348 | phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high, | ||
4349 | &mqe->un.read_rev); | ||
4350 | phba->vpd.rev.fcphLow = bf_get(lpfc_mbx_rd_rev_fcph_low, | ||
4351 | &mqe->un.read_rev); | ||
4352 | phba->vpd.rev.feaLevelHigh = bf_get(lpfc_mbx_rd_rev_ftr_lvl_high, | ||
4353 | &mqe->un.read_rev); | ||
4354 | phba->vpd.rev.feaLevelLow = bf_get(lpfc_mbx_rd_rev_ftr_lvl_low, | ||
4355 | &mqe->un.read_rev); | ||
4356 | phba->vpd.rev.sli1FwRev = mqe->un.read_rev.fw_id_rev; | ||
4357 | memcpy(phba->vpd.rev.sli1FwName, mqe->un.read_rev.fw_name, 16); | ||
4358 | phba->vpd.rev.sli2FwRev = mqe->un.read_rev.ulp_fw_id_rev; | ||
4359 | memcpy(phba->vpd.rev.sli2FwName, mqe->un.read_rev.ulp_fw_name, 16); | ||
4360 | phba->vpd.rev.opFwRev = mqe->un.read_rev.fw_id_rev; | ||
4361 | memcpy(phba->vpd.rev.opFwName, mqe->un.read_rev.fw_name, 16); | ||
4362 | lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, | ||
4363 | "(%d):0380 READ_REV Status x%x " | ||
4364 | "fw_rev:%s fcphHi:%x fcphLo:%x flHi:%x flLo:%x\n", | ||
4365 | mboxq->vport ? mboxq->vport->vpi : 0, | ||
4366 | bf_get(lpfc_mqe_status, mqe), | ||
4367 | phba->vpd.rev.opFwName, | ||
4368 | phba->vpd.rev.fcphHigh, phba->vpd.rev.fcphLow, | ||
4369 | phba->vpd.rev.feaLevelHigh, phba->vpd.rev.feaLevelLow); | ||
4370 | 4370 | ||
4371 | /* | 4371 | /* |
4372 | * Discover the port's supported feature set and match it against the | 4372 | * Discover the port's supported feature set and match it against the |
@@ -5030,6 +5030,92 @@ out_not_finished: | |||
5030 | } | 5030 | } |
5031 | 5031 | ||
5032 | /** | 5032 | /** |
5033 | * lpfc_sli4_async_mbox_block - Block posting SLI4 asynchronous mailbox command | ||
5034 | * @phba: Pointer to HBA context object. | ||
5035 | * | ||
5036 | * The function blocks the posting of SLI4 asynchronous mailbox commands from | ||
5037 | * the driver internal pending mailbox queue. It will then try to wait out the | ||
5038 | * possible outstanding mailbox command before return. | ||
5039 | * | ||
5040 | * Returns: | ||
5041 | * 0 - the outstanding mailbox command completed; otherwise, the wait for | ||
5042 | * the outstanding mailbox command timed out. | ||
5043 | **/ | ||
5044 | static int | ||
5045 | lpfc_sli4_async_mbox_block(struct lpfc_hba *phba) | ||
5046 | { | ||
5047 | struct lpfc_sli *psli = &phba->sli; | ||
5048 | uint8_t actcmd = MBX_HEARTBEAT; | ||
5049 | int rc = 0; | ||
5050 | unsigned long timeout; | ||
5051 | |||
5052 | /* Mark the asynchronous mailbox command posting as blocked */ | ||
5053 | spin_lock_irq(&phba->hbalock); | ||
5054 | psli->sli_flag |= LPFC_SLI_ASYNC_MBX_BLK; | ||
5055 | if (phba->sli.mbox_active) | ||
5056 | actcmd = phba->sli.mbox_active->u.mb.mbxCommand; | ||
5057 | spin_unlock_irq(&phba->hbalock); | ||
5058 | /* Determine how long we might wait for the active mailbox | ||
5059 | * command to be gracefully completed by firmware. | ||
5060 | */ | ||
5061 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, actcmd) * 1000) + | ||
5062 | jiffies; | ||
5063 | /* Wait for the outstnading mailbox command to complete */ | ||
5064 | while (phba->sli.mbox_active) { | ||
5065 | /* Check active mailbox complete status every 2ms */ | ||
5066 | msleep(2); | ||
5067 | if (time_after(jiffies, timeout)) { | ||
5068 | /* Timeout, marked the outstanding cmd not complete */ | ||
5069 | rc = 1; | ||
5070 | break; | ||
5071 | } | ||
5072 | } | ||
5073 | |||
5074 | /* Can not cleanly block async mailbox command, fails it */ | ||
5075 | if (rc) { | ||
5076 | spin_lock_irq(&phba->hbalock); | ||
5077 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | ||
5078 | spin_unlock_irq(&phba->hbalock); | ||
5079 | } | ||
5080 | return rc; | ||
5081 | } | ||
5082 | |||
5083 | /** | ||
5084 | * lpfc_sli4_async_mbox_unblock - Block posting SLI4 async mailbox command | ||
5085 | * @phba: Pointer to HBA context object. | ||
5086 | * | ||
5087 | * The function unblocks and resume posting of SLI4 asynchronous mailbox | ||
5088 | * commands from the driver internal pending mailbox queue. It makes sure | ||
5089 | * that there is no outstanding mailbox command before resuming posting | ||
5090 | * asynchronous mailbox commands. If, for any reason, there is outstanding | ||
5091 | * mailbox command, it will try to wait it out before resuming asynchronous | ||
5092 | * mailbox command posting. | ||
5093 | **/ | ||
5094 | static void | ||
5095 | lpfc_sli4_async_mbox_unblock(struct lpfc_hba *phba) | ||
5096 | { | ||
5097 | struct lpfc_sli *psli = &phba->sli; | ||
5098 | |||
5099 | spin_lock_irq(&phba->hbalock); | ||
5100 | if (!(psli->sli_flag & LPFC_SLI_ASYNC_MBX_BLK)) { | ||
5101 | /* Asynchronous mailbox posting is not blocked, do nothing */ | ||
5102 | spin_unlock_irq(&phba->hbalock); | ||
5103 | return; | ||
5104 | } | ||
5105 | |||
5106 | /* Outstanding synchronous mailbox command is guaranteed to be done, | ||
5107 | * successful or timeout, after timing-out the outstanding mailbox | ||
5108 | * command shall always be removed, so just unblock posting async | ||
5109 | * mailbox command and resume | ||
5110 | */ | ||
5111 | psli->sli_flag &= ~LPFC_SLI_ASYNC_MBX_BLK; | ||
5112 | spin_unlock_irq(&phba->hbalock); | ||
5113 | |||
5114 | /* wake up worker thread to post asynchronlous mailbox command */ | ||
5115 | lpfc_worker_wake_up(phba); | ||
5116 | } | ||
5117 | |||
5118 | /** | ||
5033 | * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox | 5119 | * lpfc_sli4_post_sync_mbox - Post an SLI4 mailbox to the bootstrap mailbox |
5034 | * @phba: Pointer to HBA context object. | 5120 | * @phba: Pointer to HBA context object. |
5035 | * @mboxq: Pointer to mailbox object. | 5121 | * @mboxq: Pointer to mailbox object. |
@@ -5204,14 +5290,35 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
5204 | psli->sli_flag, flag); | 5290 | psli->sli_flag, flag); |
5205 | return rc; | 5291 | return rc; |
5206 | } else if (flag == MBX_POLL) { | 5292 | } else if (flag == MBX_POLL) { |
5207 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | 5293 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, |
5208 | "(%d):2542 Mailbox command x%x (x%x) " | 5294 | "(%d):2542 Try to issue mailbox command " |
5209 | "cannot issue Data: x%x x%x\n", | 5295 | "x%x (x%x) synchronously ahead of async" |
5296 | "mailbox command queue: x%x x%x\n", | ||
5210 | mboxq->vport ? mboxq->vport->vpi : 0, | 5297 | mboxq->vport ? mboxq->vport->vpi : 0, |
5211 | mboxq->u.mb.mbxCommand, | 5298 | mboxq->u.mb.mbxCommand, |
5212 | lpfc_sli4_mbox_opcode_get(phba, mboxq), | 5299 | lpfc_sli4_mbox_opcode_get(phba, mboxq), |
5213 | psli->sli_flag, flag); | 5300 | psli->sli_flag, flag); |
5214 | return -EIO; | 5301 | /* Try to block the asynchronous mailbox posting */ |
5302 | rc = lpfc_sli4_async_mbox_block(phba); | ||
5303 | if (!rc) { | ||
5304 | /* Successfully blocked, now issue sync mbox cmd */ | ||
5305 | rc = lpfc_sli4_post_sync_mbox(phba, mboxq); | ||
5306 | if (rc != MBX_SUCCESS) | ||
5307 | lpfc_printf_log(phba, KERN_ERR, | ||
5308 | LOG_MBOX | LOG_SLI, | ||
5309 | "(%d):2597 Mailbox command " | ||
5310 | "x%x (x%x) cannot issue " | ||
5311 | "Data: x%x x%x\n", | ||
5312 | mboxq->vport ? | ||
5313 | mboxq->vport->vpi : 0, | ||
5314 | mboxq->u.mb.mbxCommand, | ||
5315 | lpfc_sli4_mbox_opcode_get(phba, | ||
5316 | mboxq), | ||
5317 | psli->sli_flag, flag); | ||
5318 | /* Unblock the async mailbox posting afterward */ | ||
5319 | lpfc_sli4_async_mbox_unblock(phba); | ||
5320 | } | ||
5321 | return rc; | ||
5215 | } | 5322 | } |
5216 | 5323 | ||
5217 | /* Now, interrupt mode asynchrous mailbox command */ | 5324 | /* Now, interrupt mode asynchrous mailbox command */ |
@@ -5814,11 +5921,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5814 | bf_set(lpfc_wqe_gen_context, &wqe->generic, | 5921 | bf_set(lpfc_wqe_gen_context, &wqe->generic, |
5815 | iocbq->iocb.ulpContext); | 5922 | iocbq->iocb.ulpContext); |
5816 | 5923 | ||
5817 | if (iocbq->vport->fc_myDID != 0) { | ||
5818 | bf_set(els_req64_sid, &wqe->els_req, | ||
5819 | iocbq->vport->fc_myDID); | ||
5820 | bf_set(els_req64_sp, &wqe->els_req, 1); | ||
5821 | } | ||
5822 | bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct); | 5924 | bf_set(lpfc_wqe_gen_ct, &wqe->generic, ct); |
5823 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); | 5925 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); |
5824 | /* CCP CCPE PV PRI in word10 were set in the memcpy */ | 5926 | /* CCP CCPE PV PRI in word10 were set in the memcpy */ |
@@ -5877,14 +5979,19 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5877 | * is set and we are sending our 2nd or greater command on | 5979 | * is set and we are sending our 2nd or greater command on |
5878 | * this exchange. | 5980 | * this exchange. |
5879 | */ | 5981 | */ |
5982 | /* Always open the exchange */ | ||
5983 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | ||
5880 | 5984 | ||
5881 | /* ALLOW read & write to fall through to ICMD64 */ | 5985 | wqe->words[10] &= 0xffff0000; /* zero out ebde count */ |
5986 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU); | ||
5987 | break; | ||
5882 | case CMD_FCP_ICMND64_CR: | 5988 | case CMD_FCP_ICMND64_CR: |
5883 | /* Always open the exchange */ | 5989 | /* Always open the exchange */ |
5884 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | 5990 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); |
5885 | 5991 | ||
5992 | wqe->words[4] = 0; | ||
5886 | wqe->words[10] &= 0xffff0000; /* zero out ebde count */ | 5993 | wqe->words[10] &= 0xffff0000; /* zero out ebde count */ |
5887 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, iocbq->iocb.ulpPU); | 5994 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); |
5888 | break; | 5995 | break; |
5889 | case CMD_GEN_REQUEST64_CR: | 5996 | case CMD_GEN_REQUEST64_CR: |
5890 | /* word3 command length is described as byte offset to the | 5997 | /* word3 command length is described as byte offset to the |
@@ -11020,10 +11127,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) | |||
11020 | rpi_page->start_rpi); | 11127 | rpi_page->start_rpi); |
11021 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); | 11128 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); |
11022 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); | 11129 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); |
11023 | if (!phba->sli4_hba.intr_enable) | 11130 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); |
11024 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
11025 | else | ||
11026 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | ||
11027 | shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; | 11131 | shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; |
11028 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 11132 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
11029 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | 11133 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); |