[RFC 7/7] efi_loader: use uclass_get_dp_node

Heinrich Schuchardt heinrich.schuchardt at canonical.com
Sun Mar 26 19:27:43 CEST 2023


Use function uclass_get_dp_node() to construct device paths.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
 lib/efi_loader/efi_device_path.c | 325 +++----------------------------
 1 file changed, 28 insertions(+), 297 deletions(-)

diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index d5cc495830..288baa1ca7 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -45,24 +45,6 @@ static const struct efi_device_path_vendor ROOT = {
 	.guid = U_BOOT_GUID,
 };
 
-#if defined(CONFIG_MMC)
-/*
- * Determine if an MMC device is an SD card.
- *
- * @desc	block device descriptor
- * Return:	true if the device is an SD card
- */
-static bool is_sd(struct blk_desc *desc)
-{
-	struct mmc *mmc = find_mmc_device(desc->devnum);
-
-	if (!mmc)
-		return false;
-
-	return IS_SD(mmc) != 0U;
-}
-#endif
-
 /*
  * Iterate to next block in device-path, terminating (returning NULL)
  * at /End* node.
@@ -500,87 +482,24 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
 /* size of device-path not including END node for device and all parents
  * up to the root device.
  */
-__maybe_unused static unsigned int dp_size(struct udevice *dev)
+__maybe_unused static size_t dp_size(struct udevice *dev)
 {
-	if (!dev || !dev->driver)
-		return sizeof(ROOT);
-
-	switch (device_get_uclass_id(dev)) {
-	case UCLASS_ROOT:
-	case UCLASS_SIMPLE_BUS:
-		/* stop traversing parents at this point: */
-		return sizeof(ROOT);
-	case UCLASS_ETH:
-		return dp_size(dev->parent) +
-			sizeof(struct efi_device_path_mac_addr);
-	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)
-		case UCLASS_SCSI:
-			return dp_size(dev->parent) +
-				sizeof(struct efi_device_path_scsi);
-#endif
-#if defined(CONFIG_MMC)
-		case UCLASS_MMC:
-			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) +
-				sizeof(struct efi_device_path_nvme);
-#endif
-#ifdef CONFIG_SANDBOX
-		case UCLASS_HOST:
-			 /*
-			  * Sandbox's host device will be represented
-			  * as vendor device with extra one byte for
-			  * device number
-			  */
-			return dp_size(dev->parent)
-				+ sizeof(struct efi_device_path_vendor) + 1;
-#endif
-#ifdef CONFIG_USB
-		case UCLASS_MASS_STORAGE:
-			return dp_size(dev->parent)
-				+ sizeof(struct efi_device_path_controller);
-#endif
-#ifdef CONFIG_VIRTIO_BLK
-		case UCLASS_VIRTIO:
-			 /*
-			  * Virtio devices will be represented as a vendor
-			  * device node with an extra byte for the device
-			  * number.
-			  */
-			return dp_size(dev->parent)
-				+ sizeof(struct efi_device_path_vendor) + 1;
-#endif
-		default:
-			return dp_size(dev->parent);
-		}
-#if defined(CONFIG_MMC)
-	case UCLASS_MMC:
-		return dp_size(dev->parent) +
-			sizeof(struct efi_device_path_sd_mmc_path);
-#endif
-	case UCLASS_MASS_STORAGE:
-	case UCLASS_USB_HUB:
-		return dp_size(dev->parent) +
-			sizeof(struct efi_device_path_usb);
-	default:
-		/* just skip over unknown classes: */
-		return dp_size(dev->parent);
+	unsigned int size = 0;
+	struct efi_device_path *dp;
+
+	if (!dev)
+		return 0;
+
+	if (dev->parent)
+		size = dp_size(dev->parent);
+
+	dp = uclass_get_dp_node(dev);
+	if (dp) {
+		size += dp->length;
+		efi_free_pool(dp);
 	}
