Skip to content

Commit af20bb7

Browse files
Justin Teemartinkpetersen
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent e780c94 commit af20bb7

File tree

5 files changed

+80
-38
lines changed

5 files changed

+80
-38
lines changed

drivers/scsi/lpfc/lpfc_hw4.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,14 @@ struct sli4_sge { /* SLI-4 */
21462146
uint32_t sge_len;
21472147
};
21482148

2149+
struct sli4_sge_le {
2150+
__le32 addr_hi;
2151+
__le32 addr_lo;
2152+
2153+
__le32 word2;
2154+
__le32 sge_len;
2155+
};
2156+
21492157
struct sli4_hybrid_sgl {
21502158
struct list_head list_node;
21512159
struct sli4_sge *dma_sgl;

drivers/scsi/lpfc/lpfc_init.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4773,7 +4773,10 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
47734773
shost->max_id = LPFC_MAX_TARGET;
47744774
shost->max_lun = vport->cfg_max_luns;
47754775
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;
47774780

47784781
if (phba->sli_rev == LPFC_SLI_REV4) {
47794782
if (!phba->cfg_fcp_mq_threshold ||
@@ -8231,7 +8234,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
82318234
* our max amount and we need to limit lpfc_sg_seg_cnt
82328235
* to minimize the risk of running out.
82338236
*/
8234-
phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
8237+
phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd32) +
82358238
sizeof(struct fcp_rsp) + max_buf_size;
82368239

82378240
/* Total SGEs for scsi_sg_list and scsi_sg_prot_list */
@@ -8253,7 +8256,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
82538256
* the FCP rsp, a SGE for each, and a SGE for up to
82548257
* cfg_sg_seg_cnt data segments.
82558258
*/
8256-
phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
8259+
phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd32) +
82578260
sizeof(struct fcp_rsp) +
82588261
((phba->cfg_sg_seg_cnt + extra) *
82598262
sizeof(struct sli4_sge));
@@ -8316,7 +8319,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
83168319
phba->lpfc_cmd_rsp_buf_pool =
83178320
dma_pool_create("lpfc_cmd_rsp_buf_pool",
83188321
&phba->pcidev->dev,
8319-
sizeof(struct fcp_cmnd) +
8322+
sizeof(struct fcp_cmnd32) +
83208323
sizeof(struct fcp_rsp),
83218324
i, 0);
83228325
if (!phba->lpfc_cmd_rsp_buf_pool) {

drivers/scsi/lpfc/lpfc_scsi.c

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
600600
{
601601
struct lpfc_io_buf *lpfc_cmd;
602602
struct lpfc_sli4_hdw_queue *qp;
603-
struct sli4_sge *sgl;
603+
struct sli4_sge_le *sgl;
604604
dma_addr_t pdma_phys_fcp_rsp;
605605
dma_addr_t pdma_phys_fcp_cmd;
606606
uint32_t cpu, idx;
@@ -651,23 +651,23 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
651651
* The balance are sg list bdes. Initialize the
652652
* first two and leave the rest for queuecommand.
653653
*/
654-
sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl;
654+
sgl = (struct sli4_sge_le *)lpfc_cmd->dma_sgl;
655655
pdma_phys_fcp_cmd = tmp->fcp_cmd_rsp_dma_handle;
656656
sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd));
657657
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+
662664
sgl++;
663665

664666
/* 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);
666668
sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_rsp));
667669
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);
671671
sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp));
672672

673673
if (lpfc_ndlp_check_qdepth(phba, ndlp)) {
@@ -2608,7 +2608,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba,
26082608
iocb_cmd->ulpLe = 1;
26092609

26102610
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);
26122612

26132613
/*
26142614
* Due to difference in data length between DIF/non-DIF paths,
@@ -3225,14 +3225,18 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
32253225
* explicitly reinitialized.
32263226
* all iocb memory resources are reused.
32273227
*/
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));
32293233
/* Set first-burst provided it was successfully negotiated */
32303234
if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) &&
32313235
vport->cfg_first_burst_size &&
32323236
scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) {
32333237
u32 init_len, total_len;
32343238

3235-
total_len = be32_to_cpu(fcp_cmnd->fcpDl);
3239+
total_len = scsi_bufflen(scsi_cmnd);
32363240
init_len = min(total_len, vport->cfg_first_burst_size);
32373241

32383242
/* Word 4 & 5 */
@@ -3420,24 +3424,26 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
34203424
}
34213425

