// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2021 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY UCLASS_BOOTSTD

#include <common.h>
#include <dm.h>
#include <bootdev.h>
#include <bootflow.h>
#include <bootmeth.h>
#include <bootstd.h>
#include <fs.h>
#include <log.h>
#include <malloc.h>
#include <part.h>
#include <sort.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>

enum {
	/*
	 * Set some sort of limit on the number of partitions a bootdev can
	 * have. Note that for disks this limits the partitions numbers that
	 * are scanned to 1..MAX_BOOTFLOWS_PER_BOOTDEV
	 */
	MAX_PART_PER_BOOTDEV	= 30,

	/* Maximum supported length of the "boot_targets" env string */
	BOOT_TARGETS_MAX_LEN	= 100,
};

int bootdev_add_bootflow(struct bootflow *bflow)
{
	struct bootstd_priv *std;
	struct bootflow *new;
	int ret;

	assert(bflow->dev);
	ret = bootstd_get_priv(&std);
	if (ret)
		return ret;

	new = malloc(sizeof(*bflow));
	if (!new)
		return log_msg_ret("bflow", -ENOMEM);
	memcpy(new, bflow, sizeof(*bflow));

	list_add_tail(&new->glob_node, &std->glob_head);
	if (bflow->dev) {
		struct bootdev_uc_plat *ucp = dev_get_uclass_plat(bflow->dev);

		list_add_tail(&new->bm_node, &ucp->bootflow_head);
	}

	return 0;
}

int bootdev_first_bootflow(struct udevice *dev, struct bootflow **bflowp)
{
	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);

	if (list_empty(&ucp->bootflow_head))
		return -ENOENT;

	*bflowp = list_first_entry(&ucp->bootflow_head, struct bootflow,
				   bm_node);

	return 0;
}

int bootdev_next_bootflow(struct bootflow **bflowp)
{
	struct bootflow *bflow = *bflowp;
	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(bflow->dev);

	*bflowp = NULL;

	if (list_is_last(&bflow->bm_node, &ucp->bootflow_head))
		return -ENOENT;

	*bflowp = list_entry(bflow->bm_node.next, struct bootflow, bm_node);

	return 0;
}

int bootdev_bind(struct udevice *parent, const char *drv_name, const char *name,
		 struct udevice **devp)
{
	struct udevice *dev;
	char dev_name[30];
	char *str;
	int ret;

	snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
	str = strdup(dev_name);
	if (!str)
		return -ENOMEM;
	ret = device_bind_driver(parent, drv_name, str, &dev);
	if (ret)
		return ret;
	device_set_name_alloced(dev);
	*devp = dev;

	return 0;
}

int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
			struct bootflow_iter *iter, struct bootflow *bflow)
{
	struct blk_desc *desc = dev_get_uclass_plat(blk);
	struct disk_partition info;
	char partstr[20];
	char name[60];
	int ret;

	/* Sanity check */
	if (iter->part >= MAX_PART_PER_BOOTDEV)
		return log_msg_ret("max", -ESHUTDOWN);

	bflow->blk = blk;
	if (iter->part)
		snprintf(partstr, sizeof(partstr), "part_%x", iter->part);
	else
		strcpy(partstr, "whole");
	snprintf(name, sizeof(name), "%s.%s", dev->name, partstr);
	bflow->name = strdup(name);
	if (!bflow->name)
		return log_msg_ret("name", -ENOMEM);

	bflow->part = iter->part;

	ret = bootmeth_check(bflow->method, iter);
	if (ret)
		return log_msg_ret("check", ret);

	/*
	 * partition numbers start at 0 so this cannot succeed, but it can tell
	 * us whether there is valid media there
	 */
	ret = part_get_info(desc, iter->part, &info);
	if (!iter->part && ret == -ENOENT)
		ret = 0;

	/*
	 * This error indicates the media is not present. Otherwise we just
	 * blindly scan the next partition. We could be more intelligent here
	 * and check which partition numbers actually exist.
	 */
	if (ret == -EOPNOTSUPP)
		ret = -ESHUTDOWN;
	else
		bflow->state = BOOTFLOWST_MEDIA;
	if (ret) {
		/* allow partition 1 to be missing */
		if (iter->part == 1) {
			iter->max_part = 3;
			ret = -ENOENT;
		}

		return log_msg_ret("part", ret);
	}

