Hi Alexey,

On 2026-09-18T06:35:41, Alexey Charkov <[email protected]> wrote:
> scsi: allow a controller to declare well known logical units
>
> 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.

This only holds for the last controller scanned. Device numbers are
allocated across the whole SCSI uclass (blk_create_devicef() is called
with -1) and scsi_scan() walks the controllers in turn, so a W-LU
found on the first controller shifts every unit on the controllers
after it. A board with both UFS and AHCI would see its SATA disks
renumbered once bBootLunEn is set.

Please can you either mention this limitation here, or do the W-LU
pass in scsi_scan() after all controllers have had their ordinary
range scanned? I suspect the latter is not much more code, since
scsi_scan_dev() has no other callers. What do you think?

>
> Signed-off-by: Alexey Charkov <[email protected]>
>
> drivers/scsi/scsi.c | 16 +++++++++++++++-
>  include/scsi.h      |  4 ++++
>  2 files changed, 19 insertions(+), 1 deletion(-)

> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
> @@ -694,10 +695,23 @@ int scsi_scan_dev(struct udevice *dev, bool 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);
> +     }

Since this is inside the target loop, the W-LUs are not scanned last
when max_id is greater than 1: those of target 0 land before the
ordinary units of target 1 and shift their numbers. It makes no
difference for UFS, where UFSHCD_MAX_ID is 1, but this is generic
code. Please can you move this into its own loop over the targets,
after the existing one, so that the comment is true?

> diff --git a/include/scsi.h b/include/scsi.h
> @@ -269,12 +269,16 @@ struct __packed scsi_write10_req {
> + * @wluns: Well known logical units to scan on top of 0..@max_lun - 1, or 
> NULL
> + * @wlun_count: Number of entries in @wluns

Please can you mention that each value is passed as is in the lun
field of struct scsi_cmd, so it is in whatever encoding the
controller's exec() method expects (the UPIU form for UFS) rather than
a SAM W-LUN address, which would not fit in a u8.

With the sandbox W-LU suggested on the previous patch, please can
test/dm/scsi.c also check that the unit appears after the ordinary
ones, with the expected LUN?

Regards,
Simon

Reply via email to