diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 12:06:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 12:06:02 -0500 |
commit | fb2e2c85375a0380d6818f153ffa2ae9ebbd055f (patch) | |
tree | cf8498a01357c220e4d664ff67125f60146f0da3 /drivers/char/tpm | |
parent | ec513b16c480c6cdda1e3d597e611eafca05227b (diff) | |
parent | 923b49ff69fcbffe6f8b2739de218c45544392a7 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris:
"Changes for this kernel include maintenance updates for Smack, SELinux
(and several networking fixes), IMA and TPM"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (39 commits)
SELinux: Fix memory leak upon loading policy
tpm/tpm-sysfs: active_show() can be static
tpm: tpm_tis: Fix compile problems with CONFIG_PM_SLEEP/CONFIG_PNP
tpm: Make tpm-dev allocate a per-file structure
tpm: Use the ops structure instead of a copy in tpm_vendor_specific
tpm: Create a tpm_class_ops structure and use it in the drivers
tpm: Pull all driver sysfs code into tpm-sysfs.c
tpm: Move sysfs functions from tpm-interface to tpm-sysfs
tpm: Pull everything related to /dev/tpmX into tpm-dev.c
char: tpm: nuvoton: remove unused variable
tpm: MAINTAINERS: Cleanup TPM Maintainers file
tpm/tpm_i2c_atmel: fix coccinelle warnings
tpm/tpm_ibmvtpm: fix unreachable code warning (smatch warning)
tpm/tpm_i2c_stm_st33: Check return code of get_burstcount
tpm/tpm_ppi: Check return value of acpi_get_name
tpm/tpm_ppi: Do not compare strcmp(a,b) == -1
ima: remove unneeded size_limit argument from ima_eventdigest_init_common()
ima: update IMA-templates.txt documentation
ima: pass HASH_ALGO__LAST as hash algo in ima_eventdigest_init()
ima: change the default hash algorithm to SHA1 in ima_eventdigest_ng_init()
...
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r-- | drivers/char/tpm/Makefile | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-dev.c | 213 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 488 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-sysfs.c | 318 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 83 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_atmel.c | 28 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_atmel.c | 44 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_infineon.c | 42 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_nuvoton.c | 43 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.c | 48 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_ibmvtpm.c | 41 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 28 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_nsc.c | 28 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_ppi.c | 8 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 49 | ||||
-rw-r--r-- | drivers/char/tpm/xen-tpmfront.c | 45 |
16 files changed, 623 insertions, 885 deletions
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index b80a4000daee..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 | # |
4 | obj-$(CONFIG_TCG_TPM) += tpm.o | 4 | obj-$(CONFIG_TCG_TPM) += tpm.o |
5 | tpm-y := tpm-interface.o | 5 | tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o |
6 | tpm-$(CONFIG_ACPI) += tpm_ppi.o | 6 | tpm-$(CONFIG_ACPI) += tpm_ppi.o |
7 | 7 | ||
8 | ifdef CONFIG_ACPI | 8 | ifdef CONFIG_ACPI |
diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c new file mode 100644 index 000000000000..d9b774e02a1f --- /dev/null +++ b/drivers/char/tpm/tpm-dev.c | |||
@@ -0,0 +1,213 @@ | |||
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 | * Copyright (C) 2013 Obsidian Research Corp | ||
10 | * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
11 | * | ||
12 | * Device file system interface to the TPM | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation, version 2 of the | ||
17 | * License. | ||
18 | * | ||
19 | */ | ||
20 | #include <linux/miscdevice.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/uaccess.h> | ||
23 | #include "tpm.h" | ||
24 | |||
25 | struct file_priv { | ||
26 | struct tpm_chip *chip; | ||
27 | |||
28 | /* Data passed to and from the tpm via the read/write calls */ | ||
29 | atomic_t data_pending; | ||
30 | struct mutex buffer_mutex; | ||
31 | |||
32 | struct timer_list user_read_timer; /* user needs to claim result */ | ||
33 | struct work_struct work; | ||
34 | |||
35 | u8 data_buffer[TPM_BUFSIZE]; | ||
36 | }; | ||
37 | |||
38 | static void user_reader_timeout(unsigned long ptr) | ||
39 | { | ||
40 | struct file_priv *priv = (struct file_priv *)ptr; | ||
41 | |||
42 | schedule_work(&priv->work); | ||
43 | } | ||
44 | |||
45 | static void timeout_work(struct work_struct *work) | ||
46 | { | ||
47 | struct file_priv *priv = container_of(work, struct file_priv, work); | ||
48 | |||
49 | mutex_lock(&priv->buffer_mutex); | ||
50 | atomic_set(&priv->data_pending, 0); | ||
51 | memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); | ||
52 | mutex_unlock(&priv->buffer_mutex); | ||
53 | } | ||
54 | |||
55 | static int tpm_open(struct inode *inode, struct file *file) | ||
56 | { | ||
57 | struct miscdevice *misc = file->private_data; | ||
58 | struct tpm_chip *chip = container_of(misc, struct tpm_chip, | ||
59 | vendor.miscdev); | ||
60 | struct file_priv *priv; | ||
61 | |||
62 | /* It's assured that the chip will be opened just once, | ||
63 | * by the check of is_open variable, which is protected | ||
64 | * by driver_lock. */ | ||
65 | if (test_and_set_bit(0, &chip->is_open)) { | ||
66 | dev_dbg(chip->dev, "Another process owns this TPM\n"); | ||
67 | return -EBUSY; | ||
68 | } | ||
69 | |||
70 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
71 | if (priv == NULL) { | ||
72 | clear_bit(0, &chip->is_open); | ||
73 | return -ENOMEM; | ||
74 | } | ||
75 | |||
76 | priv->chip = chip; | ||
77 | atomic_set(&priv->data_pending, 0); | ||
78 | mutex_init(&priv->buffer_mutex); | ||
79 | setup_timer(&priv->user_read_timer, user_reader_timeout, | ||
80 | (unsigned long)priv); | ||
81 | INIT_WORK(&priv->work, timeout_work); | ||
82 | |||
83 | file->private_data = priv; | ||
84 | get_device(chip->dev); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static ssize_t tpm_read(struct file *file, char __user *buf, | ||
89 | size_t size, loff_t *off) | ||
90 | { | ||
91 | struct file_priv *priv = file->private_data; | ||
92 | ssize_t ret_size; | ||
93 | int rc; | ||
94 | |||
95 | del_singleshot_timer_sync(&priv->user_read_timer); | ||
96 | flush_work(&priv->work); | ||
97 | ret_size = atomic_read(&priv->data_pending); | ||
98 | if (ret_size > 0) { /* relay data */ | ||
99 | ssize_t orig_ret_size = ret_size; | ||
100 | if (size < ret_size) | ||
101 | ret_size = size; | ||
102 | |||
103 | mutex_lock(&priv->buffer_mutex); | ||
104 | rc = copy_to_user(buf, priv->data_buffer, ret_size); | ||
105 | memset(priv->data_buffer, 0, orig_ret_size); | ||
106 | if (rc) | ||
107 | ret_size = -EFAULT; | ||
108 | |||
109 | mutex_unlock(&priv->buffer_mutex); | ||
110 | } | ||
111 | |||
112 | atomic_set(&priv->data_pending, 0); | ||
113 | |||
114 | return ret_size; | ||
115 | } | ||
116 | |||
117 | static ssize_t tpm_write(struct file *file, const char __user *buf, | ||
118 | size_t size, loff_t *off) | ||
119 | { | ||
120 | struct file_priv *priv = file->private_data; | ||
121 | size_t in_size = size; | ||
122 | ssize_t out_size; | ||
123 | |||
124 | /* cannot perform a write until the read has cleared | ||
125 | either via tpm_read or a user_read_timer timeout. | ||
126 | This also prevents splitted buffered writes from blocking here. | ||
127 | */ | ||
128 | if (atomic_read(&priv->data_pending) != 0) | ||
129 | return -EBUSY; | ||
130 | |||
131 | if (in_size > TPM_BUFSIZE) | ||
132 | return -E2BIG; | ||
133 | |||
134 | mutex_lock(&priv->buffer_mutex); | ||
135 | |||
136 | if (copy_from_user | ||
137 | (priv->data_buffer, (void __user *) buf, in_size)) { | ||
138 | mutex_unlock(&priv->buffer_mutex); | ||
139 | return -EFAULT; | ||
140 | } | ||
141 | |||
142 | /* atomic tpm command send and result receive */ | ||
143 | out_size = tpm_transmit(priv->chip, priv->data_buffer, | ||
144 | sizeof(priv->data_buffer)); | ||
145 | if (out_size < 0) { | ||
146 | mutex_unlock(&priv->buffer_mutex); | ||
147 | return out_size; | ||
148 | } | ||
149 | |||
150 | atomic_set(&priv->data_pending, out_size); | ||
151 | mutex_unlock(&priv->buffer_mutex); | ||
152 | |||
153 | /* Set a timeout by which the reader must come claim the result */ | ||
154 | mod_timer(&priv->user_read_timer, jiffies + (60 * HZ)); | ||
155 | |||
156 | return in_size; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Called on file close | ||
161 | */ | ||
162 | static int tpm_release(struct inode *inode, struct file *file) | ||
163 | { | ||
164 | struct file_priv *priv = file->private_data; | ||
165 | |||
166 | del_singleshot_timer_sync(&priv->user_read_timer); | ||
167 | flush_work(&priv->work); | ||
168 | file->private_data = NULL; | ||
169 | atomic_set(&priv->data_pending, 0); | ||
170 | clear_bit(0, &priv->chip->is_open); | ||
171 | put_device(priv->chip->dev); | ||
172 | kfree(priv); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static const struct file_operations tpm_fops = { | ||
177 | .owner = THIS_MODULE, | ||
178 | .llseek = no_llseek, | ||
179 | .open = tpm_open, | ||
180 | .read = tpm_read, | ||
181 | .write = tpm_write, | ||
182 | .release = tpm_release, | ||
183 | }; | ||
184 | |||
185 | int tpm_dev_add_device(struct tpm_chip *chip) | ||
186 | { | ||
187 | int rc; | ||
188 | |||
189 | chip->vendor.miscdev.fops = &tpm_fops; | ||
190 | if (chip->dev_num == 0) | ||
191 | chip->vendor.miscdev.minor = TPM_MINOR; | ||
192 | else | ||
193 | chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; | ||
194 | |||
195 | chip->vendor.miscdev.name = chip->devname; | ||
196 | chip->vendor.miscdev.parent = chip->dev; | ||
197 | |||
198 | rc = misc_register(&chip->vendor.miscdev); | ||
199 | if (rc) { | ||
200 | chip->vendor.miscdev.name = NULL; | ||
201 | dev_err(chip->dev, | ||
202 | "unable to misc_register %s, minor %d err=%d\n", | ||
203 | chip->vendor.miscdev.name, | ||
204 | chip->vendor.miscdev.minor, rc); | ||
205 | } | ||
206 | return rc; | ||
207 | } | ||
208 | |||
209 | void tpm_dev_del_device(struct tpm_chip *chip) | ||
210 | { | ||
211 | if (chip->vendor.miscdev.name) | ||
212 | misc_deregister(&chip->vendor.miscdev); | ||
213 | } | ||
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 6ae41d337630..62e10fd1e1cb 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 | ||
35 | enum 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 |
@@ -312,23 +305,6 @@ static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = { | |||
312 | TPM_MEDIUM, | 305 | TPM_MEDIUM, |
313 | }; | 306 | }; |
314 | 307 | ||
315 | static void user_reader_timeout(unsigned long ptr) | ||
316 | { | ||
317 | struct tpm_chip *chip = (struct tpm_chip *) ptr; | ||
318 | |||
319 | schedule_work(&chip->work); | ||
320 | } | ||
321 | |||
322 | static void timeout_work(struct work_struct *work) | ||
323 | { | ||
324 | struct tpm_chip *chip = container_of(work, struct tpm_chip, work); | ||
325 | |||
326 | mutex_lock(&chip->buffer_mutex); | ||
327 | atomic_set(&chip->data_pending, 0); | ||
328 | memset(chip->data_buffer, 0, TPM_BUFSIZE); | ||
329 | mutex_unlock(&chip->buffer_mutex); | ||
330 | } | ||
331 | |||
332 | /* | 308 | /* |
333 | * Returns max number of jiffies to wait | 309 | * Returns max number of jiffies to wait |
334 | */ | 310 | */ |
@@ -355,8 +331,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); | |||
355 | /* | 331 | /* |
356 | * Internal kernel interface to transmit TPM commands | 332 | * Internal kernel interface to transmit TPM commands |
357 | */ | 333 | */ |
358 | static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | 334 | ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, |
359 | size_t bufsiz) | 335 | size_t bufsiz) |
360 | { | 336 | { |
361 | ssize_t rc; | 337 | ssize_t rc; |
362 | u32 count, ordinal; | 338 | u32 count, ordinal; |
@@ -377,7 +353,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
377 | 353 | ||
378 | mutex_lock(&chip->tpm_mutex); | 354 | mutex_lock(&chip->tpm_mutex); |
379 | 355 | ||
380 | rc = chip->vendor.send(chip, (u8 *) buf, count); | 356 | rc = chip->ops->send(chip, (u8 *) buf, count); |
381 | if (rc < 0) { | 357 | if (rc < 0) { |
382 | dev_err(chip->dev, | 358 | dev_err(chip->dev, |
383 | "tpm_transmit: tpm_send: error %zd\n", rc); | 359 | "tpm_transmit: tpm_send: error %zd\n", rc); |
@@ -389,12 +365,12 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
389 | 365 | ||
390 | stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal); | 366 | stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal); |
391 | do { | 367 | do { |
392 | u8 status = chip->vendor.status(chip); | 368 | u8 status = chip->ops->status(chip); |
393 | if ((status & chip->vendor.req_complete_mask) == | 369 | if ((status & chip->ops->req_complete_mask) == |
394 | chip->vendor.req_complete_val) | 370 | chip->ops->req_complete_val) |
395 | goto out_recv; | 371 | goto out_recv; |
396 | 372 | ||
397 | if (chip->vendor.req_canceled(chip, status)) { | 373 | if (chip->ops->req_canceled(chip, status)) { |
398 | dev_err(chip->dev, "Operation Canceled\n"); | 374 | dev_err(chip->dev, "Operation Canceled\n"); |
399 | rc = -ECANCELED; | 375 | rc = -ECANCELED; |
400 | goto out; | 376 | goto out; |
@@ -404,13 +380,13 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
404 | rmb(); | 380 | rmb(); |
405 | } while (time_before(jiffies, stop)); | 381 | } while (time_before(jiffies, stop)); |
406 | 382 | ||
407 | chip->vendor.cancel(chip); | 383 | chip->ops->cancel(chip); |
408 | dev_err(chip->dev, "Operation Timed out\n"); | 384 | dev_err(chip->dev, "Operation Timed out\n"); |
409 | rc = -ETIME; | 385 | rc = -ETIME; |
410 | goto out; | 386 | goto out; |
411 | 387 | ||
412 | out_recv: | 388 | out_recv: |
413 | rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz); | 389 | rc = chip->ops->recv(chip, (u8 *) buf, bufsiz); |
414 | if (rc < 0) | 390 | if (rc < 0) |
415 | dev_err(chip->dev, | 391 | dev_err(chip->dev, |
416 | "tpm_transmit: tpm_recv: error %zd\n", rc); | 392 | "tpm_transmit: tpm_recv: error %zd\n", rc); |
@@ -422,24 +398,6 @@ out: | |||
422 | #define TPM_DIGEST_SIZE 20 | 398 | #define TPM_DIGEST_SIZE 20 |
423 | #define TPM_RET_CODE_IDX 6 | 399 | #define TPM_RET_CODE_IDX 6 |
424 | 400 | ||
425 | enum tpm_capabilities { | ||
426 | TPM_CAP_FLAG = cpu_to_be32(4), | ||
427 | TPM_CAP_PROP = cpu_to_be32(5), | ||
428 | CAP_VERSION_1_1 = cpu_to_be32(0x06), | ||
429 | CAP_VERSION_1_2 = cpu_to_be32(0x1A) | ||
430 | }; | ||
431 | |||
432 | enum tpm_sub_capabilities { | ||
433 | TPM_CAP_PROP_PCR = cpu_to_be32(0x101), | ||
434 | TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103), | ||
435 | TPM_CAP_FLAG_PERM = cpu_to_be32(0x108), | ||
436 | TPM_CAP_FLAG_VOL = cpu_to_be32(0x109), | ||
437 | TPM_CAP_PROP_OWNER = cpu_to_be32(0x111), | ||
438 | TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115), | ||
439 | TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120), | ||
440 | |||
441 | }; | ||
442 | |||
443 | static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, | 401 | static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, |
444 | int len, const char *desc) | 402 | int len, const char *desc) |
445 | { | 403 | { |
@@ -459,7 +417,6 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, | |||
459 | } | 417 | } |
460 | 418 | ||
461 | #define TPM_INTERNAL_RESULT_SIZE 200 | 419 | #define TPM_INTERNAL_RESULT_SIZE 200 |
462 | #define TPM_TAG_RQU_COMMAND cpu_to_be16(193) | ||
463 | #define TPM_ORD_GET_CAP cpu_to_be32(101) | 420 | #define TPM_ORD_GET_CAP cpu_to_be32(101) |
464 | #define TPM_ORD_GET_RANDOM cpu_to_be32(70) | 421 | #define TPM_ORD_GET_RANDOM cpu_to_be32(70) |
465 | 422 | ||
@@ -659,70 +616,6 @@ static int tpm_continue_selftest(struct tpm_chip *chip) | |||
659 | return rc; | 616 | return rc; |
660 | } | 617 | } |
661 | 618 | ||
662 | ssize_t tpm_show_enabled(struct device *dev, struct device_attribute *attr, | ||
663 | char *buf) | ||
664 | { | ||
665 | cap_t cap; | ||
666 | ssize_t rc; | ||
667 | |||
668 | rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, | ||
669 | "attempting to determine the permanent enabled state"); | ||
670 | if (rc) | ||
671 | return 0; | ||
672 | |||
673 | rc = sprintf(buf, "%d\n", !cap.perm_flags.disable); | ||
674 | return rc; | ||
675 | } | ||
676 | EXPORT_SYMBOL_GPL(tpm_show_enabled); | ||
677 | |||
678 | ssize_t tpm_show_active(struct device *dev, struct device_attribute *attr, | ||
679 | char *buf) | ||
680 | { | ||
681 | cap_t cap; | ||
682 | ssize_t rc; | ||
683 | |||
684 | rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, | ||
685 | "attempting to determine the permanent active state"); | ||
686 | if (rc) | ||
687 | return 0; | ||
688 | |||
689 | rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated); | ||
690 | return rc; | ||
691 | } | ||
692 | EXPORT_SYMBOL_GPL(tpm_show_active); | ||
693 | |||
694 | ssize_t tpm_show_owned(struct device *dev, struct device_attribute *attr, | ||
695 | char *buf) | ||
696 | { | ||
697 | cap_t cap; | ||
698 | ssize_t rc; | ||
699 | |||
700 | rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap, | ||
701 | "attempting to determine the owner state"); | ||
702 | if (rc) | ||
703 | return 0; | ||
704 | |||
705 | rc = sprintf(buf, "%d\n", cap.owned); | ||
706 | return rc; | ||
707 | } | ||
708 | EXPORT_SYMBOL_GPL(tpm_show_owned); | ||
709 | |||
710 | ssize_t tpm_show_temp_deactivated(struct device *dev, | ||
711 | struct device_attribute *attr, char *buf) | ||
712 | { | ||
713 | cap_t cap; | ||
714 | ssize_t rc; | ||
715 | |||
716 | rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap, | ||
717 | "attempting to determine the temporary state"); | ||
718 | if (rc) | ||
719 | return 0; | ||
720 | |||
721 | rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated); | ||
722 | return rc; | ||
723 | } | ||
724 | EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); | ||
725 | |||
726 | /* | 619 | /* |
727 | * tpm_chip_find_get - return tpm_chip for given chip number | 620 | * tpm_chip_find_get - return tpm_chip for given chip number |
728 | */ | 621 | */ |
@@ -752,7 +645,7 @@ static struct tpm_input_header pcrread_header = { | |||
752 | .ordinal = TPM_ORDINAL_PCRREAD | 645 | .ordinal = TPM_ORDINAL_PCRREAD |
753 | }; | 646 | }; |
754 | 647 | ||
755 | static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) | 648 | int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) |
756 | { | 649 | { |
757 | int rc; | 650 | int rc; |
758 | struct tpm_cmd_t cmd; | 651 | struct tpm_cmd_t cmd; |
@@ -787,7 +680,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) | |||
787 | chip = tpm_chip_find_get(chip_num); | 680 | chip = tpm_chip_find_get(chip_num); |
788 | if (chip == NULL) | 681 | if (chip == NULL) |
789 | return -ENODEV; | 682 | return -ENODEV; |
790 | rc = __tpm_pcr_read(chip, pcr_idx, res_buf); | 683 | rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf); |
791 | tpm_chip_put(chip); | 684 | tpm_chip_put(chip); |
792 | return rc; | 685 | return rc; |
793 | } | 686 | } |
@@ -911,196 +804,15 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen) | |||
911 | } | 804 | } |
912 | EXPORT_SYMBOL_GPL(tpm_send); | 805 | EXPORT_SYMBOL_GPL(tpm_send); |
913 | 806 | ||
914 | ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | ||
915 | char *buf) | ||
916 | { | ||
917 | cap_t cap; | ||
918 | u8 digest[TPM_DIGEST_SIZE]; | ||
919 | ssize_t rc; | ||
920 | int i, j, num_pcrs; | ||
921 | char *str = buf; | ||
922 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
923 | |||
924 | rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap, | ||
925 | "attempting to determine the number of PCRS"); | ||
926 | if (rc) | ||
927 | return 0; | ||
928 | |||
929 | num_pcrs = be32_to_cpu(cap.num_pcrs); | ||
930 | for (i = 0; i < num_pcrs; i++) { | ||
931 | rc = __tpm_pcr_read(chip, i, digest); | ||
932 | if (rc) | ||
933 | break; | ||
934 | str += sprintf(str, "PCR-%02d: ", i); | ||
935 | for (j = 0; j < TPM_DIGEST_SIZE; j++) | ||
936 | str += sprintf(str, "%02X ", digest[j]); | ||
937 | str += sprintf(str, "\n"); | ||
938 | } | ||
939 | return str - buf; | ||
940 | } | ||
941 | EXPORT_SYMBOL_GPL(tpm_show_pcrs); | ||
942 | |||
943 | #define READ_PUBEK_RESULT_SIZE 314 | ||
944 | #define TPM_ORD_READPUBEK cpu_to_be32(124) | ||
945 | static struct tpm_input_header tpm_readpubek_header = { | ||
946 | .tag = TPM_TAG_RQU_COMMAND, | ||
947 | .length = cpu_to_be32(30), | ||
948 | .ordinal = TPM_ORD_READPUBEK | ||
949 | }; | ||
950 | |||
951 | ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | ||
952 | char *buf) | ||
953 | { | ||
954 | u8 *data; | ||
955 | struct tpm_cmd_t tpm_cmd; | ||
956 | ssize_t err; | ||
957 | int i, rc; | ||
958 | char *str = buf; | ||
959 | |||
960 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
961 | |||
962 | tpm_cmd.header.in = tpm_readpubek_header; | ||
963 | err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, | ||
964 | "attempting to read the PUBEK"); | ||
965 | if (err) | ||
966 | goto out; | ||
967 | |||
968 | /* | ||
969 | ignore header 10 bytes | ||
970 | algorithm 32 bits (1 == RSA ) | ||
971 | encscheme 16 bits | ||
972 | sigscheme 16 bits | ||
973 | parameters (RSA 12->bytes: keybit, #primes, expbit) | ||
974 | keylenbytes 32 bits | ||
975 | 256 byte modulus | ||
976 | ignore checksum 20 bytes | ||
977 | */ | ||
978 | data = tpm_cmd.params.readpubek_out_buffer; | ||
979 | str += | ||
980 | sprintf(str, | ||
981 | "Algorithm: %02X %02X %02X %02X\n" | ||
982 | "Encscheme: %02X %02X\n" | ||
983 | "Sigscheme: %02X %02X\n" | ||
984 | "Parameters: %02X %02X %02X %02X " | ||
985 | "%02X %02X %02X %02X " | ||
986 | "%02X %02X %02X %02X\n" | ||
987 | "Modulus length: %d\n" | ||
988 | "Modulus:\n", | ||
989 | data[0], data[1], data[2], data[3], | ||
990 | data[4], data[5], | ||
991 | data[6], data[7], | ||
992 | data[12], data[13], data[14], data[15], | ||
993 | data[16], data[17], data[18], data[19], | ||
994 | data[20], data[21], data[22], data[23], | ||
995 | be32_to_cpu(*((__be32 *) (data + 24)))); | ||
996 | |||
997 | for (i = 0; i < 256; i++) { | ||
998 | str += sprintf(str, "%02X ", data[i + 28]); | ||
999 | if ((i + 1) % 16 == 0) | ||
1000 | str += sprintf(str, "\n"); | ||
1001 | } | ||
1002 | out: | ||
1003 | rc = str - buf; | ||
1004 | return rc; | ||
1005 | } | ||
1006 | EXPORT_SYMBOL_GPL(tpm_show_pubek); | ||
1007 | |||
1008 | |||
1009 | ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, | ||
1010 | char *buf) | ||
1011 | { | ||
1012 | cap_t cap; | ||
1013 | ssize_t rc; | ||
1014 | char *str = buf; | ||
1015 | |||
1016 | rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, | ||
1017 | "attempting to determine the manufacturer"); | ||
1018 | if (rc) | ||
1019 | return 0; | ||
1020 | str += sprintf(str, "Manufacturer: 0x%x\n", | ||
1021 | be32_to_cpu(cap.manufacturer_id)); | ||
1022 | |||
1023 | /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ | ||
1024 | rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, | ||
1025 | "attempting to determine the 1.2 version"); | ||
1026 | if (!rc) { | ||
1027 | str += sprintf(str, | ||
1028 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
1029 | cap.tpm_version_1_2.Major, | ||
1030 | cap.tpm_version_1_2.Minor, | ||
1031 | cap.tpm_version_1_2.revMajor, | ||
1032 | cap.tpm_version_1_2.revMinor); | ||
1033 | } else { | ||
1034 | /* Otherwise just use TPM_STRUCT_VER */ | ||
1035 | rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, | ||
1036 | "attempting to determine the 1.1 version"); | ||
1037 | if (rc) | ||
1038 | return 0; | ||
1039 | str += sprintf(str, | ||
1040 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
1041 | cap.tpm_version.Major, | ||
1042 | cap.tpm_version.Minor, | ||
1043 | cap.tpm_version.revMajor, | ||
1044 | cap.tpm_version.revMinor); | ||
1045 | } | ||
1046 | |||
1047 | return str - buf; | ||
1048 | } | ||
1049 | EXPORT_SYMBOL_GPL(tpm_show_caps); | ||
1050 | |||
1051 | ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr, | ||
1052 | char *buf) | ||
1053 | { | ||
1054 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
1055 | |||
1056 | if (chip->vendor.duration[TPM_LONG] == 0) | ||
1057 | return 0; | ||
1058 | |||
1059 | return sprintf(buf, "%d %d %d [%s]\n", | ||
1060 | jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), | ||
1061 | jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), | ||
1062 | jiffies_to_usecs(chip->vendor.duration[TPM_LONG]), | ||
1063 | chip->vendor.duration_adjusted | ||
1064 | ? "adjusted" : "original"); | ||
1065 | } | ||
1066 | EXPORT_SYMBOL_GPL(tpm_show_durations); | ||
1067 | |||
1068 | ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr, | ||
1069 | char *buf) | ||
1070 | { | ||
1071 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
1072 | |||
1073 | return sprintf(buf, "%d %d %d %d [%s]\n", | ||
1074 | jiffies_to_usecs(chip->vendor.timeout_a), | ||
1075 | jiffies_to_usecs(chip->vendor.timeout_b), | ||
1076 | jiffies_to_usecs(chip->vendor.timeout_c), | ||
1077 | jiffies_to_usecs(chip->vendor.timeout_d), | ||
1078 | chip->vendor.timeout_adjusted | ||
1079 | ? "adjusted" : "original"); | ||
1080 | } | ||
1081 | EXPORT_SYMBOL_GPL(tpm_show_timeouts); | ||
1082 | |||
1083 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | ||
1084 | const char *buf, size_t count) | ||
1085 | { | ||
1086 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
1087 | if (chip == NULL) | ||
1088 | return 0; | ||
1089 | |||
1090 | chip->vendor.cancel(chip); | ||
1091 | return count; | ||
1092 | } | ||
1093 | EXPORT_SYMBOL_GPL(tpm_store_cancel); | ||
1094 | |||
1095 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, | 807 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, |
1096 | bool check_cancel, bool *canceled) | 808 | bool check_cancel, bool *canceled) |
1097 | { | 809 | { |
1098 | u8 status = chip->vendor.status(chip); | 810 | u8 status = chip->ops->status(chip); |
1099 | 811 | ||
1100 | *canceled = false; | 812 | *canceled = false; |
1101 | if ((status & mask) == mask) | 813 | if ((status & mask) == mask) |
1102 | return true; | 814 | return true; |
1103 | if (check_cancel && chip->vendor.req_canceled(chip, status)) { | 815 | if (check_cancel && chip->ops->req_canceled(chip, status)) { |
1104 | *canceled = true; | 816 | *canceled = true; |
1105 | return true; | 817 | return true; |
1106 | } | 818 | } |
@@ -1116,7 +828,7 @@ int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | |||
1116 | bool canceled = false; | 828 | bool canceled = false; |
1117 | 829 | ||
1118 | /* check current status */ | 830 | /* check current status */ |
1119 | status = chip->vendor.status(chip); | 831 | status = chip->ops->status(chip); |
1120 | if ((status & mask) == mask) | 832 | if ((status & mask) == mask) |
1121 | return 0; | 833 | return 0; |
1122 | 834 | ||
@@ -1143,7 +855,7 @@ again: | |||
1143 | } else { | 855 | } else { |
1144 | do { | 856 | do { |
1145 | msleep(TPM_TIMEOUT); | 857 | msleep(TPM_TIMEOUT); |
1146 | status = chip->vendor.status(chip); | 858 | status = chip->ops->status(chip); |
1147 | if ((status & mask) == mask) | 859 | if ((status & mask) == mask) |
1148 | return 0; | 860 | return 0; |
1149 | } while (time_before(jiffies, stop)); | 861 | } while (time_before(jiffies, stop)); |
@@ -1151,127 +863,6 @@ again: | |||
1151 | return -ETIME; | 863 | return -ETIME; |
1152 | } | 864 | } |
1153 | EXPORT_SYMBOL_GPL(wait_for_tpm_stat); | 865 | EXPORT_SYMBOL_GPL(wait_for_tpm_stat); |
1154 | /* | ||
1155 | * Device file system interface to the TPM | ||
1156 | * | ||
1157 | * It's assured that the chip will be opened just once, | ||
1158 | * by the check of is_open variable, which is protected | ||
1159 | * by driver_lock. | ||
1160 | */ | ||
1161 | int tpm_open(struct inode *inode, struct file *file) | ||
1162 | { | ||
1163 | struct miscdevice *misc = file->private_data; | ||
1164 | struct tpm_chip *chip = container_of(misc, struct tpm_chip, | ||
1165 | vendor.miscdev); | ||
1166 | |||
1167 | if (test_and_set_bit(0, &chip->is_open)) { | ||
1168 | dev_dbg(chip->dev, "Another process owns this TPM\n"); | ||
1169 | return -EBUSY; | ||
1170 | } | ||
1171 | |||
1172 | chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); | ||
1173 | if (chip->data_buffer == NULL) { | ||
1174 | clear_bit(0, &chip->is_open); | ||
1175 | return -ENOMEM; | ||
1176 | } | ||
1177 | |||
1178 | atomic_set(&chip->data_pending, 0); | ||
1179 | |||
1180 | file->private_data = chip; | ||
1181 | get_device(chip->dev); | ||
1182 | return 0; | ||
1183 | } | ||
1184 | EXPORT_SYMBOL_GPL(tpm_open); | ||
1185 | |||
1186 | /* | ||
1187 | * Called on file close | ||
1188 | */ | ||
1189 | int tpm_release(struct inode *inode, struct file *file) | ||
1190 | { | ||
1191 | struct tpm_chip *chip = file->private_data; | ||
1192 | |||
1193 | del_singleshot_timer_sync(&chip->user_read_timer); | ||
1194 | flush_work(&chip->work); | ||
1195 | file->private_data = NULL; | ||
1196 | atomic_set(&chip->data_pending, 0); | ||
1197 | kzfree(chip->data_buffer); | ||
1198 | clear_bit(0, &chip->is_open); | ||
1199 | put_device(chip->dev); | ||
1200 | return 0; | ||
1201 | } | ||
1202 | EXPORT_SYMBOL_GPL(tpm_release); | ||
1203 | |||
1204 | ssize_t tpm_write(struct file *file, const char __user *buf, | ||
1205 | size_t size, loff_t *off) | ||
1206 | { | ||
1207 | struct tpm_chip *chip = file->private_data; | ||
1208 | size_t in_size = size; | ||
1209 | ssize_t out_size; | ||
1210 | |||
1211 | /* cannot perform a write until the read has cleared | ||
1212 | either via tpm_read or a user_read_timer timeout. | ||
1213 | This also prevents splitted buffered writes from blocking here. | ||
1214 | */ | ||
1215 | if (atomic_read(&chip->data_pending) != 0) | ||
1216 | return -EBUSY; | ||
1217 | |||
1218 | if (in_size > TPM_BUFSIZE) | ||
1219 | return -E2BIG; | ||
1220 | |||
1221 | mutex_lock(&chip->buffer_mutex); | ||
1222 | |||
1223 | if (copy_from_user | ||
1224 | (chip->data_buffer, (void __user *) buf, in_size)) { | ||
1225 | mutex_unlock(&chip->buffer_mutex); | ||
1226 | return -EFAULT; | ||
1227 | } | ||
1228 | |||
1229 | /* atomic tpm command send and result receive */ | ||
1230 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); | ||
1231 | if (out_size < 0) { | ||
1232 | mutex_unlock(&chip->buffer_mutex); | ||
1233 | return out_size; | ||
1234 | } | ||
1235 | |||
1236 | atomic_set(&chip->data_pending, out_size); | ||
1237 | mutex_unlock(&chip->buffer_mutex); | ||
1238 | |||
1239 | /* Set a timeout by which the reader must come claim the result */ | ||
1240 | mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); | ||
1241 | |||
1242 | return in_size; | ||
1243 | } | ||
1244 | EXPORT_SYMBOL_GPL(tpm_write); | ||
1245 | |||
1246 | ssize_t tpm_read(struct file *file, char __user *buf, | ||
1247 | size_t size, loff_t *off) | ||
1248 | { | ||
1249 | struct tpm_chip *chip = file->private_data; | ||
1250 | ssize_t ret_size; | ||
1251 | int rc; | ||
1252 | |||
1253 | del_singleshot_timer_sync(&chip->user_read_timer); | ||
1254 | flush_work(&chip->work); | ||
1255 | ret_size = atomic_read(&chip->data_pending); | ||
1256 | if (ret_size > 0) { /* relay data */ | ||
1257 | ssize_t orig_ret_size = ret_size; | ||
1258 | if (size < ret_size) | ||
1259 | ret_size = size; | ||
1260 | |||
1261 | mutex_lock(&chip->buffer_mutex); | ||
1262 | rc = copy_to_user(buf, chip->data_buffer, ret_size); | ||
1263 | memset(chip->data_buffer, 0, orig_ret_size); | ||
1264 | if (rc) | ||
1265 | ret_size = -EFAULT; | ||
1266 | |||
1267 | mutex_unlock(&chip->buffer_mutex); | ||
1268 | } | ||
1269 | |||
1270 | atomic_set(&chip->data_pending, 0); | ||
1271 | |||
1272 | return ret_size; | ||
1273 | } | ||
1274 | EXPORT_SYMBOL_GPL(tpm_read); | ||
1275 | 866 | ||
1276 | void tpm_remove_hardware(struct device *dev) | 867 | void tpm_remove_hardware(struct device *dev) |
1277 | { | 868 | { |
@@ -1287,8 +878,8 @@ void tpm_remove_hardware(struct device *dev) | |||
1287 | spin_unlock(&driver_lock); | 878 | spin_unlock(&driver_lock); |
1288 | synchronize_rcu(); | 879 | synchronize_rcu(); |
1289 | 880 | ||
1290 | misc_deregister(&chip->vendor.miscdev); | 881 | tpm_dev_del_device(chip); |
1291 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); | 882 | tpm_sysfs_del_device(chip); |
1292 | tpm_remove_ppi(&dev->kobj); | 883 | tpm_remove_ppi(&dev->kobj); |
1293 | tpm_bios_log_teardown(chip->bios_dir); | 884 | tpm_bios_log_teardown(chip->bios_dir); |
1294 | 885 | ||
@@ -1436,9 +1027,6 @@ void tpm_dev_vendor_release(struct tpm_chip *chip) | |||
1436 | if (!chip) | 1027 | if (!chip) |
1437 | return; | 1028 | return; |
1438 | 1029 | ||
1439 | if (chip->vendor.release) | ||
1440 | chip->vendor.release(chip->dev); | ||
1441 | |||
1442 | clear_bit(chip->dev_num, dev_mask); | 1030 | clear_bit(chip->dev_num, dev_mask); |
1443 | } | 1031 | } |
1444 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | 1032 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); |
@@ -1448,7 +1036,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | |||
1448 | * Once all references to platform device are down to 0, | 1036 | * Once all references to platform device are down to 0, |
1449 | * release all allocated structures. | 1037 | * release all allocated structures. |
1450 | */ | 1038 | */ |
1451 | void tpm_dev_release(struct device *dev) | 1039 | static void tpm_dev_release(struct device *dev) |
1452 | { | 1040 | { |
1453 | struct tpm_chip *chip = dev_get_drvdata(dev); | 1041 | struct tpm_chip *chip = dev_get_drvdata(dev); |
1454 | 1042 | ||
@@ -1460,7 +1048,6 @@ void tpm_dev_release(struct device *dev) | |||
1460 | chip->release(dev); | 1048 | chip->release(dev); |
1461 | kfree(chip); | 1049 | kfree(chip); |
1462 | } | 1050 | } |
1463 | EXPORT_SYMBOL_GPL(tpm_dev_release); | ||
1464 | 1051 | ||
1465 | /* | 1052 | /* |
1466 | * Called from tpm_<specific>.c probe function only for devices | 1053 | * Called from tpm_<specific>.c probe function only for devices |
@@ -1470,7 +1057,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_release); | |||
1470 | * pci_disable_device | 1057 | * pci_disable_device |
1471 | */ | 1058 | */ |
1472 | struct tpm_chip *tpm_register_hardware(struct device *dev, | 1059 | struct tpm_chip *tpm_register_hardware(struct device *dev, |
1473 | const struct tpm_vendor_specific *entry) | 1060 | const struct tpm_class_ops *ops) |
1474 | { | 1061 | { |
1475 | struct tpm_chip *chip; | 1062 | struct tpm_chip *chip; |
1476 | 1063 | ||
@@ -1480,56 +1067,35 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
1480 | if (chip == NULL) | 1067 | if (chip == NULL) |
1481 | return NULL; | 1068 | return NULL; |
1482 | 1069 | ||
1483 | mutex_init(&chip->buffer_mutex); | ||
1484 | mutex_init(&chip->tpm_mutex); | 1070 | mutex_init(&chip->tpm_mutex); |
1485 | INIT_LIST_HEAD(&chip->list); | 1071 | INIT_LIST_HEAD(&chip->list); |
1486 | 1072 | ||
1487 | INIT_WORK(&chip->work, timeout_work); | 1073 | chip->ops = ops; |
1488 | |||
1489 | setup_timer(&chip->user_read_timer, user_reader_timeout, | ||
1490 | (unsigned long)chip); | ||
1491 | |||
1492 | memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific)); | ||
1493 | |||
1494 | chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); | 1074 | chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); |
1495 | 1075 | ||
1496 | if (chip->dev_num >= TPM_NUM_DEVICES) { | 1076 | if (chip->dev_num >= TPM_NUM_DEVICES) { |
1497 | dev_err(dev, "No available tpm device numbers\n"); | 1077 | dev_err(dev, "No available tpm device numbers\n"); |
1498 | goto out_free; | 1078 | goto out_free; |
1499 | } else if (chip->dev_num == 0) | 1079 | } |
1500 | chip->vendor.miscdev.minor = TPM_MINOR; | ||
1501 | else | ||
1502 | chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; | ||
1503 | 1080 | ||
1504 | set_bit(chip->dev_num, dev_mask); | 1081 | set_bit(chip->dev_num, dev_mask); |
1505 | 1082 | ||
1506 | scnprintf(chip->devname, sizeof(chip->devname), "%s%d", "tpm", | 1083 | scnprintf(chip->devname, sizeof(chip->devname), "%s%d", "tpm", |
1507 | chip->dev_num); | 1084 | chip->dev_num); |
1508 | chip->vendor.miscdev.name = chip->devname; | ||
1509 | 1085 | ||
1510 | chip->vendor.miscdev.parent = dev; | ||
1511 | chip->dev = get_device(dev); | 1086 | chip->dev = get_device(dev); |
1512 | chip->release = dev->release; | 1087 | chip->release = dev->release; |
1513 | dev->release = tpm_dev_release; | 1088 | dev->release = tpm_dev_release; |
1514 | dev_set_drvdata(dev, chip); | 1089 | dev_set_drvdata(dev, chip); |
1515 | 1090 | ||
1516 | if (misc_register(&chip->vendor.miscdev)) { | 1091 | if (tpm_dev_add_device(chip)) |
1517 | dev_err(chip->dev, | ||
1518 | "unable to misc_register %s, minor %d\n", | ||
1519 | chip->vendor.miscdev.name, | ||
1520 | chip->vendor.miscdev.minor); | ||
1521 | goto put_device; | 1092 | goto put_device; |
1522 | } | ||
1523 | 1093 | ||
1524 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { | 1094 | if (tpm_sysfs_add_device(chip)) |
1525 | misc_deregister(&chip->vendor.miscdev); | 1095 | goto del_misc; |
1526 | goto put_device; | ||
1527 | } | ||
1528 | 1096 | ||
1529 | if (tpm_add_ppi(&dev->kobj)) { | 1097 | if (tpm_add_ppi(&dev->kobj)) |
1530 | misc_deregister(&chip->vendor.miscdev); | 1098 | goto del_misc; |
1531 | goto put_device; | ||
1532 | } | ||
1533 | 1099 | ||
1534 | chip->bios_dir = tpm_bios_log_setup(chip->devname); | 1100 | chip->bios_dir = tpm_bios_log_setup(chip->devname); |
1535 | 1101 | ||
@@ -1540,6 +1106,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
1540 | 1106 | ||
1541 | return chip; | 1107 | return chip; |
1542 | 1108 | ||
1109 | del_misc: | ||
1110 | tpm_dev_del_device(chip); | ||
1543 | put_device: | 1111 | put_device: |
1544 | put_device(chip->dev); | 1112 | put_device(chip->dev); |
1545 | out_free: | 1113 | out_free: |
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c new file mode 100644 index 000000000000..01730a27ae07 --- /dev/null +++ b/drivers/char/tpm/tpm-sysfs.c | |||
@@ -0,0 +1,318 @@ | |||
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 | * Copyright (C) 2013 Obsidian Research Corp | ||
10 | * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | ||
11 | * | ||
12 | * sysfs filesystem inspection interface to the TPM | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation, version 2 of the | ||
17 | * License. | ||
18 | * | ||
19 | */ | ||
20 | #include <linux/device.h> | ||
21 | #include "tpm.h" | ||
22 | |||
23 | /* XXX for now this helper is duplicated in tpm-interface.c */ | ||
24 | static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd, | ||
25 | int len, const char *desc) | ||
26 | { | ||
27 | int err; | ||
28 | |||
29 | len = tpm_transmit(chip, (u8 *) cmd, len); | ||
30 | if (len < 0) | ||
31 | return len; | ||
32 | else if (len < TPM_HEADER_SIZE) | ||
33 | return -EFAULT; | ||
34 | |||
35 | err = be32_to_cpu(cmd->header.out.return_code); | ||
36 | if (err != 0 && desc) | ||
37 | dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); | ||
38 | |||
39 | return err; | ||
40 | } | ||
41 | |||
42 | #define READ_PUBEK_RESULT_SIZE 314 | ||
43 | #define TPM_ORD_READPUBEK cpu_to_be32(124) | ||
44 | static struct tpm_input_header tpm_readpubek_header = { | ||
45 | .tag = TPM_TAG_RQU_COMMAND, | ||
46 | .length = cpu_to_be32(30), | ||
47 | .ordinal = TPM_ORD_READPUBEK | ||
48 | }; | ||
49 | static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, | ||
50 | char *buf) | ||
51 | { | ||
52 | u8 *data; | ||
53 | struct tpm_cmd_t tpm_cmd; | ||
54 | ssize_t err; | ||
55 | int i, rc; | ||
56 | char *str = buf; | ||
57 | |||
58 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
59 | |||
60 | tpm_cmd.header.in = tpm_readpubek_header; | ||
61 | err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, | ||
62 | "attempting to read the PUBEK"); | ||
63 | if (err) | ||
64 | goto out; | ||
65 | |||
66 | /* | ||
67 | ignore header 10 bytes | ||
68 | algorithm 32 bits (1 == RSA ) | ||
69 | encscheme 16 bits | ||
70 | sigscheme 16 bits | ||
71 | parameters (RSA 12->bytes: keybit, #primes, expbit) | ||
72 | keylenbytes 32 bits | ||
73 | 256 byte modulus | ||
74 | ignore checksum 20 bytes | ||
75 | */ | ||
76 | data = tpm_cmd.params.readpubek_out_buffer; | ||
77 | str += | ||
78 | sprintf(str, | ||
79 | "Algorithm: %02X %02X %02X %02X\n" | ||
80 | "Encscheme: %02X %02X\n" | ||
81 | "Sigscheme: %02X %02X\n" | ||
82 | "Parameters: %02X %02X %02X %02X " | ||
83 | "%02X %02X %02X %02X " | ||
84 | "%02X %02X %02X %02X\n" | ||
85 | "Modulus length: %d\n" | ||
86 | "Modulus:\n", | ||
87 | data[0], data[1], data[2], data[3], | ||
88 | data[4], data[5], | ||
89 | data[6], data[7], | ||
90 | data[12], data[13], data[14], data[15], | ||
91 | data[16], data[17], data[18], data[19], | ||
92 | data[20], data[21], data[22], data[23], | ||
93 | be32_to_cpu(*((__be32 *) (data + 24)))); | ||
94 | |||
95 | for (i = 0; i < 256; i++) { | ||
96 | str += sprintf(str, "%02X ", data[i + 28]); | ||
97 | if ((i + 1) % 16 == 0) | ||
98 | str += sprintf(str, "\n"); | ||
99 | } | ||
100 | out: | ||
101 | rc = str - buf; | ||
102 | return rc; | ||
103 | } | ||
104 | static DEVICE_ATTR_RO(pubek); | ||
105 | |||
106 | static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr, | ||
107 | char *buf) | ||
108 | { | ||
109 | cap_t cap; | ||
110 | u8 digest[TPM_DIGEST_SIZE]; | ||
111 | ssize_t rc; | ||
112 | int i, j, num_pcrs; | ||
113 | char *str = buf; | ||
114 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
115 | |||
116 | rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap, | ||
117 | "attempting to determine the number of PCRS"); | ||
118 | if (rc) | ||
119 | return 0; | ||
120 | |||
121 | num_pcrs = be32_to_cpu(cap.num_pcrs); | ||
122 | for (i = 0; i < num_pcrs; i++) { | ||
123 | rc = tpm_pcr_read_dev(chip, i, digest); | ||
124 | if (rc) | ||
125 | break; | ||
126 | str += sprintf(str, "PCR-%02d: ", i); | ||
127 | for (j = 0; j < TPM_DIGEST_SIZE; j++) | ||
128 | str += sprintf(str, "%02X ", digest[j]); | ||
129 | str += sprintf(str, "\n"); | ||
130 | } | ||
131 | return str - buf; | ||
132 | } | ||
133 | static DEVICE_ATTR_RO(pcrs); | ||
134 | |||
135 | static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, | ||
136 | char *buf) | ||
137 | { | ||
138 | cap_t cap; | ||
139 | ssize_t rc; | ||
140 | |||
141 | rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, | ||
142 | "attempting to determine the permanent enabled state"); | ||
143 | if (rc) | ||
144 | return 0; | ||
145 | |||
146 | rc = sprintf(buf, "%d\n", !cap.perm_flags.disable); | ||
147 | return rc; | ||
148 | } | ||
149 | static DEVICE_ATTR_RO(enabled); | ||
150 | |||
151 | static ssize_t active_show(struct device *dev, struct device_attribute *attr, | ||
152 | char *buf) | ||
153 | { | ||
154 | cap_t cap; | ||
155 | ssize_t rc; | ||
156 | |||
157 | rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap, | ||
158 | "attempting to determine the permanent active state"); | ||
159 | if (rc) | ||
160 | return 0; | ||
161 | |||
162 | rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated); | ||
163 | return rc; | ||
164 | } | ||
165 | static DEVICE_ATTR_RO(active); | ||
166 | |||
167 | static ssize_t owned_show(struct device *dev, struct device_attribute *attr, | ||
168 | char *buf) | ||
169 | { | ||
170 | cap_t cap; | ||
171 | ssize_t rc; | ||
172 | |||
173 | rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap, | ||
174 | "attempting to determine the owner state"); | ||
175 | if (rc) | ||
176 | return 0; | ||
177 | |||
178 | rc = sprintf(buf, "%d\n", cap.owned); | ||
179 | return rc; | ||
180 | } | ||
181 | static DEVICE_ATTR_RO(owned); | ||
182 | |||
183 | static ssize_t temp_deactivated_show(struct device *dev, | ||
184 | struct device_attribute *attr, char *buf) | ||
185 | { | ||
186 | cap_t cap; | ||
187 | ssize_t rc; | ||
188 | |||
189 | rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap, | ||
190 | "attempting to determine the temporary state"); | ||
191 | if (rc) | ||
192 | return 0; | ||
193 | |||
194 | rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated); | ||
195 | return rc; | ||
196 | } | ||
197 | static DEVICE_ATTR_RO(temp_deactivated); | ||
198 | |||
199 | static ssize_t caps_show(struct device *dev, struct device_attribute *attr, | ||
200 | char *buf) | ||
201 | { | ||
202 | cap_t cap; | ||
203 | ssize_t rc; | ||
204 | char *str = buf; | ||
205 | |||
206 | rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap, | ||
207 | "attempting to determine the manufacturer"); | ||
208 | if (rc) | ||
209 | return 0; | ||
210 | str += sprintf(str, "Manufacturer: 0x%x\n", | ||
211 | be32_to_cpu(cap.manufacturer_id)); | ||
212 | |||
213 | /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ | ||
214 | rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap, | ||
215 | "attempting to determine the 1.2 version"); | ||
216 | if (!rc) { | ||
217 | str += sprintf(str, | ||
218 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
219 | cap.tpm_version_1_2.Major, | ||
220 | cap.tpm_version_1_2.Minor, | ||
221 | cap.tpm_version_1_2.revMajor, | ||
222 | cap.tpm_version_1_2.revMinor); | ||
223 | } else { | ||
224 | /* Otherwise just use TPM_STRUCT_VER */ | ||
225 | rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap, | ||
226 | "attempting to determine the 1.1 version"); | ||
227 | if (rc) | ||
228 | return 0; | ||
229 | str += sprintf(str, | ||
230 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
231 | cap.tpm_version.Major, | ||
232 | cap.tpm_version.Minor, | ||
233 | cap.tpm_version.revMajor, | ||
234 | cap.tpm_version.revMinor); | ||
235 | } | ||
236 | |||
237 | return str - buf; | ||
238 | } | ||
239 | static DEVICE_ATTR_RO(caps); | ||
240 | |||
241 | static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, | ||
242 | const char *buf, size_t count) | ||
243 | { | ||
244 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
245 | if (chip == NULL) | ||
246 | return 0; | ||
247 | |||
248 | chip->ops->cancel(chip); | ||
249 | return count; | ||
250 | } | ||
251 | static DEVICE_ATTR_WO(cancel); | ||
252 | |||
253 | static ssize_t durations_show(struct device *dev, struct device_attribute *attr, | ||
254 | char *buf) | ||
255 | { | ||
256 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
257 | |||
258 | if (chip->vendor.duration[TPM_LONG] == 0) | ||
259 | return 0; | ||
260 | |||
261 | return sprintf(buf, "%d %d %d [%s]\n", | ||
262 | jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), | ||
263 | jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), | ||
264 | jiffies_to_usecs(chip->vendor.duration[TPM_LONG]), | ||
265 | chip->vendor.duration_adjusted | ||
266 | ? "adjusted" : "original"); | ||
267 | } | ||
268 | static DEVICE_ATTR_RO(durations); | ||
269 | |||
270 | static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, | ||
271 | char *buf) | ||
272 | { | ||
273 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
274 | |||
275 | return sprintf(buf, "%d %d %d %d [%s]\n", | ||
276 | jiffies_to_usecs(chip->vendor.timeout_a), | ||
277 | jiffies_to_usecs(chip->vendor.timeout_b), | ||
278 | jiffies_to_usecs(chip->vendor.timeout_c), | ||
279 | jiffies_to_usecs(chip->vendor.timeout_d), | ||
280 | chip->vendor.timeout_adjusted | ||
281 | ? "adjusted" : "original"); | ||
282 | } | ||
283 | static DEVICE_ATTR_RO(timeouts); | ||
284 | |||
285 | static struct attribute *tpm_dev_attrs[] = { | ||
286 | &dev_attr_pubek.attr, | ||
287 | &dev_attr_pcrs.attr, | ||
288 | &dev_attr_enabled.attr, | ||
289 | &dev_attr_active.attr, | ||
290 | &dev_attr_owned.attr, | ||
291 | &dev_attr_temp_deactivated.attr, | ||
292 | &dev_attr_caps.attr, | ||
293 | &dev_attr_cancel.attr, | ||
294 | &dev_attr_durations.attr, | ||
295 | &dev_attr_timeouts.attr, | ||
296 | NULL, | ||
297 | }; | ||
298 | |||
299 | static const struct attribute_group tpm_dev_group = { | ||
300 | .attrs = tpm_dev_attrs, | ||
301 | }; | ||
302 | |||
303 | int tpm_sysfs_add_device(struct tpm_chip *chip) | ||
304 | { | ||
305 | int err; | ||
306 | err = sysfs_create_group(&chip->dev->kobj, | ||
307 | &tpm_dev_group); | ||
308 | |||
309 | if (err) | ||
310 | dev_err(chip->dev, | ||
311 | "failed to create sysfs attributes, %d\n", err); | ||
312 | return err; | ||
313 | } | ||
314 | |||
315 | void tpm_sysfs_del_device(struct tpm_chip *chip) | ||
316 | { | ||
317 | sysfs_remove_group(&chip->dev->kobj, &tpm_dev_group); | ||
318 | } | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index f32847872193..e4d0888d2eab 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 */ | ||
50 | enum 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 |
@@ -53,33 +61,9 @@ enum tpm_addr { | |||
53 | #define TPM_ERR_INVALID_POSTINIT 38 | 61 | #define TPM_ERR_INVALID_POSTINIT 38 |
54 | 62 | ||
55 | #define TPM_HEADER_SIZE 10 | 63 | #define TPM_HEADER_SIZE 10 |
56 | extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, | ||
57 | char *); | ||
58 | extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, | ||
59 | char *); | ||
60 | extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, | ||
61 | char *); | ||
62 | extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, | ||
63 | const char *, size_t); | ||
64 | extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, | ||
65 | char *); | ||
66 | extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr, | ||
67 | char *); | ||
68 | extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, | ||
69 | char *); | ||
70 | extern ssize_t tpm_show_temp_deactivated(struct device *, | ||
71 | struct device_attribute *attr, char *); | ||
72 | extern ssize_t tpm_show_durations(struct device *, | ||
73 | struct device_attribute *attr, char *); | ||
74 | extern ssize_t tpm_show_timeouts(struct device *, | ||
75 | struct device_attribute *attr, char *); | ||
76 | |||
77 | struct tpm_chip; | 64 | struct tpm_chip; |
78 | 65 | ||
79 | struct tpm_vendor_specific { | 66 | struct tpm_vendor_specific { |
80 | const u8 req_complete_mask; | ||
81 | const u8 req_complete_val; | ||
82 | bool (*req_canceled)(struct tpm_chip *chip, u8 status); | ||
83 | void __iomem *iobase; /* ioremapped address */ | 67 | void __iomem *iobase; /* ioremapped address */ |
84 | unsigned long base; /* TPM base address */ | 68 | unsigned long base; /* TPM base address */ |
85 | 69 | ||
@@ -89,13 +73,7 @@ struct tpm_vendor_specific { | |||
89 | int region_size; | 73 | int region_size; |
90 | int have_region; | 74 | int have_region; |
91 | 75 | ||
92 | int (*recv) (struct tpm_chip *, u8 *, size_t); | ||
93 | int (*send) (struct tpm_chip *, u8 *, size_t); | ||
94 | void (*cancel) (struct tpm_chip *); | ||
95 | u8 (*status) (struct tpm_chip *); | ||
96 | void (*release) (struct device *); | ||
97 | struct miscdevice miscdev; | 76 | struct miscdevice miscdev; |
98 | struct attribute_group *attr_group; | ||
99 | struct list_head list; | 77 | struct list_head list; |
100 | int locality; | 78 | int locality; |
101 | unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */ | 79 | unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */ |
@@ -118,19 +96,13 @@ struct tpm_vendor_specific { | |||
118 | 96 | ||
119 | struct tpm_chip { | 97 | struct tpm_chip { |
120 | struct device *dev; /* Device stuff */ | 98 | struct device *dev; /* Device stuff */ |
99 | const struct tpm_class_ops *ops; | ||
121 | 100 | ||
122 | int dev_num; /* /dev/tpm# */ | 101 | int dev_num; /* /dev/tpm# */ |
123 | char devname[7]; | 102 | char devname[7]; |
124 | unsigned long is_open; /* only one allowed */ | 103 | unsigned long is_open; /* only one allowed */ |
125 | int time_expired; | 104 | int time_expired; |
126 | 105 | ||
127 | /* Data passed to and from the tpm via the read/write calls */ | ||
128 | u8 *data_buffer; | ||
129 | atomic_t data_pending; | ||
130 | struct mutex buffer_mutex; | ||
131 | |||
132 | struct timer_list user_read_timer; /* user needs to claim result */ | ||
133 | struct work_struct work; | ||
134 | struct mutex tpm_mutex; /* tpm is processing */ | 106 | struct mutex tpm_mutex; /* tpm is processing */ |
135 | 107 | ||
136 | struct tpm_vendor_specific vendor; | 108 | struct tpm_vendor_specific vendor; |
@@ -171,6 +143,8 @@ struct tpm_output_header { | |||
171 | __be32 return_code; | 143 | __be32 return_code; |
172 | } __packed; | 144 | } __packed; |
173 | 145 | ||
146 | #define TPM_TAG_RQU_COMMAND cpu_to_be16(193) | ||
147 | |||
174 | struct stclear_flags_t { | 148 | struct stclear_flags_t { |
175 | __be16 tag; | 149 | __be16 tag; |
176 | u8 deactivated; | 150 | u8 deactivated; |
@@ -244,6 +218,24 @@ typedef union { | |||
244 | struct duration_t duration; | 218 | struct duration_t duration; |
245 | } cap_t; | 219 | } cap_t; |
246 | 220 | ||
221 | enum tpm_capabilities { | ||
222 | TPM_CAP_FLAG = cpu_to_be32(4), | ||
223 | TPM_CAP_PROP = cpu_to_be32(5), | ||
224 | CAP_VERSION_1_1 = cpu_to_be32(0x06), | ||
225 | CAP_VERSION_1_2 = cpu_to_be32(0x1A) | ||
226 | }; | ||
227 | |||
228 | enum tpm_sub_capabilities { | ||
229 | TPM_CAP_PROP_PCR = cpu_to_be32(0x101), | ||
230 | TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103), | ||
231 | TPM_CAP_FLAG_PERM = cpu_to_be32(0x108), | ||
232 | TPM_CAP_FLAG_VOL = cpu_to_be32(0x109), | ||
233 | TPM_CAP_PROP_OWNER = cpu_to_be32(0x111), | ||
234 | TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115), | ||
235 | TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120), | ||
236 | |||
237 | }; | ||
238 | |||
247 | struct tpm_getcap_params_in { | 239 | struct tpm_getcap_params_in { |
248 | __be32 cap; | 240 | __be32 cap; |
249 | __be32 subcap_size; | 241 | __be32 subcap_size; |
@@ -323,25 +315,28 @@ struct tpm_cmd_t { | |||
323 | 315 | ||
324 | ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); | 316 | ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); |
325 | 317 | ||
318 | ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | ||
319 | size_t bufsiz); | ||
326 | extern int tpm_get_timeouts(struct tpm_chip *); | 320 | extern int tpm_get_timeouts(struct tpm_chip *); |
327 | extern void tpm_gen_interrupt(struct tpm_chip *); | 321 | extern void tpm_gen_interrupt(struct tpm_chip *); |
328 | extern int tpm_do_selftest(struct tpm_chip *); | 322 | extern int tpm_do_selftest(struct tpm_chip *); |
329 | extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); | 323 | extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); |
330 | extern struct tpm_chip* tpm_register_hardware(struct device *, | 324 | extern struct tpm_chip* tpm_register_hardware(struct device *, |
331 | const struct tpm_vendor_specific *); | 325 | const struct tpm_class_ops *ops); |
332 | extern int tpm_open(struct inode *, struct file *); | ||
333 | extern int tpm_release(struct inode *, struct file *); | ||
334 | extern void tpm_dev_release(struct device *dev); | ||
335 | extern void tpm_dev_vendor_release(struct tpm_chip *); | 326 | extern void tpm_dev_vendor_release(struct tpm_chip *); |
336 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | ||
337 | loff_t *); | ||
338 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); | ||
339 | extern void tpm_remove_hardware(struct device *); | 327 | extern void tpm_remove_hardware(struct device *); |
340 | extern int tpm_pm_suspend(struct device *); | 328 | extern int tpm_pm_suspend(struct device *); |
341 | extern int tpm_pm_resume(struct device *); | 329 | extern int tpm_pm_resume(struct device *); |
342 | extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, | 330 | extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, |
343 | wait_queue_head_t *, bool); | 331 | wait_queue_head_t *, bool); |
344 | 332 | ||
333 | int tpm_dev_add_device(struct tpm_chip *chip); | ||
334 | void tpm_dev_del_device(struct tpm_chip *chip); | ||
335 | int tpm_sysfs_add_device(struct tpm_chip *chip); | ||
336 | void tpm_sysfs_del_device(struct tpm_chip *chip); | ||
337 | |||
338 | int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); | ||
339 | |||
345 | #ifdef CONFIG_ACPI | 340 | #ifdef CONFIG_ACPI |
346 | extern int tpm_add_ppi(struct kobject *); | 341 | extern int tpm_add_ppi(struct kobject *); |
347 | extern void tpm_remove_ppi(struct kobject *); | 342 | extern void tpm_remove_ppi(struct kobject *); |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index c9a528d25d22..6069d13ae4ac 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -121,31 +121,7 @@ static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status) | |||
121 | return (status == ATML_STATUS_READY); | 121 | return (status == ATML_STATUS_READY); |
122 | } | 122 | } |
123 | 123 | ||
124 | static const struct file_operations atmel_ops = { | 124 | static const struct tpm_class_ops tpm_atmel = { |
125 | .owner = THIS_MODULE, | ||
126 | .llseek = no_llseek, | ||
127 | .open = tpm_open, | ||
128 | .read = tpm_read, | ||
129 | .write = tpm_write, | ||
130 | .release = tpm_release, | ||
131 | }; | ||
132 | |||
133 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
134 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
135 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
136 | static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel); | ||
137 | |||
138 | static struct attribute* atmel_attrs[] = { | ||
139 | &dev_attr_pubek.attr, | ||
140 | &dev_attr_pcrs.attr, | ||
141 | &dev_attr_caps.attr, | ||
142 | &dev_attr_cancel.attr, | ||
143 | NULL, | ||
144 | }; | ||
145 | |||
146 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; | ||
147 | |||
148 | static const struct tpm_vendor_specific tpm_atmel = { | ||
149 | .recv = tpm_atml_recv, | 125 | .recv = tpm_atml_recv, |
150 | .send = tpm_atml_send, | 126 | .send = tpm_atml_send, |
151 | .cancel = tpm_atml_cancel, | 127 | .cancel = tpm_atml_cancel, |
@@ -153,8 +129,6 @@ static const struct tpm_vendor_specific tpm_atmel = { | |||
153 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, | 129 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, |
154 | .req_complete_val = ATML_STATUS_DATA_AVAIL, | 130 | .req_complete_val = ATML_STATUS_DATA_AVAIL, |
155 | .req_canceled = tpm_atml_req_canceled, | 131 | .req_canceled = tpm_atml_req_canceled, |
156 | .attr_group = &atmel_attr_grp, | ||
157 | .miscdev = { .fops = &atmel_ops, }, | ||
158 | }; | 132 | }; |
159 | 133 | ||
160 | static struct platform_device *pdev; | 134 | static struct platform_device *pdev; |
diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index c3cd7fe481a1..77272925dee6 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c | |||
@@ -135,50 +135,12 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip) | |||
135 | return ATMEL_STS_OK; | 135 | return ATMEL_STS_OK; |
136 | } | 136 | } |
137 | 137 | ||
138 | static const struct file_operations i2c_atmel_ops = { | ||
139 | .owner = THIS_MODULE, | ||
140 | .llseek = no_llseek, | ||
141 | .open = tpm_open, | ||
142 | .read = tpm_read, | ||
143 | .write = tpm_write, | ||
144 | .release = tpm_release, | ||
145 | }; | ||
146 | |||
147 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
148 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
149 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
150 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
151 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
152 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
153 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
154 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
155 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
156 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
157 | |||
158 | static struct attribute *i2c_atmel_attrs[] = { | ||
159 | &dev_attr_pubek.attr, | ||
160 | &dev_attr_pcrs.attr, | ||
161 | &dev_attr_enabled.attr, | ||
162 | &dev_attr_active.attr, | ||
163 | &dev_attr_owned.attr, | ||
164 | &dev_attr_temp_deactivated.attr, | ||
165 | &dev_attr_caps.attr, | ||
166 | &dev_attr_cancel.attr, | ||
167 | &dev_attr_durations.attr, | ||
168 | &dev_attr_timeouts.attr, | ||
169 | NULL, | ||
170 | }; | ||
171 | |||
172 | static struct attribute_group i2c_atmel_attr_grp = { | ||
173 | .attrs = i2c_atmel_attrs | ||
174 | }; | ||
175 | |||
176 | static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status) | 138 | static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status) |
177 | { | 139 | { |
178 | return 0; | 140 | return false; |
179 | } | 141 | } |
180 | 142 | ||
181 | static const struct tpm_vendor_specific i2c_atmel = { | 143 | static const struct tpm_class_ops i2c_atmel = { |
182 | .status = i2c_atmel_read_status, | 144 | .status = i2c_atmel_read_status, |
183 | .recv = i2c_atmel_recv, | 145 | .recv = i2c_atmel_recv, |
184 | .send = i2c_atmel_send, | 146 | .send = i2c_atmel_send, |
@@ -186,8 +148,6 @@ static const struct tpm_vendor_specific i2c_atmel = { | |||
186 | .req_complete_mask = ATMEL_STS_OK, | 148 | .req_complete_mask = ATMEL_STS_OK, |
187 | .req_complete_val = ATMEL_STS_OK, | 149 | .req_complete_val = ATMEL_STS_OK, |
188 | .req_canceled = i2c_atmel_req_canceled, | 150 | .req_canceled = i2c_atmel_req_canceled, |
189 | .attr_group = &i2c_atmel_attr_grp, | ||
190 | .miscdev.fops = &i2c_atmel_ops, | ||
191 | }; | 151 | }; |
192 | 152 | ||
193 | static int i2c_atmel_probe(struct i2c_client *client, | 153 | static int i2c_atmel_probe(struct i2c_client *client, |
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index fefd2aa5c81e..52b9b2b2f300 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c | |||
@@ -566,45 +566,7 @@ static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status) | |||
566 | return (status == TPM_STS_COMMAND_READY); | 566 | return (status == TPM_STS_COMMAND_READY); |
567 | } | 567 | } |
568 | 568 | ||
569 | static const struct file_operations tis_ops = { | 569 | static const struct tpm_class_ops tpm_tis_i2c = { |
570 | .owner = THIS_MODULE, | ||
571 | .llseek = no_llseek, | ||
572 | .open = tpm_open, | ||
573 | .read = tpm_read, | ||
574 | .write = tpm_write, | ||
575 | .release = tpm_release, | ||
576 | }; | ||
577 | |||
578 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
579 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
580 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
581 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
582 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
583 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
584 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
585 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
586 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
587 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
588 | |||
589 | static struct attribute *tis_attrs[] = { | ||
590 | &dev_attr_pubek.attr, | ||
591 | &dev_attr_pcrs.attr, | ||
592 | &dev_attr_enabled.attr, | ||
593 | &dev_attr_active.attr, | ||
594 | &dev_attr_owned.attr, | ||
595 | &dev_attr_temp_deactivated.attr, | ||
596 | &dev_attr_caps.attr, | ||
597 | &dev_attr_cancel.attr, | ||
598 | &dev_attr_durations.attr, | ||
599 | &dev_attr_timeouts.attr, | ||
600 | NULL, | ||
601 | }; | ||
602 | |||
603 | static struct attribute_group tis_attr_grp = { | ||
604 | .attrs = tis_attrs | ||
605 | }; | ||
606 | |||
607 | static struct tpm_vendor_specific tpm_tis_i2c = { | ||
608 | .status = tpm_tis_i2c_status, | 570 | .status = tpm_tis_i2c_status, |
609 | .recv = tpm_tis_i2c_recv, | 571 | .recv = tpm_tis_i2c_recv, |
610 | .send = tpm_tis_i2c_send, | 572 | .send = tpm_tis_i2c_send, |
@@ -612,8 +574,6 @@ static struct tpm_vendor_specific tpm_tis_i2c = { | |||
612 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 574 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
613 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 575 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
614 | .req_canceled = tpm_tis_i2c_req_canceled, | 576 | .req_canceled = tpm_tis_i2c_req_canceled, |
615 | .attr_group = &tis_attr_grp, | ||
616 | .miscdev.fops = &tis_ops, | ||
617 | }; | 577 | }; |
618 | 578 | ||
619 | static int tpm_tis_i2c_init(struct device *dev) | 579 | static int tpm_tis_i2c_init(struct device *dev) |
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index 6276fea01ff0..7b158efd49f7 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c | |||
@@ -178,7 +178,6 @@ static int i2c_nuvoton_wait_for_stat(struct tpm_chip *chip, u8 mask, u8 value, | |||
178 | { | 178 | { |
179 | if (chip->vendor.irq && queue) { | 179 | if (chip->vendor.irq && queue) { |
180 | s32 rc; | 180 | s32 rc; |
181 | DEFINE_WAIT(wait); | ||
182 | struct priv_data *priv = chip->vendor.priv; | 181 | struct priv_data *priv = chip->vendor.priv; |
183 | unsigned int cur_intrs = priv->intrs; | 182 | unsigned int cur_intrs = priv->intrs; |
184 | 183 | ||
@@ -456,45 +455,7 @@ static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status) | |||
456 | return (status == TPM_STS_COMMAND_READY); | 455 | return (status == TPM_STS_COMMAND_READY); |
457 | } | 456 | } |
458 | 457 | ||
459 | static const struct file_operations i2c_nuvoton_ops = { | 458 | static const struct tpm_class_ops tpm_i2c = { |
460 | .owner = THIS_MODULE, | ||
461 | .llseek = no_llseek, | ||
462 | .open = tpm_open, | ||
463 | .read = tpm_read, | ||
464 | .write = tpm_write, | ||
465 | .release = tpm_release, | ||
466 | }; | ||
467 | |||
468 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
469 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
470 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
471 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
472 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
473 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
474 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
475 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
476 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
477 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
478 | |||
479 | static struct attribute *i2c_nuvoton_attrs[] = { | ||
480 | &dev_attr_pubek.attr, | ||
481 | &dev_attr_pcrs.attr, | ||
482 | &dev_attr_enabled.attr, | ||
483 | &dev_attr_active.attr, | ||
484 | &dev_attr_owned.attr, | ||
485 | &dev_attr_temp_deactivated.attr, | ||
486 | &dev_attr_caps.attr, | ||
487 | &dev_attr_cancel.attr, | ||
488 | &dev_attr_durations.attr, | ||
489 | &dev_attr_timeouts.attr, | ||
490 | NULL, | ||
491 | }; | ||
492 | |||
493 | static struct attribute_group i2c_nuvoton_attr_grp = { | ||
494 | .attrs = i2c_nuvoton_attrs | ||
495 | }; | ||
496 | |||
497 | static const struct tpm_vendor_specific tpm_i2c = { | ||
498 | .status = i2c_nuvoton_read_status, | 459 | .status = i2c_nuvoton_read_status, |
499 | .recv = i2c_nuvoton_recv, | 460 | .recv = i2c_nuvoton_recv, |
500 | .send = i2c_nuvoton_send, | 461 | .send = i2c_nuvoton_send, |
@@ -502,8 +463,6 @@ static const struct tpm_vendor_specific tpm_i2c = { | |||
502 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 463 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
503 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 464 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
504 | .req_canceled = i2c_nuvoton_req_canceled, | 465 | .req_canceled = i2c_nuvoton_req_canceled, |
505 | .attr_group = &i2c_nuvoton_attr_grp, | ||
506 | .miscdev.fops = &i2c_nuvoton_ops, | ||
507 | }; | 466 | }; |
508 | 467 | ||
509 | /* The only purpose for the handler is to signal to any waiting threads that | 468 | /* The only purpose for the handler is to signal to any waiting threads that |
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index a0d6ceb5d005..5b0dd8ef74c0 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c | |||
@@ -410,6 +410,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) | |||
410 | &chip->vendor.read_queue) | 410 | &chip->vendor.read_queue) |
411 | == 0) { | 411 | == 0) { |
412 | burstcnt = get_burstcount(chip); | 412 | burstcnt = get_burstcount(chip); |
413 | if (burstcnt < 0) | ||
414 | return burstcnt; | ||
413 | len = min_t(int, burstcnt, count - size); | 415 | len = min_t(int, burstcnt, count - size); |
414 | I2C_READ_DATA(client, TPM_DATA_FIFO, buf + size, len); | 416 | I2C_READ_DATA(client, TPM_DATA_FIFO, buf + size, len); |
415 | size += len; | 417 | size += len; |
@@ -451,7 +453,8 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) | |||
451 | static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, | 453 | static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, |
452 | size_t len) | 454 | size_t len) |
453 | { | 455 | { |
454 | u32 status, burstcnt = 0, i, size; | 456 | u32 status, i, size; |
457 | int burstcnt = 0; | ||
455 | int ret; | 458 | int ret; |
456 | u8 data; | 459 | u8 data; |
457 | struct i2c_client *client; | 460 | struct i2c_client *client; |
@@ -482,6 +485,8 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, | |||
482 | 485 | ||
483 | for (i = 0; i < len - 1;) { | 486 | for (i = 0; i < len - 1;) { |
484 | burstcnt = get_burstcount(chip); | 487 | burstcnt = get_burstcount(chip); |
488 | if (burstcnt < 0) | ||
489 | return burstcnt; | ||
485 | size = min_t(int, len - i - 1, burstcnt); | 490 | size = min_t(int, len - i - 1, burstcnt); |
486 | ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size); | 491 | ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size); |
487 | if (ret < 0) | 492 | if (ret < 0) |
@@ -559,7 +564,7 @@ static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf, | |||
559 | } | 564 | } |
560 | 565 | ||
561 | out: | 566 | out: |
562 | chip->vendor.cancel(chip); | 567 | chip->ops->cancel(chip); |
563 | release_locality(chip); | 568 | release_locality(chip); |
564 | return size; | 569 | return size; |
565 | } | 570 | } |
@@ -569,40 +574,7 @@ static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status) | |||
569 | return (status == TPM_STS_COMMAND_READY); | 574 | return (status == TPM_STS_COMMAND_READY); |
570 | } | 575 | } |
571 | 576 | ||
572 | static const struct file_operations tpm_st33_i2c_fops = { | 577 | static const struct tpm_class_ops st_i2c_tpm = { |
573 | .owner = THIS_MODULE, | ||
574 | .llseek = no_llseek, | ||
575 | .read = tpm_read, | ||
576 | .write = tpm_write, | ||
577 | .open = tpm_open, | ||
578 | .release = tpm_release, | ||
579 | }; | ||
580 | |||
581 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
582 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
583 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
584 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
585 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
586 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); | ||
587 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
588 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
589 | |||
590 | static struct attribute *stm_tpm_attrs[] = { | ||
591 | &dev_attr_pubek.attr, | ||
592 | &dev_attr_pcrs.attr, | ||
593 | &dev_attr_enabled.attr, | ||
594 | &dev_attr_active.attr, | ||
595 | &dev_attr_owned.attr, | ||
596 | &dev_attr_temp_deactivated.attr, | ||
597 | &dev_attr_caps.attr, | ||
598 | &dev_attr_cancel.attr, NULL, | ||
599 | }; | ||
600 | |||
601 | static struct attribute_group stm_tpm_attr_grp = { | ||
602 | .attrs = stm_tpm_attrs | ||
603 | }; | ||
604 | |||
605 | static struct tpm_vendor_specific st_i2c_tpm = { | ||
606 | .send = tpm_stm_i2c_send, | 578 | .send = tpm_stm_i2c_send, |
607 | .recv = tpm_stm_i2c_recv, | 579 | .recv = tpm_stm_i2c_recv, |
608 | .cancel = tpm_stm_i2c_cancel, | 580 | .cancel = tpm_stm_i2c_cancel, |
@@ -610,8 +582,6 @@ static struct tpm_vendor_specific st_i2c_tpm = { | |||
610 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 582 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
611 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 583 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
612 | .req_canceled = tpm_st33_i2c_req_canceled, | 584 | .req_canceled = tpm_st33_i2c_req_canceled, |
613 | .attr_group = &stm_tpm_attr_grp, | ||
614 | .miscdev = {.fops = &tpm_st33_i2c_fops,}, | ||
615 | }; | 585 | }; |
616 | 586 | ||
617 | static int interrupts; | 587 | static int interrupts; |
@@ -837,7 +807,7 @@ static int tpm_st33_i2c_pm_resume(struct device *dev) | |||
837 | if (power_mgt) { | 807 | if (power_mgt) { |
838 | gpio_set_value(pin_infos->io_lpcpd, 1); | 808 | gpio_set_value(pin_infos->io_lpcpd, 1); |
839 | ret = wait_for_serirq_timeout(chip, | 809 | ret = wait_for_serirq_timeout(chip, |
840 | (chip->vendor.status(chip) & | 810 | (chip->ops->status(chip) & |
841 | TPM_STS_VALID) == TPM_STS_VALID, | 811 | TPM_STS_VALID) == TPM_STS_VALID, |
842 | chip->vendor.timeout_b); | 812 | chip->vendor.timeout_b); |
843 | } else { | 813 | } else { |
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 2783a42aa732..af74c57e5090 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c | |||
@@ -403,43 +403,7 @@ static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status) | |||
403 | return (status == 0); | 403 | return (status == 0); |
404 | } | 404 | } |
405 | 405 | ||
406 | static const struct file_operations ibmvtpm_ops = { | 406 | static const struct tpm_class_ops tpm_ibmvtpm = { |
407 | .owner = THIS_MODULE, | ||
408 | .llseek = no_llseek, | ||
409 | .open = tpm_open, | ||
410 | .read = tpm_read, | ||
411 | .write = tpm_write, | ||
412 | .release = tpm_release, | ||
413 | }; | ||
414 | |||
415 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
416 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
417 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
418 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
419 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
420 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | ||
421 | NULL); | ||
422 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
423 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
424 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
425 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
426 | |||
427 | static struct attribute *ibmvtpm_attrs[] = { | ||
428 | &dev_attr_pubek.attr, | ||
429 | &dev_attr_pcrs.attr, | ||
430 | &dev_attr_enabled.attr, | ||
431 | &dev_attr_active.attr, | ||
432 | &dev_attr_owned.attr, | ||
433 | &dev_attr_temp_deactivated.attr, | ||
434 | &dev_attr_caps.attr, | ||
435 | &dev_attr_cancel.attr, | ||
436 | &dev_attr_durations.attr, | ||
437 | &dev_attr_timeouts.attr, NULL, | ||
438 | }; | ||
439 | |||
440 | static struct attribute_group ibmvtpm_attr_grp = { .attrs = ibmvtpm_attrs }; | ||
441 | |||
442 | static const struct tpm_vendor_specific tpm_ibmvtpm = { | ||
443 | .recv = tpm_ibmvtpm_recv, | 407 | .recv = tpm_ibmvtpm_recv, |
444 | .send = tpm_ibmvtpm_send, | 408 | .send = tpm_ibmvtpm_send, |
445 | .cancel = tpm_ibmvtpm_cancel, | 409 | .cancel = tpm_ibmvtpm_cancel, |
@@ -447,8 +411,6 @@ static const struct tpm_vendor_specific tpm_ibmvtpm = { | |||
447 | .req_complete_mask = 0, | 411 | .req_complete_mask = 0, |
448 | .req_complete_val = 0, | 412 | .req_complete_val = 0, |
449 | .req_canceled = tpm_ibmvtpm_req_canceled, | 413 | .req_canceled = tpm_ibmvtpm_req_canceled, |
450 | .attr_group = &ibmvtpm_attr_grp, | ||
451 | .miscdev = { .fops = &ibmvtpm_ops, }, | ||
452 | }; | 414 | }; |
453 | 415 | ||
454 | static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = { | 416 | static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = { |
@@ -507,7 +469,6 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq, | |||
507 | dev_err(ibmvtpm->dev, "Unknown crq message type: %d\n", crq->msg); | 469 | dev_err(ibmvtpm->dev, "Unknown crq message type: %d\n", crq->msg); |
508 | return; | 470 | return; |
509 | } | 471 | } |
510 | return; | ||
511 | case IBMVTPM_VALID_CMD: | 472 | case IBMVTPM_VALID_CMD: |
512 | switch (crq->msg) { | 473 | switch (crq->msg) { |
513 | case VTPM_GET_RTCE_BUFFER_SIZE_RES: | 474 | case VTPM_GET_RTCE_BUFFER_SIZE_RES: |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 2b480c2960bb..dc0a2554034e 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -371,39 +371,13 @@ static u8 tpm_inf_status(struct tpm_chip *chip) | |||
371 | return tpm_data_in(STAT); | 371 | return tpm_data_in(STAT); |
372 | } | 372 | } |
373 | 373 | ||
374 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 374 | static const struct tpm_class_ops tpm_inf = { |
375 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
376 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
377 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
378 | |||
379 | static struct attribute *inf_attrs[] = { | ||
380 | &dev_attr_pubek.attr, | ||
381 | &dev_attr_pcrs.attr, | ||
382 | &dev_attr_caps.attr, | ||
383 | &dev_attr_cancel.attr, | ||
384 | NULL, | ||
385 | }; | ||
386 | |||
387 | static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; | ||
388 | |||
389 | static const struct file_operations inf_ops = { | ||
390 | .owner = THIS_MODULE, | ||
391 | .llseek = no_llseek, | ||
392 | .open = tpm_open, | ||
393 | .read = tpm_read, | ||
394 | .write = tpm_write, | ||
395 | .release = tpm_release, | ||
396 | }; | ||
397 | |||
398 | static const struct tpm_vendor_specific tpm_inf = { | ||
399 | .recv = tpm_inf_recv, | 375 | .recv = tpm_inf_recv, |
400 | .send = tpm_inf_send, | 376 | .send = tpm_inf_send, |
401 | .cancel = tpm_inf_cancel, | 377 | .cancel = tpm_inf_cancel, |
402 | .status = tpm_inf_status, | 378 | .status = tpm_inf_status, |
403 | .req_complete_mask = 0, | 379 | .req_complete_mask = 0, |
404 | .req_complete_val = 0, | 380 | .req_complete_val = 0, |
405 | .attr_group = &inf_attr_grp, | ||
406 | .miscdev = {.fops = &inf_ops,}, | ||
407 | }; | 381 | }; |
408 | 382 | ||
409 | static const struct pnp_device_id tpm_inf_pnp_tbl[] = { | 383 | static const struct pnp_device_id tpm_inf_pnp_tbl[] = { |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 770c46f8eb30..3179ec9cffdc 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -232,31 +232,7 @@ static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status) | |||
232 | return (status == NSC_STATUS_RDY); | 232 | return (status == NSC_STATUS_RDY); |
233 | } | 233 | } |
234 | 234 | ||
235 | static const struct file_operations nsc_ops = { | 235 | static const struct tpm_class_ops tpm_nsc = { |
236 | .owner = THIS_MODULE, | ||
237 | .llseek = no_llseek, | ||
238 | .open = tpm_open, | ||
239 | .read = tpm_read, | ||
240 | .write = tpm_write, | ||
241 | .release = tpm_release, | ||
242 | }; | ||
243 | |||
244 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
245 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
246 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
247 | static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel); | ||
248 | |||
249 | static struct attribute * nsc_attrs[] = { | ||
250 | &dev_attr_pubek.attr, | ||
251 | &dev_attr_pcrs.attr, | ||
252 | &dev_attr_caps.attr, | ||
253 | &dev_attr_cancel.attr, | ||
254 | NULL, | ||
255 | }; | ||
256 | |||
257 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; | ||
258 | |||
259 | static const struct tpm_vendor_specific tpm_nsc = { | ||
260 | .recv = tpm_nsc_recv, | 236 | .recv = tpm_nsc_recv, |
261 | .send = tpm_nsc_send, | 237 | .send = tpm_nsc_send, |
262 | .cancel = tpm_nsc_cancel, | 238 | .cancel = tpm_nsc_cancel, |
@@ -264,8 +240,6 @@ static const struct tpm_vendor_specific tpm_nsc = { | |||
264 | .req_complete_mask = NSC_STATUS_OBF, | 240 | .req_complete_mask = NSC_STATUS_OBF, |
265 | .req_complete_val = NSC_STATUS_OBF, | 241 | .req_complete_val = NSC_STATUS_OBF, |
266 | .req_canceled = tpm_nsc_req_canceled, | 242 | .req_canceled = tpm_nsc_req_canceled, |
267 | .attr_group = &nsc_attr_grp, | ||
268 | .miscdev = { .fops = &nsc_ops, }, | ||
269 | }; | 243 | }; |
270 | 244 | ||
271 | static struct platform_device *pdev = NULL; | 245 | static struct platform_device *pdev = NULL; |
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index e1f3337a0cf9..2db4419831be 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
@@ -172,7 +172,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev, | |||
172 | * is updated with function index from SUBREQ to SUBREQ2 since PPI | 172 | * is updated with function index from SUBREQ to SUBREQ2 since PPI |
173 | * version 1.1 | 173 | * version 1.1 |
174 | */ | 174 | */ |
175 | if (strcmp(version, "1.1") == -1) | 175 | if (strcmp(version, "1.1") < 0) |
176 | params[2].integer.value = TPM_PPI_FN_SUBREQ; | 176 | params[2].integer.value = TPM_PPI_FN_SUBREQ; |
177 | else | 177 | else |
178 | params[2].integer.value = TPM_PPI_FN_SUBREQ2; | 178 | params[2].integer.value = TPM_PPI_FN_SUBREQ2; |
@@ -182,7 +182,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev, | |||
182 | * string/package type. For PPI version 1.0 and 1.1, use buffer type | 182 | * string/package type. For PPI version 1.0 and 1.1, use buffer type |
183 | * for compatibility, and use package type since 1.2 according to spec. | 183 | * for compatibility, and use package type since 1.2 according to spec. |
184 | */ | 184 | */ |
185 | if (strcmp(version, "1.2") == -1) { | 185 | if (strcmp(version, "1.2") < 0) { |
186 | params[3].type = ACPI_TYPE_BUFFER; | 186 | params[3].type = ACPI_TYPE_BUFFER; |
187 | params[3].buffer.length = sizeof(req); | 187 | params[3].buffer.length = sizeof(req); |
188 | sscanf(buf, "%d", &req); | 188 | sscanf(buf, "%d", &req); |
@@ -248,7 +248,7 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev, | |||
248 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for | 248 | * (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for |
249 | * compatibility, define params[3].type as buffer, if PPI version < 1.2 | 249 | * compatibility, define params[3].type as buffer, if PPI version < 1.2 |
250 | */ | 250 | */ |
251 | if (strcmp(version, "1.2") == -1) { | 251 | if (strcmp(version, "1.2") < 0) { |
252 | params[3].type = ACPI_TYPE_BUFFER; | 252 | params[3].type = ACPI_TYPE_BUFFER; |
253 | params[3].buffer.length = 0; | 253 | params[3].buffer.length = 0; |
254 | params[3].buffer.pointer = NULL; | 254 | params[3].buffer.pointer = NULL; |
@@ -390,7 +390,7 @@ static ssize_t show_ppi_operations(char *buf, u32 start, u32 end) | |||
390 | kfree(output.pointer); | 390 | kfree(output.pointer); |
391 | output.length = ACPI_ALLOCATE_BUFFER; | 391 | output.length = ACPI_ALLOCATE_BUFFER; |
392 | output.pointer = NULL; | 392 | output.pointer = NULL; |
393 | if (strcmp(version, "1.2") == -1) | 393 | if (strcmp(version, "1.2") < 0) |
394 | return -EPERM; | 394 | return -EPERM; |
395 | 395 | ||
396 | params[2].integer.value = TPM_PPI_FN_GETOPR; | 396 | params[2].integer.value = TPM_PPI_FN_GETOPR; |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 1b74459c0723..a9ed2270c25d 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -432,45 +432,7 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) | |||
432 | } | 432 | } |
433 | } | 433 | } |
434 | 434 | ||
435 | static const struct file_operations tis_ops = { | 435 | static const struct tpm_class_ops tpm_tis = { |
436 | .owner = THIS_MODULE, | ||
437 | .llseek = no_llseek, | ||
438 | .open = tpm_open, | ||
439 | .read = tpm_read, | ||
440 | .write = tpm_write, | ||
441 | .release = tpm_release, | ||
442 | }; | ||
443 | |||
444 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
445 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
446 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
447 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
448 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
449 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | ||
450 | NULL); | ||
451 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
452 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
453 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
454 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
455 | |||
456 | static struct attribute *tis_attrs[] = { | ||
457 | &dev_attr_pubek.attr, | ||
458 | &dev_attr_pcrs.attr, | ||
459 | &dev_attr_enabled.attr, | ||
460 | &dev_attr_active.attr, | ||
461 | &dev_attr_owned.attr, | ||
462 | &dev_attr_temp_deactivated.attr, | ||
463 | &dev_attr_caps.attr, | ||
464 | &dev_attr_cancel.attr, | ||
465 | &dev_attr_durations.attr, | ||
466 | &dev_attr_timeouts.attr, NULL, | ||
467 | }; | ||
468 | |||
469 | static struct attribute_group tis_attr_grp = { | ||
470 | .attrs = tis_attrs | ||
471 | }; | ||
472 | |||
473 | static struct tpm_vendor_specific tpm_tis = { | ||
474 | .status = tpm_tis_status, | 436 | .status = tpm_tis_status, |
475 | .recv = tpm_tis_recv, | 437 | .recv = tpm_tis_recv, |
476 | .send = tpm_tis_send, | 438 | .send = tpm_tis_send, |
@@ -478,9 +440,6 @@ static struct tpm_vendor_specific tpm_tis = { | |||
478 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 440 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
479 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | 441 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, |
480 | .req_canceled = tpm_tis_req_canceled, | 442 | .req_canceled = tpm_tis_req_canceled, |
481 | .attr_group = &tis_attr_grp, | ||
482 | .miscdev = { | ||
483 | .fops = &tis_ops,}, | ||
484 | }; | 443 | }; |
485 | 444 | ||
486 | static irqreturn_t tis_int_probe(int irq, void *dev_id) | 445 | static irqreturn_t tis_int_probe(int irq, void *dev_id) |
@@ -743,7 +702,7 @@ out_err: | |||
743 | return rc; | 702 | return rc; |
744 | } | 703 | } |
745 | 704 | ||
746 | #if defined(CONFIG_PNP) || defined(CONFIG_PM_SLEEP) | 705 | #ifdef CONFIG_PM_SLEEP |
747 | static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) | 706 | static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) |
748 | { | 707 | { |
749 | u32 intmask; | 708 | u32 intmask; |
@@ -764,9 +723,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) | |||
764 | iowrite32(intmask, | 723 | iowrite32(intmask, |
765 | chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); | 724 | chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); |
766 | } | 725 | } |
767 | #endif | ||
768 | 726 | ||
769 | #ifdef CONFIG_PM_SLEEP | ||
770 | static int tpm_tis_resume(struct device *dev) | 727 | static int tpm_tis_resume(struct device *dev) |
771 | { | 728 | { |
772 | struct tpm_chip *chip = dev_get_drvdata(dev); | 729 | struct tpm_chip *chip = dev_get_drvdata(dev); |
@@ -835,11 +792,9 @@ static struct pnp_driver tis_pnp_driver = { | |||
835 | .id_table = tpm_pnp_tbl, | 792 | .id_table = tpm_pnp_tbl, |
836 | .probe = tpm_tis_pnp_init, | 793 | .probe = tpm_tis_pnp_init, |
837 | .remove = tpm_tis_pnp_remove, | 794 | .remove = tpm_tis_pnp_remove, |
838 | #ifdef CONFIG_PM_SLEEP | ||
839 | .driver = { | 795 | .driver = { |
840 | .pm = &tpm_tis_pm, | 796 | .pm = &tpm_tis_pm, |
841 | }, | 797 | }, |
842 | #endif | ||
843 | }; | 798 | }; |
844 | 799 | ||
845 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 | 800 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 |
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index c8ff4df81779..92b097064df5 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c | |||
@@ -143,46 +143,7 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
143 | return length; | 143 | return length; |
144 | } | 144 | } |
145 | 145 | ||
146 | static const struct file_operations vtpm_ops = { | 146 | static const struct tpm_class_ops tpm_vtpm = { |
147 | .owner = THIS_MODULE, | ||
148 | .llseek = no_llseek, | ||
149 | .open = tpm_open, | ||
150 | .read = tpm_read, | ||
151 | .write = tpm_write, | ||
152 | .release = tpm_release, | ||
153 | }; | ||
154 | |||
155 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
156 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
157 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
158 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
159 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
160 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | ||
161 | NULL); | ||
162 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | ||
163 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
164 | static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL); | ||
165 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
166 | |||
167 | static struct attribute *vtpm_attrs[] = { | ||
168 | &dev_attr_pubek.attr, | ||
169 | &dev_attr_pcrs.attr, | ||
170 | &dev_attr_enabled.attr, | ||
171 | &dev_attr_active.attr, | ||
172 | &dev_attr_owned.attr, | ||
173 | &dev_attr_temp_deactivated.attr, | ||
174 | &dev_attr_caps.attr, | ||
175 | &dev_attr_cancel.attr, | ||
176 | &dev_attr_durations.attr, | ||
177 | &dev_attr_timeouts.attr, | ||
178 | NULL, | ||
179 | }; | ||
180 | |||
181 | static struct attribute_group vtpm_attr_grp = { | ||
182 | .attrs = vtpm_attrs, | ||
183 | }; | ||
184 | |||
185 | static const struct tpm_vendor_specific tpm_vtpm = { | ||
186 | .status = vtpm_status, | 147 | .status = vtpm_status, |
187 | .recv = vtpm_recv, | 148 | .recv = vtpm_recv, |
188 | .send = vtpm_send, | 149 | .send = vtpm_send, |
@@ -190,10 +151,6 @@ static const struct tpm_vendor_specific tpm_vtpm = { | |||
190 | .req_complete_mask = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, | 151 | .req_complete_mask = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, |
191 | .req_complete_val = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, | 152 | .req_complete_val = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT, |
192 | .req_canceled = vtpm_req_canceled, | 153 | .req_canceled = vtpm_req_canceled, |
193 | .attr_group = &vtpm_attr_grp, | ||
194 | .miscdev = { | ||
195 | .fops = &vtpm_ops, | ||
196 | }, | ||
197 | }; | 154 | }; |
198 | 155 | ||
199 | static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) | 156 | static irqreturn_t tpmif_interrupt(int dummy, void *dev_id) |