efi_loader: device path for SATA devices
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Wed, 20 May 2020 21:12:02 +0000 (23:12 +0200)
committerHeinrich Schuchardt <xypron.glpk@gmx.de>
Thu, 21 May 2020 08:00:17 +0000 (10:00 +0200)
Provide device path nodes for SATA devices.

This avoids creation of two handles with the same device path indicating
our root node.

This is what the device paths for a SATA drive with four partitions could
like:

/VenHw(..)/Sata(0x0,0xffff,0x0)
/VenHw(..)/Sata(0x0,0xffff,0x0)/HD(1,MBR,0x81ea591f,0x800,0x63ff830)
/VenHw(..)/Sata(0x0,0xffff,0x0)/HD(2,MBR,0x81ea591f,0x6400800,0x9ff830)
/VenHw(..)/Sata(0x0,0xffff,0x0)/HD(3,MBR,0x81ea591f,0x6e00800,0x16ef2ab0)
/VenHw(..)/Sata(0x0,0xffff,0x0)/HD(4,MBR,0x81ea591f,0x1dcf3800,0x1dcedab0)

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
include/efi_api.h
lib/efi_loader/efi_device_path.c
lib/efi_loader/efi_device_path_to_text.c

index 77d6bf2660b9f38060f8b5a2db41f45d7d3f7506..759d9118758e7db4dc23a5e61ff7d28a06351945 100644 (file)
@@ -457,6 +457,7 @@ struct efi_device_path_acpi_path {
 #  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_SATA                0x12
 #  define DEVICE_PATH_SUB_TYPE_MSG_NVME                0x17
 #  define DEVICE_PATH_SUB_TYPE_MSG_SD          0x1a
 #  define DEVICE_PATH_SUB_TYPE_MSG_MMC         0x1d
@@ -480,6 +481,13 @@ struct efi_device_path_usb {
        u8 usb_interface;
 } __packed;
 
+struct efi_device_path_sata {
+       struct efi_device_path dp;
+       u16 hba_port;
+       u16 port_multiplier_port;
+       u16 logical_unit_number;
+} __packed;
+
 struct efi_device_path_mac_addr {
        struct efi_device_path dp;
        struct efi_mac_addr mac;
index f049b9e0cd0843e19e3f67238b5fb7b37878d739..7ae14f342396ad2235e8b9b8edffb139d5451dc0 100644 (file)
@@ -458,6 +458,11 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
                        return dp_size(dev->parent) +
                                sizeof(struct efi_device_path_sd_mmc_path);
 #endif
+#if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
+               case UCLASS_AHCI:
+                       return dp_size(dev->parent) +
+                               sizeof(struct efi_device_path_sata);
+#endif
 #if defined(CONFIG_NVME)
                case UCLASS_NVME:
                        return dp_size(dev->parent) +
@@ -623,6 +628,22 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
                        return &sddp[1];
                        }
 #endif
+#if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
+               case UCLASS_AHCI: {
+                       struct efi_device_path_sata *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_SATA;
+                       dp->dp.length   = sizeof(*dp);
+                       dp->hba_port = desc->devnum;
+                       /* default 0xffff implies no port multiplier */
+                       dp->port_multiplier_port = 0xffff;
+                       dp->logical_unit_number = desc->lun;
+                       return &dp[1];
+                       }
+#endif
 #if defined(CONFIG_NVME)
                case UCLASS_NVME: {
                        struct efi_device_path_nvme *dp =
index 49bebb58cc25377bee719d585a76e339fe012c88..5ae4833fa78c7180b0634854c6182d8fe85a24d4 100644 (file)
@@ -149,6 +149,16 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 
                break;
        }
+       case DEVICE_PATH_SUB_TYPE_MSG_SATA: {
+               struct efi_device_path_sata *sdp =
+                       (struct efi_device_path_sata *) dp;
+
+               s += sprintf(s, "Sata(0x%x,0x%x,0x%x)",
+                            sdp->hba_port,
+                            sdp->port_multiplier_port,
+                            sdp->logical_unit_number);
+               break;
+       }
        case DEVICE_PATH_SUB_TYPE_MSG_NVME: {
                struct efi_device_path_nvme *ndp =
                        (struct efi_device_path_nvme *)dp;