34223426
fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd);
3423-
fcp_cmnd->fcpDl = be32_to_cpu(fcpdl);
3427+
if (lpfc_cmd->pCmd->cmd_len > LPFC_FCP_CDB_LEN)
3428+
((struct fcp_cmnd32 *)fcp_cmnd)->fcpDl = cpu_to_be32(fcpdl);
3429+
else
3430+
fcp_cmnd->fcpDl = cpu_to_be32(fcpdl);
34243431

34253432
/* Set first-burst provided it was successfully negotiated */
34263433
if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag) &&
34273434
vport->cfg_first_burst_size &&
34283435
scsi_cmnd->sc_data_direction == DMA_TO_DEVICE) {
34293436
u32 init_len, total_len;
34303437

3431-
total_len = be32_to_cpu(fcp_cmnd->fcpDl);
3438+
total_len = fcpdl;
34323439
init_len = min(total_len, vport->cfg_first_burst_size);
34333440

34343441
/* Word 4 & 5 */
34353442
wqe->fcp_iwrite.initial_xfer_len = init_len;
34363443
wqe->fcp_iwrite.total_xfer_len = total_len;
34373444
} else {
34383445
/* Word 4 */
3439-
wqe->fcp_iwrite.total_xfer_len =
3440-
be32_to_cpu(fcp_cmnd->fcpDl);
3446+
wqe->fcp_iwrite.total_xfer_len = fcpdl;
34413447
}
34423448

