aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2013-11-26 15:30:41 -0500
committerPeter Huewe <peterhuewe@gmx.de>2014-01-06 08:37:24 -0500
commit000a07b0aac1bc69bcf602b468d975c3e37a155c (patch)
tree44803c680363cae1f463d40ed3ede17ab67e3573
parentafdba32e2a9ea729a9f9f280dbf6c718773c7ded (diff)
tpm: Move sysfs functions from tpm-interface to tpm-sysfs
CLASS-sysfs.c is a common idiom for linux subsystems. This is the first step to pulling all the sysfs support code from the drivers into tpm-sysfs. This is a plain text copy from tpm-interface with support changes to make it compile. _tpm_pcr_read is made non-static and is called tpm_pcr_read_dev. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
-rw-r--r--drivers/char/tpm/Makefile2
-rw-r--r--drivers/char/tpm/tpm-interface.c275
-rw-r--r--drivers/char/tpm/tpm-sysfs.c281
-rw-r--r--drivers/char/tpm/tpm.h30
4 files changed, 314 insertions, 274 deletions
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index d835e87d2d38..4d85dd681b81 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the kernel tpm device drivers. 2# Makefile for the kernel tpm device drivers.
3# 3#
4obj-$(CONFIG_TCG_TPM) += tpm.o 4obj-$(CONFIG_TCG_TPM) += tpm.o
5tpm-y := tpm-interface.o tpm-dev.o 5tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o
6tpm-$(CONFIG_ACPI) += tpm_ppi.o 6tpm-$(CONFIG_ACPI) += tpm_ppi.o
7 7
8ifdef CONFIG_ACPI 8ifdef CONFIG_ACPI
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 0b9e9ca05ef3..3f8bddf8f7ed 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -32,13 +32,6 @@
32#include "tpm.h" 32#include "tpm.h"
33#include "tpm_eventlog.h" 33#include "tpm_eventlog.h"
34 34
35enum tpm_duration {
36 TPM_SHORT = 0,
37 TPM_MEDIUM = 1,
38 TPM_LONG = 2,
39 TPM_UNDEFINED,
40};
41
42#define TPM_MAX_ORDINAL 243 35#define TPM_MAX_ORDINAL 243
43#define TSC_MAX_ORDINAL 12 36#define TSC_MAX_ORDINAL 12
44#define TPM_PROTECTED_COMMAND 0x00 37#define TPM_PROTECTED_COMMAND 0x00
@@ -405,24 +398,6 @@ out:
405#define TPM_DIGEST_SIZE 20 398#define TPM_DIGEST_SIZE 20
406#define TPM_RET_CODE_IDX 6 399#define TPM_RET_CODE_IDX 6
407 400
408enum tpm_capabilities {
409 TPM_CAP_FLAG = cpu_to_be32(4),
410 TPM_CAP_PROP = cpu_to_be32(5),
411 CAP_VERSION_1_1 = cpu_to_be32(0x06),
412 CAP_VERSION_1_2 = cpu_to_be32(0x1A)
413};
414
415enum tpm_sub_capabilities {
416 TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
417 TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
418 TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
419 TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
420 TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
421 TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
422 TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
423
424};
425
426static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, 401static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
427 int len, const char *desc) 402 int len, const char *desc)
428{ 403{
@@ -442,7 +417,6 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
442} 417}
443 418
444#define TPM_INTERNAL_RESULT_SIZE 200 419#define TPM_INTERNAL_RESULT_SIZE 200
445#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
446#define TPM_ORD_GET_CAP cpu_to_be32(101) 420#define TPM_ORD_GET_CAP cpu_to_be32(101)
447#define TPM_ORD_GET_RANDOM cpu_to_be32(70) 421#define TPM_ORD_GET_RANDOM cpu_to_be32(70)
448 422
@@ -642,70 +616,6 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
642 return rc; 616 return rc;
643} 617}
644 618
645ssize_t tpm_show_enabled(struct device *dev, struct device_attribute *attr,
646 char *buf)
647{
648 cap_t cap;
649 ssize_t rc;
650
651 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
652 "attempting to determine the permanent enabled state");
653 if (rc)
654 return 0;
655
656 rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
657 return rc;
658}
659EXPORT_SYMBOL_GPL(tpm_show_enabled);
660
661ssize_t tpm_show_active(struct device *dev, struct device_attribute *attr,
662 char *buf)
663{
664 cap_t cap;
665 ssize_t rc;
666
667 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
668 "attempting to determine the permanent active state");
669 if (rc)
670 return 0;
671
672 rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
673 return rc;
674}
675EXPORT_SYMBOL_GPL(tpm_show_active);
676
677ssize_t tpm_show_owned(struct device *dev, struct device_attribute *attr,
678 char *buf)
679{
680 cap_t cap;
681 ssize_t rc;
682
683 rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
684 "attempting to determine the owner state");
685 if (rc)
686 return 0;
687
688 rc = sprintf(buf, "%d\n", cap.owned);
689 return rc;
690}
691EXPORT_SYMBOL_GPL(tpm_show_owned);
692
693ssize_t tpm_show_temp_deactivated(struct device *dev,
694 struct device_attribute *attr, char *buf)
695{
696 cap_t cap;
697 ssize_t rc;
698
699 rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
700 "attempting to determine the temporary state");
701 if (rc)
702 return 0;
703
704 rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
705 return rc;
706}
707EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
708
709/* 619/*
710 * tpm_chip_find_get - return tpm_chip for given chip number 620 * tpm_chip_find_get - return tpm_chip for given chip number
711 */ 621 */
@@ -735,7 +645,7 @@ static struct tpm_input_header pcrread_header = {
735 .ordinal = TPM_ORDINAL_PCRREAD 645 .ordinal = TPM_ORDINAL_PCRREAD
736}; 646};
737 647
738static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) 648int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
739{ 649{
740 int rc; 650 int rc;
741 struct tpm_cmd_t cmd; 651 struct tpm_cmd_t cmd;
@@ -770,7 +680,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
770 chip = tpm_chip_find_get(chip_num); 680 chip = tpm_chip_find_get(chip_num);
771 if (chip == NULL) 681 if (chip == NULL)
772 return -ENODEV; 682 return -ENODEV;
773 rc = __tpm_pcr_read(chip, pcr_idx, res_buf); 683 rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
774 tpm_chip_put(chip); 684 tpm_chip_put(chip);
775 return rc; 685 return rc;
776} 686}
@@ -894,187 +804,6 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
894} 804}
895EXPORT_SYMBOL_GPL(tpm_send); 805EXPORT_SYMBOL_GPL(tpm_send);
896 806
897ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
898 char *buf)
899{
900 cap_t cap;
901 u8 digest[TPM_DIGEST_SIZE];
902 ssize_t rc;
903 int i, j, num_pcrs;
904 char *str = buf;
905 struct tpm_chip *chip = dev_get_drvdata(dev);
906
907 rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
908 "attempting to determine the number of PCRS");
909 if (rc)
910 return 0;
911
912 num_pcrs = be32_to_cpu(cap.num_pcrs);
913 for (i = 0; i < num_pcrs; i++) {
914 rc = __tpm_pcr_read(chip, i, digest);
915 if (rc)
916 break;
917 str += sprintf(str, "PCR-%02d: ", i);
918 for (j = 0; j < TPM_DIGEST_SIZE; j++)
919 str += sprintf(str, "%02X ", digest[j]);
920 str += sprintf(str, "\n");
921 }
922 return str - buf;
923}
924EXPORT_SYMBOL_GPL(tpm_show_pcrs);
925
926#define READ_PUBEK_RESULT_SIZE 314
927#define TPM_ORD_READPUBEK cpu_to_be32(124)
928static struct tpm_input_header tpm_readpubek_header = {
929 .tag = TPM_TAG_RQU_COMMAND,
930 .length = cpu_to_be32(30),
931 .ordinal = TPM_ORD_READPUBEK
932};
933
934ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
935 char *buf)
936{
937 u8 *data;
938 struct tpm_cmd_t tpm_cmd;
939 ssize_t err;
940 int i, rc;
941 char *str = buf;
942
943 struct tpm_chip *chip = dev_get_drvdata(dev);
944
945 tpm_cmd.header.in = tpm_readpubek_header;
946 err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
947 "attempting to read the PUBEK");
948 if (err)
949 goto out;
950
951 /*
952 ignore header 10 bytes
953 algorithm 32 bits (1 == RSA )
954 encscheme 16 bits
955 sigscheme 16 bits
956 parameters (RSA 12->bytes: keybit, #primes, expbit)
957 keylenbytes 32 bits
958 256 byte modulus
959 ignore checksum 20 bytes
960 */
961 data = tpm_cmd.params.readpubek_out_buffer;
962 str +=
963 sprintf(str,
964 "Algorithm: %02X %02X %02X %02X\n"
965 "Encscheme: %02X %02X\n"
966 "Sigscheme: %02X %02X\n"
967 "Parameters: %02X %02X %02X %02X "
968 "%02X %02X %02X %02X "
969 "%02X %02X %02X %02X\n"
970 "Modulus length: %d\n"
971 "Modulus:\n",
972 data[0], data[1], data[2], data[3],
973 data[4], data[5],
974 data[6], data[7],
975 data[12], data[13], data[14], data[15],
976 data[16], data[17], data[18], data[19],
977 data[20], data[21], data[22], data[23],
978 be32_to_cpu(*((__be32 *) (data + 24))));
979
980 for (i = 0; i < 256; i++) {
981 str += sprintf(str, "%02X ", data[i + 28]);
982 if ((i + 1) % 16 == 0)
983 str += sprintf(str, "\n");
984 }
985out:
986 rc = str - buf;
987 return rc;
988}
989EXPORT_SYMBOL_GPL(tpm_show_pubek);
990
991
992ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
993 char *buf)
994{
995 cap_t cap;
996 ssize_t rc;
997 char *str = buf;
998
999 rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
1000 "attempting to determine the manufacturer");
1001 if (rc)
1002 return 0;
1003 str += sprintf(str, "Manufacturer: 0x%x\n",
1004 be32_to_cpu(cap.manufacturer_id));
1005
1006 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
1007 rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
1008 "attempting to determine the 1.2 version");
1009 if (!rc) {
1010 str += sprintf(str,
1011 "TCG version: %d.%d\nFirmware version: %d.%d\n",
1012 cap.tpm_version_1_2.Major,
1013 cap.tpm_version_1_2.Minor,
1014 cap.tpm_version_1_2.revMajor,
1015 cap.tpm_version_1_2.revMinor);
1016 } else {
1017 /* Otherwise just use TPM_STRUCT_VER */
1018 rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
1019 "attempting to determine the 1.1 version");
1020 if (rc)
1021 return 0;
1022 str += sprintf(str,
1023 "TCG version: %d.%d\nFirmware version: %d.%d\n",
1024 cap.tpm_version.Major,
1025 cap.tpm_version.Minor,
1026 cap.tpm_version.revMajor,
1027 cap.tpm_version.revMinor);
1028 }
1029
1030 return str - buf;
1031}
1032EXPORT_SYMBOL_GPL(tpm_show_caps);
1033
1034ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr,
1035 char *buf)
1036{
1037 struct tpm_chip *chip = dev_get_drvdata(dev);
1038
1039 if (chip->vendor.duration[TPM_LONG] == 0)
1040 return 0;
1041
1042 return sprintf(buf, "%d %d %d [%s]\n",
1043 jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
1044 jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
1045 jiffies_to_usecs(chip->vendor.duration[TPM_LONG]),
1046 chip->vendor.duration_adjusted
1047 ? "adjusted" : "original");
1048}
1049EXPORT_SYMBOL_GPL(tpm_show_durations);
1050
1051ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr,
1052 char *buf)
1053{
1054 struct tpm_chip *chip = dev_get_drvdata(dev);
1055
1056 return sprintf(buf, "%d %d %d %d [%s]\n",
1057 jiffies_to_usecs(chip->vendor.timeout_a),
1058 jiffies_to_usecs(chip->vendor.timeout_b),
1059 jiffies_to_usecs(chip->vendor.timeout_c),
1060 jiffies_to_usecs(chip->vendor.timeout_d),
1061 chip->vendor.timeout_adjusted
1062 ? "adjusted" : "original");
1063}
1064EXPORT_SYMBOL_GPL(tpm_show_timeouts);
1065
1066ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
1067 const char *buf, size_t count)
1068{
1069 struct tpm_chip *chip = dev_get_drvdata(dev);
1070 if (chip == NULL)
1071 return 0;
1072
1073 chip->vendor.cancel(chip);
1074 return count;
1075}
1076EXPORT_SYMBOL_GPL(tpm_store_cancel);
1077
1078static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, 807static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
1079 bool check_cancel, bool *canceled) 808 bool check_cancel, bool *canceled)
1080{ 809{
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
new file mode 100644
index 000000000000..310d9609566f
--- /dev/null
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -0,0 +1,281 @@
1/*
2 * Copyright (C) 2004 IBM Corporation
3 * Authors:
4 * Leendert van Doorn <leendert@watson.ibm.com>
5 * Dave Safford <safford@watson.ibm.com>
6 * Reiner Sailer <sailer@watson.ibm.com>
7 * Kylene Hall <kjhall@us.ibm.com>
8 *
9 * sysfs filesystem inspection interface to the TPM
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2 of the
14 * License.
15 *
16 */
17#include <linux/device.h>
18#include "tpm.h"
19
20/* XXX for now this helper is duplicated in tpm-interface.c */
21static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
22 int len, const char *desc)
23{
24 int err;
25
26 len = tpm_transmit(chip, (u8 *) cmd, len);
27 if (len < 0)
28 return len;
29 else if (len < TPM_HEADER_SIZE)
30 return -EFAULT;
31
32 err = be32_to_cpu(cmd->header.out.return_code);
33 if (err != 0 && desc)
34 dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
35
36 return err;
37}
38
39#define READ_PUBEK_RESULT_SIZE 314
40#define TPM_ORD_READPUBEK cpu_to_be32(124)
41static struct tpm_input_header tpm_readpubek_header = {
42 .tag = TPM_TAG_RQU_COMMAND,
43 .length = cpu_to_be32(30),
44 .ordinal = TPM_ORD_READPUBEK
45};
46
47ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
48 char *buf)
49{
50 u8 *data;
51 struct tpm_cmd_t tpm_cmd;
52 ssize_t err;
53 int i, rc;
54 char *str = buf;
55
56 struct tpm_chip *chip = dev_get_drvdata(dev);
57
58 tpm_cmd.header.in = tpm_readpubek_header;
59 err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
60 "attempting to read the PUBEK");
61 if (err)
62 goto out;
63
64 /*
65 ignore header 10 bytes
66 algorithm 32 bits (1 == RSA )
67 encscheme 16 bits
68 sigscheme 16 bits
69 parameters (RSA 12->bytes: keybit, #primes, expbit)
70 keylenbytes 32 bits
71 256 byte modulus
72 ignore checksum 20 bytes
73 */
74 data = tpm_cmd.params.readpubek_out_buffer;
75 str +=
76 sprintf(str,
77 "Algorithm: %02X %02X %02X %02X\n"
78 "Encscheme: %02X %02X\n"
79 "Sigscheme: %02X %02X\n"
80 "Parameters: %02X %02X %02X %02X "
81 "%02X %02X %02X %02X "
82 "%02X %02X %02X %02X\n"
83 "Modulus length: %d\n"
84 "Modulus:\n",
85 data[0], data[1], data[2], data[3],
86 data[4], data[5],
87 data[6], data[7],
88 data[12], data[13], data[14], data[15],
89 data[16], data[17], data[18], data[19],
90 data[20], data[21], data[22], data[23],
91 be32_to_cpu(*((__be32 *) (data + 24))));
92
93 for (i = 0; i < 256; i++) {
94 str += sprintf(str, "%02X ", data[i + 28]);
95 if ((i + 1) % 16 == 0)
96 str += sprintf(str, "\n");
97 }
98out:
99 rc = str - buf;
100 return rc;
101}
102EXPORT_SYMBOL_GPL(tpm_show_pubek);
103
104ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
105 char *buf)
106{
107 cap_t cap;
108 u8 digest[TPM_DIGEST_SIZE];
109 ssize_t rc;
110 int i, j, num_pcrs;
111 char *str = buf;
112 struct tpm_chip *chip = dev_get_drvdata(dev);
113
114 rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
115 "attempting to determine the number of PCRS");
116 if (rc)
117 return 0;
118
119 num_pcrs = be32_to_cpu(cap.num_pcrs);
120 for (i = 0; i < num_pcrs; i++) {
121 rc = tpm_pcr_read_dev(chip, i, digest);
122 if (rc)
123 break;
124 str += sprintf(str, "PCR-%02d: ", i);
125 for (j = 0; j < TPM_DIGEST_SIZE; j++)
126 str += sprintf(str, "%02X ", digest[j]);
127 str += sprintf(str, "\n");
128 }
129 return str - buf;
130}
131EXPORT_SYMBOL_GPL(tpm_show_pcrs);
132
133ssize_t tpm_show_enabled(struct device *dev, struct device_attribute *attr,
134 char *buf)
135{
136 cap_t cap;
137 ssize_t rc;
138
139 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
140 "attempting to determine the permanent enabled state");
141 if (rc)
142 return 0;
143
144 rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
145 return rc;
146}
147EXPORT_SYMBOL_GPL(tpm_show_enabled);
148
149ssize_t tpm_show_active(struct device *dev, struct device_attribute *attr,
150 char *buf)
151{
152 cap_t cap;
153 ssize_t rc;
154
155 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
156 "attempting to determine the permanent active state");
157 if (rc)
158 return 0;
159
160 rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
161 return rc;
162}
163EXPORT_SYMBOL_GPL(tpm_show_active);
164
165ssize_t tpm_show_owned(struct device *dev, struct device_attribute *attr,
166 char *buf)
167{
168 cap_t cap;
169 ssize_t rc;
170
171 rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
172 "attempting to determine the owner state");
173 if (rc)
174 return 0;
175
176 rc = sprintf(buf, "%d\n", cap.owned);
177 return rc;
178}
179EXPORT_SYMBOL_GPL(tpm_show_owned);
180
181ssize_t tpm_show_temp_deactivated(struct device *dev,
182 struct device_attribute *attr, char *buf)
183{
184 cap_t cap;
185 ssize_t rc;
186
187 rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
188 "attempting to determine the temporary state");
189 if (rc)
190 return 0;
191
192 rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
193 return rc;
194}
195EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
196
197ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
198 char *buf)
199{
200 cap_t cap;
201 ssize_t rc;
202 char *str = buf;
203
204 rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
205 "attempting to determine the manufacturer");
206 if (rc)
207 return 0;
208 str += sprintf(str, "Manufacturer: 0x%x\n",
209 be32_to_cpu(cap.manufacturer_id));
210
211 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
212 rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
213 "attempting to determine the 1.2 version");
214 if (!rc) {
215 str += sprintf(str,
216 "TCG version: %d.%d\nFirmware version: %d.%d\n",
217 cap.tpm_version_1_2.Major,
218 cap.tpm_version_1_2.Minor,
219 cap.tpm_version_1_2.revMajor,
220 cap.tpm_version_1_2.revMinor);
221 } else {
222 /* Otherwise just use TPM_STRUCT_VER */
223 rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
224 "attempting to determine the 1.1 version");
225 if (rc)
226 return 0;
227 str += sprintf(str,
228 "TCG version: %d.%d\nFirmware version: %d.%d\n",
229 cap.tpm_version.Major,
230 cap.tpm_version.Minor,
231 cap.tpm_version.revMajor,
232 cap.tpm_version.revMinor);
233 }
234
235 return str - buf;
236}
237EXPORT_SYMBOL_GPL(tpm_show_caps);
238
239ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
240 const char *buf, size_t count)
241{
242 struct tpm_chip *chip = dev_get_drvdata(dev);
243 if (chip == NULL)
244 return 0;
245
246 chip->vendor.cancel(chip);
247 return count;
248}
249EXPORT_SYMBOL_GPL(tpm_store_cancel);
250
251ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr,
252 char *buf)
253{
254 struct tpm_chip *chip = dev_get_drvdata(dev);
255
256 if (chip->vendor.duration[TPM_LONG] == 0)
257 return 0;
258
259 return sprintf(buf, "%d %d %d [%s]\n",
260 jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
261 jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
262 jiffies_to_usecs(chip->vendor.duration[TPM_LONG]),
263 chip->vendor.duration_adjusted
264 ? "adjusted" : "original");
265}
266EXPORT_SYMBOL_GPL(tpm_show_durations);
267
268ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr,
269 char *buf)
270{
271 struct tpm_chip *chip = dev_get_drvdata(dev);
272
273 return sprintf(buf, "%d %d %d %d [%s]\n",
274 jiffies_to_usecs(chip->vendor.timeout_a),
275 jiffies_to_usecs(chip->vendor.timeout_b),
276 jiffies_to_usecs(chip->vendor.timeout_c),
277 jiffies_to_usecs(chip->vendor.timeout_d),
278 chip->vendor.timeout_adjusted
279 ? "adjusted" : "original");
280}
281EXPORT_SYMBOL_GPL(tpm_show_timeouts);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 496228cf1d81..41b1480e6e17 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -46,6 +46,14 @@ enum tpm_addr {
46 TPM_ADDR = 0x4E, 46 TPM_ADDR = 0x4E,
47}; 47};
48 48
49/* Indexes the duration array */
50enum tpm_duration {
51 TPM_SHORT = 0,
52 TPM_MEDIUM = 1,
53 TPM_LONG = 2,
54 TPM_UNDEFINED,
55};
56
49#define TPM_WARN_RETRY 0x800 57#define TPM_WARN_RETRY 0x800
50#define TPM_WARN_DOING_SELFTEST 0x802 58#define TPM_WARN_DOING_SELFTEST 0x802
51#define TPM_ERR_DEACTIVATED 0x6 59#define TPM_ERR_DEACTIVATED 0x6
@@ -171,6 +179,8 @@ struct tpm_output_header {
171 __be32 return_code; 179 __be32 return_code;
172} __packed; 180} __packed;
173 181
182#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
183
174struct stclear_flags_t { 184struct stclear_flags_t {
175 __be16 tag; 185 __be16 tag;
176 u8 deactivated; 186 u8 deactivated;
@@ -244,6 +254,24 @@ typedef union {
244 struct duration_t duration; 254 struct duration_t duration;
245} cap_t; 255} cap_t;
246 256
257enum tpm_capabilities {
258 TPM_CAP_FLAG = cpu_to_be32(4),
259 TPM_CAP_PROP = cpu_to_be32(5),
260 CAP_VERSION_1_1 = cpu_to_be32(0x06),
261 CAP_VERSION_1_2 = cpu_to_be32(0x1A)
262};
263
264enum tpm_sub_capabilities {
265 TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
266 TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
267 TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
268 TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
269 TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
270 TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
271 TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
272
273};
274
247struct tpm_getcap_params_in { 275struct tpm_getcap_params_in {
248 __be32 cap; 276 __be32 cap;
249 __be32 subcap_size; 277 __be32 subcap_size;
@@ -341,6 +369,8 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
341int tpm_dev_add_device(struct tpm_chip *chip); 369int tpm_dev_add_device(struct tpm_chip *chip);
342void tpm_dev_del_device(struct tpm_chip *chip); 370void tpm_dev_del_device(struct tpm_chip *chip);
343 371
372int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
373
344#ifdef CONFIG_ACPI 374#ifdef CONFIG_ACPI
345extern int tpm_add_ppi(struct kobject *); 375extern int tpm_add_ppi(struct kobject *);
346extern void tpm_remove_ppi(struct kobject *); 376extern void tpm_remove_ppi(struct kobject *);