[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