[PATCH] Revert "drivers: scsi: fix inaccurate block count reporting in scsi operations"

Tony Dinh mibodhi at gmail.com
Tue Dec 9 03:53:52 CET 2025


This reverts commit b32dda34506b4f486bc803d0c7251f987edd2455.

Currently, scsi is broken and causes data abort. I did a bisect and found
that this commit was the cause. Reverting it and scsi is working again.

=== Error Log with data abort

U-Boot 2026.01-rc4-tld-1-g0e0a198a68be (Dec 08 2025 - 17:42:05 -0800)
Synology DS116

DS116> scsi reset

Reset SCSI
scanning bus for devices...
Target spinup took 0 ms.
SATA link 1 timeout.
AHCI 0001.0000 32 slots 2 ports 6 Gbps 0x3 impl SATA mode
flags: 64bit ncq led only pmp fbss pio slum part sxs
  Device 0: (0:0) Vendor: ATA Prod.: FUJITSU MHY2250B Rev: 890B
            Type: Hard Disk
            Capacity: 238475.1 MB = 232.8 GB (488397169 x 512)

DS116> ext2ls scsi 0:1 /boot
data abort
pc : [<3ffa5d3e>]	   lr : [<3ffc1515>]
sp : 3fb65ad8  ip : 0000000c	 fp : 3fb7f220
r10: 00002710  r9 : 3fb6aed0	 r8 : 3fb85e40
r7 : f10a8100  r6 : 000003e8	 r5 : 000003e8  r4 : 3fb65ae0
r3 : e38e39c1  r2 : 00000000	 r1 : 3fb65ae0  r0 : 00931767
Flags: Nzcv  IRQs off  FIQs off  Mode SVC_32 (T)
Code: 3ffd b510 6803 460c (6bdb) 681b

Signed-off-by: Tony Dinh <mibodhi at gmail.com>
---

 drivers/scsi/scsi.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index b414d022f3f..715271b1d69 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -228,11 +228,13 @@ 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",
@@ -242,7 +244,6 @@ 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
@@ -285,11 +286,13 @@ 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);
@@ -298,7 +301,6 @@ 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);
 
@@ -320,7 +322,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, blocks;
+	lbaint_t start, blks, max_blks;
 	struct scsi_cmd *pccb = (struct scsi_cmd *)&tempccb;
 
 	/* Setup device */
@@ -337,20 +339,19 @@ 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;
 }
-- 
2.47.3

base-commit: 0e0a198a68be71148f5ec27ef86796174f91436f
branch: master


More information about the U-Boot mailing list