tpmdd-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] tpm: Apply a sane minimum adapterlimit value for retransmission.
@ 2017-03-01 15:36 Enric Balletbo i Serra
       [not found] ` <20170301153617.10106-1-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Enric Balletbo i Serra @ 2017-03-01 15:36 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Bryan Freed, tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g

From: Bryan Freed <bfreed-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

When the I2C Infineon part is attached to an I2C adapter that imposes
a size limitation, large requests will fail with -EOPNOTSUPP. Retry
them with a sane minimum size without re-issuing the 0x05 command
as this appears to occasionally put the TPM in a bad state.

Signed-off-by: Bryan Freed <bfreed-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
[rework the patch to adapt to the feedback received]
Signed-off-by: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
---
This is a reworked version of the original patch based on the
suggestion made by Wolfram Sang to simply fall back to a sane minimum
when the maximum fails.

Changes since v1:
 - Check the correct return value (-EOPNOTSUPP instead of -EINVAL)
 - Fall back len to I2C_SMBUS_BLOCK_MAX if fails.

 drivers/char/tpm/tpm_i2c_infineon.c | 45 +++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 62ee44e..88bf947 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -107,39 +107,27 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 		.len = len,
 		.buf = buffer
 	};
-	struct i2c_msg msgs[] = {msg1, msg2};
 
 	int rc = 0;
 	int count;
+	unsigned int adapterlimit = len;
 
 	/* Lock the adapter for the duration of the whole sequence. */
 	if (!tpm_dev.client->adapter->algo->master_xfer)
 		return -EOPNOTSUPP;
 	i2c_lock_adapter(tpm_dev.client->adapter);
 
-	if (tpm_dev.chip_type == SLB9645) {
-		/* use a combined read for newer chips
-		 * unfortunately the smbus functions are not suitable due to
-		 * the 32 byte limit of the smbus.
-		 * retries should usually not be needed, but are kept just to
-		 * be on the safe side.
-		 */
-		for (count = 0; count < MAX_COUNT; count++) {
-			rc = __i2c_transfer(tpm_dev.client->adapter, msgs, 2);
-			if (rc > 0)
-				break;	/* break here to skip sleep */
-			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
-		}
-	} else {
+	/* Expect to send one command message and one data message, but
+	 * support looping over each or both if necessary.
+	 */
+	while (len > 0) {
 		/* slb9635 protocol should work in all cases */
 		for (count = 0; count < MAX_COUNT; count++) {
 			rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
 			if (rc > 0)
-				break;	/* break here to skip sleep */
-
+				break;
 			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
 		}
-
 		if (rc <= 0)
 			goto out;
 
@@ -148,11 +136,30 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 		 * retrieving the data
 		 */
 		for (count = 0; count < MAX_COUNT; count++) {
+			unsigned int msglen = msg2.len =
+					min_t(unsigned int, adapterlimit, len);
 			usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
 			rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
-			if (rc > 0)
+			if (rc > 0) {
+				/* Since len is unsigned, make doubly sure we
+				 * do not underflow it.
+				 */
+				if (msglen > len)
+					len = 0;
+				else
+					len -= msglen;
+				msg2.buf += msglen;
 				break;
+			}
+			/* If the I2C adapter rejected the request (e.g when
+			 * the quirk read_max_len < len) fall back to a sane
+			 * minimum value and try again.
+			 */
+			if (rc == -EOPNOTSUPP)
+				adapterlimit = I2C_SMBUS_BLOCK_MAX;
 		}
+		if (rc <= 0)
+			goto out;
 	}
 
 out:
-- 
2.9.3


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-03-02 17:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-01 15:36 [PATCH v2] tpm: Apply a sane minimum adapterlimit value for retransmission Enric Balletbo i Serra
     [not found] ` <20170301153617.10106-1-enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2017-03-02  0:27   ` Andrew Lunn
2017-03-02 12:55   ` Jarkko Sakkinen
     [not found]     ` <20170302125543.bsn7z5zkerabzh4u-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-03-02 13:43       ` Peter Huewe
     [not found]         ` <BA3AA3EA-054E-4B65-82C2-C01EBD2849F2-Mmb7MZpHnFY@public.gmane.org>
2017-03-02 16:34           ` Enric Balletbo i Serra
     [not found]             ` <2c648dea-35df-cdf7-3882-40bb855d3573-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
2017-03-02 17:24               ` Andrew Lunn
     [not found]                 ` <20170302172419.GA11265-g2DYL2Zd6BY@public.gmane.org>
2017-03-02 17:31                   ` Enric Balletbo i Serra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).