aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm
diff options
context:
space:
mode:
authorStefan Berger <stefanb@linux.vnet.ibm.com>2013-01-22 14:52:35 -0500
committerKent Yoder <key@linux.vnet.ibm.com>2013-02-05 10:38:24 -0500
commit1f866057291fc00f14e4962473bd7724ffa8f578 (patch)
treeea780b029f24530a32913fa983a60f1a01a4d0d4 /drivers/char/tpm
parent3e3a5e906998b090ad929010a5f5082ac0dbbdfb (diff)
tpm: Fix cancellation of TPM commands (polling mode)
On one of my machines the cancellation of TPM commands does not work. The reason is that by writing into sysfs 'cancel' the tpm_tis_ready call causes the status flag TPM_STS_VALID to be set in the statusregister. However, the TIS driver seems to wait for TPM_STS_COMMAND_READY. Once a 2nd time sysfs 'cancel' is written to, the TPM_STS_COMMAND_READY flag also gets set, resulting in TPM_STS_VALID|TPM_STS_COMMAND_READY to be read from the status register. This patch now converts req_canceled into a function to enable more complex comparisons against possible cancellation status codes. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com> Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r--drivers/char/tpm/tpm.c2
-rw-r--r--drivers/char/tpm/tpm.h4
-rw-r--r--drivers/char/tpm/tpm_atmel.c7
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c7
-rw-r--r--drivers/char/tpm/tpm_i2c_stm_st33.c7
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c7
-rw-r--r--drivers/char/tpm/tpm_nsc.c7
-rw-r--r--drivers/char/tpm/tpm_tis.c15
8 files changed, 48 insertions, 8 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index e38054b33bb4..a244cd3e7dbc 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -393,7 +393,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
393 chip->vendor.req_complete_val) 393 chip->vendor.req_complete_val)
394 goto out_recv; 394 goto out_recv;
395 395
396 if ((status == chip->vendor.req_canceled)) { 396 if (chip->vendor.req_canceled(chip, status)) {
397 dev_err(chip->dev, "Operation Canceled\n"); 397 dev_err(chip->dev, "Operation Canceled\n");
398 rc = -ECANCELED; 398 rc = -ECANCELED;
399 goto out; 399 goto out;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index ef4ba5fcf7d9..725cb9b657dd 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -78,7 +78,7 @@ struct tpm_chip;
78struct tpm_vendor_specific { 78struct tpm_vendor_specific {
79 const u8 req_complete_mask; 79 const u8 req_complete_mask;
80 const u8 req_complete_val; 80 const u8 req_complete_val;
81 const u8 req_canceled; 81 bool (*req_canceled)(struct tpm_chip *chip, u8 status);
82 void __iomem *iobase; /* ioremapped address */ 82 void __iomem *iobase; /* ioremapped address */
83 unsigned long base; /* TPM base address */ 83 unsigned long base; /* TPM base address */
84 84
@@ -112,6 +112,8 @@ struct tpm_vendor_specific {
112#define TPM_VPRIV(c) (c)->vendor.priv 112#define TPM_VPRIV(c) (c)->vendor.priv
113 113
114#define TPM_VID_INTEL 0x8086 114#define TPM_VID_INTEL 0x8086
115#define TPM_VID_WINBOND 0x1050
116#define TPM_VID_STM 0x104A
115 117
116struct tpm_chip { 118struct tpm_chip {
117 struct device *dev; /* Device stuff */ 119 struct device *dev; /* Device stuff */
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 678d57019dc4..99d6820c611d 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -116,6 +116,11 @@ static u8 tpm_atml_status(struct tpm_chip *chip)
116 return ioread8(chip->vendor.iobase + 1); 116 return ioread8(chip->vendor.iobase + 1);
117} 117}
118 118
119static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status)
120{
121 return (status == ATML_STATUS_READY);
122}
123
119static const struct file_operations atmel_ops = { 124static const struct file_operations atmel_ops = {
120 .owner = THIS_MODULE, 125 .owner = THIS_MODULE,
121 .llseek = no_llseek, 126 .llseek = no_llseek,
@@ -147,7 +152,7 @@ static const struct tpm_vendor_specific tpm_atmel = {
147 .status = tpm_atml_status, 152 .status = tpm_atml_status,
148 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, 153 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
149 .req_complete_val = ATML_STATUS_DATA_AVAIL, 154 .req_complete_val = ATML_STATUS_DATA_AVAIL,
150 .req_canceled = ATML_STATUS_READY, 155 .req_canceled = tpm_atml_req_canceled,
151 .attr_group = &atmel_attr_grp, 156 .attr_group = &atmel_attr_grp,
152 .miscdev = { .fops = &atmel_ops, }, 157 .miscdev = { .fops = &atmel_ops, },
153}; 158};
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index fb447bd0cb61..8fe7ac3d095b 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -505,6 +505,11 @@ out_err:
505 return rc; 505 return rc;
506} 506}
507 507
508static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status)
509{
510 return (status == TPM_STS_COMMAND_READY);
511}
512
508static const struct file_operations tis_ops = { 513static const struct file_operations tis_ops = {
509 .owner = THIS_MODULE, 514 .owner = THIS_MODULE,
510 .llseek = no_llseek, 515 .llseek = no_llseek,
@@ -550,7 +555,7 @@ static struct tpm_vendor_specific tpm_tis_i2c = {
550 .cancel = tpm_tis_i2c_ready, 555 .cancel = tpm_tis_i2c_ready,
551 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 556 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
552 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 557 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
553 .req_canceled = TPM_STS_COMMAND_READY, 558 .req_canceled = tpm_tis_i2c_req_canceled,
554 .attr_group = &tis_attr_grp, 559 .attr_group = &tis_attr_grp,
555 .miscdev.fops = &tis_ops, 560 .miscdev.fops = &tis_ops,
556}; 561};
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c
index 36524ed8ada9..e4154bfc8be7 100644
--- a/drivers/char/tpm/tpm_i2c_stm_st33.c
+++ b/drivers/char/tpm/tpm_i2c_stm_st33.c
@@ -587,6 +587,11 @@ out:
587 return size; 587 return size;
588} 588}
589 589
590static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status)
591{
592 return (status == TPM_STS_COMMAND_READY);
593}
594
590static const struct file_operations tpm_st33_i2c_fops = { 595static const struct file_operations tpm_st33_i2c_fops = {
591 .owner = THIS_MODULE, 596 .owner = THIS_MODULE,
592 .llseek = no_llseek, 597 .llseek = no_llseek,
@@ -627,7 +632,7 @@ static struct tpm_vendor_specific st_i2c_tpm = {
627 .status = tpm_stm_i2c_status, 632 .status = tpm_stm_i2c_status,
628 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 633 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
629 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 634 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
630 .req_canceled = TPM_STS_COMMAND_READY, 635 .req_canceled = tpm_st33_i2c_req_canceled,
631 .attr_group = &stm_tpm_attr_grp, 636 .attr_group = &stm_tpm_attr_grp,
632 .miscdev = {.fops = &tpm_st33_i2c_fops,}, 637 .miscdev = {.fops = &tpm_st33_i2c_fops,},
633}; 638};
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index 6cd99bc1c5d4..56b07c35a13e 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -398,6 +398,11 @@ static int tpm_ibmvtpm_resume(struct device *dev)
398 return rc; 398 return rc;
399} 399}
400 400
401static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status)
402{
403 return (status == 0);
404}
405
401static const struct file_operations ibmvtpm_ops = { 406static const struct file_operations ibmvtpm_ops = {
402 .owner = THIS_MODULE, 407 .owner = THIS_MODULE,
403 .llseek = no_llseek, 408 .llseek = no_llseek,
@@ -441,7 +446,7 @@ static const struct tpm_vendor_specific tpm_ibmvtpm = {
441 .status = tpm_ibmvtpm_status, 446 .status = tpm_ibmvtpm_status,
442 .req_complete_mask = 0, 447 .req_complete_mask = 0,
443 .req_complete_val = 0, 448 .req_complete_val = 0,
444 .req_canceled = 0, 449 .req_canceled = tpm_ibmvtpm_req_canceled,
445 .attr_group = &ibmvtpm_attr_grp, 450 .attr_group = &ibmvtpm_attr_grp,
446 .miscdev = { .fops = &ibmvtpm_ops, }, 451 .miscdev = { .fops = &ibmvtpm_ops, },
447}; 452};
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 640c9a427b59..770c46f8eb30 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -227,6 +227,11 @@ static u8 tpm_nsc_status(struct tpm_chip *chip)
227 return inb(chip->vendor.base + NSC_STATUS); 227 return inb(chip->vendor.base + NSC_STATUS);
228} 228}
229 229
230static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status)
231{
232 return (status == NSC_STATUS_RDY);
233}
234
230static const struct file_operations nsc_ops = { 235static const struct file_operations nsc_ops = {
231 .owner = THIS_MODULE, 236 .owner = THIS_MODULE,
232 .llseek = no_llseek, 237 .llseek = no_llseek,
@@ -258,7 +263,7 @@ static const struct tpm_vendor_specific tpm_nsc = {
258 .status = tpm_nsc_status, 263 .status = tpm_nsc_status,
259 .req_complete_mask = NSC_STATUS_OBF, 264 .req_complete_mask = NSC_STATUS_OBF,
260 .req_complete_val = NSC_STATUS_OBF, 265 .req_complete_val = NSC_STATUS_OBF,
261 .req_canceled = NSC_STATUS_RDY, 266 .req_canceled = tpm_nsc_req_canceled,
262 .attr_group = &nsc_attr_grp, 267 .attr_group = &nsc_attr_grp,
263 .miscdev = { .fops = &nsc_ops, }, 268 .miscdev = { .fops = &nsc_ops, },
264}; 269};
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 3615d210e603..e4e0c65df768 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -400,6 +400,19 @@ out:
400 return rc; 400 return rc;
401} 401}
402 402
403static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
404{
405 switch (chip->vendor.manufacturer_id) {
406 case TPM_VID_WINBOND:
407 return ((status == TPM_STS_VALID) ||
408 (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
409 case TPM_VID_STM:
410 return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY));
411 default:
412 return (status == TPM_STS_COMMAND_READY);
413 }
414}
415
403static const struct file_operations tis_ops = { 416static const struct file_operations tis_ops = {
404 .owner = THIS_MODULE, 417 .owner = THIS_MODULE,
405 .llseek = no_llseek, 418 .llseek = no_llseek,
@@ -445,7 +458,7 @@ static struct tpm_vendor_specific tpm_tis = {
445 .cancel = tpm_tis_ready, 458 .cancel = tpm_tis_ready,
446 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 459 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
447 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, 460 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
448 .req_canceled = TPM_STS_COMMAND_READY, 461 .req_canceled = tpm_tis_req_canceled,
449 .attr_group = &tis_attr_grp, 462 .attr_group = &tis_attr_grp,
450 .miscdev = { 463 .miscdev = {
451 .fops = &tis_ops,}, 464 .fops = &tis_ops,},