
Correctly create the evice path for ide disks.
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de --- include/efi_api.h | 9 ++++++ lib/efi_loader/efi_device_path.c | 53 ++++++++++++++++++++++++++++++++ lib/efi_loader/efi_device_path_to_text.c | 7 +++++ 3 files changed, 69 insertions(+)
diff --git a/include/efi_api.h b/include/efi_api.h index 9a66efde45..4f0bfc417d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -329,12 +329,21 @@ struct efi_device_path_acpi_path { } __packed;
#define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03 +# define DEVICE_PATH_SUB_TYPE_MSG_ATAPI 0x01 +# define DEVICE_PATH_SUB_TYPE_MSG_SCSI 0x02 # define DEVICE_PATH_SUB_TYPE_MSG_USB 0x05 # define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b # define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS 0x0f # define DEVICE_PATH_SUB_TYPE_MSG_SD 0x1a # define DEVICE_PATH_SUB_TYPE_MSG_MMC 0x1d
+struct efi_device_path_atapi { + struct efi_device_path dp; + u8 primary_secondary; + u8 slave_master; + u8 logical_unit_number; +} __packed; + struct efi_device_path_usb { struct efi_device_path dp; u8 parent_port_number; diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 31cdd38773..a3eb077e45 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -295,6 +295,42 @@ static unsigned dp_size(struct udevice *dev) } }
+#ifdef CONFIG_BLK +/* + * Determine the logical unit number as the index of the device + * in the device class. + * + * @uclass_id device class + * @devnum device number from the device descriptor + * @return logical unit number or a negative error code + */ +static int dev_get_lun(enum uclass_id uclass_id, int devnum) +{ + struct uclass *uc; + struct udevice *dev; + int ret; + + ret = uclass_get(uclass_id, &uc); + if (ret) + return ret; + uclass_foreach_dev(dev, uc) { + struct blk_desc *desc = dev_get_uclass_platdata(dev); + + if (desc->devnum == devnum) + return ret; + ++ret; + } + return -ENOENT; +} +#endif + +/* + * Recursively build a device path. + * + * @buf output buffer + * @dev device + * @return pointer to the end of the device path + */ static void *dp_fill(void *buf, struct udevice *dev) { if (!dev || !dev->driver) @@ -308,6 +344,23 @@ static void *dp_fill(void *buf, struct udevice *dev) *vdp = ROOT; return &vdp[1]; } +#if defined(CONFIG_IDE) && defined(CONFIG_BLK) + case UCLASS_IDE: { + struct efi_device_path_atapi *idedp = + dp_fill(buf, dev->parent); + struct blk_desc *ide = dev_get_uclass_platdata(dev); + int lun = dev_get_lun(UCLASS_IDE, ide->devnum); + + idedp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + idedp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_ATAPI; + idedp->dp.length = sizeof(*idedp); + idedp->logical_unit_number = lun; + idedp->primary_secondary = IDE_BUS(lun); + idedp->slave_master = lun % + (CONFIG_SYS_IDE_MAXDEVICE / CONFIG_SYS_IDE_MAXBUS); + return &idedp[1]; + } +#endif #if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC) case UCLASS_MMC: { struct efi_device_path_sd_mmc_path *sddp = diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 21c5678d20..7070ac909d 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -87,6 +87,13 @@ static char *dp_acpi(char *s, struct efi_device_path *dp) static char *dp_msging(char *s, struct efi_device_path *dp) { switch (dp->sub_type) { + case DEVICE_PATH_SUB_TYPE_MSG_ATAPI: { + struct efi_device_path_atapi *ide = + (struct efi_device_path_atapi *)dp; + s += sprintf(s, "Ata(%d,%d,%d)", ide->primary_secondary, + ide->slave_master, ide->logical_unit_number); + break; + } case DEVICE_PATH_SUB_TYPE_MSG_USB: { struct efi_device_path_usb *udp = (struct efi_device_path_usb *)dp;