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

#define LOG_CATEGORY UCLASS_BOOTSTD

#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 <spl.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_first_bootflow(struct udevice *dev, struct bootflow **bflowp)
{
	struct bootstd_priv *std;
	struct bootflow *bflow;
	int ret;

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

	bflow = alist_getw(&std->bootflows, 0, struct bootflow);
	if (!bflow)
		return -ENOENT;
	*bflowp = bflow;

	return 0;
}

int bootdev_next_bootflow(struct bootflow **bflowp)
{
	struct bootstd_priv *std;
	struct bootflow *bflow;
	int ret;

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

	bflow = alist_nextw(&std->bootflows, *bflowp);
	if (!bflow)
		return -ENOENT;
	*bflowp = bflow;

	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 bootmeth_uc_plat *plat = dev_get_uclass_plat(bflow->method);
	bool allow_any_part = plat->flags & BOOTMETHF_ANY_PART;
	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);
	log_debug("part_get_info() returned %d\n", ret);
	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_any_part) {
		/* 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 (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) {
		/* a particular partition was specified, scan it without checking */
	} else if (!iter->part) {
		/* This is the whole disk, check if we have bootable partitions */
		iter->first_bootable = part_get_bootable(desc);
		log_debug("checking bootable=%d\n", iter->first_bootable);
	} else if (allow_any_part) {
		/*
		 * allow any partition to be scanned, by skipping any checks
		 * for filesystems or partition contents on this disk
		 */

	/* if there are bootable partitions, scan only those */
	} else if ((iter->flags & BOOTFLOWIF_ONLY_BOOTABLE) &&
		   iter->first_bootable >= 0 &&
		   (iter->first_bootable ? !info.bootable : iter->part != 1)) {
		log_debug("Skipping non-bootable partition %d\n", iter->part);
		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);

		log_debug("%s: Found partition %x type %x fstype %d\n",
			  blk->name, bflow->part,
			  IS_ENABLED(CONFIG_DOS_PARTITION) ?
			  disk_partition_sys_ind(&info) : 0,
			  ret ? -1 : fs_get_type());
		bflow->blk = blk;
		bflow->state = BOOTFLOWST_FS;
	}

	log_debug("method %s\n", bflow->method->name);
	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_for_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");
	if (xpl_phase() < PHASE_BOARD_R) {
		strlcpy(dev_name, blk->name, sizeof(dev_name) - 5);
		strcat(dev_name, ".sib");
	} else {
		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_for_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;
}

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_for_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;

	if (!CONFIG_IS_ENABLED(BLK))
		return -ENOSYS;

	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 (seq == -1)
				method_flags |= BOOTFLOW_METHF_SINGLE_UCLASS;
			if (method_flagsp)
				*method_flagsp = method_flags;
			log_debug("method flags %x\n", 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);
	log_debug("sibling_blk ret=%d, blk=%s\n", ret,
		  ret ? "(none)" : blk->name);
	/*
	 * 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,%x=%p\n", dev->name, iter->part,
		  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);
}

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

	log_debug("next\n");
	if (iter->cur_label >= 0 && !iter->labels[iter->cur_label])
		return log_msg_ret("fil", -ENODEV);

	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");
	found = false;
	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("- bootdev_hunt_prio() 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);
			else
				found = true;
		}
	} while (!found);

	*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;
	char buf[32];
	int ret;

	if (label) {
		const char *end = strchr(label, ':');

		if (end) {
			size_t len = (size_t)(end - label);
			const char *part = end + 1;

			if (len + 1 > sizeof(buf)) {
				log_err("label \"%s\" is way too long\n", label);
				return -EINVAL;
			}

			memcpy(buf, label, len);
			buf[len] = '\0';
			label = buf;

			unsigned long tmp;

			if (strict_strtoul(part, 0, &tmp)) {
				log_err("Invalid partition number: %s\n", part);
				return -EINVAL;
			}

			iter->flags |= BOOTFLOWIF_SINGLE_PARTITION;
			iter->part = tmp;
		}
	}

	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);
		log_debug("- bootdev_hunt_prio() ret %d\n", ret);
		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);
			log_debug("  - hunt result %d\n", ret);
			if (ret && ret != -ENOENT)
				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_unhunt(enum uclass_id id)
{
	struct bootdev_hunter *start;
	int n_ent, i;

	start = ll_entry_start(struct bootdev_hunter, bootdev_hunter);
	n_ent = ll_entry_count(struct bootdev_hunter, bootdev_hunter);
	for (i = 0; i < n_ent; i++) {
		struct bootdev_hunter *info = start + i;

		if (info->uclass == id) {
			struct bootstd_priv *std;
			int ret;

			ret = bootstd_get_priv(&std);
			if (ret)
				return log_msg_ret("std", ret);
			if (!(std->hunters_used & BIT(i)))
				return -EALREADY;
			std->hunters_used &= ~BIT(i);
			return 0;
		}
	}

	return -ENOENT;
}

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);
		log_debug("bootdev_hunt_drv() return %d\n", ret);
		if (ret && ret != -ENOENT)
			result = ret;
	}
	log_debug("exit %d\n", result);

	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_pre_unbind(struct udevice *dev)
{
	int ret;

	ret = bootstd_clear_bootflows_for_bootdev(dev);
	if (ret)
		return log_msg_ret("bun", ret);

	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),
	.pre_unbind	= bootdev_pre_unbind,
};
