Am 2. März 2017 13:55:43 MEZ schrieb Jarkko Sakkinen <jarkko.sakki...@linux.intel.com>: >On Wed, Mar 01, 2017 at 04:36:17PM +0100, Enric Balletbo i Serra wrote: >> From: Bryan Freed <bfr...@chromium.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. > >What is 0x05 command? 0x05 is the address of the fifo. I honestly think that it needs toll be repeated after a stop condition. I'll look that up.
> >/Jarkko > >> Signed-off-by: Bryan Freed <bfr...@chromium.org> >> [rework the patch to adapt to the feedback received] >> Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com> >> --- >> 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) { Why are you / bryan removing this code path here? I put it there for a good reason (i.e. faster transfers) Thanks, Peter >> - /* 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 >> _______________________________________________ >> tpmdd-devel mailing list >> tpmdd-de...@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel -- Sent from my mobile