[PATCH 1/1] efi_loader: improve block device integration with DM

Heinrich Schuchardt xypron.glpk at gmx.de
Thu Jun 17 17:15:32 CEST 2021


Up to now when devices became available after executing the UEFI
sub-system initialization where not available for EFI applications.

With the patch block devices are added to the UEFI object list whenever
they are probed.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 drivers/core/device.c               |  7 +++
 include/efi_loader.h                |  6 +++
 lib/efi_driver/Makefile             |  1 +
 lib/efi_driver/efi_dm_integration.c | 36 +++++++++++++++
 lib/efi_loader/efi_disk.c           | 72 +++++++++++++++++------------
 5 files changed, 93 insertions(+), 29 deletions(-)
 create mode 100644 lib/efi_driver/efi_dm_integration.c

diff --git a/drivers/core/device.c b/drivers/core/device.c
index cb960f8ec4..7355a5c2a9 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -14,6 +14,7 @@
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <clk.h>
+#include <efi_loader.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
 #include <malloc.h>
@@ -579,6 +580,12 @@ int device_probe(struct udevice *dev)
 	if (dev->parent && device_get_uclass_id(dev) == UCLASS_PINCTRL)
 		pinctrl_select_state(dev, "default");

+	if (CONFIG_IS_ENABLED(EFI_LOADER)) {
+		ret = efi_post_probe_device(dev);
+		if (ret)
+			goto fail_uclass;
+	}
+
 	return 0;
 fail_uclass:
 	if (device_remove(dev, DM_REMOVE_NORMAL)) {
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 0a9c82a257..78dd687913 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -17,6 +17,7 @@
 #include <pe.h>

 struct blk_desc;
+struct udevice;

 static inline int guidcmp(const void *g1, const void *g2)
 {
@@ -28,6 +29,9 @@ static inline void *guidcpy(void *dst, const void *src)
 	return memcpy(dst, src, sizeof(efi_guid_t));
 }

+/* Called by device_probe() */
+int efi_post_probe_device(struct udevice *dev);
+
 /* No need for efi loader support in SPL */
 #if CONFIG_IS_ENABLED(EFI_LOADER)

@@ -420,6 +424,8 @@ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t debug_disposition,
 void efi_carve_out_dt_rsv(void *fdt);
 /* Called by bootefi to make console interface available */
 efi_status_t efi_console_register(void);
+/* Called when a block devices has been probed */
+efi_status_t efi_block_device_register(struct udevice *dev);
 /* Called by bootefi to make all disk storage accessible as EFI objects */
 efi_status_t efi_disk_register(void);
 /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */
diff --git a/lib/efi_driver/Makefile b/lib/efi_driver/Makefile
index 83baa1c9a4..f0d5fa5074 100644
--- a/lib/efi_driver/Makefile
+++ b/lib/efi_driver/Makefile
@@ -5,6 +5,7 @@
 # This file only gets included with CONFIG_EFI_LOADER set, so all
 # object inclusion implicitly depends on it

+obj-y += efi_dm_integration.o
 obj-y += efi_uclass.o
 ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
 obj-y += efi_block_device.o
diff --git a/lib/efi_driver/efi_dm_integration.c b/lib/efi_driver/efi_dm_integration.c
new file mode 100644
index 0000000000..9c6c339473
--- /dev/null
+++ b/lib/efi_driver/efi_dm_integration.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021, Heinrich Schuchardt <xypron.glpk at gmx.de>
+ */
+
+#define LOG_CATEGORY LOGC_EFI
+
+#include <common.h>
+#include <dm.h>
+#include <efi_loader.h>
+#include <log.h>
+
+/**
+ * efi_post_probe_device() - set up handle for probed device
+ *
+ * This function is called by device_probe(). After the UEFI sub-system is
+ * initialized this function adds handles for new devices.
+ *
+ * @dev:	probed device
+ * Return:	0 on success
+ */
+int efi_post_probe_device(struct udevice *dev)
+{
+	if (!dev || !dev->uclass)
+		return -EINVAL;
+
+	switch (dev->uclass->uc_drv->id) {
+	case UCLASS_BLK:
+		if (efi_block_device_register(dev) != EFI_SUCCESS)
+			log_err("Failed to register %s\n", dev->name);
+	default:
+		break;
+	}
+
+	return 0;
+}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 988907ecb9..b798cab345 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <blk.h>
 #include <dm.h>
+#include <dm/device-internal.h>
 #include <efi_loader.h>
 #include <fs.h>
 #include <log.h>
@@ -535,6 +536,41 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
 	return disks;
 }

