cros-ec: Avoid infinitely looping in google_chromeec_pd_get_amode

Currently, google_chromeec_pd_get_amode infinitely loops if a TCPC port
is connected to a device with alternate mode(s) and the call is made
for the mode with the index higher than 0 (e.g. Zinger).

Cros EC manages alternative modes entered in an array (amode[]). The
command is designed to accept a query for an particular index and a
particular SVID.

Zinger has a 'Google' mode. It's stored in amode[0]. When AP queries
first time for DisplayPort with index=0, EC says 'no' as expected.

AP sends the next query with index=1 but EC_CMD_PROTO_VERSION (0x00)
is sent instead because cmd_code is cleared by google_chromeec_command.
res.svid is supposed to be 0 when EC hits the last index + 1 but
res.svid is set to 2 by the EC_CMD_PROTO_VERSION handler because
EC_PROTO_VERSION is currently 2. So, the call succeeds and AP goes to
the next index and this repeats forever.

Any USB-C device with non-DisplayPort alternate mode can cause this
hang unless HDMI port is used.

This patch resets all the fields of chromeec_command in each iteration
in case google_chromeec_command changes them.

BUG=b:78630899
BRANCH=none
TEST=Verify Fizz boots without monitors on Zinger. Verify the svid
enumeration happens as expected.

Change-Id: I388ed4bdfac9176d8e690c429e99674ed267004f
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://review.coreboot.org/25878
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c
index fb3ffab..5ce3f68 100644
--- a/src/ec/google/chromeec/ec.c
+++ b/src/ec/google/chromeec/ec.c
@@ -963,23 +963,26 @@
 	for (i = 0; i < r.num_ports; i++) {
 		struct ec_params_usb_pd_get_mode_request p;
 		struct ec_params_usb_pd_get_mode_response res;
-
-		p.port = i;
-		p.svid_idx = 0;
-		cmd.cmd_code = EC_CMD_USB_PD_GET_AMODE;
-		cmd.cmd_version = 0;
-		cmd.cmd_data_in = &p;
-		cmd.cmd_size_in = sizeof(p);
-		cmd.cmd_data_out = &res;
-		cmd.cmd_size_out = sizeof(res);
-		cmd.cmd_dev_index = 0;
+		int svid_idx = 0;
 
 		do {
+			/* Reset cmd in each iteration in case
+			   google_chromeec_command changes it. */
+			p.port = i;
+			p.svid_idx = svid_idx;
+			cmd.cmd_code = EC_CMD_USB_PD_GET_AMODE;
+			cmd.cmd_version = 0;
+			cmd.cmd_data_in = &p;
+			cmd.cmd_size_in = sizeof(p);
+			cmd.cmd_data_out = &res;
+			cmd.cmd_size_out = sizeof(res);
+			cmd.cmd_dev_index = 0;
+
 			if (google_chromeec_command(&cmd) < 0)
 				return -1;
 			if (res.svid == svid)
 				return 1;
-			p.svid_idx++;
+			svid_idx++;
 		} while (res.svid);
 	}