Chromium Code Reviews| Index: firmware/lib/tpm_lite/tlcl.c |
| diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c |
| index 6252700d81dd092c781fe8912f86a82a16a1116c..249922e61c767979f49998114bba903a31278eb2 100644 |
| --- a/firmware/lib/tpm_lite/tlcl.c |
| +++ b/firmware/lib/tpm_lite/tlcl.c |
| @@ -44,11 +44,11 @@ static INLINE int TpmReturnCode(const uint8_t* buffer) { |
| return TpmCommandCode(buffer); |
| } |
| -/* Sends a TPM command and gets a response. Returns 0 if success or the TPM |
| - * error code if error. */ |
| -static uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, |
| - int max_length) { |
| - |
| +/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or |
| + * DOING_SELFTEST errors are returned. |
| + */ |
| +static uint32_t TlclSendReceiveNoRetry(const uint8_t* request, |
| + uint8_t* response, int max_length) { |
| uint32_t result; |
| #ifdef EXTRA_LOGGING |
| @@ -83,6 +83,31 @@ static uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, |
| } |
| +/* Sends a TPM command and gets a response. Returns 0 if success or the TPM |
| + * error code if error. Waits for self test to complete if needed. */ |
| +static uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, |
| + int max_length) { |
| + uint32_t result = TlclSendReceiveNoRetry(request, response, max_length); |
| + if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) { |
| + result = TlclContinueSelfTest(); |
| + if (result != TPM_SUCCESS) { |
| + return result; |
| + } |
| +#ifdef TPM_BLOCKING_CONTINUESELFTEST |
| + result = TlclSendReceiveNoRetry(request, response, max_length); |
| +#else |
| + /* This needs serious testing. The TPM specification says: iii. The caller |
| + * MUST wait for the actions of TPM_ContinueSelfTest to complete before |
| + * reissuing the command C1. But, how do we know that the actions have |
| + * completed other than trying again? */ |
| + do { |
| + result = TlclSendReceiveNoRetry(request, response, max_length); |
| + } while (result == TPM_E_DOING_SELFTEST); |
|
Randall Spangler
2011/03/16 19:23:06
If the TPM gets in a wonky state, this could block
Luigi Semenzato
2011/03/16 20:51:59
Ah, now I remember, that's why we wanted the compi
|
| +#endif |
| + } |
| + return result; |
| +} |
| + |
| /* Sends a command and returns the error code. */ |
| static uint32_t Send(const uint8_t* command) { |
| uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; |
| @@ -116,8 +141,11 @@ uint32_t TlclSelfTestFull(void) { |
| } |
| uint32_t TlclContinueSelfTest(void) { |
| + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; |
| VBDEBUG(("TPM: Continue self test\n")); |
| - return Send(tpm_continueselftest_cmd.buffer); |
| + /* Call the No Retry version of SendReceive to avoid recursion. */ |
| + return TlclSendReceiveNoRetry(tpm_continueselftest_cmd.buffer, |
| + response, sizeof(response)); |
| } |
| uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { |