diff options
Diffstat (limited to 'drivers/char/tpm/tpm-sysfs.c')
-rw-r--r-- | drivers/char/tpm/tpm-sysfs.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c index d9caedda075b..d52bf4df0bca 100644 --- a/drivers/char/tpm/tpm-sysfs.c +++ b/drivers/char/tpm/tpm-sysfs.c @@ -217,6 +217,7 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr, char *buf) { struct tpm_chip *chip = to_tpm_chip(dev); + struct tpm1_version *version; ssize_t rc = 0; char *str = buf; cap_t cap; @@ -232,31 +233,31 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr, str += sprintf(str, "Manufacturer: 0x%x\n", be32_to_cpu(cap.manufacturer_id)); - /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */ - rc = tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap, + /* TPM 1.2 */ + if (!tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap, "attempting to determine the 1.2 version", - sizeof(cap.tpm_version_1_2)); - if (!rc) { - str += sprintf(str, - "TCG version: %d.%d\nFirmware version: %d.%d\n", - cap.tpm_version_1_2.Major, - cap.tpm_version_1_2.Minor, - cap.tpm_version_1_2.revMajor, - cap.tpm_version_1_2.revMinor); - } else { - /* Otherwise just use TPM_STRUCT_VER */ - if (tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap, - "attempting to determine the 1.1 version", - sizeof(cap.tpm_version))) - goto out_ops; - str += sprintf(str, - "TCG version: %d.%d\nFirmware version: %d.%d\n", - cap.tpm_version.Major, - cap.tpm_version.Minor, - cap.tpm_version.revMajor, - cap.tpm_version.revMinor); + sizeof(cap.version2))) { + version = &cap.version2.version; + goto out_print; } + + /* TPM 1.1 */ + if (tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap, + "attempting to determine the 1.1 version", + sizeof(cap.version1))) { + goto out_ops; + } + + version = &cap.version1; + +out_print: + str += sprintf(str, + "TCG version: %d.%d\nFirmware version: %d.%d\n", + version->major, version->minor, + version->rev_major, version->rev_minor); + rc = str - buf; + out_ops: tpm_put_ops(chip); return rc; @@ -309,7 +310,17 @@ static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(timeouts); -static struct attribute *tpm_dev_attrs[] = { +static ssize_t tpm_version_major_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpm_chip *chip = to_tpm_chip(dev); + + return sprintf(buf, "%s\n", chip->flags & TPM_CHIP_FLAG_TPM2 + ? "2" : "1"); +} +static DEVICE_ATTR_RO(tpm_version_major); + +static struct attribute *tpm1_dev_attrs[] = { &dev_attr_pubek.attr, &dev_attr_pcrs.attr, &dev_attr_enabled.attr, @@ -320,25 +331,28 @@ static struct attribute *tpm_dev_attrs[] = { &dev_attr_cancel.attr, &dev_attr_durations.attr, &dev_attr_timeouts.attr, + &dev_attr_tpm_version_major.attr, NULL, }; -static const struct attribute_group tpm_dev_group = { - .attrs = tpm_dev_attrs, +static struct attribute *tpm2_dev_attrs[] = { + &dev_attr_tpm_version_major.attr, + NULL +}; + +static const struct attribute_group tpm1_dev_group = { + .attrs = tpm1_dev_attrs, +}; + +static const struct attribute_group tpm2_dev_group = { + .attrs = tpm2_dev_attrs, }; void tpm_sysfs_add_device(struct tpm_chip *chip) { - /* XXX: If you wish to remove this restriction, you must first update - * tpm_sysfs to explicitly lock chip->ops. - */ - if (chip->flags & TPM_CHIP_FLAG_TPM2) - return; - - /* The sysfs routines rely on an implicit tpm_try_get_ops, device_del - * is called before ops is null'd and the sysfs core synchronizes this - * removal so that no callbacks are running or can run again - */ WARN_ON(chip->groups_cnt != 0); - chip->groups[chip->groups_cnt++] = &tpm_dev_group; + if (chip->flags & TPM_CHIP_FLAG_TPM2) + chip->groups[chip->groups_cnt++] = &tpm2_dev_group; + else + chip->groups[chip->groups_cnt++] = &tpm1_dev_group; } |