[coreboot-gerrit] New patch to review for coreboot: drivers/i2c/tpm/cr50: Improve data handling and function names

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Tue Sep 20 04:53:10 CEST 2016


Duncan Laurie (dlaurie at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16668

-gerrit

commit e21b79835be805a1c172099fc693f47d19963a31
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Mon Sep 19 17:19:10 2016 -0700

    drivers/i2c/tpm/cr50: Improve data handling and function names
    
    Unify the function names to be consistent throughout the driver
    and improve the handling while waiting for data available and
    data expected flags from the TPM.
    
    BUG=chrome-os-partner:53336
    
    Change-Id: Ie2dfb7ede1bcda0e77070df945c47c1428115907
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/drivers/i2c/tpm/cr50.c | 93 ++++++++++++++++++++++------------------------
 1 file changed, 45 insertions(+), 48 deletions(-)

diff --git a/src/drivers/i2c/tpm/cr50.c b/src/drivers/i2c/tpm/cr50.c
index a3ff781..37f0881 100644
--- a/src/drivers/i2c/tpm/cr50.c
+++ b/src/drivers/i2c/tpm/cr50.c
@@ -189,7 +189,7 @@ static int request_locality(struct tpm_chip *chip, int loc)
 }
 
 /* cr50 requires all 4 bytes of status register to be read */
