From 875975231fca08d80840330c7fe3c1c4617c867f Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Apr 2019 20:46:49 +0000 Subject: [PATCH] MFC r344260, r344335 r344260: Allow the u-boot loaderdev env var to be formatted in the "usual" loader(8) way: device[s|p]. E.g., disk0s2a or disk3p12. The code first tries to parse the variable in this format using the standard disk_parsedev(). If that fails, it falls back to parsing the legacy format that has been supported by ubldr for years. In addition to 'disk', all the valid uboot device names can also be used: mmc, sata, usb, ide, scsi. The 'disk' device serves as an alias for all those types and will match the Nth storage-type device found (where N is the unit number). r344335: Fix the handling of legacy-format devices in the u-boot loaderdev variable. When I added support for the standard loader(8) disk0s2a: type formats, the parsing of legacy format was broken because it also contains a colon, but it comes before the slice and partition. That would cause disk_parsedev() to return success with the slice and partition set to wildcard values. This change examines the string first, and if it contains spaces, dots, or a colon at any position other than the end, it must be a legacy-format string and we don't even try to use disk_parsedev() on it. --- stand/uboot/common/main.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c index b1534b00d26..04de7c42e3f 100644 --- a/stand/uboot/common/main.c +++ b/stand/uboot/common/main.c @@ -182,6 +182,14 @@ device_typename(int type) * The returned values for slice and partition are interpreted by * disk_open(). * + * The device string can be a standard loader(8) disk specifier: + * + * disks disk0s1 + * disks disk1s2a + * diskp disk0p4 + * + * or one of the following formats: + * * Valid device strings: For device types: * * DEV_TYP_STOR, DEV_TYP_NET @@ -198,6 +206,7 @@ device_typename(int type) static void get_load_device(int *type, int *unit, int *slice, int *partition) { + struct disk_devdesc dev; char *devstr; const char *p; char *endp; @@ -216,6 +225,26 @@ get_load_device(int *type, int *unit, int *slice, int *partition) p = get_device_type(devstr, type); + /* + * If type is DEV_TYP_STOR we have a disk-like device. If the remainder + * of the string contains spaces, dots, or a colon in any location other + * than the last char, it's legacy format. Otherwise it might be + * standard loader(8) format (e.g., disk0s2a or mmc1p12), so try to + * parse the remainder of the string as such, and if it works, return + * those results. Otherwise we'll fall through to the code that parses + * the legacy format. + */ + if (*type & DEV_TYP_STOR) { + size_t len = strlen(p); + if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 && + disk_parsedev(&dev, p, NULL) == 0) { + *unit = dev.dd.d_unit; + *slice = dev.d_slice; + *partition = dev.d_partition; + return; + } + } + /* Ignore optional spaces after the device name. */ while (*p == ' ') p++; -- 2.45.0