
Use function uclass_get_dp_node() to construct device paths.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@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)