aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-06-10 17:22:44 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-15 11:09:32 -0400
commitf1126688805d77a4798b694439fa48bba6629388 (patch)
tree8a6169f70dba7e8644f07c8ca654ebad1786281d /drivers/scsi/lpfc/lpfc_sli.c
parent43fac4d97a1a30085f1cae61aa565e5e7e5e5d7d (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.c198
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 **/
5044static int
5045lpfc_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 **/
5094static void
5095lpfc_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);