[fastboot] support `erase userdata` as a no-op

A common Android workflow is to pass `-w` to fastboot which triggers an
`erase userdata` command; we can't really support this at the moment
because userdata is nested inside the FVM/super image and gets
automatically erased when we flash that partition, but we've been asked
to ignore this request rather than error out.

Bug: b/322897225
Change-Id: I0ca301c723ae9b5d7057e9b472e0bc1f40b5597d
Reviewed-on: https://turquoise-internal-review.googlesource.com/c/third_party/u-boot/+/803950
Reviewed-by: Yecheng Zhao <zyecheng@google.com>
GitOrigin-RevId: 77d68b2c514684a1848243941640f25453b0ee0f
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 301f133..d70b4a2 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -464,8 +464,12 @@
 	// but is just the FVM.
 	{ GPT_FVM_NAME,			"super",	WRITE | ERASE },
 	{ GPT_DURABLE_BOOT_NAME,	"misc",		ERASE },
-	// Upstream code also aliases userdata -> data and dts -> dtb, but we
-	// don't need these at the moment.
+	// `fastboot -w` flag triggers `erase userdata`; functionally this doesn't
+	// apply for Fuchsia since userdata is stored in the FVM and we can't wipe
+	// it separately, so for now we accept `erase userdata` but it's just a
+	// no-op.
+	{ "userdata",			NULL,		ERASE },
+	// Upstream also aliases dts -> dtb, but we don't need this at the moment.
 	// clang-format on
 };
 
@@ -926,10 +930,6 @@
 		if (has_boot_slot == 0) {
 			strncat(response, "ext4", chars_left);
 		}
-	} else if (!strcmp_l1("partition-type:data", cmd)) {
-		strncat(response, "ext4", chars_left);
-	} else if (!strcmp_l1("partition-type:userdata", cmd)) {
-		strncat(response, "ext4", chars_left);
 	} else if (!strcmp_l1("partition-type:system", cmd)) {
 		strncat(response, "ext4", chars_left);
 	} else if (!strcmp_l1("partition-type:vendor", cmd)) {
@@ -1392,6 +1392,19 @@
 	char* response = response_str;
 	char *cmd = req->buf;
 
+	// Set `send_okay` when we've previously sent an INFO response and just want
+	// to finish the command with OKAY.
+	//
+	// Do this first, since in this case we've already parsed the command string
+	// and would fail to find the partition name if we try to do it again here.
+	static int send_okay = 0;
+	if (send_okay) {
+		send_okay = 0;
+		fastboot_okay(NULL);
+		fastboot_tx_write_str(response_str);
+		return;
+	}
+
 	printf("cmd cb_erase is %s\n", cmd);
 	const char *part = parse_fb_cmd_partition(cmd);
 	if (!part) {
@@ -1404,6 +1417,19 @@
 		return;
 	}
 
+	// Special case for "userdata" partition, we just ignore requests to erase
+	// so that `fastboot -w` doesn't error out (b/322897225). In our case
+	// flashing FVM/super automatically wipes userdata.
+	if (strcmp(part, "userdata") == 0) {
+		// This is a bit non-standard so send an INFO message first to alert
+		// users that we're not actually erasing userdata here.
+		fastboot_busy(
+			"erase userdata is a no-op; flash super to wipe userdata");
+		fastboot_tx_write_str(response_str);
+		send_okay = 1;
+		return;
+	}
+
 	//strcpy(response, "FAILno erase device defined");
 	if (is_mainstorage_emmc()) {
 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV