]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/char/tpm/tpm_tis_core.c
Merge tag 'acpi-extra-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-artful-kernel.git] / drivers / char / tpm / tpm_tis_core.c
index e3bf31b3713862cc759391f9ce0bfd22a2932007..7993678954a2b7c2910233f77c6af1b5070af9cc 100644 (file)
@@ -180,12 +180,19 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
        struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
        int size = 0, burstcnt, rc;
 
-       while (size < count &&
-              wait_for_tpm_stat(chip,
+       while (size < count) {
+               rc = wait_for_tpm_stat(chip,
                                 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
                                 chip->timeout_c,
-                                &priv->read_queue, true) == 0) {
-               burstcnt = min_t(int, get_burstcount(chip), count - size);
+                                &priv->read_queue, true);
+               if (rc < 0)
+                       return rc;
+               burstcnt = get_burstcount(chip);
+               if (burstcnt < 0) {
+                       dev_err(&chip->dev, "Unable to read burstcount\n");
+                       return burstcnt;
+               }
+               burstcnt = min_t(int, burstcnt, count - size);
 
                rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality),
                                        burstcnt, buf + size);
@@ -229,8 +236,11 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
                goto out;
        }
 
-       wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-                         &priv->int_queue, false);
+       if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+                               &priv->int_queue, false) < 0) {
+               size = -ETIME;
+               goto out;
+       }
        status = tpm_tis_status(chip);
        if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
                dev_err(&chip->dev, "Error left over data\n");
@@ -271,7 +281,13 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
        }
 
        while (count < len - 1) {
-               burstcnt = min_t(int, get_burstcount(chip), len - count - 1);
+               burstcnt = get_burstcount(chip);
+               if (burstcnt < 0) {
+                       dev_err(&chip->dev, "Unable to read burstcount\n");
+                       rc = burstcnt;
+                       goto out_err;
+               }
+               burstcnt = min_t(int, burstcnt, len - count - 1);
                rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality),
                                         burstcnt, buf + count);
                if (rc < 0)
@@ -279,8 +295,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
 
                count += burstcnt;
 
-               wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-                                 &priv->int_queue, false);
+               if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+                                       &priv->int_queue, false) < 0) {
+                       rc = -ETIME;
+                       goto out_err;
+               }
                status = tpm_tis_status(chip);
                if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
                        rc = -EIO;
@@ -293,8 +312,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
        if (rc < 0)
                goto out_err;
 
-       wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
-                         &priv->int_queue, false);
+       if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
+                               &priv->int_queue, false) < 0) {
+               rc = -ETIME;
+               goto out_err;
+       }
        status = tpm_tis_status(chip);
        if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) {
                rc = -EIO;
@@ -755,20 +777,20 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
        if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
                dev_dbg(dev, "\tData Avail Int Support\n");
 
-       /* Very early on issue a command to the TPM in polling mode to make
-        * sure it works. May as well use that command to set the proper
-        *  timeouts for the driver.
-        */
-       if (tpm_get_timeouts(chip)) {
-               dev_err(dev, "Could not get TPM timeouts and durations\n");
-               rc = -ENODEV;
-               goto out_err;
-       }
-
        /* INTERRUPT Setup */
        init_waitqueue_head(&priv->read_queue);
        init_waitqueue_head(&priv->int_queue);
        if (irq != -1) {
+               /* Before doing irq testing issue a command to the TPM in polling mode
+                * to make sure it works. May as well use that command to set the
+                * proper timeouts for the driver.
+                */
+               if (tpm_get_timeouts(chip)) {
+                       dev_err(dev, "Could not get TPM timeouts and durations\n");
+                       rc = -ENODEV;
+                       goto out_err;
+               }
+
                if (irq) {
                        tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
                                                 irq);