	/*
	 * Currently we don't get the number of partitions, so just
	 * assume a large number
	 */
	iter->max_part = MAX_PART_PER_BOOTDEV;

	/* If this is the whole disk, check if we have bootable partitions */
	if (!iter->part) {
		iter->first_bootable = part_get_bootable(desc);
		log_debug("checking bootable=%d\n", iter->first_bootable);

	/* if there are bootable partitions, scan only those */
	} else if (iter->first_bootable ? !info.bootable : iter->part != 1) {
		return log_msg_ret("boot", -EINVAL);
	} else {
		ret = fs_set_blk_dev_with_part(desc, bflow->part);
		bflow->state = BOOTFLOWST_PART;
		if (ret)
			return log_msg_ret("fs", ret);

		/* Use an #ifdef due to info.sys_ind */
#ifdef CONFIG_DOS_PARTITION
		log_debug("%s: Found partition %x type %x fstype %d\n",
			  blk->name, bflow->part, info.sys_ind,
			  ret ? -1 : fs_get_type());
#endif
		bflow->blk = blk;
		bflow->state = BOOTFLOWST_FS;
	}

	ret = bootmeth_read_bootflow(bflow->method, bflow);
	if (ret)
		return log_msg_ret("method", ret);

	return 0;
}

void bootdev_list(bool probe)
{
	struct udevice *dev;
	int ret;
	int i;

	printf("Seq  Probed  Status  Uclass    Name\n");
	printf("---  ------  ------  --------  ------------------\n");
	if (probe)
		ret = uclass_first_device_check(UCLASS_BOOTDEV, &dev);
	else
		ret = uclass_find_first_device(UCLASS_BOOTDEV, &dev);
	for (i = 0; dev; i++) {
		printf("%3x   [ %c ]  %6s  %-9.9s %s\n", dev_seq(dev),
		       device_active(dev) ? '+' : ' ',
		       ret ? simple_itoa(ret) : "OK",
		       dev_get_uclass_name(dev_get_parent(dev)), dev->name);
		if (probe)
			ret = uclass_next_device_check(&dev);
		else
			ret = uclass_find_next_device(&dev);
	}
	printf("---  ------  ------  --------  ------------------\n");
	printf("(%d bootdev%s)\n", i, i != 1 ? "s" : "");
}

int bootdev_setup_for_dev(struct udevice *parent, const char *drv_name)
{
	struct udevice *bdev;
	int ret;

	ret = device_find_first_child_by_uclass(parent, UCLASS_BOOTDEV,
						&bdev);
	if (ret) {
		if (ret != -ENODEV) {
			log_debug("Cannot access bootdev device\n");
			return ret;
		}

		ret = bootdev_bind(parent, drv_name, "bootdev", &bdev);
		if (ret) {
			log_debug("Cannot create bootdev device\n");
			return ret;
		}
	}

	return 0;
}

static int bootdev_get_suffix_start(struct udevice *dev, const char *suffix)
{
	int len, slen;

	len = strlen(dev->name);
	slen = strlen(suffix);
	if (len > slen && !strcmp(suffix, dev->name + len - slen))
		return len - slen;

	return len;
}

int bootdev_setup_sibling_blk(struct udevice *blk, const char *drv_name)
{
	struct udevice *parent, *dev;
	char dev_name[50];
	int ret, len;

	len = bootdev_get_suffix_start(blk, ".blk");
	snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name,
		 "bootdev");

	parent = dev_get_parent(blk);
	ret = device_find_child_by_name(parent, dev_name, &dev);
	if (ret) {
		char *str;

		if (ret != -ENODEV) {
			log_debug("Cannot access bootdev device\n");
			return ret;
		}
		str = strdup(dev_name);
		if (!str)
			return -ENOMEM;

		ret = device_bind_driver(parent, drv_name, str, &dev);
		if (ret) {
			log_debug("Cannot create bootdev device\n");
			return ret;
		}
		device_set_name_alloced(dev);
	}

	return 0;
}

