Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: lpfc: Add support for 32 byte CDBs

The driver's I/O path is updated to support 32 byte CDBs.

Changes to accommodate 32 byte CDBs include:

- Updating various size fields to allow for the larger 32 byte CDB.

- Starting the FCP command payload at an earlier offset in WQE submission
to fit the 32 byte CDB.

- Redefining relevant structs to __le32/__be32 data types for proper cpu
endianness macro usage.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240429221547.6842-7-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Justin Tee and committed by
Martin K. Petersen
af20bb73 e780c942

+80 -38
+8
drivers/scsi/lpfc/lpfc_hw4.h
··· 2146 2146 uint32_t sge_len; 2147 2147 }; 2148 2148 2149 + struct sli4_sge_le { 2150 + __le32 addr_hi; 2151 + __le32 addr_lo; 2152 + 2153 + __le32 word2; 2154 + __le32 sge_len; 2155 + }; 2156 + 2149 2157 struct sli4_hybrid_sgl { 2150 2158 struct list_head list_node; 2151 2159 struct sli4_sge *dma_sgl;
+7 -4
drivers/scsi/lpfc/lpfc_init.c
··· 4773 4773 shost->max_id = LPFC_MAX_TARGET; 4774 4774 shost->max_lun = vport->cfg_max_luns; 4775 4775 shost->this_id = -1; 4776 - shost->max_cmd_len = 16; 4776 + if (phba->sli_rev == LPFC_SLI_REV4) 4777 + shost->max_cmd_len = LPFC_FCP_CDB_LEN_32; 4778 + else 4779 + shost->max_cmd_len = LPFC_FCP_CDB_LEN; 4777 4780 4778 4781 if (phba->sli_rev == LPFC_SLI_REV4) { 4779 4782 if (!phba->cfg_fcp_mq_threshold || ··· 8234 8231 * our max amount and we need to limit lpfc_sg_seg_cnt 8235 8232 * to minimize the risk of running out. 8236 8233 */ 8237 - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + 8234 + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd32) + 8238 8235 sizeof(struct fcp_rsp) + max_buf_size; 8239 8236 8240 8237 /* Total SGEs for scsi_sg_list and scsi_sg_prot_list */ ··· 8256 8253 * the FCP rsp, a SGE for each, and a SGE for up to 8257 8254 * cfg_sg_seg_cnt data segments. 8258 8255 */ 8259 - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + 8256 + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd32) + 8260 8257 sizeof(struct fcp_rsp) + 8261 8258 ((phba->cfg_sg_seg_cnt + extra) * 8262 8259 sizeof(struct sli4_sge)); ··· 8319 8316 phba->lpfc_cmd_rsp_buf_pool = 8320 8317 dma_pool_create("lpfc_cmd_rsp_buf_pool", 8321 8318 &phba->pcidev->dev, 8322 - sizeof(struct fcp_cmnd) + 8319 + sizeof(struct fcp_cmnd32) + 8323 8320 sizeof(struct fcp_rsp), 8324 8321 i, 0); 8325 8322 if (!phba->lpfc_cmd_rsp_buf_pool) {
+37 -20
drivers/scsi/lpfc/lpfc_scsi.c
··· 600 600 { 601 601 struct lpfc_io_buf *lpfc_cmd; 602 602 struct lpfc_sli4_hdw_queue *qp; 603 - struct sli4_sge *sgl; 603 + struct sli4_sge_le *sgl; 604 604 dma_addr_t pdma_phys_fcp_rsp; 605 605 dma_addr_t pdma_phys_fcp_cmd; 606 606 uint32_t cpu, idx; ··· 651 651 * The balance are sg list bdes. Initialize the 652 652 * first two and leave the rest for queuecommand. 653 653 */ 654 - sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl; 654 + sgl = (struct sli4_sge_le *)lpfc_cmd->dma_sgl; 655 655 pdma_phys_fcp_cmd = tmp->fcp_cmd_rsp_dma_handle; 656 656 sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd)); 657 657 sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd)); 658 - sgl->word2 = le32_to_cpu(sgl->word2); 659 - bf_set(lpfc_sli4_sge_last, sgl, 0); 660 - sgl->word2 = cpu_to_le32(sgl->word2); 661 - sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd)); 658 + bf_set_le32(lpfc_sli4_sge_last, sgl, 0); 659 + if (cmnd && cmnd->cmd_len > LPFC_FCP_CDB_LEN) 660 + sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd32)); 661 + else 662 + sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd)); 663 + 662 664 sgl++; 663 665 664 666 /* Setup the physical region for the FCP RSP */ 665 - pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd); 667 + pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd32); 666 668 sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp)); 667 669 sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_rsp)); 668 - sgl->word2 = le32_to_cpu(sgl->word2); 669 - bf_set(lpfc_sli4_sge_last, sgl, 1); 670 - sgl->word2 = cpu_to_le32(sgl->word2); 670 + bf_set_le32(lpfc_sli4_sge_last, sgl, 1); 671 671 sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp)); 672 672 673 673 if (lpfc_ndlp_check_qdepth(phba, ndlp)) { ··· 2608 2608 iocb_cmd->ulpLe = 1; 2609 2609 2610 2610 fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); 2611 - fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); 2611 + fcp_cmnd->fcpDl = cpu_to_be32(fcpdl); 2612 2612 2613 2613 /* 2614 2614 * Due to difference in data length between DIF/non-DIF paths, ··· 3225 3225 * explicitly reinitialized. 3226 3226 * all iocb memory resources are reused. 3227 3227 */ 3228 - fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); 3228 + if (scsi_cmnd->cmd_len > LPFC_FCP_CDB_LEN) 3229 + ((struct fcp_cmnd32 *)fcp_cmnd)->fcpDl = 3230 + cpu_to_be32(scsi_bufflen(scsi_cmnd)); 3231 + else 3232 + fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); 3229 3233 /* Set first-burst provided it was successfully negotiated */ 3230 3234 if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) && 3231 3235 vport->cfg_first_burst_size && 3232 3236 scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) { 3233 3237 u32 init_len, total_len; 3234 3238 3235 - total_len = be32_to_cpu(fcp_cmnd->fcpDl); 3239 + total_len = scsi_bufflen(scsi_cmnd); 3236 3240 init_len = min(total_len, vport->cfg_first_burst_size); 3237 3241 3238 3242 /* Word 4 & 5 */ ··· 3424 3420 } 3425 3421 3426 3422 fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); 3427 - fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); 3423 + if (lpfc_cmd->pCmd->cmd_len > LPFC_FCP_CDB_LEN) 3424 + ((struct fcp_cmnd32 *)fcp_cmnd)->fcpDl = cpu_to_be32(fcpdl); 3425 + else 3426 + fcp_cmnd->fcpDl = cpu_to_be32(fcpdl); 3428 3427 3429 3428 /* Set first-burst provided it was successfully negotiated */ 3430 3429 if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) && ··· 3435 3428 scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) { 3436 3429 u32 init_len, total_len; 3437 3430 3438 - total_len = be32_to_cpu(fcp_cmnd->fcpDl); 3431 + total_len = fcpdl; 3439 3432 init_len = min(total_len, vport->cfg_first_burst_size); 3440 3433 3441 3434 /* Word 4 & 5 */ ··· 3443 3436 wqe->fcp_iwrite.total_xfer_len = total_len; 3444 3437 } else { 3445 3438 /* Word 4 */ 3446 - wqe->fcp_iwrite.total_xfer_len = 3447 - be32_to_cpu(fcp_cmnd->fcpDl); 3439 + wqe->fcp_iwrite.total_xfer_len = fcpdl; 3448 3440 } 3449 3441 3450 3442 /* ··· 3900 3894 fcprsp->rspInfo3); 3901 3895 3902 3896 scsi_set_resid(cmnd, 0); 3903 - fcpDl = be32_to_cpu(fcpcmd->fcpDl); 3897 + if (cmnd->cmd_len > LPFC_FCP_CDB_LEN) 3898 + fcpDl = be32_to_cpu(((struct fcp_cmnd32 *)fcpcmd)->fcpDl); 3899 + else 3900 + fcpDl = be32_to_cpu(fcpcmd->fcpDl); 3904 3901 if (resp_info & RESID_UNDER) { 3905 3902 scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); 3906 3903 ··· 4732 4723 bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, 4733 4724 LPFC_WQE_IOD_NONE); 4734 4725 } 4726 + 4727 + /* Additional fcp cdb length field calculation. 4728 + * LPFC_FCP_CDB_LEN_32 - normal 16 byte cdb length, 4729 + * then divide by 4 for the word count. 4730 + * shift 2 because of the RDDATA/WRDATA. 4731 + */ 4732 + if (scsi_cmnd->cmd_len > LPFC_FCP_CDB_LEN) 4733 + fcp_cmnd->fcpCntl3 |= 4 << 2; 4735 4734 } else { 4736 4735 /* From the icmnd template, initialize words 4 - 11 */ 4737 4736 memcpy(&wqe->words[4], &lpfc_icmnd_cmd_template.words[4], ··· 4760 4743 4761 4744 /* Word 3 */ 4762 4745 bf_set(payload_offset_len, &wqe->fcp_icmd, 4763 - sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); 4746 + sizeof(struct fcp_cmnd32) + sizeof(struct fcp_rsp)); 4764 4747 4765 4748 /* Word 6 */ 4766 4749 bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com, ··· 4815 4798 int_to_scsilun(lpfc_cmd->pCmd->device->lun, 4816 4799 &lpfc_cmd->fcp_cmnd->fcp_lun); 4817 4800 4818 - ptr = &fcp_cmnd->fcpCdb[0]; 4801 + ptr = &((struct fcp_cmnd32 *)fcp_cmnd)->fcpCdb[0]; 4819 4802 memcpy(ptr, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); 4820 4803 if (scsi_cmnd->cmd_len < LPFC_FCP_CDB_LEN) { 4821 4804 ptr += scsi_cmnd->cmd_len;
+22 -8
drivers/scsi/lpfc/lpfc_scsi.h
··· 24 24 25 25 struct lpfc_hba; 26 26 #define LPFC_FCP_CDB_LEN 16 27 + #define LPFC_FCP_CDB_LEN_32 32 27 28 28 29 #define list_remove_head(list, entry, type, member) \ 29 30 do { \ ··· 100 99 #define SNSCOD_BADCMD 0x20 /* sense code is byte 13 ([12]) */ 101 100 }; 102 101 103 - struct fcp_cmnd { 104 - struct scsi_lun fcp_lun; 105 - 106 - uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ 107 - uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */ 108 102 #define SIMPLE_Q 0x00 109 103 #define HEAD_OF_Q 0x01 110 104 #define ORDERED_Q 0x02 111 105 #define ACA_Q 0x04 112 106 #define UNTAGGED 0x05 113 - uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */ 114 107 #define FCP_ABORT_TASK_SET 0x02 /* Bit 1 */ 115 108 #define FCP_CLEAR_TASK_SET 0x04 /* bit 2 */ 116 109 #define FCP_BUS_RESET 0x08 /* bit 3 */ ··· 112 117 #define FCP_TARGET_RESET 0x20 /* bit 5 */ 113 118 #define FCP_CLEAR_ACA 0x40 /* bit 6 */ 114 119 #define FCP_TERMINATE_TASK 0x80 /* bit 7 */ 115 - uint8_t fcpCntl3; 116 120 #define WRITE_DATA 0x01 /* Bit 0 */ 117 121 #define READ_DATA 0x02 /* Bit 1 */ 118 122 123 + struct fcp_cmnd { 124 + struct scsi_lun fcp_lun; 125 + 126 + uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ 127 + uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */ 128 + uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */ 129 + uint8_t fcpCntl3; 130 + 119 131 uint8_t fcpCdb[LPFC_FCP_CDB_LEN]; /* SRB cdb field is copied here */ 120 - uint32_t fcpDl; /* Total transfer length */ 132 + __be32 fcpDl; /* Total transfer length */ 133 + 134 + }; 135 + struct fcp_cmnd32 { 136 + struct scsi_lun fcp_lun; 137 + 138 + uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */ 139 + uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */ 140 + uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */ 141 + uint8_t fcpCntl3; 142 + 143 + uint8_t fcpCdb[LPFC_FCP_CDB_LEN_32]; /* SRB cdb field is copied here */ 144 + __be32 fcpDl; /* Total transfer length */ 121 145 122 146 }; 123 147
+6 -6
drivers/scsi/lpfc/lpfc_sli.c
··· 10595 10595 BUFF_TYPE_BDE_IMMED; 10596 10596 wqe->generic.bde.tus.f.bdeSize = sgl->sge_len; 10597 10597 wqe->generic.bde.addrHigh = 0; 10598 - wqe->generic.bde.addrLow = 88; /* Word 22 */ 10598 + wqe->generic.bde.addrLow = 72; /* Word 18 */ 10599 10599 10600 10600 bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1); 10601 10601 bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0); 10602 10602 10603 - /* Word 22-29 FCP CMND Payload */ 10604 - ptr = &wqe->words[22]; 10605 - memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); 10603 + /* Word 18-29 FCP CMND Payload */ 10604 + ptr = &wqe->words[18]; 10605 + memcpy(ptr, fcp_cmnd, sgl->sge_len); 10606 10606 } else { 10607 10607 /* Word 0-2 - Inline BDE */ 10608 10608 wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; 10609 - wqe->generic.bde.tus.f.bdeSize = sizeof(struct fcp_cmnd); 10609 + wqe->generic.bde.tus.f.bdeSize = sgl->sge_len; 10610 10610 wqe->generic.bde.addrHigh = sgl->addr_hi; 10611 10611 wqe->generic.bde.addrLow = sgl->addr_lo; 10612 10612 ··· 22469 22469 } 22470 22470 22471 22471 tmp->fcp_rsp = (struct fcp_rsp *)((uint8_t *)tmp->fcp_cmnd + 22472 - sizeof(struct fcp_cmnd)); 22472 + sizeof(struct fcp_cmnd32)); 22473 22473 22474 22474 spin_lock_irqsave(&hdwq->hdwq_lock, iflags); 22475 22475 list_add_tail(&tmp->list_node, &lpfc_buf->dma_cmd_rsp_list);