Commit fd6d0e37 authored by Damien Le Moal's avatar Damien Le Moal Committed by Martin K. Petersen

scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()

Make sure that the __le32 fields of struct sata_cmd 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, fix some code identation and add blank lines after variable
declarations and in some other places to make this code more readable.

Link: https://lore.kernel.org/r/20220220031810.738362-12-damien.lemoal@opensource.wdc.com
Fixes: 0ecdf00b ("[SCSI] pm80xx: 4G boundary fix.")
Reviewed-by: default avatarJack Wang <jinpu.wang@ionos.com>
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 970404cc
...@@ -4534,7 +4534,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4534,7 +4534,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
u32 q_index, cpu_id; u32 q_index, cpu_id;
struct sata_start_req sata_cmd; struct sata_start_req sata_cmd;
u32 hdr_tag, ncg_tag = 0; u32 hdr_tag, ncg_tag = 0;
u64 phys_addr, start_addr, end_addr; u64 phys_addr, end_addr;
u32 end_addr_high, end_addr_low; u32 end_addr_high, end_addr_low;
u32 ATAP = 0x0; u32 ATAP = 0x0;
u32 dir; u32 dir;
...@@ -4595,32 +4595,38 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4595,32 +4595,38 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
pm8001_chip_make_sg(task->scatter, pm8001_chip_make_sg(task->scatter,
ccb->n_elem, ccb->buf_prd); ccb->n_elem, ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle; phys_addr = ccb->ccb_dma_handle;
sata_cmd.enc_addr_low = lower_32_bits(phys_addr); sata_cmd.enc_addr_low =
sata_cmd.enc_addr_high = upper_32_bits(phys_addr); cpu_to_le32(lower_32_bits(phys_addr));
sata_cmd.enc_addr_high =
cpu_to_le32(upper_32_bits(phys_addr));
sata_cmd.enc_esgl = cpu_to_le32(1 << 31); sata_cmd.enc_esgl = cpu_to_le32(1 << 31);
} else if (task->num_scatter == 1) { } else if (task->num_scatter == 1) {
u64 dma_addr = sg_dma_address(task->scatter); u64 dma_addr = sg_dma_address(task->scatter);
sata_cmd.enc_addr_low = lower_32_bits(dma_addr);
sata_cmd.enc_addr_high = upper_32_bits(dma_addr); sata_cmd.enc_addr_low =
cpu_to_le32(lower_32_bits(dma_addr));
sata_cmd.enc_addr_high =
cpu_to_le32(upper_32_bits(dma_addr));
sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len); sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len);
sata_cmd.enc_esgl = 0; sata_cmd.enc_esgl = 0;
/* Check 4G Boundary */ /* Check 4G Boundary */
start_addr = cpu_to_le64(dma_addr); end_addr = dma_addr + le32_to_cpu(sata_cmd.enc_len) - 1;
end_addr = (start_addr + sata_cmd.enc_len) - 1; end_addr_low = lower_32_bits(end_addr);
end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); end_addr_high = upper_32_bits(end_addr);
end_addr_high = cpu_to_le32(upper_32_bits(end_addr)); if (end_addr_high != le32_to_cpu(sata_cmd.enc_addr_high)) {
if (end_addr_high != sata_cmd.enc_addr_high) {
pm8001_dbg(pm8001_ha, FAIL, 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", "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, sata_cmd.enc_len, dma_addr,
le32_to_cpu(sata_cmd.enc_len),
end_addr_high, end_addr_low); end_addr_high, end_addr_low);
pm8001_chip_make_sg(task->scatter, 1, pm8001_chip_make_sg(task->scatter, 1,
ccb->buf_prd); ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle; phys_addr = ccb->ccb_dma_handle;
sata_cmd.enc_addr_low = sata_cmd.enc_addr_low =
lower_32_bits(phys_addr); cpu_to_le32(lower_32_bits(phys_addr));
sata_cmd.enc_addr_high = sata_cmd.enc_addr_high =
upper_32_bits(phys_addr); cpu_to_le32(upper_32_bits(phys_addr));
sata_cmd.enc_esgl = sata_cmd.enc_esgl =
cpu_to_le32(1 << 31); cpu_to_le32(1 << 31);
} }
...@@ -4631,7 +4637,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4631,7 +4637,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
sata_cmd.enc_esgl = 0; sata_cmd.enc_esgl = 0;
} }
/* XTS mode. All other fields are 0 */ /* XTS mode. All other fields are 0 */
sata_cmd.key_index_mode = 0x6 << 4; sata_cmd.key_index_mode = cpu_to_le32(0x6 << 4);
/* set tweak values. Should be the start lba */ /* set tweak values. Should be the start lba */
sata_cmd.twk_val0 = sata_cmd.twk_val0 =
cpu_to_le32((sata_cmd.sata_fis.lbal_exp << 24) | cpu_to_le32((sata_cmd.sata_fis.lbal_exp << 24) |
...@@ -4657,31 +4664,31 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4657,31 +4664,31 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
phys_addr = ccb->ccb_dma_handle; phys_addr = ccb->ccb_dma_handle;
sata_cmd.addr_low = lower_32_bits(phys_addr); sata_cmd.addr_low = lower_32_bits(phys_addr);
sata_cmd.addr_high = upper_32_bits(phys_addr); sata_cmd.addr_high = upper_32_bits(phys_addr);
sata_cmd.esgl = cpu_to_le32(1 << 31); sata_cmd.esgl = cpu_to_le32(1U << 31);
} else if (task->num_scatter == 1) { } else if (task->num_scatter == 1) {
u64 dma_addr = sg_dma_address(task->scatter); u64 dma_addr = sg_dma_address(task->scatter);
sata_cmd.addr_low = lower_32_bits(dma_addr); sata_cmd.addr_low = lower_32_bits(dma_addr);
sata_cmd.addr_high = upper_32_bits(dma_addr); sata_cmd.addr_high = upper_32_bits(dma_addr);
sata_cmd.len = cpu_to_le32(task->total_xfer_len); sata_cmd.len = cpu_to_le32(task->total_xfer_len);
sata_cmd.esgl = 0; sata_cmd.esgl = 0;
/* Check 4G Boundary */ /* Check 4G Boundary */
start_addr = cpu_to_le64(dma_addr); end_addr = dma_addr + le32_to_cpu(sata_cmd.len) - 1;
end_addr = (start_addr + sata_cmd.len) - 1; end_addr_low = lower_32_bits(end_addr);
end_addr_low = cpu_to_le32(lower_32_bits(end_addr)); end_addr_high = upper_32_bits(end_addr);
end_addr_high = cpu_to_le32(upper_32_bits(end_addr));
if (end_addr_high != sata_cmd.addr_high) { if (end_addr_high != sata_cmd.addr_high) {
pm8001_dbg(pm8001_ha, FAIL, pm8001_dbg(pm8001_ha, FAIL,
"The sg list address start_addr=0x%016llx data_len=0x%xend_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n", "The sg list address start_addr=0x%016llx data_len=0x%xend_addr_high=0x%08x end_addr_low=0x%08x has crossed 4G boundary\n",
start_addr, sata_cmd.len, dma_addr,
le32_to_cpu(sata_cmd.len),
end_addr_high, end_addr_low); end_addr_high, end_addr_low);
pm8001_chip_make_sg(task->scatter, 1, pm8001_chip_make_sg(task->scatter, 1,
ccb->buf_prd); ccb->buf_prd);
phys_addr = ccb->ccb_dma_handle; phys_addr = ccb->ccb_dma_handle;
sata_cmd.addr_low = sata_cmd.addr_low = lower_32_bits(phys_addr);
lower_32_bits(phys_addr); sata_cmd.addr_high = upper_32_bits(phys_addr);
sata_cmd.addr_high = sata_cmd.esgl = cpu_to_le32(1U << 31);
upper_32_bits(phys_addr);
sata_cmd.esgl = cpu_to_le32(1 << 31);
} }
} else if (task->num_scatter == 0) { } else if (task->num_scatter == 0) {
sata_cmd.addr_low = 0; sata_cmd.addr_low = 0;
...@@ -4689,6 +4696,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4689,6 +4696,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
sata_cmd.len = cpu_to_le32(task->total_xfer_len); sata_cmd.len = cpu_to_le32(task->total_xfer_len);
sata_cmd.esgl = 0; sata_cmd.esgl = 0;
} }
/* scsi cdb */ /* scsi cdb */
sata_cmd.atapi_scsi_cdb[0] = sata_cmd.atapi_scsi_cdb[0] =
cpu_to_le32(((task->ata_task.atapi_packet[0]) | cpu_to_le32(((task->ata_task.atapi_packet[0]) |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment