mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-24 14:25:56 +00:00
bootstd: Allow iterating to the next label in a list
Add a function which moves to the next label in a list of labels. This allows processing the boot_targets environment variable. This works using a new label list in the bootflow iterator. The logic to set this up is included in a subsequent commit. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
66e3dce787
commit
e4b694893f
4 changed files with 123 additions and 3 deletions
|
@ -566,6 +566,25 @@ void bootdev_clear_bootflows(struct udevice *dev)
|
|||
}
|
||||
}
|
||||
|
||||
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];) {
|
||||
log_debug("Scanning: %s\n", iter->labels[iter->cur_label]);
|
||||
bootdev_hunt_and_find_by_label(iter->labels[iter->cur_label],
|
||||
&dev, method_flagsp);
|
||||
}
|
||||
|
||||
if (!dev)
|
||||
return log_msg_ret("fin", -ENODEV);
|
||||
*devp = dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* h_cmp_bootdev() - Compare two bootdevs to find out which should go first
|
||||
*
|
||||
|
@ -763,8 +782,11 @@ int bootdev_hunt(const char *spec, bool show)
|
|||
|
||||
log_debug("looking at %.*s for %s\n",
|
||||
(int)max(strlen(name), len), spec, name);
|
||||
if (spec && strncmp(spec, name, max(strlen(name), len)))
|
||||
continue;
|
||||
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;
|
||||
|
|
|
@ -333,6 +333,22 @@ int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show);
|
|||
int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
|
||||
int *method_flagsp);
|
||||
|
||||
/**
|
||||
* bootdev_next_label() - Move to the next bootdev in the label sequence
|
||||
*
|
||||
* Looks through the remaining labels until it finds one that matches a bootdev.
|
||||
* Bootdev scanners are used as needed. For example a label "mmc1" results in
|
||||
* running the "mmc" bootdrv.
|
||||
*
|
||||
* @iter: Interation info, containing iter->cur_label
|
||||
* @devp: New bootdev found, if any was found
|
||||
* @method_flagsp: If non-NULL, returns any flags implied by the label
|
||||
* (enum bootflow_meth_flags_t), 0 if none
|
||||
* Returns 0 if OK, -ENODEV if no bootdev was found
|
||||
*/
|
||||
int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
|
||||
int *method_flagsp);
|
||||
|
||||
#if CONFIG_IS_ENABLED(BOOTSTD)
|
||||
/**
|
||||
* bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
|
||||
|
|
|
@ -175,6 +175,8 @@ enum bootflow_meth_flags_t {
|
|||
* @cur_dev: Current bootdev number, an index into @dev_order[]
|
||||
* @dev_order: List of bootdevs to scan, in order of priority. The scan starts
|
||||
* with the first one on the list
|
||||
* @labels: List of labels to scan for bootdevs
|
||||
* @cur_label: Current label being processed
|
||||
* @num_methods: Number of bootmeth devices in @method_order
|
||||
* @cur_method: Current method number, an index into @method_order
|
||||
* @first_glob_method: First global method, if any, else -1
|
||||
|
@ -196,6 +198,8 @@ struct bootflow_iter {
|
|||
int num_devs;
|
||||
int cur_dev;
|
||||
struct udevice **dev_order;
|
||||
const char *const *labels;
|
||||
int cur_label;
|
||||
int num_methods;
|
||||
int cur_method;
|
||||
int first_glob_method;
|
||||
|
|
|
@ -355,7 +355,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
|
|||
ut_assert_console_end();
|
||||
|
||||
/* Scan all hunters */
|
||||
sandbox_set_eth_enable(false);
|
||||
test_set_eth_enable(false);
|
||||
test_set_skip_delays(true);
|
||||
ut_assertok(run_command("bootdev hunt", 0));
|
||||
ut_assert_nextline("Hunting with: ethernet");
|
||||
|
@ -510,3 +510,81 @@ static int bootdev_test_hunt_label(struct unit_test_state *uts)
|
|||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST(bootdev_test_hunt_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
|
||||
|
||||
/* Check iterating to the next label in a list */
|
||||
static int bootdev_test_next_label(struct unit_test_state *uts)
|
||||
{
|
||||
const char *const labels[] = {"mmc0", "scsi", "dhcp", "pxe", NULL};
|
||||
struct bootflow_iter iter;
|
||||
struct bootstd_priv *std;
|
||||
struct bootflow bflow;
|
||||
struct udevice *dev;
|
||||
int mflags;
|
||||
|
||||
test_set_eth_enable(false);
|
||||
|
||||
/* get access to the used hunters */
|
||||
ut_assertok(bootstd_get_priv(&std));
|
||||
|
||||
memset(&iter, '\0', sizeof(iter));
|
||||
memset(&bflow, '\0', sizeof(bflow));
|
||||
iter.part = 0;
|
||||
uclass_first_device(UCLASS_BOOTMETH, &bflow.method);
|
||||
iter.cur_label = -1;
|
||||
iter.labels = labels;
|
||||
|
||||
dev = NULL;
|
||||
mflags = 123;
|
||||
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
|
||||
console_record_reset_enable();
|
||||
ut_assert_console_end();
|
||||
ut_assertnonnull(dev);
|
||||
ut_asserteq_str("mmc0.bootdev", dev->name);
|
||||
ut_asserteq(0, mflags);
|
||||
|
||||
ut_assertok(bootstd_test_check_mmc_hunter(uts));
|
||||
|
||||
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
|
||||
ut_assert_nextline("scanning bus for devices...");
|
||||
ut_assert_skip_to_line(
|
||||
" Capacity: 1.9 MB = 0.0 GB (4095 x 512)");
|
||||
ut_assert_console_end();
|
||||
ut_assertnonnull(dev);
|
||||
ut_asserteq_str("scsi.id0lun0.bootdev", dev->name);
|
||||
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
|
||||
|
||||
/* SCSI is fifth in the list, so bit 4 */
|
||||
ut_asserteq(BIT(2) | BIT(4), std->hunters_used);
|
||||
|
||||
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
|
||||
ut_assert_console_end();
|
||||
ut_assertnonnull(dev);
|
||||
ut_asserteq_str("eth@10002000.bootdev", dev->name);
|
||||
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_DHCP_ONLY,
|
||||
mflags);
|
||||
|
||||
/* dhcp: Ethernet is first so bit 0 */
|
||||
ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
|
||||
|
||||
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
|
||||
ut_assert_console_end();
|
||||
ut_assertnonnull(dev);
|
||||
ut_asserteq_str("eth@10002000.bootdev", dev->name);
|
||||
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS | BOOTFLOW_METHF_PXE_ONLY,
|
||||
mflags);
|
||||
|
||||
/* pxe: Ethernet is first so bit 0 */
|
||||
ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
|
||||
|
||||
mflags = 123;
|
||||
ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags));
|
||||
ut_asserteq(123, mflags);
|
||||
ut_assert_console_end();
|
||||
|
||||
/* no change */
|
||||
ut_asserteq(BIT(2) | BIT(4) | BIT(0), std->hunters_used);
|
||||
|
||||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST(bootdev_test_next_label, UT_TESTF_DM | UT_TESTF_SCAN_FDT |
|
||||
UT_TESTF_ETH_BOOTDEV | UT_TESTF_SF_BOOTDEV);
|
||||
|
|
Loading…
Add table
Reference in a new issue