aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Berger <stefanb@linux.vnet.ibm.com>2011-11-11 12:57:04 -0500
committerRajiv Andrade <srajiv@linux.vnet.ibm.com>2011-11-16 06:42:59 -0500
commit68d6e6713fcb2ea6278661aaaf5f1c9c821b3751 (patch)
treefb02641cb1941a6d9c23ac3df37d6aafcd4f7f3a /drivers
parentd97c6ade5926afb6d52df36c33a3491d62cd0dc0 (diff)
tpm: Introduce function to poll for result of self test
This patch introduces a function that runs the TPM_ContinueSelfTest() function and then polls the TPM to check whether it finished the selftest and can receive new commands. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/tpm/tpm.c44
-rw-r--r--drivers/char/tpm/tpm.h4
-rw-r--r--drivers/char/tpm/tpm_tis.c9
3 files changed, 51 insertions, 6 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9bd4668e2855..2e12b3f98139 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -627,7 +627,7 @@ static struct tpm_input_header continue_selftest_header = {
627 * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing 627 * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
628 * a TPM error code. 628 * a TPM error code.
629 */ 629 */
630int tpm_continue_selftest(struct tpm_chip *chip) 630static int tpm_continue_selftest(struct tpm_chip *chip)
631{ 631{
632 int rc; 632 int rc;
633 struct tpm_cmd_t cmd; 633 struct tpm_cmd_t cmd;
@@ -637,7 +637,6 @@ int tpm_continue_selftest(struct tpm_chip *chip)
637 "continue selftest"); 637 "continue selftest");
638 return rc; 638 return rc;
639} 639}
640EXPORT_SYMBOL_GPL(tpm_continue_selftest);
641 640
642ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, 641ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
643 char *buf) 642 char *buf)
@@ -732,7 +731,7 @@ static struct tpm_input_header pcrread_header = {
732 .ordinal = TPM_ORDINAL_PCRREAD 731 .ordinal = TPM_ORDINAL_PCRREAD
733}; 732};
734 733
735int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) 734static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
736{ 735{
737 int rc; 736 int rc;
738 struct tpm_cmd_t cmd; 737 struct tpm_cmd_t cmd;
@@ -812,6 +811,45 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
812} 811}
813EXPORT_SYMBOL_GPL(tpm_pcr_extend); 812EXPORT_SYMBOL_GPL(tpm_pcr_extend);
814 813
814/**
815 * tpm_do_selftest - have the TPM continue its selftest and wait until it
816 * can receive further commands
817 * @chip: TPM chip to use
818 *
819 * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
820 * a TPM error code.
821 */
822int tpm_do_selftest(struct tpm_chip *chip)
823{
824 int rc;
825 u8 digest[TPM_DIGEST_SIZE];
826 unsigned int loops;
827 unsigned int delay_msec = 1000;
828 unsigned long duration;
829
830 duration = tpm_calc_ordinal_duration(chip,
831 TPM_ORD_CONTINUE_SELFTEST);
832
833 loops = jiffies_to_msecs(duration) / delay_msec;
834
835 rc = tpm_continue_selftest(chip);
836 /* This may fail if there was no TPM driver during a suspend/resume
837 * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
838 */
839 if (rc)
840 return rc;
841
842 do {
843 rc = __tpm_pcr_read(chip, 0, digest);
844 if (rc != TPM_WARN_DOING_SELFTEST)
845 return rc;
846 msleep(delay_msec);
847 } while (--loops > 0);
848
849 return rc;
850}
851EXPORT_SYMBOL_GPL(tpm_do_selftest);
852
815int tpm_send(u32 chip_num, void *cmd, size_t buflen) 853int tpm_send(u32 chip_num, void *cmd, size_t buflen)
816{ 854{
817 struct tpm_chip *chip; 855 struct tpm_chip *chip;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 5d2be8ae1b48..e264de16285f 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -38,6 +38,8 @@ enum tpm_addr {
38 TPM_ADDR = 0x4E, 38 TPM_ADDR = 0x4E,
39}; 39};
40 40
41#define TPM_WARN_DOING_SELFTEST 0x802
42
41extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, 43extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
42 char *); 44 char *);
43extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, 45extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
@@ -281,7 +283,7 @@ ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
281 283
282extern int tpm_get_timeouts(struct tpm_chip *); 284extern int tpm_get_timeouts(struct tpm_chip *);
283extern void tpm_gen_interrupt(struct tpm_chip *); 285extern void tpm_gen_interrupt(struct tpm_chip *);
284extern int tpm_continue_selftest(struct tpm_chip *); 286extern int tpm_do_selftest(struct tpm_chip *);
285extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); 287extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
286extern struct tpm_chip* tpm_register_hardware(struct device *, 288extern struct tpm_chip* tpm_register_hardware(struct device *,
287 const struct tpm_vendor_specific *); 289 const struct tpm_vendor_specific *);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 3f4051a7c5a7..d30d5c3c6c02 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -616,6 +616,12 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
616 /* get the timeouts before testing for irqs */ 616 /* get the timeouts before testing for irqs */
617 tpm_get_timeouts(chip); 617 tpm_get_timeouts(chip);
618 618
619 if (tpm_do_selftest(chip)) {
620 dev_err(dev, "TPM self test failed\n");
621 rc = -ENODEV;
622 goto out_err;
623 }
624
619 /* INTERRUPT Setup */ 625 /* INTERRUPT Setup */
620 init_waitqueue_head(&chip->vendor.read_queue); 626 init_waitqueue_head(&chip->vendor.read_queue);
621 init_waitqueue_head(&chip->vendor.int_queue); 627 init_waitqueue_head(&chip->vendor.int_queue);
@@ -722,7 +728,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
722 list_add(&chip->vendor.list, &tis_chips); 728 list_add(&chip->vendor.list, &tis_chips);
723 spin_unlock(&tis_lock); 729 spin_unlock(&tis_lock);
724 730
725 tpm_continue_selftest(chip);
726 731
727 return 0; 732 return 0;
728out_err: 733out_err:
@@ -790,7 +795,7 @@ static int tpm_tis_pnp_resume(struct pnp_dev *dev)
790 795
791 ret = tpm_pm_resume(&dev->dev); 796 ret = tpm_pm_resume(&dev->dev);
792 if (!ret) 797 if (!ret)
793 tpm_continue_selftest(chip); 798 tpm_do_selftest(chip);
794 799
795 return ret; 800 return ret;
796} 801}