Re: [RFC PATCH v3] tpm_tis: verify interrupt during init

From: Jason Gunthorpe
Date: Thu Aug 28 2014 - 12:54:11 EST

On Thu, Aug 28, 2014 at 12:35:16AM +0000, Scot Doyle wrote:

> > To move it means we have to understand why you are getting timeouts:
> >
> > [ 33.247720] tpm_tis 00:08: tpm_transmit: tpm_send: error -62
> > [ 33.247731] tpm_tis 00:08: [Hardware Error]: TPM command timed out during continue self test
> >
> > I had thought based on your other patch that these should not happen
> > since the raw register is polled after the timer expires?
> It is polled after the timer expires in tpm_tis_send_data, but not in
> tpm_tis_send, and the return value is used in tpm_tis_send...

tpm_tis_send does:

tpm_calc_ordinal_duration(chip, ordinal),
&chip->vendor.read_queue, false)

Which is:
rc = wait_event_interruptible_timeout(*queue,
wait_for_tpm_stat_cond(chip, mask, check_cancel,

And we know that wait_event_interruptible_timeout returns 1 if
the condition is true when the timeout expires.

So, all calls to wait_for_tpm_stat should succeed if the register has
the requested bits set at the end of the timer - thus if interrupts
are broken we should never see ETIME from wait_for_tpm_stat as the
chip does actually complete its work. (and this is the correct,
desired, behavior)

Is this analysis wrong somehow?

Lets simplify, instead of wrapping the whole command let us target
only the first part, tpm_tis_send, and let us do that for

--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -367,6 +367,12 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
rc = -ETIME;
goto out_err;
+ if (!chip->vendor.int_received) {
+ msleep(1);
+ if (!chip->vendor.int_received)
+ disable_interrupts();
+ }
return len;

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at
Please read the FAQ at