From 21eb7c16ec86e239482386238ea606170ef4e90d Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Mon, 19 Jun 2023 14:14:03 +0300 Subject: efi_loader: make efi_remove_protocol() static A previous patch is removing the last consumer of efi_remove_protocol(). Switch that to static and treat it as an internal API in order to force users install and remove protocols with the appropriate EFI functions. It's worth noting that we still have files using efi_add_protocol(). We should convert all these to efi_install_multiple_protocol_interfaces() and treat efi_add_protocol() in a similar manner Reviewed-by: Heinrich Schuchardt Signed-off-by: Ilias Apalodimas --- include/efi_loader.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/efi_loader.h b/include/efi_loader.h index 604fd765f75..b5fa0fe01de 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -662,10 +662,6 @@ efi_status_t efi_protocol_open(struct efi_handler *handler, void **protocol_interface, void *agent_handle, void *controller_handle, uint32_t attributes); -/* Delete protocol from a handle */ -efi_status_t efi_remove_protocol(const efi_handle_t handle, - const efi_guid_t *protocol, - void *protocol_interface); /* Install multiple protocol interfaces */ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...); -- cgit v1.3.1 From e07368ea57d224557570a6715dcffdbc883a8079 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 19 Jul 2023 06:43:08 +0200 Subject: efi_loader: support all uclasses in device path On devices with multiple USB mass storage devices errors like Path /../USB(0x0,0x0)/USB(0x1,0x0)/Ctrl(0x0) already installed. are seen. This is due to creating non-unique device paths. To uniquely identify devices we must provide path nodes for all devices on the path from the root device. Add support for generating device path nodes for all uclasses. Reported-by: Suniel Mahesh Signed-off-by: Heinrich Schuchardt --- include/efi_api.h | 7 +++++ lib/efi_loader/efi_device_path.c | 56 ++++++++++++++++++---------------------- 2 files changed, 32 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/include/efi_api.h b/include/efi_api.h index 55a4c989fc7..8f5ef5f680f 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -579,6 +579,13 @@ struct efi_device_path_vendor { u8 vendor_data[]; } __packed; +struct efi_device_path_udevice { + struct efi_device_path dp; + efi_guid_t guid; + int uclass_id; + int dev_number; +} __packed; + struct efi_device_path_controller { struct efi_device_path dp; u32 controller_number; diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index c135e2883db..19e8861ef49 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -38,16 +39,6 @@ const struct efi_device_path END = { .length = sizeof(END), }; -/* template ROOT node: */ -static const struct efi_device_path_vendor ROOT = { - .dp = { - .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, - .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, - .length = sizeof(ROOT), - }, - .guid = U_BOOT_GUID, -}; - #if defined(CONFIG_MMC) /* * Determine if an MMC device is an SD card. @@ -497,13 +488,12 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp) __maybe_unused static unsigned int dp_size(struct udevice *dev) { if (!dev || !dev->driver) - return sizeof(ROOT); + return sizeof(struct efi_device_path_udevice); switch (device_get_uclass_id(dev)) { case UCLASS_ROOT: - case UCLASS_SIMPLE_BUS: /* stop traversing parents at this point: */ - return sizeof(ROOT); + return sizeof(struct efi_device_path_udevice); case UCLASS_ETH: return dp_size(dev->parent) + sizeof(struct efi_device_path_mac_addr); @@ -582,8 +572,8 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev) return dp_size(dev->parent) + sizeof(struct efi_device_path_usb); default: - /* just skip over unknown classes: */ - return dp_size(dev->parent); + return dp_size(dev->parent) + + sizeof(struct efi_device_path_udevice); } } @@ -600,13 +590,6 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) return buf; 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 = @@ -805,11 +788,24 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) 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); + default: { + struct efi_device_path_udevice *vdp; + enum uclass_id uclass_id = device_get_uclass_id(dev); + + if (uclass_id == UCLASS_ROOT) + vdp = buf; + else + vdp = dp_fill(buf, dev->parent); + + vdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; + vdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; + vdp->dp.length = sizeof(*vdp); + memcpy(&vdp->guid, &efi_u_boot_guid, sizeof(efi_guid_t)); + vdp->uclass_id = uclass_id; + vdp->dev_number = dev->seq_; + + return &vdp[1]; + } } } @@ -1046,14 +1042,12 @@ struct efi_device_path *efi_dp_from_uart(void) { void *buf, *pos; struct efi_device_path_uart *uart; - size_t dpsize = sizeof(ROOT) + sizeof(*uart) + sizeof(END); + size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END); buf = efi_alloc(dpsize); if (!buf) return NULL; - pos = buf; - memcpy(pos, &ROOT, sizeof(ROOT)); - pos += sizeof(ROOT); + pos = dp_fill(buf, dm_root()); uart = pos; uart->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART; -- cgit v1.3.1