-static uint8_t cr50_tis_i2c_status(struct tpm_chip *chip)
+static uint8_t cr50_i2c_tis_status(struct tpm_chip *chip)
 {
 	uint8_t buf[4];
 	if (cr50_i2c_read(chip, TPM_STS(chip->vendor.locality),
@@ -201,7 +201,7 @@ static uint8_t cr50_tis_i2c_status(struct tpm_chip *chip)
 }
 
 /* cr50 requires all 4 bytes of status register to be written */
-static void cr50_tis_i2c_ready(struct tpm_chip *chip)
+static void cr50_i2c_tis_ready(struct tpm_chip *chip)
 {
 	uint8_t buf[4] = { TPM_STS_COMMAND_READY };
 	cr50_i2c_write(chip, TPM_STS(chip->vendor.locality), buf, sizeof(buf));
@@ -210,7 +210,7 @@ static void cr50_tis_i2c_ready(struct tpm_chip *chip)
 
 /* cr50 uses bytes 3:2 of status register for burst count and
  * all 4 bytes must be read */
-static int cr50_wait_burst_status(struct tpm_chip *chip, uint8_t mask,
+static int cr50_i2c_wait_burststs(struct tpm_chip *chip, uint8_t mask,
 				  size_t *burst, int *status)
 {
 	uint8_t buf[4];
@@ -240,28 +240,26 @@ static int cr50_wait_burst_status(struct tpm_chip *chip, uint8_t mask,
 	return -1;
 }
 
-static int cr50_tis_i2c_recv(struct tpm_chip *chip, uint8_t *buf,
+static int cr50_i2c_tis_recv(struct tpm_chip *chip, uint8_t *buf,
 			     size_t buf_len)
 {
 	size_t burstcnt, current, len, expected;
 	uint8_t addr = TPM_DATA_FIFO(chip->vendor.locality);
+	uint8_t mask = TPM_STS_VALID | TPM_STS_DATA_AVAIL;
 	int status;
-	int ret = -1;
 
 	if (buf_len < TPM_HEADER_SIZE)
-		goto out;
+		goto out_err;
 
-	if (cr50_wait_burst_status(chip, TPM_STS_VALID, &burstcnt, &status) < 0)
-		goto out;
-	if (!(status & TPM_STS_DATA_AVAIL)) {
+	if (cr50_i2c_wait_burststs(chip, mask, &burstcnt, &status) < 0) {
 		printk(BIOS_ERR, "%s: First chunk not available\n", __func__);
-		goto out;
+		goto out_err;
 	}
 
 	/* Read first chunk of burstcnt bytes */
 	if (cr50_i2c_read(chip, addr, buf, burstcnt) != 0) {
 		printk(BIOS_ERR, "%s: Read failed\n", __func__);
-		goto out;
+		goto out_err;
 	}
 
 	/* Determine expected data in the return buffer */
@@ -269,45 +267,43 @@ static int cr50_tis_i2c_recv(struct tpm_chip *chip, uint8_t *buf,
 	if (expected > buf_len) {
 		printk(BIOS_ERR, "%s: Too much data: %zu > %zu\n",
 		       __func__, expected, buf_len);
-		goto out;
+		goto out_err;
 	}
 
 	/* Now read the rest of the data */
 	current = burstcnt;
 	while (current < expected) {
 		/* Read updated burst count and check status */
-		if (cr50_wait_burst_status(chip, TPM_STS_VALID,
-					   &burstcnt, &status) < 0)
-			goto out;
-		if (!(status & TPM_STS_DATA_AVAIL)) {
-			printk(BIOS_ERR, "%s: Data not available\n", __func__);
-			goto out;
-		}
+		if (cr50_i2c_wait_burststs(chip, mask, &burstcnt, &status) < 0)
+			goto out_err;
 
 		len = min(burstcnt, expected - current);
 		if (cr50_i2c_read(chip, addr, buf + current, len) != 0) {
 			printk(BIOS_ERR, "%s: Read failed\n", __func__);
-			goto out;
+			goto out_err;
 		}
 
 		current += len;
 	}
 
 	/* Ensure TPM is done reading data */
-	if (cr50_wait_burst_status(chip, TPM_STS_VALID, &burstcnt, &status) < 0)
-		goto out;
+	if (cr50_i2c_wait_burststs(chip, TPM_STS_VALID, &burstcnt, &status) < 0)
+		goto out_err;
 	if (status & TPM_STS_DATA_AVAIL) {
 		printk(BIOS_ERR, "%s: Data still available\n", __func__);
-		goto out;
+		goto out_err;
 	}
 
-	ret = current;
+	return current;
 
-out:
-	return ret;
+out_err:
+	/* Abort current transaction if still pending */
+	if (cr50_i2c_tis_status(chip) & TPM_STS_COMMAND_READY)
+		cr50_i2c_tis_ready(chip);
+	return -1;
 }
 
-static int cr50_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
+static int cr50_i2c_tis_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
 {
 	int status;
 	size_t burstcnt, limit, sent = 0;
@@ -317,25 +313,26 @@ static int cr50_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
 	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);
 
 	/* Wait until TPM is ready for a command */
-	while (!(cr50_tis_i2c_status(chip) & TPM_STS_COMMAND_READY)) {
+	while (!(cr50_i2c_tis_status(chip) & TPM_STS_COMMAND_READY)) {
 		if (stopwatch_expired(&sw)) {
 			printk(BIOS_ERR, "%s: Command ready timeout\n",
 			       __func__);
 			return -1;
 		}
 
-		cr50_tis_i2c_ready(chip);
+		cr50_i2c_tis_ready(chip);
 	}
 
 	while (len > 0) {
+		uint8_t mask = TPM_STS_VALID;
+
+		/* Wait for data if this is not the first chunk */
+		if (sent > 0)
+			mask |= TPM_STS_DATA_EXPECT;
+
 		/* Read burst count and check status */
-		if (cr50_wait_burst_status(chip, TPM_STS_VALID,
-					   &burstcnt, &status) < 0)
-			goto out;
-		if (sent > 0 && !(status & TPM_STS_DATA_EXPECT)) {
-			printk(BIOS_ERR, "%s: Data not expected\n", __func__);
-			goto out;
-		}
+		if (cr50_i2c_wait_burststs(chip, mask, &burstcnt, &status) < 0)
+			goto out_err;
 
 		/* Use burstcnt - 1 to account for the address byte
 		 * that is inserted by cr50_i2c_write() */
@@ -343,7 +340,7 @@ static int cr50_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
 		if (cr50_i2c_write(chip, TPM_DATA_FIFO(chip->vendor.locality),
 				   &buf[sent], limit) != 0) {
 			printk(BIOS_ERR, "%s: Write failed\n", __func__);
-			goto out;
+			goto out_err;
 		}
 
 		sent += limit;
@@ -351,25 +348,25 @@ static int cr50_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
 	}
 
 	/* Ensure TPM is not expecting more data */
-	if (cr50_wait_burst_status(chip, TPM_STS_VALID, &burstcnt, &status) < 0)
-		goto out;
+	if (cr50_i2c_wait_burststs(chip, TPM_STS_VALID, &burstcnt, &status) < 0)
+		goto out_err;
 	if (status & TPM_STS_DATA_EXPECT) {
 		printk(BIOS_ERR, "%s: Data still expected\n", __func__);
-		goto out;
+		goto out_err;
 	}
 
 	/* Start the TPM command */
 	if (cr50_i2c_write(chip, TPM_STS(chip->vendor.locality), tpm_go,
 			   sizeof(tpm_go)) < 0) {
 		printk(BIOS_ERR, "%s: Start command failed\n", __func__);
-		goto out;
+		goto out_err;
 	}
 	return sent;
 
-out:
+out_err:
 	/* Abort current transaction if still pending */
-	if (cr50_tis_i2c_status(chip) & TPM_STS_COMMAND_READY)
-		cr50_tis_i2c_ready(chip);
+	if (cr50_i2c_tis_status(chip) & TPM_STS_COMMAND_READY)
+		cr50_i2c_tis_ready(chip);
 	return -1;
 }
 
@@ -379,10 +376,10 @@ static void cr50_vendor_init(struct tpm_chip *chip)
 	chip->vendor.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
 	chip->vendor.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
 	chip->vendor.req_canceled = TPM_STS_COMMAND_READY;
-	chip->vendor.status = &cr50_tis_i2c_status;
-	chip->vendor.recv = &cr50_tis_i2c_recv;
-	chip->vendor.send = &cr50_tis_i2c_send;
-	chip->vendor.cancel = &cr50_tis_i2c_ready;
+	chip->vendor.status = &cr50_i2c_tis_status;
+	chip->vendor.recv = &cr50_i2c_tis_recv;
+	chip->vendor.send = &cr50_i2c_tis_send;
+	chip->vendor.cancel = &cr50_i2c_tis_ready;
 }
 
 int tpm_vendor_probe(unsigned bus, uint32_t addr)



More information about the coreboot-gerrit mailing list