[vim3] add unbootable reason fastboot var
Adds `slot-unbootable-reason:{a,b}` fastboot variables to report the
A/B/R unbootable reason, or "N/A" if the slot is not unbootable.
Bug: b/378736089
Test: corrupted slot B and tried to boot, unbootable reason correctly
reported "3 (verification failure)"
Change-Id: I22fb52a085f3c3b492d0873e21844a39f68ef27b
Reviewed-on: https://turquoise-internal-review.googlesource.com/c/third_party/u-boot/+/919651
Reviewed-by: Yecheng Zhao <zyecheng@google.com>
GitOrigin-RevId: 74f1413fc26635c3ddea0741a96185794a89b4a6
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 7ac2768..b0b1032 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -708,6 +708,8 @@
"slot-suffixes",
"slot-unbootable:a",
"slot-unbootable:b",
+ "slot-unbootable-reason:a",
+ "slot-unbootable-reason:b",
"version",
"version-bootloader",
"vx-locked",
@@ -981,6 +983,47 @@
slot_info->is_marked_successful ? "yes" : "no",
chars_left);
}
+ // Note: this must come before `slot-unbootable` because we use prefix
+ // matching to identify the command w/o any args, so `slot-unbootable`
+ // would match here if it came first.
+ } else if (!strcmp_l1("slot-unbootable-reason", cmd)) {
+ strsep(&cmd, ":");
+ FB_DBG("cmd is %s\n", cmd);
+
+ AbrSlotInfo *slot_info = get_slot_info(cmd);
+ if (slot_info == NULL) {
+ fastboot_fail("Invalid slot suffix");
+ } else if (slot_info->is_bootable) {
+ strncat(response, "N/A", chars_left);
+ } else {
+ const char *str = "unknown";
+ // Cast to `AbrUnbootableReason` so the compiler checks
+ // that we've handled all the known cases (but it still
+ // might not be one of these values if the metadata
+ // writer had a newer libabr version with additional
+ // reasons we don't know about).
+ AbrUnbootableReason reason =
+ slot_info->unbootable_reason;
+ switch (reason) {
+ case kAbrUnbootableReasonNone:
+ str = "none given";
+ break;
+ case kAbrUnbootableReasonNoMoreTries:
+ str = "no more attempts";
+ break;
+ case kAbrUnbootableReasonOsRequested:
+ str = "OS requested";
+ break;
+ case kAbrUnbootableReasonVerificationFailure:
+ str = "verification failure";
+ break;
+ }
+ // Give a human-readable string as well as the raw value
+ // for programmatic parsing and in case of unknown
+ // values.
+ snprintf(response + strlen(response), chars_left,
+ "%d (%s)", slot_info->unbootable_reason, str);
+ }
} else if (!strcmp_l1("slot-unbootable", cmd)) {
strsep(&cmd, ":");
FB_DBG("cmd is %s\n", cmd);