diff options
author | James Smart <james.smart@emulex.com> | 2012-05-09 21:19:03 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-05-17 06:09:55 -0400 |
commit | 939723a4a680a7863fc95179b1480c5529f31d88 (patch) | |
tree | 247a5737b39aea3e3dfda95d9f59210bda5f6704 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 27aa1b73539f2c7118a68c9baaad590d3a92462f (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.c | 70 |
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); |