summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2011-01-20 21:05:15 +0000
committerStefan Reinauer <stefan.reinauer@coreboot.org>2011-01-20 21:05:15 +0000
commitff30d8a5383553d4df035cdcf0e24a0b44d4241a (patch)
tree781dcdd83da3a820d1f73a1e906af6f06a473a0c
parent051e2366fbf453aa39ecd826027fbf553a33c3d4 (diff)
downloadast2050-flashrom-ff30d8a5383553d4df035cdcf0e24a0b44d4241a.zip
ast2050-flashrom-ff30d8a5383553d4df035cdcf0e24a0b44d4241a.tar.gz
Secret knowledge is cool, but public knowledge is better
Implement all Dediprog commands found in USB traces, even if their purpose is not yet known. Annotate unknown commands with info about the call sequence they are embedded in and the firmware version of the log. Add a new shutdown command for firmware 5.x (of which Stefan thinks it's "switch the Pass light on" hence it is called late in the game) Corresponding to flashrom svn r1254. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Stefan Reinauer <reinauer@google.com>
-rw-r--r--dediprog.c122
1 files changed, 117 insertions, 5 deletions
diff --git a/dediprog.c b/dediprog.c
index bbe7c86..2529ac6 100644
--- a/dediprog.c
+++ b/dediprog.c
@@ -27,6 +27,7 @@
#define DEFAULT_TIMEOUT 3000
static usb_dev_handle *dediprog_handle;
+static int dediprog_firmwareversion;
static int dediprog_endpoint;
#if 0
@@ -317,6 +318,7 @@ static int dediprog_check_devicestring(void)
fw[1], fw[2]);
return 1;
}
+ dediprog_firmwareversion = fw[0];
return 0;
}
@@ -342,6 +344,32 @@ static int dediprog_command_a(void)
return 0;
}
+#if 0
+/* Something.
+ * Present in eng_detect_blink.log with firmware 3.1.8
+ * Always preceded by Command Receive Device String
+ */
+static int dediprog_command_b(void)
+{
+ int ret;
+ char buf[0x3];
+
+ memset(buf, 0, sizeof(buf));
+ ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, 0x3, DEFAULT_TIMEOUT);
+ if (ret < 0) {
+ msg_perr("Command B failed (%s)!\n", usb_strerror());
+ return 1;
+ }
+ if ((ret != 0x3) || (buf[0] != 0xff) || (buf[1] != 0xff) ||
+ (buf[2] != 0xff)) {
+ msg_perr("Unexpected response to Command B!\n");
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+
/* Command C is only sent after dediprog_check_devicestring, but not after every
* invocation of dediprog_check_devicestring. It is only sent after the first
* dediprog_command_a(); dediprog_check_devicestring() sequence in each session.
@@ -353,7 +381,7 @@ static int dediprog_command_c(void)
ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT);
if (ret != 0x0) {
- msg_perr("Unexpected response to Command C!\n");
+ msg_perr("Command C failed (%s)!\n", usb_strerror());
return 1;
}
return 0;
@@ -363,6 +391,7 @@ static int dediprog_command_c(void)
/* Very strange. Seems to be a programmer keepalive or somesuch.
* Wait unsuccessfully for timeout ms to read one byte.
* Is usually called after setting voltage to 0.
+ * Present in all logs with Firmware 2.1.1 and 3.1.8
*/
static int dediprog_command_f(int timeout)
{
@@ -371,8 +400,85 @@ static int dediprog_command_f(int timeout)
memset(buf, 0, sizeof(buf));
ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout);
+ /* This check is most probably wrong. Command F always causes a timeout
+ * in the logs, so we should check for timeout instead of checking for
+ * success.
+ */
+ if (ret != 0x1) {
+ msg_perr("Command F failed (%s)!\n", usb_strerror());
+ return 1;
+ }
+ return 0;
+}
+
+/* Start/stop blinking?
+ * Present in eng_detect_blink.log with firmware 3.1.8
+ * Preceded by Command J
+ */
+static int dediprog_command_g(void)
+{
+ int ret;
+
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT);
+ if (ret != 0x0) {
+ msg_perr("Command G failed (%s)!\n", usb_strerror());
+ return 1;
+ }
+ return 0;
+}
+
+/* Something.
+ * Present in all logs with firmware 5.1.5
+ * Always preceded by Command Receive Device String
+ * Always followed by Command Set SPI Voltage nonzero
+ */
+static int dediprog_command_h(void)
+{
+ int ret;
+
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT);
+ if (ret != 0x0) {
+ msg_perr("Command H failed (%s)!\n", usb_strerror());
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+/* Shutdown for firmware 5.x?
+ * This command swithces the "Pass" LED on.
+ * Present in all logs with firmware 5.1.5
+ * Often preceded by a SPI operation (Command Read SPI Bulk or Receive SPI)
+ * Always followed by Command Set SPI Voltage 0x0000
+ */
+static int dediprog_command_i(void)
+{
+ int ret;
+
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT);
if (ret != 0x0) {
- msg_perr("Unexpected response to Command F!\n");
+ msg_perr("Command I failed (%s)!\n", usb_strerror());
+ return 1;
+ }
+ return 0;
+}
+
+#if 0
+/* Start/stop blinking?
+ * Present in all logs with firmware 5.1.5
+ * Always preceded by Command Receive Device String on 5.1.5
+ * Always followed by Command Set SPI Voltage nonzero on 5.1.5
+ * Present in eng_detect_blink.log with firmware 3.1.8
+ * Preceded by Command B in eng_detect_blink.log
+ * Followed by Command G in eng_detect_blink.log
+ */
+static int dediprog_command_j(void)
+{
+ int ret;
+
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT);
+ if (ret != 0x0) {
+ msg_perr("Command J failed (%s)!\n", usb_strerror());
return 1;
}
return 0;
@@ -550,9 +656,11 @@ static int dediprog_do_stuff(void)
/* URB 136 is just URB 9. */
/* URB 137 is just URB 11. */
- /* Command I is probably Start Bulk Read. Data is u16 blockcount, u16 blocksize. */
- /* Command J is probably Start Bulk Write. Data is u16 blockcount, u16 blocksize. */
- /* Bulk transfer sizes for Command I/J are always 512 bytes, rest is filled with 0xff. */
+ /* Command Start Bulk Read. Data is u16 blockcount, u16 blocksize. */
+ /* Command Start Bulk Write. Data is u16 blockcount, u16 blocksize. */
+ /* Bulk transfer sizes for Command Start Bulk Read/Write are always
+ * 512 bytes, rest is filled with 0xff.
+ */
return 0;
}
@@ -562,6 +670,10 @@ int dediprog_shutdown(void)
{
msg_pspew("%s\n", __func__);
+ /* Shutdown on firmware 5.x */
+ if (dediprog_firmwareversion == 5)
+ if (dediprog_command_i())
+ return 1;
/* URB 28. Command Set SPI Voltage to 0. */
if (dediprog_set_spi_voltage(0x0))
return 1;
OpenPOWER on IntegriCloud