瀏覽代碼

[PATCH] tpm: add cancel function

This patch provides the logic to check if an operation has been canceled while
waiting for the response to arrive.

Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Kylene Hall 20 年之前
父節點
當前提交
d9e5b6bf9c
共有 4 個文件被更改,包括 23 次插入12 次删除
  1. 20 12
      drivers/char/tpm/tpm.c
  2. 1 0
      drivers/char/tpm/tpm.h
  3. 1 0
      drivers/char/tpm/tpm_atmel.c
  4. 1 0
      drivers/char/tpm/tpm_nsc.c

+ 20 - 12
drivers/char/tpm/tpm.c

@@ -141,7 +141,7 @@ EXPORT_SYMBOL_GPL(tpm_lpc_bus_init);
 static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 			    size_t bufsiz)
 {
-	ssize_t len;
+	ssize_t rc;
 	u32 count;
 	unsigned long stop;
 
@@ -157,10 +157,10 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 
 	down(&chip->tpm_mutex);
 
-	if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
 		dev_err(&chip->pci_dev->dev,
-			"tpm_transmit: tpm_send: error %zd\n", len);
-		return len;
+			"tpm_transmit: tpm_send: error %zd\n", rc);
+		goto out;
 	}
 
 	stop = jiffies + 2 * 60 * HZ;
@@ -170,23 +170,31 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 		    chip->vendor->req_complete_val) {
 			goto out_recv;
 		}
-		msleep(TPM_TIMEOUT); /* CHECK */
+
+		if ((status == chip->vendor->req_canceled)) {
+			dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
+			rc = -ECANCELED;
+			goto out;
+		}
+
+		msleep(TPM_TIMEOUT);	/* CHECK */
 		rmb();
 	} while (time_before(jiffies, stop));
 
 
 	chip->vendor->cancel(chip);
-	dev_err(&chip->pci_dev->dev, "Time expired\n");
-	up(&chip->tpm_mutex);
-	return -EIO;
+	dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
+	rc = -ETIME;
+	goto out;
 
 out_recv:
-	len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
-	if (len < 0)
+	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+	if (rc < 0)
 		dev_err(&chip->pci_dev->dev,
-			"tpm_transmit: tpm_recv: error %zd\n", len);
+			"tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
 	up(&chip->tpm_mutex);
-	return len;
+	return rc;
 }
 
 #define TPM_DIGEST_SIZE 20

+ 1 - 0
drivers/char/tpm/tpm.h

@@ -49,6 +49,7 @@ struct tpm_chip;
 struct tpm_vendor_specific {
 	u8 req_complete_mask;
 	u8 req_complete_val;
+	u8 req_canceled;
 	u16 base;		/* TPM base address */
 
 	int (*recv) (struct tpm_chip *, u8 *, size_t);

+ 1 - 0
drivers/char/tpm/tpm_atmel.c

@@ -147,6 +147,7 @@ static struct tpm_vendor_specific tpm_atmel = {
 	.cancel = tpm_atml_cancel,
 	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
 	.req_complete_val = ATML_STATUS_DATA_AVAIL,
+	.req_canceled = ATML_STATUS_READY,
 	.base = TPM_ATML_BASE,
 	.attr_group = &atmel_attr_grp,
 	.miscdev = { .fops = &atmel_ops, },

+ 1 - 0
drivers/char/tpm/tpm_nsc.c

@@ -245,6 +245,7 @@ static struct tpm_vendor_specific tpm_nsc = {
 	.cancel = tpm_nsc_cancel,
 	.req_complete_mask = NSC_STATUS_OBF,
 	.req_complete_val = NSC_STATUS_OBF,
+	.req_canceled = NSC_STATUS_RDY,
 	.base = TPM_NSC_BASE,
 	.attr_group = &nsc_attr_grp,
 	.miscdev = { .fops = &nsc_ops, },