diff options
author | Simon Glass <sjg@chromium.org> | 2011-12-20 14:50:45 -0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2012-01-06 12:44:28 -0800 |
commit | b17b4764a18f243b246ebde0ebc6c4ea2e16c8b1 (patch) | |
tree | d4db6458b63f101661b130d41bc72a70f6bdf731 /drivers | |
parent | e712ffb3ea9de6fa08b50032d772531cc607bc7e (diff) |
Collect statistics for TPM failures
The TPM fails every second transaction because it goes to sleep and fails
to wake up in time. Add stats for how many transactions are performed
and the number of retries required for each.
BUG=chromium-os:22938
TEST=build and boot on Kaen
Change-Id: I079da55e71e637e3afdacfe38c27b8742da09dc5
Reviewed-on: https://gerrit.chromium.org/gerrit/13373
Reviewed-by: Rong Chang <rongchang@chromium.org>
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
Commit-Ready: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/tpm/slb9635_i2c/tpm_tis_i2c.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c b/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c index d07140f031d..c72d782e5a3 100644 --- a/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c +++ b/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c @@ -77,6 +77,17 @@ static struct tpm_inf_dev tpm_dev = { .addr = TPM_I2C_ADDR }; +struct op_stats { + int ok; + int fail; + int ok_retries; + int fail_retries; +}; + +static struct stats_info { + struct op_stats read, write; +} stats; + /* * iic_tpm_read() - read from TPM register * @addr: register address to read from @@ -106,20 +117,25 @@ int iic_tpm_read(u8 addr, u8 *buffer, size_t len) udelay(SLEEP_DURATION); } - if (rc) - return -rc; - /* After the TPM has successfully received the register address it needs * some time, thus we're sleeping here again, before retrieving the data */ - for (count = 0; count < MAX_COUNT; count++) { - udelay(SLEEP_DURATION); - rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len); - if (rc == 0) - break; /*success, break to skip sleep*/ - + if (!rc) { + for (count = 0; count < MAX_COUNT; count++) { + udelay(SLEEP_DURATION); + rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len); + if (rc == 0) + break; /*success, break to skip sleep*/ + } } + if (rc) { + stats.read.fail++; + stats.read.fail_retries += count; + } else { + stats.read.ok++; + stats.read.ok_retries += count; + } if (rc) return -rc; @@ -145,6 +161,13 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len, udelay(sleep_time); } + if (rc) { + stats.write.fail++; + stats.write.fail_retries += count; + } else { + stats.write.ok++; + stats.write.ok_retries += count; + } if (rc) return -rc; @@ -552,3 +575,16 @@ void tpm_vendor_cleanup(struct tpm_chip *chip) { release_locality(chip, chip->vendor.locality, 1); } + +static void show_stats(const char *op_name, struct op_stats *stats) +{ + printf("TPM stats for %s\n", op_name); + printf(" ok %d, retries %d\n", stats->ok, stats->ok_retries); + printf(" fail %d, retries %d\n", stats->fail, stats->fail_retries); +} + +void tpm_show_stats(void) +{ + show_stats("read", &stats.read); + show_stats("write", &stats.read); +} |