[U-Boot] [PATCH v3 6/6] efi_loader: support device path for IDE and SCSI disks

Heinrich Schuchardt xypron.glpk at gmx.de
Mon Dec 11 11:56:44 UTC 2017


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 at gmx.de>
---
v3
	new patch
---
 include/efi_api.h                        | 15 ++++++++
 lib/efi_loader/efi_device_path.c         | 64 ++++++++++++++++++++++++++++++++
 lib/efi_loader/efi_device_path_to_text.c | 14 +++++++
 3 files changed, 93 insertions(+)

diff --git a/include/efi_api.h b/include/efi_api.h
index 584016dc30..46963f2891 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -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;
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 492a7643e6..ed30f1cabf 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -282,6 +282,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);
@@ -295,6 +312,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)
@@ -308,6 +332,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 =
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 50d9e911c0..40eae730ed 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -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;
-- 
2.15.1



More information about the U-Boot mailing list