summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2018-05-16 11:53:29 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-21 21:18:02 -0700
commit70091bf0f76ccf88c2956c22cfcb3807e95e1849 (patch)
treeb1d25541320728543b9ed4dda1e638081f66ebf1
parent338c594ce37a22a12e8f879bf2eec55f486fd9bf (diff)
downloadchrome-ec-70091bf0f76ccf88c2956c22cfcb3807e95e1849.tar.gz
ite_flash: handle termination signal gracefully
Since we wait indefinitely for the ITE chip to be ready when we are flashing it, we need to be able to handle the console terminal signal gracefully so the host USB ports do not get in a bad state. BRANCH=none BUG=none TEST=Can exit while loop gracefully Change-Id: Ica8e7c6c707cd58bdaa754be76fffef418d870e4 Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1067788 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Justin TerAvest <teravest@chromium.org>
-rw-r--r--util/iteflash.c146
1 files changed, 92 insertions, 54 deletions
diff --git a/util/iteflash.c b/util/iteflash.c
index 849cd5cc49..0b246a56d4 100644
--- a/util/iteflash.c
+++ b/util/iteflash.c
@@ -7,8 +7,9 @@
#include <errno.h>
#include <getopt.h>
-#include <stdio.h>
+#include <signal.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -67,6 +68,7 @@ static int usb_pid = SERVO_USB_PID;
static int usb_interface = SERVO_INTERFACE;
static char *usb_serial;
static int flash_size;
+static int exit_requested;
/* debug traces : default OFF*/
static int debug;
@@ -90,6 +92,10 @@ static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf,
uint8_t failed_ack = 0;
for (i = 0; i < tcnt; i++) {
+ /* If we got a termination signal, stop sending data */
+ if (exit_requested)
+ return -1;
+
/* WORKAROUND: force SDA before sending the next byte */
*b++ = SET_BITS_LOW; *b++ = SDA_BIT; *b++ = SCL_BIT | SDA_BIT;
/* write byte */
@@ -184,6 +190,10 @@ static int i2c_add_recv_bytes(struct ftdi_context *ftdi, uint8_t *buf,
rbuf_idx = 0;
do {
+ /* If we got a termination signal, stop sending data */
+ if (exit_requested)
+ return -1;
+
ret = ftdi_read_data(ftdi, &rbuf[rbuf_idx], rcnt);
if (ret < 0) {
fprintf(stderr, "read byte failed\n");
@@ -513,70 +523,76 @@ static int send_special_waveform(struct ftdi_context *ftdi)
printf("Waiting for the EC power-on sequence ...");
fflush(stdout);
-retry:
- /* Reset the FTDI into a known state */
- ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET);
- if (ret != 0) {
- fprintf(stderr, "failed to reset FTDI\n");
- goto special_failed;
- }
+ do {
+ /* Reset the FTDI into a known state */
+ ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET);
+ if (ret != 0) {
+ fprintf(stderr, "failed to reset FTDI\n");
+ break;
+ }
- /*
- * set the clock divider,
- * so we output a new bitbang value every 2.5us.
- */
- ret = ftdi_set_baudrate(ftdi, 160000);
- if (ret != 0) {
- fprintf(stderr, "failed to set bitbang clock\n");
- goto special_failed;
- }
+ /*
+ * set the clock divider,
+ * so we output a new bitbang value every 2.5us.
+ */
+ ret = ftdi_set_baudrate(ftdi, 160000);
+ if (ret != 0) {
+ fprintf(stderr, "failed to set bitbang clock\n");
+ break;
+ }
- /* Enable asynchronous bit-bang mode */
- ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG);
- if (ret != 0) {
- fprintf(stderr, "failed to set bitbang mode\n");
- goto special_failed;
- }
+ /* Enable asynchronous bit-bang mode */
+ ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG);
+ if (ret != 0) {
+ fprintf(stderr, "failed to set bitbang mode\n");
+ break;
+ }
+
+ /* do usb special waveform */
+ wave[0] = 0x0;
+ ftdi_write_data(ftdi, (uint8_t *)wave, 1);
+ usleep(5000);
- /* do usb special waveform */
+ /* program each special tick */
+ for (i = 0; i < TICK_COUNT; ) {
+ wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
+ wave[i++] = SPECIAL_PATTERN_SDA_H_SCL_L;
+ wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
+ }
+ wave[19] = SPECIAL_PATTERN_SDA_H_SCL_H;
- wave[0] = 0x0;
- ftdi_write_data(ftdi, (uint8_t *)wave, 1);
- usleep(5000);
+ /* fill the buffer with the waveform pattern */
+ for (i = TICK_COUNT; i < SPECIAL_BUFFER_SIZE / sizeof(uint64_t);
+ i++)
+ wave[i] = SPECIAL_PATTERN;
- /* program each special tick */
- for (i = 0; i < TICK_COUNT; ) {
- wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
- wave[i++] = SPECIAL_PATTERN_SDA_H_SCL_L;
- wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
- }
- wave[19] = SPECIAL_PATTERN_SDA_H_SCL_H;
+ ret = ftdi_write_data(ftdi, (uint8_t *)wave,
+ SPECIAL_BUFFER_SIZE);
+ if (ret < 0)
+ fprintf(stderr, "Cannot output special waveform\n");
+ /* clean everything to go back to regular I2C communication */
+ ftdi_usb_purge_buffers(ftdi);
+ ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET);
+ config_i2c(ftdi);
+ ftdi_write_data(ftdi, release_lines, sizeof(release_lines));
- /* fill the buffer with the waveform pattern */
- for (i = TICK_COUNT; i < SPECIAL_BUFFER_SIZE / sizeof(uint64_t); i++)
- wave[i] = SPECIAL_PATTERN;
+ /* wait for PLL stable for 5ms (plus remaining USB transfers) */
+ usleep(10 * MSEC);
- ret = ftdi_write_data(ftdi, (uint8_t *)wave, SPECIAL_BUFFER_SIZE);
- if (ret < 0)
- fprintf(stderr, "Cannot output special waveform\n");
+ /* If we can talk to chip, then we can break the retry loop */
+ ret = check_chipid(ftdi);
- /* clean everything to go back to regular I2C communication */
- ftdi_usb_purge_buffers(ftdi);
- ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET);
- config_i2c(ftdi);
- ftdi_write_data(ftdi, release_lines, sizeof(release_lines));
+ if (ret != 0)
+ /* Sleep before next attempt */
+ sleep(1);
+ } while (ret != 0);
- /* wait for PLL stable for 5ms (plus remaining USB transfers) */
- usleep(10 * MSEC);
+ if (ret)
+ printf(" Failed!\n");
+ else
+ printf(" Done.\n");
- /* if we cannot communicate, retry the sequence */
- if (check_chipid(ftdi) < 0) {
- sleep(1);
- goto retry;
- }
-special_failed:
- printf("Done.\n");
free(wave);
return ret;
}
@@ -1042,6 +1058,25 @@ int parse_parameters(int argc, char **argv)
return flags;
}
+static void sighandler(int signum)
+{
+ printf("\nCaught signal %d: %s\nExiting...\n",
+ signum, sys_siglist[signum]);
+ ++exit_requested;
+}
+
+static void register_sigaction(void)
+{
+ struct sigaction sigact;
+
+ sigact.sa_handler = sighandler;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigaction(SIGINT, &sigact, NULL);
+ sigaction(SIGTERM, &sigact, NULL);
+ sigaction(SIGQUIT, &sigact, NULL);
+}
+
int main(int argc, char **argv)
{
void *hnd;
@@ -1056,6 +1091,9 @@ int main(int argc, char **argv)
if (hnd == NULL)
return 1;
+ /* Register signal handler after opening USB handle. */
+ register_sigaction();
+
/* Trigger embedded monitor detection */
if (send_special_waveform(hnd) < 0)
goto terminate;