SCSI device numbers are handed out in scan order, so a caller has no general way to request a particular logical unit without relying on assumptions on the scan order. Well known units make this worse, since they are probed after a range whose population varies from device to device, even though their numbers are by definition well known.
Add a helper to unambiguously look up the block device number for a given SCSI target number and LUN. Signed-off-by: Alexey Charkov <[email protected]> --- drivers/scsi/scsi-uclass.c | 19 +++++++++++++++++++ include/scsi.h | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/drivers/scsi/scsi-uclass.c b/drivers/scsi/scsi-uclass.c index ca6a16cd8206..30f049c21cc7 100644 --- a/drivers/scsi/scsi-uclass.c +++ b/drivers/scsi/scsi-uclass.c @@ -50,6 +50,25 @@ int scsi_get_blk_by_uuid(const char *uuid, return -ENODEV; } +int scsi_get_blk_by_lun(int target, int lun, struct blk_desc **blk_desc_ptr) +{ + struct blk_desc *blk; + int i, ret; + + for (i = 0; i < blk_find_max_devnum(UCLASS_SCSI) + 1; i++) { + ret = blk_get_desc(UCLASS_SCSI, i, &blk); + if (ret) + continue; + + if (blk->target == target && blk->lun == lun) { + *blk_desc_ptr = blk; + return 0; + } + } + + return -ENODEV; +} + int scsi_wlun_alias(struct udevice *dev, int lun) { struct scsi_ops *ops = scsi_get_ops(dev); diff --git a/include/scsi.h b/include/scsi.h index fea2d0152098..a99a179d0f3a 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -395,6 +395,22 @@ int scsi_scan_dev(struct udevice *dev, bool verbose); int scsi_get_blk_by_uuid(const char *uuid, struct blk_desc **blk_desc_ptr, struct disk_partition *part_info_ptr); +/** + * scsi_get_blk_by_lun() - Look up a SCSI block device by target and LUN + * + * Unlike the SCSI device number, which is handed out in scan order, the LUN + * identifies a unit on the bus. This is the only way to address units that the + * scan does not number predictably, such as UFS well known logical units. + * + * scsi_scan() must have been called before calling this function. + * + * @target: Target id the unit sits on + * @lun: Logical unit number to look for + * @blk_desc_ptr: Provides the blk descriptor + * Return: 0 if OK, -ve on error + */ +int scsi_get_blk_by_lun(int target, int lun, struct blk_desc **blk_desc_ptr); + #define SCSI_IDENTIFY 0xC0 /* not used */ /* Hardware errors */ -- 2.54.0
