From: Seiji M. <sei...@gm...> - 2009-09-11 23:34:36
|
On Fri, Sep 11, 2009 at 5:09 AM, Rajiv Andrade <sr...@li...> wrote: > Some newer Lenovo models are shipped with a TPM that doesn't seem to set the TPM_STS_DATA_EXPECT status bit > when sending it a burst of data, so the code understands it as a failure and doesn't proceed sending the chip > the intended data. In this patch we bypass this bit check in case the itpm module parameter was set. > > This patch is based on Andy Isaacson's one: > > http://marc.info/?l=linux-kernel&m=124650185023495&w=2 > > It was heavily discussed how should we deal with identifying the chip in kernel space, but the required > patch to do so was NACK'd: > > http://marc.info/?l=linux-kernel&m=124650186423711&w=2 > > This way we let the user choose using this workaround or not based on his > observations on this code behavior when trying to use the TPM. > > Fixed a checkpatch issue present on the previous patch, thanks to Daniel Walker. > > Signed-off-by: Rajiv Andrade <sr...@li...> As far as I know, only the intel tpm has this PNP issue, so I'm fine with it. Tested-by: Seiji Munetoh <sei...@gm...> > --- > diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c > index aec1931..c9990db 100644 > --- a/drivers/char/tpm/tpm_tis.c > +++ b/drivers/char/tpm/tpm_tis.c > @@ -257,6 +257,10 @@ out: > return size; > } > > +static int itpm; > +module_param(itpm, bool, 0444); > +MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); > + > /* > * If interrupts are used (signaled by an irq set in the vendor structure) > * tpm.c can skip polling for the data to be available as the interrupt is > @@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) > wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, > &chip->vendor.int_queue); > status = tpm_tis_status(chip); > - if ((status & TPM_STS_DATA_EXPECT) == 0) { > + if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { > rc = -EIO; > goto out_err; > } > @@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, > "1.2 TPM (device-id 0x%X, rev-id %d)\n", > vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); > > + if (itpm) > + dev_info(dev, "Intel iTPM workaround enabled\n"); > + > + > /* Figure out the capabilities */ > intfcaps = > ioread32(chip->vendor.iobase + > > > |