diff options
author | James Smart <james.smart@broadcom.com> | 2016-03-31 17:12:30 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-04-11 16:57:09 -0400 |
commit | b5c539583988b70bddea73f333c640fc93a62e88 (patch) | |
tree | 48becf9f18b004f037f3167ee4a66cfe03e156b8 /drivers/scsi/lpfc | |
parent | a6517db9006eb618dfde54f4bf6a9a8bc21e16e7 (diff) |
lpfc: Utilize embedded CDB logic to minimize IO latency
Pass cmd iu payloads inline to adapter job structure rather than as
separate dma buffers.
Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com>
Signed-off-by: James Smart <james.smart@avagotech.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 20 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 128 |
5 files changed, 136 insertions, 20 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 90a3ca5a4dbd..da237d9c4b55 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -694,6 +694,7 @@ struct lpfc_hba { | |||
694 | uint8_t wwnn[8]; | 694 | uint8_t wwnn[8]; |
695 | uint8_t wwpn[8]; | 695 | uint8_t wwpn[8]; |
696 | uint32_t RandomData[7]; | 696 | uint32_t RandomData[7]; |
697 | uint32_t fcp_embed_io; | ||
697 | 698 | ||
698 | /* HBA Config Parameters */ | 699 | /* HBA Config Parameters */ |
699 | uint32_t cfg_ack0; | 700 | uint32_t cfg_ack0; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 343ae9482891..d4559a6175e2 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -5150,7 +5150,6 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport) | |||
5150 | sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); | 5150 | sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); |
5151 | } | 5151 | } |
5152 | 5152 | ||
5153 | |||
5154 | /* | 5153 | /* |
5155 | * Dynamic FC Host Attributes Support | 5154 | * Dynamic FC Host Attributes Support |
5156 | */ | 5155 | */ |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 608f9415fb08..aea00f8be9ac 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -2865,6 +2865,9 @@ struct lpfc_sli4_parameters { | |||
2865 | uint32_t word17; | 2865 | uint32_t word17; |
2866 | uint32_t word18; | 2866 | uint32_t word18; |
2867 | uint32_t word19; | 2867 | uint32_t word19; |
2868 | #define cfg_ext_embed_cb_SHIFT 0 | ||
2869 | #define cfg_ext_embed_cb_MASK 0x00000001 | ||
2870 | #define cfg_ext_embed_cb_WORD word19 | ||
2868 | }; | 2871 | }; |
2869 | 2872 | ||
2870 | struct lpfc_mbx_get_sli4_parameters { | 2873 | struct lpfc_mbx_get_sli4_parameters { |
@@ -3919,6 +3922,9 @@ union lpfc_wqe { | |||
3919 | union lpfc_wqe128 { | 3922 | union lpfc_wqe128 { |
3920 | uint32_t words[32]; | 3923 | uint32_t words[32]; |
3921 | struct lpfc_wqe_generic generic; | 3924 | struct lpfc_wqe_generic generic; |
3925 | struct fcp_icmnd64_wqe fcp_icmd; | ||
3926 | struct fcp_iread64_wqe fcp_iread; | ||
3927 | struct fcp_iwrite64_wqe fcp_iwrite; | ||
3922 | struct xmit_seq64_wqe xmit_sequence; | 3928 | struct xmit_seq64_wqe xmit_sequence; |
3923 | struct gen_req64_wqe gen_req; | 3929 | struct gen_req64_wqe gen_req; |
3924 | }; | 3930 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f57d02c3b6cf..f0d0852bee0d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -7264,8 +7264,15 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
7264 | phba->sli4_hba.fcp_cq[idx] = qdesc; | 7264 | phba->sli4_hba.fcp_cq[idx] = qdesc; |
7265 | 7265 | ||
7266 | /* Create Fast Path FCP WQs */ | 7266 | /* Create Fast Path FCP WQs */ |
7267 | qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize, | 7267 | if (phba->fcp_embed_io) { |
7268 | phba->sli4_hba.wq_ecount); | 7268 | qdesc = lpfc_sli4_queue_alloc(phba, |
7269 | LPFC_WQE128_SIZE, | ||
7270 | LPFC_WQE128_DEF_COUNT); | ||
7271 | } else { | ||
7272 | qdesc = lpfc_sli4_queue_alloc(phba, | ||
7273 | phba->sli4_hba.wq_esize, | ||
7274 | phba->sli4_hba.wq_ecount); | ||
7275 | } | ||
7269 | if (!qdesc) { | 7276 | if (!qdesc) { |
7270 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7277 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
7271 | "0503 Failed allocate fast-path FCP " | 7278 | "0503 Failed allocate fast-path FCP " |
@@ -9510,6 +9517,15 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
9510 | if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) | 9517 | if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) |
9511 | sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; | 9518 | sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; |
9512 | 9519 | ||
9520 | /* | ||
9521 | * Issue IOs with CDB embedded in WQE to minimized the number | ||
9522 | * of DMAs the firmware has to do. Setting this to 1 also forces | ||
9523 | * the driver to use 128 bytes WQEs for FCP IOs. | ||
9524 | */ | ||
9525 | if (bf_get(cfg_ext_embed_cb, mbx_sli4_parameters)) | ||
9526 | phba->fcp_embed_io = 1; | ||
9527 | else | ||
9528 | phba->fcp_embed_io = 0; | ||
9513 | return 0; | 9529 | return 0; |
9514 | } | 9530 | } |
9515 | 9531 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 035105a24298..9c8368a7149a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -4689,6 +4689,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) | |||
4689 | 4689 | ||
4690 | break; | 4690 | break; |
4691 | } | 4691 | } |
4692 | phba->fcp_embed_io = 0; /* SLI4 FC support only */ | ||
4692 | 4693 | ||
4693 | rc = lpfc_sli_config_port(phba, mode); | 4694 | rc = lpfc_sli_config_port(phba, mode); |
4694 | 4695 | ||
@@ -6321,10 +6322,12 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
6321 | 6322 | ||
6322 | mqe = &mboxq->u.mqe; | 6323 | mqe = &mboxq->u.mqe; |
6323 | phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev); | 6324 | phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev); |
6324 | if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)) | 6325 | if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)) { |
6325 | phba->hba_flag |= HBA_FCOE_MODE; | 6326 | phba->hba_flag |= HBA_FCOE_MODE; |
6326 | else | 6327 | phba->fcp_embed_io = 0; /* SLI4 FC support only */ |
6328 | } else { | ||
6327 | phba->hba_flag &= ~HBA_FCOE_MODE; | 6329 | phba->hba_flag &= ~HBA_FCOE_MODE; |
6330 | } | ||
6328 | 6331 | ||
6329 | if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) == | 6332 | if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) == |
6330 | LPFC_DCBX_CEE_MODE) | 6333 | LPFC_DCBX_CEE_MODE) |
@@ -8219,12 +8222,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8219 | else | 8222 | else |
8220 | command_type = ELS_COMMAND_NON_FIP; | 8223 | command_type = ELS_COMMAND_NON_FIP; |
8221 | 8224 | ||
8225 | if (phba->fcp_embed_io) | ||
8226 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
8222 | /* Some of the fields are in the right position already */ | 8227 | /* Some of the fields are in the right position already */ |
8223 | memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe)); | 8228 | memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe)); |
8224 | abort_tag = (uint32_t) iocbq->iotag; | ||
8225 | xritag = iocbq->sli4_xritag; | ||
8226 | wqe->generic.wqe_com.word7 = 0; /* The ct field has moved so reset */ | 8229 | wqe->generic.wqe_com.word7 = 0; /* The ct field has moved so reset */ |
8227 | wqe->generic.wqe_com.word10 = 0; | 8230 | wqe->generic.wqe_com.word10 = 0; |
8231 | |||
8232 | abort_tag = (uint32_t) iocbq->iotag; | ||
8233 | xritag = iocbq->sli4_xritag; | ||
8228 | /* words0-2 bpl convert bde */ | 8234 | /* words0-2 bpl convert bde */ |
8229 | if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { | 8235 | if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { |
8230 | numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize / | 8236 | numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize / |
@@ -8373,11 +8379,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8373 | iocbq->iocb.ulpFCP2Rcvy); | 8379 | iocbq->iocb.ulpFCP2Rcvy); |
8374 | bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS); | 8380 | bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS); |
8375 | /* Always open the exchange */ | 8381 | /* Always open the exchange */ |
8376 | bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0); | ||
8377 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); | 8382 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); |
8378 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, | 8383 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, |
8379 | LPFC_WQE_LENLOC_WORD4); | 8384 | LPFC_WQE_LENLOC_WORD4); |
8380 | bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0); | ||
8381 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); | 8385 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU); |
8382 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); | 8386 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1); |
8383 | if (iocbq->iocb_flag & LPFC_IO_OAS) { | 8387 | if (iocbq->iocb_flag & LPFC_IO_OAS) { |
@@ -8388,6 +8392,35 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8388 | (phba->cfg_XLanePriority << 1)); | 8392 | (phba->cfg_XLanePriority << 1)); |
8389 | } | 8393 | } |
8390 | } | 8394 | } |
8395 | /* Note, word 10 is already initialized to 0 */ | ||
8396 | |||
8397 | if (phba->fcp_embed_io) { | ||
8398 | struct lpfc_scsi_buf *lpfc_cmd; | ||
8399 | struct sli4_sge *sgl; | ||
8400 | union lpfc_wqe128 *wqe128; | ||
8401 | struct fcp_cmnd *fcp_cmnd; | ||
8402 | uint32_t *ptr; | ||
8403 | |||
8404 | /* 128 byte wqe support here */ | ||
8405 | wqe128 = (union lpfc_wqe128 *)wqe; | ||
8406 | |||
8407 | lpfc_cmd = iocbq->context1; | ||
8408 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | ||
8409 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | ||
8410 | |||
8411 | /* Word 0-2 - FCP_CMND */ | ||
8412 | wqe128->generic.bde.tus.f.bdeFlags = | ||
8413 | BUFF_TYPE_BDE_IMMED; | ||
8414 | wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len; | ||
8415 | wqe128->generic.bde.addrHigh = 0; | ||
8416 | wqe128->generic.bde.addrLow = 88; /* Word 22 */ | ||
8417 | |||
8418 | bf_set(wqe_wqes, &wqe128->fcp_iwrite.wqe_com, 1); | ||
8419 | |||
8420 | /* Word 22-29 FCP CMND Payload */ | ||
8421 | ptr = &wqe128->words[22]; | ||
8422 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); | ||
8423 | } | ||
8391 | break; | 8424 | break; |
8392 | case CMD_FCP_IREAD64_CR: | 8425 | case CMD_FCP_IREAD64_CR: |
8393 | /* word3 iocb=iotag wqe=payload_offset_len */ | 8426 | /* word3 iocb=iotag wqe=payload_offset_len */ |
@@ -8402,11 +8435,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8402 | iocbq->iocb.ulpFCP2Rcvy); | 8435 | iocbq->iocb.ulpFCP2Rcvy); |
8403 | bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS); | 8436 | bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS); |
8404 | /* Always open the exchange */ | 8437 | /* Always open the exchange */ |
8405 | bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0); | ||
8406 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); | 8438 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); |
8407 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, | 8439 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, |
8408 | LPFC_WQE_LENLOC_WORD4); | 8440 | LPFC_WQE_LENLOC_WORD4); |
8409 | bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0); | ||
8410 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); | 8441 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU); |
8411 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); | 8442 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1); |
8412 | if (iocbq->iocb_flag & LPFC_IO_OAS) { | 8443 | if (iocbq->iocb_flag & LPFC_IO_OAS) { |
@@ -8417,6 +8448,35 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8417 | (phba->cfg_XLanePriority << 1)); | 8448 | (phba->cfg_XLanePriority << 1)); |
8418 | } | 8449 | } |
8419 | } | 8450 | } |
8451 | /* Note, word 10 is already initialized to 0 */ | ||
8452 | |||
8453 | if (phba->fcp_embed_io) { | ||
8454 | struct lpfc_scsi_buf *lpfc_cmd; | ||
8455 | struct sli4_sge *sgl; | ||
8456 | union lpfc_wqe128 *wqe128; | ||
8457 | struct fcp_cmnd *fcp_cmnd; | ||
8458 | uint32_t *ptr; | ||
8459 | |||
8460 | /* 128 byte wqe support here */ | ||
8461 | wqe128 = (union lpfc_wqe128 *)wqe; | ||
8462 | |||
8463 | lpfc_cmd = iocbq->context1; | ||
8464 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | ||
8465 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | ||
8466 | |||
8467 | /* Word 0-2 - FCP_CMND */ | ||
8468 | wqe128->generic.bde.tus.f.bdeFlags = | ||
8469 | BUFF_TYPE_BDE_IMMED; | ||
8470 | wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len; | ||
8471 | wqe128->generic.bde.addrHigh = 0; | ||
8472 | wqe128->generic.bde.addrLow = 88; /* Word 22 */ | ||
8473 | |||
8474 | bf_set(wqe_wqes, &wqe128->fcp_iread.wqe_com, 1); | ||
8475 | |||
8476 | /* Word 22-29 FCP CMND Payload */ | ||
8477 | ptr = &wqe128->words[22]; | ||
8478 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); | ||
8479 | } | ||
8420 | break; | 8480 | break; |
8421 | case CMD_FCP_ICMND64_CR: | 8481 | case CMD_FCP_ICMND64_CR: |
8422 | /* word3 iocb=iotag wqe=payload_offset_len */ | 8482 | /* word3 iocb=iotag wqe=payload_offset_len */ |
@@ -8428,13 +8488,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8428 | /* word3 iocb=IO_TAG wqe=reserved */ | 8488 | /* word3 iocb=IO_TAG wqe=reserved */ |
8429 | bf_set(wqe_pu, &wqe->fcp_icmd.wqe_com, 0); | 8489 | bf_set(wqe_pu, &wqe->fcp_icmd.wqe_com, 0); |
8430 | /* Always open the exchange */ | 8490 | /* Always open the exchange */ |
8431 | bf_set(wqe_xc, &wqe->fcp_icmd.wqe_com, 0); | ||
8432 | bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 1); | 8491 | bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 1); |
8433 | bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_WRITE); | 8492 | bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_WRITE); |
8434 | bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1); | 8493 | bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1); |
8435 | bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, | 8494 | bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, |
8436 | LPFC_WQE_LENLOC_NONE); | 8495 | LPFC_WQE_LENLOC_NONE); |
8437 | bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0); | ||
8438 | bf_set(wqe_erp, &wqe->fcp_icmd.wqe_com, | 8496 | bf_set(wqe_erp, &wqe->fcp_icmd.wqe_com, |
8439 | iocbq->iocb.ulpFCP2Rcvy); | 8497 | iocbq->iocb.ulpFCP2Rcvy); |
8440 | if (iocbq->iocb_flag & LPFC_IO_OAS) { | 8498 | if (iocbq->iocb_flag & LPFC_IO_OAS) { |
@@ -8445,6 +8503,35 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
8445 | (phba->cfg_XLanePriority << 1)); | 8503 | (phba->cfg_XLanePriority << 1)); |
8446 | } | 8504 | } |
8447 | } | 8505 | } |
8506 | /* Note, word 10 is already initialized to 0 */ | ||
8507 | |||
8508 | if (phba->fcp_embed_io) { | ||
8509 | struct lpfc_scsi_buf *lpfc_cmd; | ||
8510 | struct sli4_sge *sgl; | ||
8511 | union lpfc_wqe128 *wqe128; | ||
8512 | struct fcp_cmnd *fcp_cmnd; | ||
8513 | uint32_t *ptr; | ||
8514 | |||
8515 | /* 128 byte wqe support here */ | ||
8516 | wqe128 = (union lpfc_wqe128 *)wqe; | ||
8517 | |||
8518 | lpfc_cmd = iocbq->context1; | ||
8519 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | ||
8520 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | ||
8521 | |||
8522 | /* Word 0-2 - FCP_CMND */ | ||
8523 | wqe128->generic.bde.tus.f.bdeFlags = | ||
8524 | BUFF_TYPE_BDE_IMMED; | ||
8525 | wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len; | ||
8526 | wqe128->generic.bde.addrHigh = 0; | ||
8527 | wqe128->generic.bde.addrLow = 88; /* Word 22 */ | ||
8528 | |||
8529 | bf_set(wqe_wqes, &wqe128->fcp_icmd.wqe_com, 1); | ||
8530 | |||
8531 | /* Word 22-29 FCP CMND Payload */ | ||
8532 | ptr = &wqe128->words[22]; | ||
8533 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); | ||
8534 | } | ||
8448 | break; | 8535 | break; |
8449 | case CMD_GEN_REQUEST64_CR: | 8536 | case CMD_GEN_REQUEST64_CR: |
8450 | /* For this command calculate the xmit length of the | 8537 | /* For this command calculate the xmit length of the |
@@ -8676,12 +8763,19 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
8676 | struct lpfc_iocbq *piocb, uint32_t flag) | 8763 | struct lpfc_iocbq *piocb, uint32_t flag) |
8677 | { | 8764 | { |
8678 | struct lpfc_sglq *sglq; | 8765 | struct lpfc_sglq *sglq; |
8679 | union lpfc_wqe wqe; | 8766 | union lpfc_wqe *wqe; |
8767 | union lpfc_wqe128 wqe128; | ||
8680 | struct lpfc_queue *wq; | 8768 | struct lpfc_queue *wq; |
8681 | struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number]; | 8769 | struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number]; |
8682 | 8770 | ||
8683 | lockdep_assert_held(&phba->hbalock); | 8771 | lockdep_assert_held(&phba->hbalock); |
8684 | 8772 | ||
8773 | /* | ||
8774 | * The WQE can be either 64 or 128 bytes, | ||
8775 | * so allocate space on the stack assuming the largest. | ||
8776 | */ | ||
8777 | wqe = (union lpfc_wqe *)&wqe128; | ||
8778 | |||
8685 | if (piocb->sli4_xritag == NO_XRI) { | 8779 | if (piocb->sli4_xritag == NO_XRI) { |
8686 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || | 8780 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || |
8687 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN) | 8781 | piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN) |
@@ -8728,7 +8822,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
8728 | return IOCB_ERROR; | 8822 | return IOCB_ERROR; |
8729 | } | 8823 | } |
8730 | 8824 | ||
8731 | if (lpfc_sli4_iocb2wqe(phba, piocb, &wqe)) | 8825 | if (lpfc_sli4_iocb2wqe(phba, piocb, wqe)) |
8732 | return IOCB_ERROR; | 8826 | return IOCB_ERROR; |
8733 | 8827 | ||
8734 | if ((piocb->iocb_flag & LPFC_IO_FCP) || | 8828 | if ((piocb->iocb_flag & LPFC_IO_FCP) || |
@@ -8738,12 +8832,12 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
8738 | } else { | 8832 | } else { |
8739 | wq = phba->sli4_hba.oas_wq; | 8833 | wq = phba->sli4_hba.oas_wq; |
8740 | } | 8834 | } |
8741 | if (lpfc_sli4_wq_put(wq, &wqe)) | 8835 | if (lpfc_sli4_wq_put(wq, wqe)) |
8742 | return IOCB_ERROR; | 8836 | return IOCB_ERROR; |
8743 | } else { | 8837 | } else { |
8744 | if (unlikely(!phba->sli4_hba.els_wq)) | 8838 | if (unlikely(!phba->sli4_hba.els_wq)) |
8745 | return IOCB_ERROR; | 8839 | return IOCB_ERROR; |
8746 | if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) | 8840 | if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, wqe)) |
8747 | return IOCB_ERROR; | 8841 | return IOCB_ERROR; |
8748 | } | 8842 | } |
8749 | lpfc_sli_ringtxcmpl_put(phba, pring, piocb); | 8843 | lpfc_sli_ringtxcmpl_put(phba, pring, piocb); |
@@ -8758,9 +8852,9 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
8758 | * pointer from the lpfc_hba struct. | 8852 | * pointer from the lpfc_hba struct. |
8759 | * | 8853 | * |
8760 | * Return codes: | 8854 | * Return codes: |
8761 | * IOCB_ERROR - Error | 8855 | * IOCB_ERROR - Error |
8762 | * IOCB_SUCCESS - Success | 8856 | * IOCB_SUCCESS - Success |
8763 | * IOCB_BUSY - Busy | 8857 | * IOCB_BUSY - Busy |
8764 | **/ | 8858 | **/ |
8765 | int | 8859 | int |
8766 | __lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, | 8860 | __lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, |