All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: masami.hiramatsu@linaro.org, u-boot@lists.denx.de,
	agraf@csgraf.de, sjg@chromium.org, ilias.apalodimas@linaro.org
Subject: Re: [RFC v2 15/20] efi_loader: disk: a helper function to create efi_disk objects from udevice
Date: Thu, 6 Jan 2022 16:16:29 +0900	[thread overview]
Message-ID: <20220106071629.GE45004@laputa> (raw)
In-Reply-To: <380c0a2f-61af-c51d-e2c7-f0fc5758a494@gmx.de>

On Sun, Jan 02, 2022 at 10:18:18AM +0100, Heinrich Schuchardt wrote:
> On 12/10/21 07:49, AKASHI Takahiro wrote:
> > Add efi_disk_probe() function.
> > This function creates an efi_disk object for a raw disk device (UCLASS_BLK)
> > and additional objects for related partitions (UCLASS_PARTITION).
> > 
> > So this function is expected to be called through driver model's "probe"
> > interface every time one raw disk device is detected and activated.
> > We assume that partition devices (UCLASS_PARTITION) have been created
> > when this function is invoked.
> > 
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >   include/efi_loader.h       |   4 +-
> >   lib/efi_loader/Kconfig     |   2 +
> >   lib/efi_loader/efi_disk.c  | 206 ++++++++++++++++++++++++-------------
> >   lib/efi_loader/efi_setup.c |  11 +-
> >   4 files changed, 142 insertions(+), 81 deletions(-)
> > 
> > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > index d52e399841ba..a51095930efa 100644
> > --- a/include/efi_loader.h
> > +++ b/include/efi_loader.h
> > @@ -519,8 +519,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 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 initialize efi_disks */
> > +efi_status_t efi_disk_init(void);
> >   /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */
> >   efi_status_t efi_rng_register(void);
> >   /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
> > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> > index 700dc838ddb9..108c00343fce 100644
> > --- a/lib/efi_loader/Kconfig
> > +++ b/lib/efi_loader/Kconfig
> > @@ -11,6 +11,7 @@ config EFI_LOADER
> >   	# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
> >   	depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT
> >   	depends on BLK
> > +	depends on EVENT
> >   	depends on DM_ETH || !NET
> >   	depends on !EFI_APP
> >   	default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
> > @@ -41,6 +42,7 @@ config CMD_BOOTEFI_BOOTMGR
> > 
> >   config EFI_SETUP_EARLY
> >   	bool
> > +	default y
> > 
> >   choice
> >   	prompt "Store for non-volatile UEFI variables"
> > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> > index 45127d176869..2941b0c3db47 100644
> > --- a/lib/efi_loader/efi_disk.c
> > +++ b/lib/efi_loader/efi_disk.c
> > @@ -10,6 +10,9 @@
> >   #include <common.h>
> >   #include <blk.h>
> >   #include <dm.h>
> > +#include <dm/device-internal.h>
> > +#include <dm/tag.h>
> > +#include <event.h>
> >   #include <efi_loader.h>
> >   #include <fs.h>
> >   #include <log.h>
> > @@ -487,103 +490,158 @@ error:
> >   	return ret;
> >   }
> > 
> > -/**
> > - * efi_disk_create_partitions() - create handles and protocols for partitions
> > +/*
> > + * Create a handle for a whole raw disk
> >    *
> > - * Create handles and protocols for the partitions of a block device.
> > + * @dev		uclass device (UCLASS_BLK)
> >    *
> > - * @parent:		handle of the parent disk
> > - * @desc:		block device
> > - * @if_typename:	interface type
> > - * @diskid:		device number
> > - * @pdevname:		device name
> > - * Return:		number of partitions created
> > + * Create an efi_disk object which is associated with @dev.
> > + * The type of @dev must be UCLASS_BLK.
> > + *
> > + * @return	0 on success, -1 otherwise
> >    */
> > -int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
> > -			       const char *if_typename, int diskid,
> > -			       const char *pdevname)
> > +static int efi_disk_create_raw(struct udevice *dev)
> >   {
> > -	int disks = 0;
> > -	char devname[32] = { 0 }; /* dp->str is u16[32] long */
> > -	int part;
> > -	struct efi_device_path *dp = NULL;
> > +	struct efi_disk_obj *disk;
> > +	struct blk_desc *desc;
> > +	const char *if_typename;
> > +	int diskid;
> >   	efi_status_t ret;
> > -	struct efi_handler *handler;
> > 
> > -	/* Get the device path of the parent */
> > -	ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
> > -	if (ret == EFI_SUCCESS)
> > -		dp = handler->protocol_interface;
> > -
> > -	/* Add devices for each partition */
> > -	for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
> > -		struct disk_partition info;
> > -
> > -		if (part_get_info(desc, part, &info))
> > -			continue;
> > -		snprintf(devname, sizeof(devname), "%s:%x", pdevname,
> > -			 part);
> > -		ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
> > -				       &info, part, NULL);
> > -		if (ret != EFI_SUCCESS) {
> > -			log_err("Adding partition %s failed\n", pdevname);
> > -			continue;
> > -		}
> > -		disks++;
> > +	desc = dev_get_uclass_plat(dev);
> > +	if_typename = blk_get_if_type_name(desc->if_type);
> > +	diskid = desc->devnum;
> > +
> > +	ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
> > +			       diskid, NULL, 0, &disk);
> > +	if (ret != EFI_SUCCESS) {
> > +		if (ret == EFI_NOT_READY)
> > +			log_notice("Disk %s not ready\n", dev->name);
> > +		else
> > +			log_err("Adding disk for %s failed\n", dev->name);
> > +
> > +		return -1;
> > +	}
> > +	disk->dev = dev;
> > +	if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
> > +		efi_free_pool(disk->dp);
> > +		efi_delete_handle(&disk->header);
> > +
> > +		return -1;
> >   	}
> > 
> > -	return disks;
> > +	return 0;
> >   }
> > 
> > -/**
> > - * efi_disk_register() - register block devices
> > - *
> > - * U-Boot doesn't have a list of all online disk devices. So when running our
> > - * EFI payload, we scan through all of the potentially available ones and
> > - * store them in our object pool.
> > +/*
> > + * Create a handle for a disk partition
> >    *
> > - * This function is called in efi_init_obj_list().
> > + * @dev		uclass device (UCLASS_PARTITION)
> >    *
> > - * TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
> > - * Consider converting the code to look up devices as needed. The EFI device
> > - * could be a child of the UCLASS_BLK block device, perhaps.
> > + * Create an efi_disk object which is associated with @dev.
> > + * The type of @dev must be UCLASS_PARTITION.
> >    *
> > - * Return:	status code
> > + * @return	0 on success, -1 otherwise
> >    */
> > -efi_status_t efi_disk_register(void)
> > +static int efi_disk_create_part(struct udevice *dev)
> >   {
> > +	efi_handle_t parent;
> > +	struct blk_desc *desc;
> > +	const char *if_typename;
> > +	struct disk_part *part_data;
> > +	struct disk_partition *info;
> > +	unsigned int part;
> > +	int diskid;
> > +	struct efi_handler *handler;
> > +	struct efi_device_path *dp_parent;
> >   	struct efi_disk_obj *disk;
> > -	int disks = 0;
> >   	efi_status_t ret;
> > +
> > +	if (dev_tag_get_ptr(dev_get_parent(dev), DM_TAG_EFI, (void **)&parent))
> > +		return -1;
> > +
> > +	desc = dev_get_uclass_plat(dev_get_parent(dev));
> > +	if_typename = blk_get_if_type_name(desc->if_type);
> > +	diskid = desc->devnum;
> > +
> > +	part_data = dev_get_uclass_plat(dev);
> > +	part = part_data->partnum;
> > +	info = &part_data->gpt_part_info;
> > +
> > +	ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
> > +	if (ret != EFI_SUCCESS)
> > +		return -1;
> > +	dp_parent = (struct efi_device_path *)handler->protocol_interface;
> > +
> > +	ret = efi_disk_add_dev(parent, dp_parent, if_typename, desc, diskid,
> > +			       info, part, &disk);
> > +	if (ret != EFI_SUCCESS) {
> > +		log_err("Adding partition for %s failed\n", dev->name);
> > +		return -1;
> > +	}
> > +	disk->dev = dev;
> > +	if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) {
> > +		efi_free_pool(disk->dp);
> > +		efi_delete_handle(&disk->header);
> > +
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +/*
> > + * Create efi_disk objects for a block device
> > + *
> > + * @dev		uclass device (UCLASS_BLK)
> > + *
> > + * Create efi_disk objects for partitions as well as a raw disk
> > + * which is associated with @dev.
> > + * The type of @dev must be UCLASS_BLK.
> > + * This function is expected to be called at EV_PM_POST_PROBE.
> > + *
> > + * @return	0 on success, -1 otherwise
> > + */
> > +static int efi_disk_probe(void *ctx, struct event *event)
> > +{
> >   	struct udevice *dev;
> > +	enum uclass_id id;
> > +	struct udevice *child;
> > +	int ret;
> > 
> > -	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);
> > +	dev = event->data.dm.dev;
> > +	id = device_get_uclass_id(dev);
> > 
> > -		/* 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);
> > -			continue;
> > -		}
> > -		disks++;
> > +	/* TODO: We won't support partitions in a partition */
> > +	if (id != UCLASS_BLK) {
> > +		if (id != UCLASS_PARTITION)
> > +			log_info("Not a block device: %s\n", dev->name);
> 
> I get the following messages on the sandbox:
> 
> Not a block device: pinmux_i2c0_pins
> Not a block device: i2c@0
> Not a block device: rtc@61
> Not a block device: bootcount@0
> Not a block device: emul
> Not a block device: emull
> 
> Why do you create these?

They are debug messages as I intended to make sure that a 'probe' hook
was always called in vain even if a given udevice was not a block device.
(In this sense, event API has room for improvement.)

On the other hand, this behavior is useful when we want to add a nested
partition, that is, partitions in a partition.

Will drop the message for now.

-Takahiro Akashi


> Best regards
> 
> Heinrich
> 
> > +		return 0;
> > +	}
> > +
> > +	ret = efi_disk_create_raw(dev);
> > +	if (ret)
> > +		return -1;
> > 
> > -		/* Partitions show up as block devices in EFI */
> > -		disks += efi_disk_create_partitions(
> > -					&disk->header, desc, if_typename,
> > -					desc->devnum, dev->name);
> > +	device_foreach_child(child, dev) {
> > +		ret = efi_disk_create_part(child);
> > +		if (ret)
> > +			return -1;
> >   	}
> > 
> > -	log_info("Found %d disks\n", disks);
> > +	return 0;
> > +}
> > +
> > +efi_status_t efi_disk_init(void)
> > +{
> > +	int ret;
> > +
> > +	ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
> > +			     efi_disk_probe, NULL);
> > +	if (ret) {
> > +		log_err("Event registration for efi_disk add failed\n");
> > +		return EFI_OUT_OF_RESOURCES;
> > +	}
> > 
> >   	return EFI_SUCCESS;
> >   }
> > diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
> > index 1aba71cd9624..1c912b0157aa 100644
> > --- a/lib/efi_loader/efi_setup.c
> > +++ b/lib/efi_loader/efi_setup.c
> > @@ -200,11 +200,12 @@ efi_status_t efi_init_obj_list(void)
> >   	if (ret != EFI_SUCCESS)
> >   		goto out;
> > 
> > -#ifdef CONFIG_PARTITIONS
> > -	ret = efi_disk_register();
> > -	if (ret != EFI_SUCCESS)
> > -		goto out;
> > -#endif
> > +	if (IS_ENABLED(CONFIG_BLK)) {
> > +		ret = efi_disk_init();
> > +		if (ret != EFI_SUCCESS)
> > +			goto out;
> > +	}
> > +
> >   	if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) {
> >   		ret = efi_rng_register();
> >   		if (ret != EFI_SUCCESS)
> 

  reply	other threads:[~2022-01-06  7:16 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-10  6:49 [RFC v2 00/20] efi_loader: more tightly integrate UEFI disks to driver model AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 01/20] part: call part_init() in blk_get_device_by_str() only for MMC AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 02/20] blk: add a helper function, blk_probe_or_unbind() AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-14  7:01     ` AKASHI Takahiro
2021-12-18 10:55       ` Heinrich Schuchardt
2021-12-20  5:19         ` AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 03/20] scsi: call device_probe() after scanning AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 04/20] usb: storage: " AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 05/20] mmc: " AKASHI Takahiro
2021-12-18  9:48   ` Heinrich Schuchardt
2021-12-18 10:03     ` Heinrich Schuchardt
2022-01-02  9:47   ` Heinrich Schuchardt
2022-01-03 10:09   ` Jaehoon Chung
2021-12-10  6:49 ` [RFC v2 06/20] nvme: " AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 07/20] sata: " AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-10  6:49 ` [RFC v2 08/20] block: ide: " AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 09/20] dm: fix an 'undefined' error in some macros AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2022-01-07 12:38     ` Ilias Apalodimas
2021-12-10  6:49 ` [RFC v2 10/20] virtio: call device_probe() in scanning AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-10  6:49 ` [RFC v2 11/20] dm: add event notification AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-14  7:07     ` AKASHI Takahiro
2021-12-19 22:17       ` Simon Glass
2022-01-02  9:41   ` Heinrich Schuchardt
2021-12-10  6:49 ` [RFC v2 12/20] dm: add tag support AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-14  7:05     ` AKASHI Takahiro
2021-12-28  8:32       ` Simon Glass
2021-12-10  6:49 ` [RFC v2 13/20] dm: disk: add UCLASS_PARTITION AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 14/20] dm: blk: add a device-probe hook for scanning disk partitions AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-10  6:49 ` [RFC v2 15/20] efi_loader: disk: a helper function to create efi_disk objects from udevice AKASHI Takahiro
2022-01-02  9:18   ` Heinrich Schuchardt
2022-01-06  7:16     ` AKASHI Takahiro [this message]
2021-12-10  6:49 ` [RFC v2 16/20] efi_loader: disk: a helper function to delete efi_disk objects AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 17/20] dm: disk: add read/write interfaces with udevice AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 18/20] efi_loader: disk: use udevice instead of blk_desc AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2021-12-10  6:49 ` [RFC v2 19/20] efi_loader: disk: not create BLK device for BLK(IF_TYPE_EFI) devices AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2022-01-02  9:19   ` Heinrich Schuchardt
2022-01-06  6:59     ` AKASHI Takahiro
2021-12-10  6:49 ` [RFC v2 20/20] efi_driver: align with efi_disk-dm integration AKASHI Takahiro
2021-12-13 12:51   ` Simon Glass
2022-01-27 15:05 ` [RFC v2 00/20] efi_loader: more tightly integrate UEFI disks to driver model Simon Glass
2022-01-28  5:01   ` AKASHI Takahiro
2022-01-28 12:32     ` AKASHI Takahiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220106071629.GE45004@laputa \
    --to=takahiro.akashi@linaro.org \
    --cc=agraf@csgraf.de \
    --cc=ilias.apalodimas@linaro.org \
    --cc=masami.hiramatsu@linaro.org \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.