On Thu, Feb 17, 2022 at 2:30 PM Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx> wrote: > > Make sure that the __le32 fields of struct ssp_ini_io_start_req are > manipulated after applying the correct endian conversion. That is, use > cpu_to_le32() for assigning values and le32_to_cpu() for consulting a > field value. In particular, make sure that the calculations for the 4G > boundary check are done using CPU endianness and *not* little endian > values. With these fixes, many sparse warnings are removed. > > While at it, add blank lines after variable declarations and in some > other places to make this code more readable. > > Fixes: 0ecdf00ba6e5 ("[SCSI] pm80xx: 4G boundary fix.") > Signed-off-by: Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx> Reviewed-by: Jack Wang <jinpu.wang@xxxxxxxxx> thx! > --- > drivers/scsi/pm8001/pm80xx_hwi.c | 41 +++++++++++++++++++------------- > 1 file changed, 25 insertions(+), 16 deletions(-) > > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c > index b06d5ded45ca..130747b5a70a 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.c > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c > @@ -4374,13 +4374,15 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, > struct ssp_ini_io_start_req ssp_cmd; > u32 tag = ccb->ccb_tag; > int ret; > - u64 phys_addr, start_addr, end_addr; > + u64 phys_addr, end_addr; > u32 end_addr_high, end_addr_low; > struct inbound_queue_table *circularQ; > u32 q_index, cpu_id; > u32 opc = OPC_INB_SSPINIIOSTART; > + > memset(&ssp_cmd, 0, sizeof(ssp_cmd)); > memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8); > + > /* data address domain added for spcv; set to 0 by host, > * used internally by controller > * 0 for SAS 1.1 and SAS 2.0 compatible TLR > @@ -4391,7 +4393,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, > ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id); > ssp_cmd.tag = cpu_to_le32(tag); > if (task->ssp_task.enable_first_burst) > - ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; > + ssp_cmd.ssp_iu.efb_prio_attr = 0x80; > ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); > ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); > memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd, > @@ -4423,21 +4425,24 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, > ssp_cmd.enc_esgl = cpu_to_le32(1<<31); > } else if (task->num_scatter == 1) { > u64 dma_addr = sg_dma_address(task->scatter); > + > ssp_cmd.enc_addr_low = > cpu_to_le32(lower_32_bits(dma_addr)); > ssp_cmd.enc_addr_high = > cpu_to_le32(upper_32_bits(dma_addr)); > ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len); > ssp_cmd.enc_esgl = 0; > + > /* Check 4G Boundary */ > - start_addr = cpu_to_le64(dma_addr); > - end_addr = (start_addr + ssp_cmd.enc_len) - 1; > - end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); > - end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); > - if (end_addr_high != ssp_cmd.enc_addr_high) { > + end_addr = dma_addr + le32_to_cpu(ssp_cmd.enc_len) - 1; > + end_addr_low = lower_32_bits(end_addr); > + end_addr_high = upper_32_bits(end_addr); > + > + if (end_addr_high != le32_to_cpu(ssp_cmd.enc_addr_high)) { > pm8001_dbg(pm8001_ha, FAIL, > "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", > - start_addr, ssp_cmd.enc_len, > + dma_addr, > + le32_to_cpu(ssp_cmd.enc_len), > end_addr_high, end_addr_low); > pm8001_chip_make_sg(task->scatter, 1, > ccb->buf_prd); > @@ -4446,7 +4451,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, > cpu_to_le32(lower_32_bits(phys_addr)); > ssp_cmd.enc_addr_high = > cpu_to_le32(upper_32_bits(phys_addr)); > - ssp_cmd.enc_esgl = cpu_to_le32(1<<31); > + ssp_cmd.enc_esgl = cpu_to_le32(1U<<31); > } > } else if (task->num_scatter == 0) { > ssp_cmd.enc_addr_low = 0; > @@ -4454,8 +4459,10 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, > ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len); > ssp_cmd.enc_esgl = 0; > } > + > /* XTS mode. All other fields are 0 */ > - ssp_cmd.key_cmode = 0x6 << 4; > + ssp_cmd.key_cmode = cpu_to_le32(0x6 << 4); > + > /* set tweak values. Should be the start lba */ > ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) | > (task->ssp_task.cmd->cmnd[3] << 16) | > @@ -4477,20 +4484,22 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, > ssp_cmd.esgl = cpu_to_le32(1<<31); > } else if (task->num_scatter == 1) { > u64 dma_addr = sg_dma_address(task->scatter); > + > ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr)); > ssp_cmd.addr_high = > cpu_to_le32(upper_32_bits(dma_addr)); > ssp_cmd.len = cpu_to_le32(task->total_xfer_len); > ssp_cmd.esgl = 0; > + > /* Check 4G Boundary */ > - start_addr = cpu_to_le64(dma_addr); > - end_addr = (start_addr + ssp_cmd.len) - 1; > - end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); > - end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); > - if (end_addr_high != ssp_cmd.addr_high) { > + end_addr = dma_addr + le32_to_cpu(ssp_cmd.len) - 1; > + end_addr_low = lower_32_bits(end_addr); > + end_addr_high = upper_32_bits(end_addr); > + if (end_addr_high != le32_to_cpu(ssp_cmd.addr_high)) { > pm8001_dbg(pm8001_ha, FAIL, > "The sg list address start_addr=0x%016llx data_len=0x%x end_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", > - start_addr, ssp_cmd.len, > + dma_addr, > + le32_to_cpu(ssp_cmd.len), > end_addr_high, end_addr_low); > pm8001_chip_make_sg(task->scatter, 1, > ccb->buf_prd); > -- > 2.34.1 >