Use function uclass_get_dp_node() to construct device paths.

Signed-off-by: Heinrich Schuchardt <[email protected]>
---
 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

Reply via email to