diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2018-02-21 17:59:44 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-02-23 03:36:30 -0800 |
commit | 1850d5908a348e31d61b2816f6f086fd4d3596de (patch) | |
tree | a106af82acd4e434a855805b92dfd91d25e5919c /extra | |
parent | 8a5a83aef357b23a274f45a4377c32b77624a5fc (diff) | |
download | chrome-ec-1850d5908a348e31d61b2816f6f086fd4d3596de.tar.gz |
gsctool: refactor PP polling into a function
Both CCD and SPI_HASH commands need to enforce physical presence. This
patch separates PP polling into a function which can be used by both
commands.
BRANCH=none
BUG=b:73668125
TEST=verified that running 'gsctool -a -o' on a Robo device still
allows to unlock CCD with PP enforced.
Change-Id: I49abb0e56ad37664eaad7cc34de44e1ac06e2d1b
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/930567
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'extra')
-rw-r--r-- | extra/usb_updater/gsctool.c | 103 |
1 files changed, 61 insertions, 42 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c index 6985501127..399c8fdba0 100644 --- a/extra/usb_updater/gsctool.c +++ b/extra/usb_updater/gsctool.c @@ -1619,57 +1619,29 @@ static void process_password(struct transfer_descriptor *td) exit(update_error); } -static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock, - int ccd_open, int ccd_lock) +/* + * This function can be used to retrieve the current PP status from Cr50 and + * prompt the user when a PP press is required. + * + * Physical presence can be required by different gsctool options, for which + * Cr50 behavior also differs. The 'command' and 'poll_type' parameters are + * used by Cr50 to tell what the host is polling for. + */ +static void poll_for_pp(struct transfer_descriptor *td, + uint16_t command, + uint8_t poll_type) { - uint8_t payload; uint8_t response; uint8_t prev_response; size_t response_size; int rv; - if (ccd_unlock) - payload = CCDV_UNLOCK; - else if (ccd_open) - payload = CCDV_OPEN; - else - payload = CCDV_LOCK; - - response_size = sizeof(response); - rv = send_vendor_command(td, VENDOR_CC_CCD, - &payload, sizeof(payload), - &response, &response_size); - - /* - * If password is required - try sending the same subcommand - * accompanied by user password. - */ - if (rv == VENDOR_RC_PASSWORD_REQUIRED) - rv = common_process_password(td, payload); - - if (rv == VENDOR_RC_SUCCESS) - return; - - if (rv != VENDOR_RC_IN_PROGRESS) { - fprintf(stderr, "Error: rv %d, response %d\n", - rv, response_size ? response : 0); - exit(update_error); - } - - /* - * Physical presence process started, poll for the state the user - * asked for. Only two subcommands would return 'IN_PROGRESS'. - */ - if (ccd_unlock) - payload = CCDV_PP_POLL_UNLOCK; - else - payload = CCDV_PP_POLL_OPEN; - prev_response = ~0; /* Guaranteed invalid value. */ + while (1) { response_size = sizeof(response); - rv = send_vendor_command(td, VENDOR_CC_CCD, - &payload, sizeof(payload), + rv = send_vendor_command(td, command, + &poll_type, sizeof(poll_type), &response, &response_size); if (((rv != VENDOR_RC_SUCCESS) && (rv != VENDOR_RC_IN_PROGRESS)) @@ -1705,6 +1677,53 @@ static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock, usleep(500 * 1000); /* Poll every half a second. */ } + +} + +static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock, + int ccd_open, int ccd_lock) +{ + uint8_t payload; + uint8_t response; + size_t response_size; + int rv; + + if (ccd_unlock) + payload = CCDV_UNLOCK; + else if (ccd_open) + payload = CCDV_OPEN; + else + payload = CCDV_LOCK; + + response_size = sizeof(response); + rv = send_vendor_command(td, VENDOR_CC_CCD, + &payload, sizeof(payload), + &response, &response_size); + + /* + * If password is required - try sending the same subcommand + * accompanied by user password. + */ + if (rv == VENDOR_RC_PASSWORD_REQUIRED) + rv = common_process_password(td, payload); + + if (rv == VENDOR_RC_SUCCESS) + return; + + if (rv != VENDOR_RC_IN_PROGRESS) { + fprintf(stderr, "Error: rv %d, response %d\n", + rv, response_size ? response : 0); + exit(update_error); + } + + /* + * Physical presence process started, poll for the state the user + * asked for. Only two subcommands would return 'IN_PROGRESS'. + */ + if (ccd_unlock) + poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_UNLOCK); + else + poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_OPEN); } static void process_bid(struct transfer_descriptor *td, |