On 9/4/26 09:12, Alexey Charkov wrote:
The scan walks a contiguous LUN range, so units that a bus places outside
it stay unreachable. UFS puts its well known units at 0x80 and above, far
past the ordinary maximum of 0x7f.
Let a controller list such units separately and probe them once the
ordinary range is done, so that block devices already created keep the
device numbers they had.
Signed-off-by: Alexey Charkov <[email protected]>
---
drivers/scsi/scsi.c | 13 ++++++++++++-
include/scsi.h | 4 ++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a60843e505ea..55915a021864 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -685,6 +685,7 @@ int scsi_scan_dev(struct udevice *dev, bool verbose)
int ret;
int i;
int lun;
+ int j;
/* probe SCSI controller driver */
ret = device_probe(dev);
@@ -694,10 +695,20 @@ int scsi_scan_dev(struct udevice *dev, bool verbose)
/* Get controller plat */
uc_plat = dev_get_uclass_plat(dev);
- for (i = 0; i < uc_plat->max_id; i++)
+ for (i = 0; i < uc_plat->max_id; i++) {
for (lun = 0; lun < uc_plat->max_lun; lun++)
do_scsi_scan_one(dev, i, lun, false, verbose);
+ /*
+ * Well known units live outside the ordinary LUN range, and
+ * are scanned last so that they do not shift the device
+ * numbers of the units before them.
+ */
+ for (j = 0; j < uc_plat->wlun_count; j++)
+ do_scsi_scan_one(dev, i, uc_plat->wluns[j], true,
+ verbose);
Perhaps check uc_plat->wluns is not NULL ?
It's not a serious issue since only UFS will declare it, and it will be valid.
+ }
+
return 0;
}
diff --git a/include/scsi.h b/include/scsi.h
index 72fb6e4bd90d..fea2d0152098 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -269,12 +269,16 @@ struct __packed scsi_write10_req {
* @max_lun: Maximum number of logical units
* @max_id: Maximum number of target ids
* @max_bytes_per_req: Maximum number of bytes per read/write request
+ * @wluns: Well known logical units to scan on top of 0..@max_lun - 1, or NULL
+ * @wlun_count: Number of entries in @wluns
*/
struct scsi_plat {
unsigned long base;
unsigned long max_lun;
unsigned long max_id;
unsigned long max_bytes_per_req;
+ const u8 *wluns;
+ int wlun_count;
};
/* Operations for SCSI */