int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp)
{
	struct udevice *parent = dev_get_parent(dev);
	struct udevice *blk;
	int ret, len;

	if (device_get_uclass_id(dev) != UCLASS_BOOTDEV)
		return -EINVAL;

	/* This should always work if bootdev_setup_sibling_blk() was used */
	len = bootdev_get_suffix_start(dev, ".bootdev");
	ret = device_find_child_by_namelen(parent, dev->name, len, &blk);
	if (ret) {
		char dev_name[50];

		snprintf(dev_name, sizeof(dev_name), "%.*s.blk", len,
			 dev->name);
		ret = device_find_child_by_name(parent, dev_name, &blk);
		if (ret)
			return log_msg_ret("find", ret);
	}
	ret = device_probe(blk);
	if (ret)
		return log_msg_ret("act", ret);
	*blkp = blk;

	return 0;
}

static int bootdev_get_from_blk(struct udevice *blk, struct udevice **bootdevp)
{
	struct udevice *parent = dev_get_parent(blk);
	struct udevice *bootdev;
	char dev_name[50];
	int ret, len;

	if (device_get_uclass_id(blk) != UCLASS_BLK)
		return -EINVAL;

	/* This should always work if bootdev_setup_sibling_blk() was used */
	len = bootdev_get_suffix_start(blk, ".blk");
	snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name,
		 "bootdev");
	ret = device_find_child_by_name(parent, dev_name, &bootdev);
	if (ret)
		return log_msg_ret("find", ret);
	*bootdevp = bootdev;

	return 0;
}

int bootdev_unbind_dev(struct udevice *parent)
{
	struct udevice *dev;
	int ret;

	ret = device_find_first_child_by_uclass(parent, UCLASS_BOOTDEV, &dev);
	if (!ret) {
		ret = device_remove(dev, DM_REMOVE_NORMAL);
		if (ret)
			return log_msg_ret("rem", ret);
		ret = device_unbind(dev);
		if (ret)
			return log_msg_ret("unb", ret);
	}

	return 0;
}

/**
 * label_to_uclass() - Convert a label to a uclass and sequence number
 *
 * @label: Label to look up (e.g. "mmc1" or "mmc0")
 * @seqp: Returns the sequence number, or -1 if none
 * @method_flagsp: If non-NULL, returns any flags implied by the label
 * (enum bootflow_meth_flags_t), 0 if none
 * Returns: sequence number on success, -EPFNOSUPPORT is the uclass is not
 * known, other -ve error code on other error
 */
static int label_to_uclass(const char *label, int *seqp, int *method_flagsp)
{
	int seq, len, method_flags;
	enum uclass_id id;
	const char *end;

	method_flags = 0;
	seq = trailing_strtoln_end(label, NULL, &end);
	len = end - label;
	if (!len)
		return -EINVAL;
	id = uclass_get_by_namelen(label, len);
	log_debug("find %s: seq=%d, id=%d/%s\n", label, seq, id,
		  uclass_get_name(id));
	if (id == UCLASS_INVALID) {
		/* try some special cases */
		if (IS_ENABLED(CONFIG_BOOTDEV_SPI_FLASH) &&
		    !strncmp("spi", label, len)) {
			id = UCLASS_SPI_FLASH;
		} else if (IS_ENABLED(CONFIG_BOOTDEV_ETH) &&
		    !strncmp("pxe", label, len)) {
			id = UCLASS_ETH;
			method_flags |= BOOTFLOW_METHF_PXE_ONLY;
		} else if (IS_ENABLED(CONFIG_BOOTDEV_ETH) &&
		    !strncmp("dhcp", label, len)) {
			id = UCLASS_ETH;
			method_flags |= BOOTFLOW_METHF_DHCP_ONLY;
		} else {
			return -EPFNOSUPPORT;
		}
	}
	if (id == UCLASS_USB)
		id = UCLASS_MASS_STORAGE;
	*seqp = seq;
	if (method_flagsp)
		*method_flagsp = method_flags;

	return id;
}

