aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-05-09 21:19:03 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-17 06:09:55 -0400
commit939723a4a680a7863fc95179b1480c5529f31d88 (patch)
tree247a5737b39aea3e3dfda95d9f59210bda5f6704 /drivers/scsi/lpfc/lpfc_sli.c
parent27aa1b73539f2c7118a68c9baaad590d3a92462f (diff)
[SCSI] lpfc 8.3.31: Correct point-to-point mode discovery errors on LPe16xxx
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.c70
1 files changed, 61 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index b035e5badd52..e84dd32553bc 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -7907,6 +7907,10 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
7907 bf_set(els_req64_sp, &wqe->els_req, 1); 7907 bf_set(els_req64_sp, &wqe->els_req, 1);
7908 bf_set(els_req64_sid, &wqe->els_req, 7908 bf_set(els_req64_sid, &wqe->els_req,
7909 iocbq->vport->fc_myDID); 7909 iocbq->vport->fc_myDID);
7910 if ((*pcmd == ELS_CMD_FLOGI) &&
7911 !(phba->fc_topology ==
7912 LPFC_TOPOLOGY_LOOP))
7913 bf_set(els_req64_sid, &wqe->els_req, 0);
7910 bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); 7914 bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
7911 bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, 7915 bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
7912 phba->vpi_ids[iocbq->vport->vpi]); 7916 phba->vpi_ids[iocbq->vport->vpi]);
@@ -8064,11 +8068,25 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8064 /* words0-2 BDE memcpy */ 8068 /* words0-2 BDE memcpy */
8065 /* word3 iocb=iotag32 wqe=response_payload_len */ 8069 /* word3 iocb=iotag32 wqe=response_payload_len */
8066 wqe->xmit_els_rsp.response_payload_len = xmit_len; 8070 wqe->xmit_els_rsp.response_payload_len = xmit_len;
8067 /* word4 iocb=did wge=rsvd. */ 8071 /* word4 */
8068 wqe->xmit_els_rsp.rsvd4 = 0; 8072 wqe->xmit_els_rsp.word4 = 0;
8069 /* word5 iocb=rsvd wge=did */ 8073 /* word5 iocb=rsvd wge=did */
8070 bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest, 8074 bf_set(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest,
8071 iocbq->iocb.un.elsreq64.remoteID); 8075 iocbq->iocb.un.xseq64.xmit_els_remoteID);
8076
8077 if_type = bf_get(lpfc_sli_intf_if_type,
8078 &phba->sli4_hba.sli_intf);
8079 if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
8080 if (iocbq->vport->fc_flag & FC_PT2PT) {
8081 bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
8082 bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
8083 iocbq->vport->fc_myDID);
8084 if (iocbq->vport->fc_myDID == Fabric_DID) {
8085 bf_set(wqe_els_did,
8086 &wqe->xmit_els_rsp.wqe_dest, 0);
8087 }
8088 }
8089 }
8072 bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 8090 bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com,
8073 ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l)); 8091 ((iocbq->iocb.ulpCt_h << 1) | iocbq->iocb.ulpCt_l));
8074 bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU); 8092 bf_set(wqe_pu, &wqe->xmit_els_rsp.wqe_com, iocbq->iocb.ulpPU);
@@ -8088,11 +8106,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8088 pcmd = (uint32_t *) (((struct lpfc_dmabuf *) 8106 pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
8089 iocbq->context2)->virt); 8107 iocbq->context2)->virt);
8090 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { 8108 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
8091 bf_set(els_req64_sp, &wqe->els_req, 1); 8109 bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1);
8092 bf_set(els_req64_sid, &wqe->els_req, 8110 bf_set(els_rsp64_sid, &wqe->xmit_els_rsp,
8093 iocbq->vport->fc_myDID); 8111 iocbq->vport->fc_myDID);
8094 bf_set(wqe_ct, &wqe->els_req.wqe_com, 1); 8112 bf_set(wqe_ct, &wqe->xmit_els_rsp.wqe_com, 1);
8095 bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com, 8113 bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
8096 phba->vpi_ids[phba->pport->vpi]); 8114 phba->vpi_ids[phba->pport->vpi]);
8097 } 8115 }
8098 command_type = OTHER_COMMAND; 8116 command_type = OTHER_COMMAND;
@@ -13636,8 +13654,13 @@ lpfc_fc_frame_to_vport(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr,
13636 uint32_t did = (fc_hdr->fh_d_id[0] << 16 | 13654 uint32_t did = (fc_hdr->fh_d_id[0] << 16 |
13637 fc_hdr->fh_d_id[1] << 8 | 13655 fc_hdr->fh_d_id[1] << 8 |
13638 fc_hdr->fh_d_id[2]); 13656 fc_hdr->fh_d_id[2]);
13657
13639 if (did == Fabric_DID) 13658 if (did == Fabric_DID)
13640 return phba->pport; 13659 return phba->pport;
13660 if ((phba->pport->fc_flag & FC_PT2PT) &&
13661 !(phba->link_state == LPFC_HBA_READY))
13662 return phba->pport;
13663
13641 vports = lpfc_create_vport_work_array(phba); 13664 vports = lpfc_create_vport_work_array(phba);
13642 if (vports != NULL) 13665 if (vports != NULL)
13643 for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { 13666 for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
@@ -14174,7 +14197,15 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
14174 /* Initialize the first IOCB. */ 14197 /* Initialize the first IOCB. */
14175 first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0; 14198 first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
14176 first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS; 14199 first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
14177 first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX; 14200
14201 /* Check FC Header to see what TYPE of frame we are rcv'ing */
14202 if (sli4_type_from_fc_hdr(fc_hdr) == FC_TYPE_ELS) {
14203 first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_ELS64_CX;
14204 first_iocbq->iocb.un.rcvels.parmRo =
14205 sli4_did_from_fc_hdr(fc_hdr);
14206 first_iocbq->iocb.ulpPU = PARM_NPIV_DID;
14207 } else
14208 first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
14178 first_iocbq->iocb.ulpContext = NO_XRI; 14209 first_iocbq->iocb.ulpContext = NO_XRI;
14179 first_iocbq->iocb.unsli3.rcvsli3.ox_id = 14210 first_iocbq->iocb.unsli3.rcvsli3.ox_id =
14180 be16_to_cpu(fc_hdr->fh_ox_id); 14211 be16_to_cpu(fc_hdr->fh_ox_id);
@@ -14304,6 +14335,7 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
14304 struct fc_frame_header *fc_hdr; 14335 struct fc_frame_header *fc_hdr;
14305 struct lpfc_vport *vport; 14336 struct lpfc_vport *vport;
14306 uint32_t fcfi; 14337 uint32_t fcfi;
14338 uint32_t did;
14307 14339
14308 /* Process each received buffer */ 14340 /* Process each received buffer */
14309 fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; 14341 fc_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt;
@@ -14319,12 +14351,32 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
14319 else 14351 else
14320 fcfi = bf_get(lpfc_rcqe_fcf_id, 14352 fcfi = bf_get(lpfc_rcqe_fcf_id,
14321 &dmabuf->cq_event.cqe.rcqe_cmpl); 14353 &dmabuf->cq_event.cqe.rcqe_cmpl);
14354
14322 vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi); 14355 vport = lpfc_fc_frame_to_vport(phba, fc_hdr, fcfi);
14323 if (!vport || !(vport->vpi_state & LPFC_VPI_REGISTERED)) { 14356 if (!vport) {
14324 /* throw out the frame */ 14357 /* throw out the frame */
14325 lpfc_in_buf_free(phba, &dmabuf->dbuf); 14358 lpfc_in_buf_free(phba, &dmabuf->dbuf);
14326 return; 14359 return;
14327 } 14360 }
14361
14362 /* d_id this frame is directed to */
14363 did = sli4_did_from_fc_hdr(fc_hdr);
14364
14365 /* vport is registered unless we rcv a FLOGI directed to Fabric_DID */
14366 if (!(vport->vpi_state & LPFC_VPI_REGISTERED) &&
14367 (did != Fabric_DID)) {
14368 /*
14369 * Throw out the frame if we are not pt2pt.
14370 * The pt2pt protocol allows for discovery frames
14371 * to be received without a registered VPI.
14372 */
14373 if (!(vport->fc_flag & FC_PT2PT) ||
14374 (phba->link_state == LPFC_HBA_READY)) {
14375 lpfc_in_buf_free(phba, &dmabuf->dbuf);
14376 return;
14377 }
14378 }
14379
14328 /* Handle the basic abort sequence (BA_ABTS) event */ 14380 /* Handle the basic abort sequence (BA_ABTS) event */
14329 if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) { 14381 if (fc_hdr->fh_r_ctl == FC_RCTL_BA_ABTS) {
14330 lpfc_sli4_handle_unsol_abort(vport, dmabuf); 14382 lpfc_sli4_handle_unsol_abort(vport, dmabuf);