diff --git a/device.c b/device.c index 79ce6a5..9922130 100644 --- a/device.c +++ b/device.c @@ -94,6 +94,8 @@ static bool device_check_access(struct device *device, return false; } +static int device_power_off(struct device *device); + struct device *device_open(const char *board, const char *username) { @@ -132,6 +134,18 @@ found: if (!device->console) errx(1, "failed to open device console"); + /* + * Power off before opening fastboot. Otherwise if the device is + * already in the fastboot state, CDBA will detect it, then power up + * procedure will restart the device causing fastboot to disappear and + * appear again. This will cause CDBA to exit, ending up with the + * unbreakable fastboot-reset-second_fastboot-quit cycle. + * */ + if (device->power_always_on) { + device_power_off(device); + sleep(2); + } + if (device->usb_always_on) device_usb(device, true); @@ -374,7 +388,8 @@ void device_close(struct device *dev) { if (!dev->usb_always_on) device_usb(dev, false); - device_power(dev, false); + if (!dev->power_always_on) + device_power(dev, false); if (device_has_control(dev, close)) device_control(dev, close); diff --git a/device.h b/device.h index 220eeb0..0b8d0e9 100644 --- a/device.h +++ b/device.h @@ -41,6 +41,7 @@ struct device { unsigned voltage; bool tickle_mmc; bool usb_always_on; + bool power_always_on; struct fastboot *fastboot; unsigned int fastboot_key_timeout; int state; diff --git a/device_parser.c b/device_parser.c index bae07b4..8b55741 100644 --- a/device_parser.c +++ b/device_parser.c @@ -171,6 +171,8 @@ static void parse_board(struct device_parser *dp) dev->ppps3_path = strdup(value); } else if (!strcmp(key, "status-cmd")) { dev->status_cmd = strdup(value); + } else if (!strcmp(key, "power_always_on")) { + dev->power_always_on = !strcmp(value, "true"); } else { fprintf(stderr, "device parser: unknown key \"%s\"\n", key); exit(1);