int bootdev_find_by_label(const char *label, struct udevice **devp,
			  int *method_flagsp)
{
	int seq, ret, method_flags = 0;
	struct udevice *media;
	struct uclass *uc;
	enum uclass_id id;

	ret = label_to_uclass(label, &seq, &method_flags);
	if (ret < 0)
		return log_msg_ret("uc", ret);
	id = ret;

	/* Iterate through devices in the media uclass (e.g. UCLASS_MMC) */
	uclass_id_foreach_dev(id, media, uc) {
		struct udevice *bdev, *blk;
		int ret;

		/* if there is no seq, match anything */
		if (seq != -1 && dev_seq(media) != seq) {
			log_debug("- skip, media seq=%d\n", dev_seq(media));
			continue;
		}

		ret = device_find_first_child_by_uclass(media, UCLASS_BOOTDEV,
							&bdev);
		if (ret) {
			log_debug("- looking via blk, seq=%d, id=%d\n", seq,
				  id);
			ret = blk_find_device(id, seq, &blk);
			if (!ret) {
				log_debug("- get from blk %s\n", blk->name);
				ret = bootdev_get_from_blk(blk, &bdev);
			}
		}
		if (!ret) {
			log_debug("- found %s\n", bdev->name);
			*devp = bdev;

			/*
			 * if no sequence number was provided, we must scan all
			 * bootdevs for this media uclass
			 */
			if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && seq == -1)
				method_flags |= BOOTFLOW_METHF_SINGLE_UCLASS;
			if (method_flagsp)
				*method_flagsp = method_flags;
			return 0;
		}
		log_debug("- no device in %s\n", media->name);
	}

	return -ENOENT;
}

int bootdev_find_by_any(const char *name, struct udevice **devp,
			int *method_flagsp)
{
	struct udevice *dev;
	int method_flags = 0;
	int ret = -ENODEV, seq;
	char *endp;

	seq = simple_strtol(name, &endp, 16);

	/* Select by name, label or number */
	if (*endp) {
		ret = uclass_get_device_by_name(UCLASS_BOOTDEV, name, &dev);
		if (ret == -ENODEV) {
			ret = bootdev_find_by_label(name, &dev, &method_flags);
			if (ret) {
				printf("Cannot find bootdev '%s' (err=%d)\n",
				       name, ret);
				return log_msg_ret("lab", ret);
			}
			ret = device_probe(dev);
		}
		if (ret) {
			printf("Cannot probe bootdev '%s' (err=%d)\n", name,
			       ret);
			return log_msg_ret("pro", ret);
		}
	} else if (IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
		ret = uclass_get_device_by_seq(UCLASS_BOOTDEV, seq, &dev);
		method_flags |= BOOTFLOW_METHF_SINGLE_DEV;
	}
	if (ret) {
		printf("Cannot find '%s' (err=%d)\n", name, ret);
		return ret;
	}

	*devp = dev;
	if (method_flagsp)
		*method_flagsp = method_flags;

	return 0;
}

int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
				   int *method_flagsp)
{
	int ret;

	ret = bootdev_hunt(label, false);
	if (ret)
		return log_msg_ret("scn", ret);
	ret = bootdev_find_by_label(label, devp, method_flagsp);
	if (ret)
		return log_msg_ret("fnd", ret);

	return 0;
}

static int default_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
				struct bootflow *bflow)
{
	struct udevice *blk;
	int ret;

	ret = bootdev_get_sibling_blk(dev, &blk);
	/*
	 * If there is no media, indicate that no more partitions should be
	 * checked
	 */
	if (ret == -EOPNOTSUPP)
		ret = -ESHUTDOWN;
	if (ret)
		return log_msg_ret("blk", ret);
	assert(blk);
	ret = bootdev_find_in_blk(dev, blk, iter, bflow);
	if (ret)
		return log_msg_ret("find", ret);

	return 0;
}

int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
			 struct bootflow *bflow)
{
	const struct bootdev_ops *ops = bootdev_get_ops(dev);

	log_debug("->get_bootflow %s=%p\n", dev->name, ops->get_bootflow);
	bootflow_init(bflow, dev, iter->method);
	if (!ops->get_bootflow)
		return default_get_bootflow(dev, iter, bflow);

	return ops->get_bootflow(dev, iter, bflow);
}

void bootdev_clear_bootflows(struct udevice *dev)
{
	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);

	while (!list_empty(&ucp->bootflow_head)) {
		struct bootflow *bflow;

		bflow = list_first_entry(&ucp->bootflow_head, struct bootflow,
					 bm_node);
		bootflow_remove(bflow);
	}
}