+/**
+ * efi_block_device_register() - register a block device in the UEFI sub-system
+ *
+ * @dev:	block device
+ * Return:	status code
+ */
+efi_status_t efi_block_device_register(struct udevice *dev)
+{
+	struct blk_desc *desc = dev_get_uclass_plat(dev);
+	const char *if_typename = blk_get_if_type_name(desc->if_type);
+	struct efi_disk_obj *disk;
+	efi_status_t ret;
+
+	/* Add block device for the full device */
+	ret = device_probe(dev);
+	if (ret)
+		return EFI_NOT_FOUND;
+	log_info("Scanning disk %s...\n", dev->name);
+	ret = efi_disk_add_dev(NULL, NULL, if_typename,
+				desc, desc->devnum, NULL, 0, &disk);
+	if (ret == EFI_NOT_READY) {
+		log_notice("Disk %s not ready\n", dev->name);
+		return ret;
+	} else if (ret != EFI_SUCCESS) {
+		log_err("ERROR: failure to add disk device %s, r = %lu\n",
+			dev->name, ret & ~EFI_ERROR_MASK);
+		return ret;
+	}
+
+	/* Partitions show up as block devices in EFI */
+	efi_disk_create_partitions(&disk->header, desc, if_typename,
+				   desc->devnum, dev->name);
+	return ret;
+}
+
 /**
  * efi_disk_register() - register block devices
  *
@@ -552,38 +588,16 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
  */
 efi_status_t efi_disk_register(void)
 {
-	struct efi_disk_obj *disk;
-	int disks = 0;
-	efi_status_t ret;
 #ifdef CONFIG_BLK
 	struct udevice *dev;
-
+	/* Probe all block devices */
 	for (uclass_first_device_check(UCLASS_BLK, &dev); dev;
-	     uclass_next_device_check(&dev)) {
-		struct blk_desc *desc = dev_get_uclass_plat(dev);
-		const char *if_typename = blk_get_if_type_name(desc->if_type);
-
-		/* Add block device for the full device */
-		log_info("Scanning disk %s...\n", dev->name);
-		ret = efi_disk_add_dev(NULL, NULL, if_typename,
-					desc, desc->devnum, NULL, 0, &disk);
-		if (ret == EFI_NOT_READY) {
-			log_notice("Disk %s not ready\n", dev->name);
-			continue;
-		}
-		if (ret) {
-			log_err("ERROR: failure to add disk device %s, r = %lu\n",
-				dev->name, ret & ~EFI_ERROR_MASK);
-			return ret;
-		}
-		disks++;
-
-		/* Partitions show up as block devices in EFI */
-		disks += efi_disk_create_partitions(
-					&disk->header, desc, if_typename,
-					desc->devnum, dev->name);
-	}
+	     uclass_next_device_check(&dev))
+		;
 #else
+	struct efi_disk_obj *disk;
+	int disks = 0;
+	efi_status_t ret;
 	int i, if_type;

 	/* Search for all available disk devices */
@@ -630,8 +644,8 @@ efi_status_t efi_disk_register(void)
 						 if_typename, i, devname);
 		}
 	}
-#endif
 	log_info("Found %d disks\n", disks);
+#endif

 	return EFI_SUCCESS;
 }
--
2.30.2



More information about the U-Boot mailing list