[prev in list] [next in list] [prev in thread] [next in thread] 

List:       tpmdd-devel
Subject:    [tpmdd-devel] [PATCH V3 2/3] Fix cancellation of TPM commands (polling mode)
From:       Stefan Berger <stefanb () linux ! vnet ! ibm ! com>
Date:       2013-01-22 15:09:45
Message-ID: 20130122151028.357584348 () linux ! vnet ! ibm ! com
[Download RAW message or body]

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 status register.
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>

---
 drivers/char/tpm/tpm.c              |    2 +-
 drivers/char/tpm/tpm.h              |    3 ++-
 drivers/char/tpm/tpm_atmel.c        |    7 ++++++-
 drivers/char/tpm/tpm_i2c_infineon.c |    7 ++++++-
 drivers/char/tpm/tpm_ibmvtpm.c      |    7 ++++++-
 drivers/char/tpm/tpm_nsc.c          |    7 ++++++-
 drivers/char/tpm/tpm_tis.c          |   13 ++++++++++++-
 7 files changed, 39 insertions(+), 7 deletions(-)

Index: linux-2.6/drivers/char/tpm/tpm.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm.c
+++ linux-2.6/drivers/char/tpm/tpm.c
@@ -410,7 +410,7 @@ static ssize_t tpm_transmit(struct tpm_c
 		    chip->vendor.req_complete_val)
 			goto out_recv;
 
-		if ((status == chip->vendor.req_canceled)) {
+		if (chip->vendor.req_canceled(chip, status)) {
 			dev_err(chip->dev, "Operation Canceled\n");
 			rc = -ECANCELED;
 			goto out;
Index: linux-2.6/drivers/char/tpm/tpm.h
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm.h
+++ linux-2.6/drivers/char/tpm/tpm.h
@@ -77,7 +77,7 @@ struct tpm_chip;
 struct tpm_vendor_specific {
 	const u8 req_complete_mask;
 	const u8 req_complete_val;
-	const u8 req_canceled;
+	bool (*req_canceled)(struct tpm_chip *chip, u8 status);
 	void __iomem *iobase;		/* ioremapped address */
 	unsigned long base;		/* TPM base address */
 
@@ -109,6 +109,7 @@ struct tpm_vendor_specific {
 };
 
 #define TPM_VID_INTEL    0x8086
+#define TPM_VID_WINBOND  0x1050
 
 struct tpm_chip {
 	struct device *dev;	/* Device stuff */
Index: linux-2.6/drivers/char/tpm/tpm_atmel.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm_atmel.c
+++ linux-2.6/drivers/char/tpm/tpm_atmel.c
@@ -116,6 +116,11 @@ static u8 tpm_atml_status(struct tpm_chi
 	return ioread8(chip->vendor.iobase + 1);
 }
 
+static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status)
+{
+	return (status == ATML_STATUS_READY);
+}
+
 static const struct file_operations atmel_ops = {
 	.owner = THIS_MODULE,
 	.llseek = no_llseek,
@@ -147,7 +152,7 @@ static const struct tpm_vendor_specific
 	.status = tpm_atml_status,
 	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
 	.req_complete_val = ATML_STATUS_DATA_AVAIL,
-	.req_canceled = ATML_STATUS_READY,
+	.req_canceled = tpm_atml_req_canceled,
 	.attr_group = &atmel_attr_grp,
 	.miscdev = { .fops = &atmel_ops, },
 };
Index: linux-2.6/drivers/char/tpm/tpm_i2c_infineon.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm_i2c_infineon.c
+++ linux-2.6/drivers/char/tpm/tpm_i2c_infineon.c
@@ -505,6 +505,11 @@ out_err:
 	return rc;
 }
 
+static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status)
+{
+	return (status == TPM_STS_COMMAND_READY);
+}
+
 static const struct file_operations tis_ops = {
 	.owner = THIS_MODULE,
 	.llseek = no_llseek,
@@ -550,7 +555,7 @@ static struct tpm_vendor_specific tpm_ti
 	.cancel = tpm_tis_i2c_ready,
 	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_canceled = TPM_STS_COMMAND_READY,
+	.req_canceled = tpm_tis_i2c_req_canceled,
 	.attr_group = &tis_attr_grp,
 	.miscdev.fops = &tis_ops,
 };
Index: linux-2.6/drivers/char/tpm/tpm_ibmvtpm.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm_ibmvtpm.c
+++ linux-2.6/drivers/char/tpm/tpm_ibmvtpm.c
@@ -399,6 +399,11 @@ static int tpm_ibmvtpm_resume(struct dev
 	return rc;
 }
 
+static tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status)
+{
+	return (status == 0);
+}
+
 static const struct file_operations ibmvtpm_ops = {
 	.owner = THIS_MODULE,
 	.llseek = no_llseek,
@@ -442,7 +447,7 @@ static const struct tpm_vendor_specific
 	.status = tpm_ibmvtpm_status,
 	.req_complete_mask = 0,
 	.req_complete_val = 0,
-	.req_canceled = 0,
+	.req_canceled = tpm_ibmvtpm_req_canceled,
 	.attr_group = &ibmvtpm_attr_grp,
 	.miscdev = { .fops = &ibmvtpm_ops, },
 };
Index: linux-2.6/drivers/char/tpm/tpm_nsc.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm_nsc.c
+++ linux-2.6/drivers/char/tpm/tpm_nsc.c
@@ -227,6 +227,11 @@ static u8 tpm_nsc_status(struct tpm_chip
 	return inb(chip->vendor.base + NSC_STATUS);
 }
 
+static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status)
+{
+	return (status == NSC_STATUS_RDY);
+}
+
 static const struct file_operations nsc_ops = {
 	.owner = THIS_MODULE,
 	.llseek = no_llseek,
@@ -258,7 +263,7 @@ static const struct tpm_vendor_specific
 	.status = tpm_nsc_status,
 	.req_complete_mask = NSC_STATUS_OBF,
 	.req_complete_val = NSC_STATUS_OBF,
-	.req_canceled = NSC_STATUS_RDY,
+	.req_canceled = tpm_nsc_req_canceled,
 	.attr_group = &nsc_attr_grp,
 	.miscdev = { .fops = &nsc_ops, },
 };
Index: linux-2.6/drivers/char/tpm/tpm_tis.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm_tis.c
+++ linux-2.6/drivers/char/tpm/tpm_tis.c
@@ -400,6 +400,17 @@ out:
 	return rc;
 }
 
+static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
+{
+	switch (chip->vendor.manufacturer_id) {
+	case TPM_VID_WINBOND:
+		return ((status == TPM_STS_VALID) ||
+			(status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
+	default:
+		return (status == TPM_STS_COMMAND_READY);
+	}
+}
+
 static const struct file_operations tis_ops = {
 	.owner = THIS_MODULE,
 	.llseek = no_llseek,
@@ -445,7 +456,7 @@ static struct tpm_vendor_specific tpm_ti
 	.cancel = tpm_tis_ready,
 	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_canceled = TPM_STS_COMMAND_READY,
+	.req_canceled = tpm_tis_req_canceled,
 	.attr_group = &tis_attr_grp,
 	.miscdev = {
 		    .fops = &tis_ops,},


------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnnow-d2d
_______________________________________________
tpmdd-devel mailing list
tpmdd-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic