summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalaji Selvanathan <[email protected]>2025-07-28 21:51:05 +0530
committerTom Rini <[email protected]>2025-08-07 11:14:23 -0600
commitb32dda34506b4f486bc803d0c7251f987edd2455 (patch)
treedbe7c1f03c168f16c8bf01987b90a75db43404c0
parente652183ca06d3795052df389992533fd539d8dee (diff)
drivers: scsi: fix inaccurate block count reporting in scsi operations
The 'blks' variable in scsi_read/write/erase functions is updated regardless of pass/fail of the scsi operation . If the scsi operation fails, 'blkcnt' is updated using an incorrect value of 'blks'. This wrong 'blkcnt' is returned to the caller and it assumes all blocks were processed correctly. Fix this by updating the 'blks' variable only if the scsi operation succeeds. Signed-off-by: Balaji Selvanathan <[email protected]> Signed-off-by: Varadarajan Narayanan <[email protected]> Reviewed-by: Neil Armstrong <[email protected]>
-rw-r--r--drivers/scsi/scsi.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 78efed6b66a..05608399be1 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -228,13 +228,11 @@ static ulong scsi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
blocks = max_blks;
scsi_setup_read_ext(pccb, start, blocks);
start += max_blks;
- blks -= max_blks;
} else {
pccb->datalen = block_dev->blksz * blks;
blocks = blks;
scsi_setup_read_ext(pccb, start, blocks);
start += blks;
- blks = 0;
}
debug("scsi_read_ext: startblk " LBAF
", blccnt " LBAF " buffer %lX\n",
@@ -244,6 +242,7 @@ static ulong scsi_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
blkcnt -= blks;
break;
}
+ blks -= blocks;
buf_addr += pccb->datalen;
} while (blks != 0);
debug("scsi_read_ext: end startblk " LBAF
@@ -286,13 +285,11 @@ static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
blocks = max_blks;
scsi_setup_write_ext(pccb, start, blocks);
start += max_blks;
- blks -= max_blks;
} else {
pccb->datalen = block_dev->blksz * blks;
blocks = blks;
scsi_setup_write_ext(pccb, start, blocks);
start += blks;
- blks = 0;
}
debug("%s: startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
__func__, start, blocks, buf_addr);
@@ -301,6 +298,7 @@ static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
blkcnt -= blks;
break;
}
+ blks -= blocks;
buf_addr += pccb->datalen;
} while (blks != 0);
@@ -322,7 +320,7 @@ static ulong scsi_erase(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt)
struct blk_desc *block_dev = dev_get_uclass_plat(dev);
struct udevice *bdev = dev->parent;
struct scsi_plat *uc_plat = dev_get_uclass_plat(bdev);
- lbaint_t start, blks, max_blks;
+ lbaint_t start, blks, max_blks, blocks;
struct scsi_cmd *pccb = (struct scsi_cmd *)&tempccb;
/* Setup device */
@@ -339,19 +337,20 @@ static ulong scsi_erase(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt)
__func__, block_dev->devnum, start, blks);
do {
if (blks > max_blks) {
+ blocks = max_blks;
scsi_setup_erase_ext(pccb, start, max_blks);
start += max_blks;
- blks -= max_blks;
} else {
+ blocks = blks;
scsi_setup_erase_ext(pccb, start, blks);
start += blks;
- blks = 0;
}
if (scsi_exec(bdev, pccb)) {
scsi_print_error(pccb);
blkcnt -= blks;
break;
}
+ blks -= blocks;
} while (blks != 0);
return blkcnt;
}