+
+	return size;
 }
 
 /*
@@ -592,210 +511,22 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
  */
 __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
 {
-	if (!dev || !dev->driver)
-		return buf;
+	struct efi_device_path *dp;
 
-	switch (device_get_uclass_id(dev)) {
-	case UCLASS_ROOT:
-	case UCLASS_SIMPLE_BUS: {
-		/* stop traversing parents at this point: */
-		struct efi_device_path_vendor *vdp = buf;
-		*vdp = ROOT;
-		return &vdp[1];
-	}
-#ifdef CONFIG_NETDEVICES
-	case UCLASS_ETH: {
-		struct efi_device_path_mac_addr *dp =
-			dp_fill(buf, dev->parent);
-		struct eth_pdata *pdata = dev_get_plat(dev);
-
-		dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
-		dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
-		dp->dp.length = sizeof(*dp);
-		memset(&dp->mac, 0, sizeof(dp->mac));
-		/* We only support IPv4 */
-		memcpy(&dp->mac, &pdata->enetaddr, ARP_HLEN);
-		/* Ethernet */
-		dp->if_type = 1;
-		return &dp[1];
-	}
-#endif
-	case UCLASS_BLK:
-		switch (dev->parent->uclass->uc_drv->id) {
-#ifdef CONFIG_SANDBOX
-		case UCLASS_HOST: {
-			/* stop traversing parents at this point: */
-			struct efi_device_path_vendor *dp;
-			struct blk_desc *desc = dev_get_uclass_plat(dev);
-
-			dp_fill(buf, dev->parent);
-			dp = buf;
-			++dp;
-			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
-			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
-			dp->dp.length = sizeof(*dp) + 1;
-			memcpy(&dp->guid, &efi_guid_host_dev,
-			       sizeof(efi_guid_t));
-			dp->vendor_data[0] = desc->devnum;
-			return &dp->vendor_data[1];
-			}
-#endif
-#ifdef CONFIG_VIRTIO_BLK
-		case UCLASS_VIRTIO: {
-			struct efi_device_path_vendor *dp;
-			struct blk_desc *desc = dev_get_uclass_plat(dev);
-
-			dp_fill(buf, dev->parent);
-			dp = buf;
-			++dp;
-			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
-			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
-			dp->dp.length = sizeof(*dp) + 1;
-			memcpy(&dp->guid, &efi_guid_virtio_dev,
-			       sizeof(efi_guid_t));
-			dp->vendor_data[0] = desc->devnum;
-			return &dp->vendor_data[1];
-			}
-#endif
-#ifdef CONFIG_IDE
-		case UCLASS_IDE: {
-			struct efi_device_path_atapi *dp =
-			dp_fill(buf, dev->parent);
-			struct blk_desc *desc = dev_get_uclass_plat(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)
-		case UCLASS_SCSI: {
-			struct efi_device_path_scsi *dp =
-				dp_fill(buf, dev->parent);
-			struct blk_desc *desc = dev_get_uclass_plat(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
-#if defined(CONFIG_MMC)
-		case UCLASS_MMC: {
-			struct efi_device_path_sd_mmc_path *sddp =
-				dp_fill(buf, dev->parent);
-			struct blk_desc *desc = dev_get_uclass_plat(dev);
-
-			sddp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
-			sddp->dp.sub_type = is_sd(desc) ?
-				DEVICE_PATH_SUB_TYPE_MSG_SD :
-				DEVICE_PATH_SUB_TYPE_MSG_MMC;
-			sddp->dp.length   = sizeof(*sddp);
-			sddp->slot_number = dev_seq(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_plat(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 =
-				dp_fill(buf, dev->parent);
-			u32 ns_id;
-
-			dp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
-			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_NVME;
-			dp->dp.length   = sizeof(*dp);
-			nvme_get_namespace_id(dev, &ns_id, dp->eui64);
-			memcpy(&dp->ns_id, &ns_id, sizeof(ns_id));
-			return &dp[1];
-			}
-#endif
-#if defined(CONFIG_USB)
-		case UCLASS_MASS_STORAGE: {
-			struct blk_desc *desc = desc = dev_get_uclass_plat(dev);
-			struct efi_device_path_controller *dp =
-				dp_fill(buf, dev->parent);
-
-			dp->dp.type	= DEVICE_PATH_TYPE_HARDWARE_DEVICE;
-			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CONTROLLER;
-			dp->dp.length	= sizeof(*dp);
-			dp->controller_number = desc->lun;
-			return &dp[1];
-		}
-#endif
-		default:
-			debug("%s(%u) %s: unhandled parent class: %s (%u)\n",
-			      __FILE__, __LINE__, __func__,
-			      dev->name, dev->parent->uclass->uc_drv->id);
-			return dp_fill(buf, dev->parent);
-		}
-#if defined(CONFIG_MMC)
-	case UCLASS_MMC: {
-		struct efi_device_path_sd_mmc_path *sddp =
-			dp_fill(buf, dev->parent);
-		struct mmc *mmc = mmc_get_mmc_dev(dev);
-		struct blk_desc *desc = mmc_get_blk_desc(mmc);
-
-		sddp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
-		sddp->dp.sub_type = is_sd(desc) ?
-			DEVICE_PATH_SUB_TYPE_MSG_SD :
-			DEVICE_PATH_SUB_TYPE_MSG_MMC;
-		sddp->dp.length   = sizeof(*sddp);
-		sddp->slot_number = dev_seq(dev);
-
-		return &sddp[1];
-	}
-#endif
-	case UCLASS_MASS_STORAGE:
-	case UCLASS_USB_HUB: {
-		struct efi_device_path_usb *udp = dp_fill(buf, dev->parent);
-
-		switch (device_get_uclass_id(dev->parent)) {
-		case UCLASS_USB_HUB: {
-			struct usb_device *udev = dev_get_parent_priv(dev);
+	if (!dev)
+		return buf;
 
-			udp->parent_port_number = udev->portnr;
-			break;
-		}
-		default:
-			udp->parent_port_number = 0;
-		}
-		udp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
-		udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
-		udp->dp.length   = sizeof(*udp);
-		udp->usb_interface = 0;
+	if (dev->parent)
+		buf = dp_fill(buf, dev->parent);
 
-		return &udp[1];
-	}
-	default:
-		/* If the uclass driver is missing, this will show NULL */
-		log_debug("unhandled device class: %s (%s)\n", dev->name,
-			  dev_get_uclass_name(dev));
-		return dp_fill(buf, dev->parent);
+	dp = uclass_get_dp_node(dev);
+	if (dp) {
+		memcpy(buf, dp, dp->length);
+		buf += dp->length;
+		efi_free_pool(dp);
 	}
+
+	return buf;
 }
 
 static unsigned dp_part_size(struct blk_desc *desc, int part)
-- 
2.39.2



More information about the U-Boot mailing list