]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.c: fix error-path memory leak
[linux-2.6-omap-h63xx.git] / drivers / char / tpm / tpm.c
index 1fee7034a386f4aa27cf1c5928e8e195f832c0fb..e70d13defde4bcc30724187ff6443f553730eeb7 100644 (file)
@@ -525,19 +525,19 @@ void tpm_get_timeouts(struct tpm_chip *chip)
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
        if (timeout)
-               chip->vendor.timeout_a = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_a = usecs_to_jiffies(timeout);
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
        if (timeout)
-               chip->vendor.timeout_b = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_b = usecs_to_jiffies(timeout);
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
        if (timeout)
-               chip->vendor.timeout_c = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_c = usecs_to_jiffies(timeout);
        timeout =
            be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
        if (timeout)
-               chip->vendor.timeout_d = msecs_to_jiffies(timeout);
+               chip->vendor.timeout_d = usecs_to_jiffies(timeout);
 
 duration:
        memcpy(data, tpm_cap, sizeof(tpm_cap));
@@ -554,15 +554,22 @@ duration:
                return;
 
        chip->vendor.duration[TPM_SHORT] =
-           msecs_to_jiffies(be32_to_cpu
+           usecs_to_jiffies(be32_to_cpu
                             (*((__be32 *) (data +
                                            TPM_GET_CAP_RET_UINT32_1_IDX))));
+       /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
+        * value wrong and apparently reports msecs rather than usecs. So we
+        * fix up the resulting too-small TPM_SHORT value to make things work.
+        */
+       if (chip->vendor.duration[TPM_SHORT] < (HZ/100))
+               chip->vendor.duration[TPM_SHORT] = HZ;
+
        chip->vendor.duration[TPM_MEDIUM] =
-           msecs_to_jiffies(be32_to_cpu
+           usecs_to_jiffies(be32_to_cpu
                             (*((__be32 *) (data +
                                            TPM_GET_CAP_RET_UINT32_2_IDX))));
        chip->vendor.duration[TPM_LONG] =
-           msecs_to_jiffies(be32_to_cpu
+           usecs_to_jiffies(be32_to_cpu
                             (*((__be32 *) (data +
                                            TPM_GET_CAP_RET_UINT32_3_IDX))));
 }
@@ -1180,11 +1187,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
 
-       if (chip == NULL || devname == NULL) {
-               kfree(chip);
-               kfree(devname);
-               return NULL;
-       }
+       if (chip == NULL || devname == NULL)
+               goto out_free;
 
        mutex_init(&chip->buffer_mutex);
        mutex_init(&chip->tpm_mutex);
@@ -1201,8 +1205,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
 
        if (chip->dev_num >= TPM_NUM_DEVICES) {
                dev_err(dev, "No available tpm device numbers\n");
-               kfree(chip);
-               return NULL;
+               goto out_free;
        } else if (chip->dev_num == 0)
                chip->vendor.miscdev.minor = TPM_MINOR;
        else
@@ -1243,6 +1246,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
        spin_unlock(&driver_lock);
 
        return chip;
+
+out_free:
+       kfree(chip);
+       kfree(devname);
+       return NULL;
 }
 EXPORT_SYMBOL_GPL(tpm_register_hardware);