From: Balaji Selvanathan Date: Mon, 28 Jul 2025 16:21:05 +0000 (+0530) Subject: drivers: scsi: fix inaccurate block count reporting in scsi operations X-Git-Tag: v2025.10-rc2~11 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b32dda34506b4f486bc803d0c7251f987edd2455;p=pandora-u-boot.git 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 Signed-off-by: Varadarajan Narayanan Reviewed-by: Neil Armstrong --- 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; }