summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2011-12-20 14:50:45 -0800
committerSimon Glass <sjg@chromium.org>2012-01-06 12:44:28 -0800
commitb17b4764a18f243b246ebde0ebc6c4ea2e16c8b1 (patch)
treed4db6458b63f101661b130d41bc72a70f6bdf731 /drivers
parente712ffb3ea9de6fa08b50032d772531cc607bc7e (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.c54
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 d07140f031..c72d782e5a 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);
+}