int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
		       int *method_flagsp)
{
	struct udevice *dev;

	log_debug("next\n");
	for (dev = NULL; !dev && iter->labels[++iter->cur_label];) {
		const char *label = iter->labels[iter->cur_label];
		int ret;

		log_debug("Scanning: %s\n", label);
		ret = bootdev_hunt_and_find_by_label(label, &dev,
						     method_flagsp);
		if (iter->flags & BOOTFLOWIF_SHOW) {
			if (ret == -EPFNOSUPPORT) {
				log_warning("Unknown uclass '%s' in label\n",
					    label);
			} else if (ret == -ENOENT) {
				/*
				 * looking for, e.g. 'scsi0' should find
				 * something if SCSI is present
				 */
				if (!trailing_strtol(label)) {
					log_warning("No bootdevs for '%s'\n",
						    label);
				}
			}
		}

	}

	if (!dev)
		return log_msg_ret("fin", -ENODEV);
	*devp = dev;

	return 0;
}

int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp)
{
	struct udevice *dev = *devp;
	bool found;
	int ret;

	/* find the next device with this priority */
	*devp = NULL;
	log_debug("next prio %d: dev=%p/%s\n", iter->cur_prio, dev,
		  dev ? dev->name : "none");
	do {
		/*
		 * Don't probe devices here since they may not be of the
		 * required priority
		 */
		if (!dev)
			uclass_find_first_device(UCLASS_BOOTDEV, &dev);
		else
			uclass_find_next_device(&dev);
		found = false;

		/* scan for the next device with the correct priority */
		while (dev) {
			struct bootdev_uc_plat *plat;

			plat = dev_get_uclass_plat(dev);
			log_debug("- %s: %d, want %d\n", dev->name, plat->prio,
				  iter->cur_prio);
			if (plat->prio == iter->cur_prio)
				break;
			uclass_find_next_device(&dev);
		}

		/* none found for this priority, so move to the next */
		if (!dev) {
			log_debug("None found at prio %d, moving to %d\n",
				  iter->cur_prio, iter->cur_prio + 1);
			if (++iter->cur_prio == BOOTDEVP_COUNT)
				return log_msg_ret("fin", -ENODEV);

			if (iter->flags & BOOTFLOWIF_HUNT) {
				/* hunt to find new bootdevs */
				ret = bootdev_hunt_prio(iter->cur_prio,
							iter->flags &
							BOOTFLOWIF_SHOW);
				log_debug("- hunt ret %d\n", ret);
				if (ret)
					return log_msg_ret("hun", ret);
			}
		} else {
			ret = device_probe(dev);
			if (ret) {
				log_debug("Device '%s' failed to probe\n",
					  dev->name);
				dev = NULL;
			}
		}
	} while (!dev);

	*devp = dev;

	return 0;
}

int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
		       struct udevice **devp, int *method_flagsp)
{
	struct udevice *bootstd, *dev = NULL;
	bool show = iter->flags & BOOTFLOWIF_SHOW;
	int method_flags;
	int ret;

	ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd);
	if (ret) {
		log_err("Missing bootstd device\n");
		return log_msg_ret("std", ret);
	}

	/* hunt for any pre-scan devices */
	if (iter->flags & BOOTFLOWIF_HUNT) {
		ret = bootdev_hunt_prio(BOOTDEVP_1_PRE_SCAN, show);
		if (ret)
			return log_msg_ret("pre", ret);
	}

	/* Handle scanning a single device */
	if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && label) {
		if (iter->flags & BOOTFLOWIF_HUNT) {
			ret = bootdev_hunt(label, show);
			if (ret)
				return log_msg_ret("hun", ret);
		}
		ret = bootdev_find_by_any(label, &dev, &method_flags);
		if (ret)
			return log_msg_ret("lab", ret);

		log_debug("method_flags: %x\n", method_flags);
		if (method_flags & BOOTFLOW_METHF_SINGLE_UCLASS)
			iter->flags |= BOOTFLOWIF_SINGLE_UCLASS;
		else if (method_flags & BOOTFLOW_METHF_SINGLE_DEV)
			iter->flags |= BOOTFLOWIF_SINGLE_DEV;
		else
			iter->flags |= BOOTFLOWIF_SINGLE_MEDIA;
		log_debug("Selected label: %s, flags %x\n", label, iter->flags);
	} else {
		bool ok;

		/* This either returns a non-empty list or NULL */
		iter->labels = bootstd_get_bootdev_order(bootstd, &ok);
		if (!ok)
			return log_msg_ret("ord", -ENOMEM);
		log_debug("setup labels %p\n", iter->labels);
		if (iter->labels) {
			iter->cur_label = -1;
			ret = bootdev_next_label(iter, &dev, &method_flags);
		} else {
			ret = bootdev_next_prio(iter, &dev);
			method_flags = 0;
		}
		if (!dev)
			return log_msg_ret("fin", -ENOENT);
		log_debug("Selected bootdev: %s\n", dev->name);
	}

	ret = device_probe(dev);
	if (ret)
		return log_msg_ret("probe", ret);
	if (method_flagsp)
		*method_flagsp = method_flags;
	*devp = dev;

	return 0;
}

