bootstd: add IGNORE_BOOTABLE option

Qualcomm devices have a ridiculous number of partitions (up in the
triple digits on modern devices) and often have random partitions with
the bootable flag set. However, there is usually not a dedicated ESP
partition, instead some partition has to be repurposed. To support this
usecase, add a new CONFIG_IGNORE_BOOTABLE option which disables the
optimisation added in f0e358f07d75 ("bootstd: Only scan bootable
partitions) and always scans all partitions.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
diff --git a/boot/Kconfig b/boot/Kconfig
index fbc49c5..850a9dc 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -452,6 +452,14 @@
 	  standard boot does not support all of the features of distro boot
 	  yet.
 
+config BOOTSTD_IGNORE_BOOTABLE
+	bool "Don't rely on the bootable flag when scanning bootflows"
+	help
+	  Enable this to avoid relying on the bootable partition flag. On some
+	  devices with complicated partition tables this flag may be set by mistake
+	  resulting in bootflows not being recognised. Set this to always scan all
+	  partitions.
+
 config BOOTMETH_GLOBAL
 	bool
 	help
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 44ae98a..d01d603 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -27,7 +27,7 @@
 	 * have. Note that for disks this limits the partitions numbers that
 	 * are scanned to 1..MAX_BOOTFLOWS_PER_BOOTDEV
 	 */
-	MAX_PART_PER_BOOTDEV	= 30,
+	MAX_PART_PER_BOOTDEV	= 96,
 
 	/* Maximum supported length of the "boot_targets" env string */
 	BOOT_TARGETS_MAX_LEN	= 100,
@@ -173,21 +173,25 @@
 	 */
 	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);
-	} else if (allow_any_part) {
-		/*
-		 * allow any partition to be scanned, by skipping any checks
-		 * for filesystems or partition contents on this disk
-		 */
+	if (!IS_ENABLED(CONFIG_BOOTSTD_IGNORE_BOOTABLE)) {
+		/* 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);
+		} 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->first_bootable >= 0 &&
-		   (iter->first_bootable ? !info.bootable : iter->part != 1)) {
-		return log_msg_ret("boot", -EINVAL);
-	} else {
+		/* if there are bootable partitions, scan only those */
+		} else if (iter->first_bootable >= 0 &&
+			(iter->first_bootable ? !info.bootable : iter->part != 1)) {
+			return log_msg_ret("boot", -EINVAL);
+		}
+	}
+
+	if (iter->part) {
 		ret = fs_set_blk_dev_with_part(desc, bflow->part);
 		bflow->state = BOOTFLOWST_PART;
 		if (ret)