34433449
/*
@@ -3894,7 +3900,10 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd,
38943900
fcprsp->rspInfo3);
38953901

38963902
scsi_set_resid(cmnd, 0);
3897-
fcpDl = be32_to_cpu(fcpcmd->fcpDl);
3903+
if (cmnd->cmd_len > LPFC_FCP_CDB_LEN)
3904+
fcpDl = be32_to_cpu(((struct fcp_cmnd32 *)fcpcmd)->fcpDl);
3905+
else
3906+
fcpDl = be32_to_cpu(fcpcmd->fcpDl);
38983907
if (resp_info & RESID_UNDER) {
38993908
scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
39003909

@@ -4723,6 +4732,14 @@ static int lpfc_scsi_prep_cmnd_buf_s4(struct lpfc_vport *vport,
47234732
bf_set(wqe_iod, &wqe->fcp_iread.wqe_com,
47244733
LPFC_WQE_IOD_NONE);
47254734
}
4735+
4736+
/* Additional fcp cdb length field calculation.
4737+
* LPFC_FCP_CDB_LEN_32 - normal 16 byte cdb length,
4738+
* then divide by 4 for the word count.
4739+
* shift 2 because of the RDDATA/WRDATA.
4740+
*/
4741+
if (scsi_cmnd->cmd_len > LPFC_FCP_CDB_LEN)
4742+
fcp_cmnd->fcpCntl3 |= 4 << 2;
47264743
} else {
47274744
/* From the icmnd template, initialize words 4 - 11 */
47284745
memcpy(&wqe->words[4], &lpfc_icmnd_cmd_template.words[4],
@@ -4743,7 +4760,7 @@ static int lpfc_scsi_prep_cmnd_buf_s4(struct lpfc_vport *vport,
47434760

47444761
/* Word 3 */
47454762
bf_set(payload_offset_len, &wqe->fcp_icmd,
4746-
sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp));
4763+
sizeof(struct fcp_cmnd32) + sizeof(struct fcp_rsp));
47474764

47484765
/* Word 6 */
47494766
bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com,
@@ -4798,7 +4815,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd,
47984815
int_to_scsilun(lpfc_cmd->pCmd->device->lun,
47994816
&lpfc_cmd->fcp_cmnd->fcp_lun);
48004817

4801-
ptr = &fcp_cmnd->fcpCdb[0];
4818+
ptr = &((struct fcp_cmnd32 *)fcp_cmnd)->fcpCdb[0];
48024819
memcpy(ptr, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
48034820
if (scsi_cmnd->cmd_len < LPFC_FCP_CDB_LEN) {
48044821
ptr += scsi_cmnd->cmd_len;

drivers/scsi/lpfc/lpfc_scsi.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
struct lpfc_hba;
2626
#define LPFC_FCP_CDB_LEN 16
27+
#define LPFC_FCP_CDB_LEN_32 32
2728

2829
#define list_remove_head(list, entry, type, member) \
2930
do { \
@@ -99,30 +100,43 @@ struct fcp_rsp {
99100
#define SNSCOD_BADCMD 0x20 /* sense code is byte 13 ([12]) */
100101
};
101102

102-
struct fcp_cmnd {
103-
struct scsi_lun fcp_lun;
104-
105-
uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */
106-
uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */
107103
#define SIMPLE_Q 0x00
108104
#define HEAD_OF_Q 0x01
109105
#define ORDERED_Q 0x02
110106
#define ACA_Q 0x04
111107
#define UNTAGGED 0x05
112-
uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */
113108
#define FCP_ABORT_TASK_SET 0x02 /* Bit 1 */
114109
#define FCP_CLEAR_TASK_SET 0x04 /* bit 2 */
115110
#define FCP_BUS_RESET 0x08 /* bit 3 */
116111
#define FCP_LUN_RESET 0x10 /* bit 4 */
117112
#define FCP_TARGET_RESET 0x20 /* bit 5 */
118113
#define FCP_CLEAR_ACA 0x40 /* bit 6 */
119114
#define FCP_TERMINATE_TASK 0x80 /* bit 7 */
120-
uint8_t fcpCntl3;
121115
#define WRITE_DATA 0x01 /* Bit 0 */
122116
#define READ_DATA 0x02 /* Bit 1 */
123117

118+
struct fcp_cmnd {
119+
struct scsi_lun fcp_lun;
120+
121+
uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */
122+
uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */
123+
uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */
124+
uint8_t fcpCntl3;
125+
124126
uint8_t fcpCdb[LPFC_FCP_CDB_LEN]; /* SRB cdb field is copied here */
125-
uint32_t fcpDl; /* Total transfer length */
127+
__be32 fcpDl; /* Total transfer length */
128+
129+
};
130+
struct fcp_cmnd32 {
131+
struct scsi_lun fcp_lun;
132+
133+
uint8_t fcpCntl0; /* FCP_CNTL byte 0 (reserved) */
134+
uint8_t fcpCntl1; /* FCP_CNTL byte 1 task codes */
135+
uint8_t fcpCntl2; /* FCP_CTL byte 2 task management codes */
136+
uint8_t fcpCntl3;
137+
138+
uint8_t fcpCdb[LPFC_FCP_CDB_LEN_32]; /* SRB cdb field is copied here */
139+
__be32 fcpDl; /* Total transfer length */
126140

127141
};
128142

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10595,18 +10595,18 @@ lpfc_prep_embed_io(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
1059510595
BUFF_TYPE_BDE_IMMED;
1059610596
wqe->generic.bde.tus.f.bdeSize = sgl->sge_len;
1059710597
wqe->generic.bde.addrHigh = 0;
10598-
wqe->generic.bde.addrLow = 88; /* Word 22 */
10598+
wqe->generic.bde.addrLow = 72; /* Word 18 */
1059910599

1060010600
bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1);
1060110601
bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0);
1060210602

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);
1060610606
} else {
1060710607
/* Word 0-2 - Inline BDE */
1060810608
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;
1061010610
wqe->generic.bde.addrHigh = sgl->addr_hi;
1061110611
wqe->generic.bde.addrLow = sgl->addr_lo;
1061210612

@@ -22469,7 +22469,7 @@ lpfc_get_cmd_rsp_buf_per_hdwq(struct lpfc_hba *phba,
2246922469
}
2247022470

2247122471
tmp->fcp_rsp = (struct fcp_rsp *)((uint8_t *)tmp->fcp_cmnd +
22472-
sizeof(struct fcp_cmnd));
22472+
sizeof(struct fcp_cmnd32));
2247322473

2247422474
spin_lock_irqsave(&hdwq->hdwq_lock, iflags);
2247522475
list_add_tail(&tmp->list_node, &lpfc_buf->dma_cmd_rsp_list);

0 commit comments

Comments
 (0)