static int bootdev_hunt_drv(struct bootdev_hunter *info, uint seq, bool show)
{
	const char *name = uclass_get_name(info->uclass);
	struct bootstd_priv *std;
	int ret;

	ret = bootstd_get_priv(&std);
	if (ret)
		return log_msg_ret("std", ret);

	if (!(std->hunters_used & BIT(seq))) {
		if (show)
			printf("Hunting with: %s\n",
			       uclass_get_name(info->uclass));
		log_debug("Hunting with: %s\n", name);
		if (info->hunt) {
			ret = info->hunt(info, show);
			if (ret)
				return ret;
		}
		std->hunters_used |= BIT(seq);
	}

	return 0;
}

int bootdev_hunt(const char *spec, bool show)
{
	struct bootdev_hunter *start;
	const char *end;
	int n_ent, i;
	int result;
	size_t len;

	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
	result = 0;

	len = SIZE_MAX;
	if (spec) {
		trailing_strtoln_end(spec, NULL, &end);
		len = end - spec;
	}

	for (i = 0; i < n_ent; i++) {
		struct bootdev_hunter *info = start + i;
		const char *name = uclass_get_name(info->uclass);
		int ret;

		log_debug("looking at %.*s for %s\n",
			  (int)max(strlen(name), len), spec, name);
		if (spec && strncmp(spec, name, max(strlen(name), len))) {
			if (info->uclass != UCLASS_ETH ||
			    (strcmp("dhcp", spec) && strcmp("pxe", spec)))
				continue;
		}
		ret = bootdev_hunt_drv(info, i, show);
		if (ret)
			result = ret;
	}

	return result;
}

int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show)
{
	struct bootdev_hunter *start;
	int n_ent, i;
	int result;

	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
	result = 0;

	log_debug("Hunting for priority %d\n", prio);
	for (i = 0; i < n_ent; i++) {
		struct bootdev_hunter *info = start + i;
		int ret;

		if (prio != info->prio)
			continue;
		ret = bootdev_hunt_drv(info, i, show);
		if (ret && ret != -ENOENT)
			result = ret;
	}

	return result;
}

void bootdev_list_hunters(struct bootstd_priv *std)
{
	struct bootdev_hunter *orig, *start;
	int n_ent, i;

	orig = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);

	/*
	 * workaround for strange bug in clang-12 which sees all the below data
	 * as zeroes. Any access of start seems to fix it, such as
	 *
	 *    printf("%p", start);
	 *
	 * Use memcpy() to force the correct behaviour.
	 */
	memcpy(&start, &orig, sizeof(orig));
	printf("%4s  %4s  %-15s  %s\n", "Prio", "Used", "Uclass", "Hunter");
	printf("%4s  %4s  %-15s  %s\n", "----", "----", "---------------", "---------------");
	for (i = 0; i < n_ent; i++) {
		struct bootdev_hunter *info = start + i;

		printf("%4d  %4s  %-15s  %s\n", info->prio,
		       std->hunters_used & BIT(i) ? "*" : "",
		       uclass_get_name(info->uclass),
		       info->drv ? info->drv->name : "(none)");
	}

	printf("(total hunters: %d)\n", n_ent);
}

static int bootdev_post_bind(struct udevice *dev)
{
	struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);

	INIT_LIST_HEAD(&ucp->bootflow_head);

	return 0;
}

static int bootdev_pre_unbind(struct udevice *dev)
{
	bootdev_clear_bootflows(dev);

	return 0;
}

UCLASS_DRIVER(bootdev) = {
	.id		= UCLASS_BOOTDEV,
	.name		= "bootdev",
	.flags		= DM_UC_FLAG_SEQ_ALIAS,
	.per_device_plat_auto	= sizeof(struct bootdev_uc_plat),
	.post_bind	= bootdev_post_bind,
	.pre_unbind	= bootdev_pre_unbind,
};
