efi_loader: support device path for IDE and SCSI disks

Correctly create the device path for IDE and SCSI disks.

Support for SATA remains to be done in a future patch.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
master
Heinrich Schuchardt 7 years ago committed by Alexander Graf
parent 2bc61b8352
commit af3106a12d
  1. 15
      include/efi_api.h
  2. 64
      lib/efi_loader/efi_device_path.c
  3. 14
      lib/efi_loader/efi_device_path_to_text.c

@ -329,12 +329,27 @@ 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;
u16 logical_unit_number;
} __packed;
struct efi_device_path_scsi {
struct efi_device_path dp;
u16 target_id;
u16 logical_unit_number;
} __packed;
struct efi_device_path_usb {
struct efi_device_path dp;
u8 parent_port_number;

@ -297,6 +297,23 @@ static unsigned dp_size(struct udevice *dev)
case UCLASS_SIMPLE_BUS:
/* stop traversing parents at this point: */
return sizeof(ROOT);
#ifdef CONFIG_BLK
case UCLASS_BLK:
switch (dev->parent->uclass->uc_drv->id) {
#ifdef CONFIG_IDE
case UCLASS_IDE:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_atapi);
#endif
#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
case UCLASS_SCSI:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_scsi);
#endif
default:
return dp_size(dev->parent);
}
#endif
case UCLASS_MMC:
return dp_size(dev->parent) +
sizeof(struct efi_device_path_sd_mmc_path);
@ -310,6 +327,13 @@ static unsigned dp_size(struct udevice *dev)
}
}
/*
* Recursively build a device path.
*
* @buf pointer to the end of the device path
* @dev device
* @return pointer to the end of the device path
*/
static void *dp_fill(void *buf, struct udevice *dev)
{
if (!dev || !dev->driver)
@ -323,6 +347,46 @@ static void *dp_fill(void *buf, struct udevice *dev)
*vdp = ROOT;
return &vdp[1];
}
#ifdef CONFIG_BLK
case UCLASS_BLK:
switch (dev->parent->uclass->uc_drv->id) {
#ifdef CONFIG_IDE
case UCLASS_IDE: {
struct efi_device_path_atapi *dp =
dp_fill(buf, dev->parent);
struct blk_desc *desc = dev_get_uclass_platdata(dev);
dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_ATAPI;
dp->dp.length = sizeof(*dp);
dp->logical_unit_number = desc->devnum;
dp->primary_secondary = IDE_BUS(desc->devnum);
dp->slave_master = desc->devnum %
(CONFIG_SYS_IDE_MAXDEVICE /
CONFIG_SYS_IDE_MAXBUS);
return &dp[1];
}
#endif
#if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
case UCLASS_SCSI: {
struct efi_device_path_scsi *dp =
dp_fill(buf, dev->parent);
struct blk_desc *desc = dev_get_uclass_platdata(dev);
dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SCSI;
dp->dp.length = sizeof(*dp);
dp->logical_unit_number = desc->lun;
dp->target_id = desc->target;
return &dp[1];
}
#endif
default:
printf("unhandled parent class: %s (%u)\n",
dev->name, dev->driver->id);
return dp_fill(buf, dev->parent);
}
#endif
#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
case UCLASS_MMC: {
struct efi_device_path_sd_mmc_path *sddp =

@ -87,6 +87,20 @@ 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_SCSI: {
struct efi_device_path_scsi *ide =
(struct efi_device_path_scsi *)dp;
s += sprintf(s, "Scsi(%u,%u)", ide->target_id,
ide->logical_unit_number);
break;
}
case DEVICE_PATH_SUB_TYPE_MSG_USB: {
struct efi_device_path_usb *udp =
(struct efi_device_path_usb *)dp;

Loading…
Cancel
Save