On 28/07/2025 18:21, Balaji Selvanathan wrote:
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 <balaji.selvanat...@oss.qualcomm.com>
Signed-off-by: Varadarajan Narayanan <quic_var...@quicinc.com>
---
  drivers/scsi/scsi.c | 13 ++++++-------
  1 file 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;
  }

Reviewed-by: Neil Armstrong <neil.armstr...@linaro.org>

Reply via email to