You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris: "Changes for this kernel include maintenance updates for Smack, SELinux (and several networking fixes), IMA and TPM" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (39 commits) SELinux: Fix memory leak upon loading policy tpm/tpm-sysfs: active_show() can be static tpm: tpm_tis: Fix compile problems with CONFIG_PM_SLEEP/CONFIG_PNP tpm: Make tpm-dev allocate a per-file structure tpm: Use the ops structure instead of a copy in tpm_vendor_specific tpm: Create a tpm_class_ops structure and use it in the drivers tpm: Pull all driver sysfs code into tpm-sysfs.c tpm: Move sysfs functions from tpm-interface to tpm-sysfs tpm: Pull everything related to /dev/tpmX into tpm-dev.c char: tpm: nuvoton: remove unused variable tpm: MAINTAINERS: Cleanup TPM Maintainers file tpm/tpm_i2c_atmel: fix coccinelle warnings tpm/tpm_ibmvtpm: fix unreachable code warning (smatch warning) tpm/tpm_i2c_stm_st33: Check return code of get_burstcount tpm/tpm_ppi: Check return value of acpi_get_name tpm/tpm_ppi: Do not compare strcmp(a,b) == -1 ima: remove unneeded size_limit argument from ima_eventdigest_init_common() ima: update IMA-templates.txt documentation ima: pass HASH_ALGO__LAST as hash algo in ima_eventdigest_init() ima: change the default hash algorithm to SHA1 in ima_eventdigest_ng_init() ...
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# Makefile for the kernel tpm device drivers.
|
||||
#
|
||||
obj-$(CONFIG_TCG_TPM) += tpm.o
|
||||
tpm-y := tpm-interface.o
|
||||
tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o
|
||||
tpm-$(CONFIG_ACPI) += tpm_ppi.o
|
||||
|
||||
ifdef CONFIG_ACPI
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2004 IBM Corporation
|
||||
* Authors:
|
||||
* Leendert van Doorn <leendert@watson.ibm.com>
|
||||
* Dave Safford <safford@watson.ibm.com>
|
||||
* Reiner Sailer <sailer@watson.ibm.com>
|
||||
* Kylene Hall <kjhall@us.ibm.com>
|
||||
*
|
||||
* Copyright (C) 2013 Obsidian Research Corp
|
||||
* Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
|
||||
*
|
||||
* Device file system interface to the TPM
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, version 2 of the
|
||||
* License.
|
||||
*
|
||||
*/
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include "tpm.h"
|
||||
|
||||
struct file_priv {
|
||||
struct tpm_chip *chip;
|
||||
|
||||
/* Data passed to and from the tpm via the read/write calls */
|
||||
atomic_t data_pending;
|
||||
struct mutex buffer_mutex;
|
||||
|
||||
struct timer_list user_read_timer; /* user needs to claim result */
|
||||
struct work_struct work;
|
||||
|
||||
u8 data_buffer[TPM_BUFSIZE];
|
||||
};
|
||||
|
||||
static void user_reader_timeout(unsigned long ptr)
|
||||
{
|
||||
struct file_priv *priv = (struct file_priv *)ptr;
|
||||
|
||||
schedule_work(&priv->work);
|
||||
}
|
||||
|
||||
static void timeout_work(struct work_struct *work)
|
||||
{
|
||||
struct file_priv *priv = container_of(work, struct file_priv, work);
|
||||
|
||||
mutex_lock(&priv->buffer_mutex);
|
||||
atomic_set(&priv->data_pending, 0);
|
||||
memset(priv->data_buffer, 0, sizeof(priv->data_buffer));
|
||||
mutex_unlock(&priv->buffer_mutex);
|
||||
}
|
||||
|
||||
static int tpm_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct miscdevice *misc = file->private_data;
|
||||
struct tpm_chip *chip = container_of(misc, struct tpm_chip,
|
||||
vendor.miscdev);
|
||||
struct file_priv *priv;
|
||||
|
||||
/* It's assured that the chip will be opened just once,
|
||||
* by the check of is_open variable, which is protected
|
||||
* by driver_lock. */
|
||||
if (test_and_set_bit(0, &chip->is_open)) {
|
||||
dev_dbg(chip->dev, "Another process owns this TPM\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (priv == NULL) {
|
||||
clear_bit(0, &chip->is_open);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->chip = chip;
|
||||
atomic_set(&priv->data_pending, 0);
|
||||
mutex_init(&priv->buffer_mutex);
|
||||
setup_timer(&priv->user_read_timer, user_reader_timeout,
|
||||
(unsigned long)priv);
|
||||
INIT_WORK(&priv->work, timeout_work);
|
||||
|
||||
file->private_data = priv;
|
||||
get_device(chip->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t tpm_read(struct file *file, char __user *buf,
|
||||
size_t size, loff_t *off)
|
||||
{
|
||||
struct file_priv *priv = file->private_data;
|
||||
ssize_t ret_size;
|
||||
int rc;
|
||||
|
||||
del_singleshot_timer_sync(&priv->user_read_timer);
|
||||
flush_work(&priv->work);
|
||||
ret_size = atomic_read(&priv->data_pending);
|
||||
if (ret_size > 0) { /* relay data */
|
||||
ssize_t orig_ret_size = ret_size;
|
||||
if (size < ret_size)
|
||||
ret_size = size;
|
||||
|
||||
mutex_lock(&priv->buffer_mutex);
|
||||
rc = copy_to_user(buf, priv->data_buffer, ret_size);
|
||||
memset(priv->data_buffer, 0, orig_ret_size);
|
||||
if (rc)
|
||||
ret_size = -EFAULT;
|
||||
|
||||
mutex_unlock(&priv->buffer_mutex);
|
||||
}
|
||||
|
||||
atomic_set(&priv->data_pending, 0);
|
||||
|
||||
return ret_size;
|
||||
}
|
||||
|
||||
static ssize_t tpm_write(struct file *file, const char __user *buf,
|
||||
size_t size, loff_t *off)
|
||||
{
|
||||
struct file_priv *priv = file->private_data;
|
||||
size_t in_size = size;
|
||||
ssize_t out_size;
|
||||
|
||||
/* cannot perform a write until the read has cleared
|
||||
either via tpm_read or a user_read_timer timeout.
|
||||
This also prevents splitted buffered writes from blocking here.
|
||||
*/
|
||||
if (atomic_read(&priv->data_pending) != 0)
|
||||
return -EBUSY;
|
||||
|
||||
if (in_size > TPM_BUFSIZE)
|
||||
return -E2BIG;
|
||||
|
||||
mutex_lock(&priv->buffer_mutex);
|
||||
|
||||
if (copy_from_user
|
||||
(priv->data_buffer, (void __user *) buf, in_size)) {
|
||||
mutex_unlock(&priv->buffer_mutex);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* atomic tpm command send and result receive */
|
||||
out_size = tpm_transmit(priv->chip, priv->data_buffer,
|
||||
sizeof(priv->data_buffer));
|
||||
if (out_size < 0) {
|
||||
mutex_unlock(&priv->buffer_mutex);
|
||||
return out_size;
|
||||
}
|
||||
|
||||
atomic_set(&priv->data_pending, out_size);
|
||||
mutex_unlock(&priv->buffer_mutex);
|
||||
|
||||
/* Set a timeout by which the reader must come claim the result */
|
||||
mod_timer(&priv->user_read_timer, jiffies + (60 * HZ));
|
||||
|
||||
return in_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called on file close
|
||||
*/
|
||||
static int tpm_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct file_priv *priv = file->private_data;
|
||||
|
||||
del_singleshot_timer_sync(&priv->user_read_timer);
|
||||
flush_work(&priv->work);
|
||||
file->private_data = NULL;
|
||||
atomic_set(&priv->data_pending, 0);
|
||||
clear_bit(0, &priv->chip->is_open);
|
||||
put_device(priv->chip->dev);
|
||||
kfree(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations tpm_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
int tpm_dev_add_device(struct tpm_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
|
||||
chip->vendor.miscdev.fops = &tpm_fops;
|
||||
if (chip->dev_num == 0)
|
||||
chip->vendor.miscdev.minor = TPM_MINOR;
|
||||
else
|
||||
chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
|
||||
|
||||
chip->vendor.miscdev.name = chip->devname;
|
||||
chip->vendor.miscdev.parent = chip->dev;
|
||||
|
||||
rc = misc_register(&chip->vendor.miscdev);
|
||||
if (rc) {
|
||||
chip->vendor.miscdev.name = NULL;
|
||||
dev_err(chip->dev,
|
||||
"unable to misc_register %s, minor %d err=%d\n",
|
||||
chip->vendor.miscdev.name,
|
||||
chip->vendor.miscdev.minor, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void tpm_dev_del_device(struct tpm_chip *chip)
|
||||
{
|
||||
if (chip->vendor.miscdev.name)
|
||||
misc_deregister(&chip->vendor.miscdev);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (C) 2004 IBM Corporation
|
||||
* Authors:
|
||||
* Leendert van Doorn <leendert@watson.ibm.com>
|
||||
* Dave Safford <safford@watson.ibm.com>
|
||||
* Reiner Sailer <sailer@watson.ibm.com>
|
||||
* Kylene Hall <kjhall@us.ibm.com>
|
||||
*
|
||||
* Copyright (C) 2013 Obsidian Research Corp
|
||||
* Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
|
||||
*
|
||||
* sysfs filesystem inspection interface to the TPM
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, version 2 of the
|
||||
* License.
|
||||
*
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include "tpm.h"
|
||||
|
||||
/* XXX for now this helper is duplicated in tpm-interface.c */
|
||||
static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
|
||||
int len, const char *desc)
|
||||
{
|
||||
int err;
|
||||
|
||||
len = tpm_transmit(chip, (u8 *) cmd, len);
|
||||
if (len < 0)
|
||||
return len;
|
||||
else if (len < TPM_HEADER_SIZE)
|
||||
return -EFAULT;
|
||||
|
||||
err = be32_to_cpu(cmd->header.out.return_code);
|
||||
if (err != 0 && desc)
|
||||
dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#define READ_PUBEK_RESULT_SIZE 314
|
||||
#define TPM_ORD_READPUBEK cpu_to_be32(124)
|
||||
static struct tpm_input_header tpm_readpubek_header = {
|
||||
.tag = TPM_TAG_RQU_COMMAND,
|
||||
.length = cpu_to_be32(30),
|
||||
.ordinal = TPM_ORD_READPUBEK
|
||||
};
|
||||
static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
u8 *data;
|
||||
struct tpm_cmd_t tpm_cmd;
|
||||
ssize_t err;
|
||||
int i, rc;
|
||||
char *str = buf;
|
||||
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
tpm_cmd.header.in = tpm_readpubek_header;
|
||||
err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
|
||||
"attempting to read the PUBEK");
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
ignore header 10 bytes
|
||||
algorithm 32 bits (1 == RSA )
|
||||
encscheme 16 bits
|
||||
sigscheme 16 bits
|
||||
parameters (RSA 12->bytes: keybit, #primes, expbit)
|
||||
keylenbytes 32 bits
|
||||
256 byte modulus
|
||||
ignore checksum 20 bytes
|
||||
*/
|
||||
data = tpm_cmd.params.readpubek_out_buffer;
|
||||
str +=
|
||||
sprintf(str,
|
||||
"Algorithm: %02X %02X %02X %02X\n"
|
||||
"Encscheme: %02X %02X\n"
|
||||
"Sigscheme: %02X %02X\n"
|
||||
"Parameters: %02X %02X %02X %02X "
|
||||
"%02X %02X %02X %02X "
|
||||
"%02X %02X %02X %02X\n"
|
||||
"Modulus length: %d\n"
|
||||
"Modulus:\n",
|
||||
data[0], data[1], data[2], data[3],
|
||||
data[4], data[5],
|
||||
data[6], data[7],
|
||||
data[12], data[13], data[14], data[15],
|
||||
data[16], data[17], data[18], data[19],
|
||||
data[20], data[21], data[22], data[23],
|
||||
be32_to_cpu(*((__be32 *) (data + 24))));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
str += sprintf(str, "%02X ", data[i + 28]);
|
||||
if ((i + 1) % 16 == 0)
|
||||
str += sprintf(str, "\n");
|
||||
}
|
||||
out:
|
||||
rc = str - buf;
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RO(pubek);
|
||||
|
||||
static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
cap_t cap;
|
||||
u8 digest[TPM_DIGEST_SIZE];
|
||||
ssize_t rc;
|
||||
int i, j, num_pcrs;
|
||||
char *str = buf;
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
|
||||
"attempting to determine the number of PCRS");
|
||||
if (rc)
|
||||
return 0;
|
||||
|
||||
num_pcrs = be32_to_cpu(cap.num_pcrs);
|
||||
for (i = 0; i < num_pcrs; i++) {
|
||||
rc = tpm_pcr_read_dev(chip, i, digest);
|
||||
if (rc)
|
||||
break;
|
||||
str += sprintf(str, "PCR-%02d: ", i);
|
||||
for (j = 0; j < TPM_DIGEST_SIZE; j++)
|
||||
str += sprintf(str, "%02X ", digest[j]);
|
||||
str += sprintf(str, "\n");
|
||||
}
|
||||
return str - buf;
|
||||
}
|
||||
static DEVICE_ATTR_RO(pcrs);
|
||||
|
||||
static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
cap_t cap;
|
||||
ssize_t rc;
|
||||
|
||||
rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
|
||||
"attempting to determine the permanent enabled state");
|
||||
if (rc)
|
||||
return 0;
|
||||
|
||||
rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RO(enabled);
|
||||
|
||||
static ssize_t active_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
cap_t cap;
|
||||
ssize_t rc;
|
||||
|
||||
rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
|
||||
"attempting to determine the permanent active state");
|
||||
if (rc)
|
||||
return 0;
|
||||
|
||||
rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RO(active);
|
||||
|
||||
static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
cap_t cap;
|
||||
ssize_t rc;
|
||||
|
||||
rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
|
||||
"attempting to determine the owner state");
|
||||
if (rc)
|
||||
return 0;
|
||||
|
||||
rc = sprintf(buf, "%d\n", cap.owned);
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RO(owned);
|
||||
|
||||
static ssize_t temp_deactivated_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
cap_t cap;
|
||||
ssize_t rc;
|
||||
|
||||
rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
|
||||
"attempting to determine the temporary state");
|
||||
if (rc)
|
||||
return 0;
|
||||
|
||||
rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RO(temp_deactivated);
|
||||
|
||||
static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
cap_t cap;
|
||||
ssize_t rc;
|
||||
char *str = buf;
|
||||
|
||||
rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
|
||||
"attempting to determine the manufacturer");
|
||||
if (rc)
|
||||
return 0;
|
||||
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 = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
|
||||
"attempting to determine the 1.2 version");
|
||||
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 */
|
||||
rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
|
||||
"attempting to determine the 1.1 version");
|
||||
if (rc)
|
||||
return 0;
|
||||
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);
|
||||
}
|
||||
|
||||
return str - buf;
|
||||
}
|
||||
static DEVICE_ATTR_RO(caps);
|
||||
|
||||
static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
if (chip == NULL)
|
||||
return 0;
|
||||
|
||||
chip->ops->cancel(chip);
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_WO(cancel);
|
||||
|
||||
static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
if (chip->vendor.duration[TPM_LONG] == 0)
|
||||
return 0;
|
||||
|
||||
return sprintf(buf, "%d %d %d [%s]\n",
|
||||
jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
|
||||
jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
|
||||
jiffies_to_usecs(chip->vendor.duration[TPM_LONG]),
|
||||
chip->vendor.duration_adjusted
|
||||
? "adjusted" : "original");
|
||||
}
|
||||
static DEVICE_ATTR_RO(durations);
|
||||
|
||||
static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
return sprintf(buf, "%d %d %d %d [%s]\n",
|
||||
jiffies_to_usecs(chip->vendor.timeout_a),
|
||||
jiffies_to_usecs(chip->vendor.timeout_b),
|
||||
jiffies_to_usecs(chip->vendor.timeout_c),
|
||||
jiffies_to_usecs(chip->vendor.timeout_d),
|
||||
chip->vendor.timeout_adjusted
|
||||
? "adjusted" : "original");
|
||||
}
|
||||
static DEVICE_ATTR_RO(timeouts);
|
||||
|
||||
static struct attribute *tpm_dev_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group tpm_dev_group = {
|
||||
.attrs = tpm_dev_attrs,
|
||||
};
|
||||
|
||||
int tpm_sysfs_add_device(struct tpm_chip *chip)
|
||||
{
|
||||
int err;
|
||||
err = sysfs_create_group(&chip->dev->kobj,
|
||||
&tpm_dev_group);
|
||||
|
||||
if (err)
|
||||
dev_err(chip->dev,
|
||||
"failed to create sysfs attributes, %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
void tpm_sysfs_del_device(struct tpm_chip *chip)
|
||||
{
|
||||
sysfs_remove_group(&chip->dev->kobj, &tpm_dev_group);
|
||||
}
|
||||
+39
-44
@@ -46,6 +46,14 @@ enum tpm_addr {
|
||||
TPM_ADDR = 0x4E,
|
||||
};
|
||||
|
||||
/* Indexes the duration array */
|
||||
enum tpm_duration {
|
||||
TPM_SHORT = 0,
|
||||
TPM_MEDIUM = 1,
|
||||
TPM_LONG = 2,
|
||||
TPM_UNDEFINED,
|
||||
};
|
||||
|
||||
#define TPM_WARN_RETRY 0x800
|
||||
#define TPM_WARN_DOING_SELFTEST 0x802
|
||||
#define TPM_ERR_DEACTIVATED 0x6
|
||||
@@ -53,33 +61,9 @@ enum tpm_addr {
|
||||
#define TPM_ERR_INVALID_POSTINIT 38
|
||||
|
||||
#define TPM_HEADER_SIZE 10
|
||||
extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
|
||||
const char *, size_t);
|
||||
extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
|
||||
char *);
|
||||
extern ssize_t tpm_show_temp_deactivated(struct device *,
|
||||
struct device_attribute *attr, char *);
|
||||
extern ssize_t tpm_show_durations(struct device *,
|
||||
struct device_attribute *attr, char *);
|
||||
extern ssize_t tpm_show_timeouts(struct device *,
|
||||
struct device_attribute *attr, char *);
|
||||
|
||||
struct tpm_chip;
|
||||
|
||||
struct tpm_vendor_specific {
|
||||
const u8 req_complete_mask;
|
||||
const u8 req_complete_val;
|
||||
bool (*req_canceled)(struct tpm_chip *chip, u8 status);
|
||||
void __iomem *iobase; /* ioremapped address */
|
||||
unsigned long base; /* TPM base address */
|
||||
|
||||
@@ -89,13 +73,7 @@ struct tpm_vendor_specific {
|
||||
int region_size;
|
||||
int have_region;
|
||||
|
||||
int (*recv) (struct tpm_chip *, u8 *, size_t);
|
||||
int (*send) (struct tpm_chip *, u8 *, size_t);
|
||||
void (*cancel) (struct tpm_chip *);
|
||||
u8 (*status) (struct tpm_chip *);
|
||||
void (*release) (struct device *);
|
||||
struct miscdevice miscdev;
|
||||
struct attribute_group *attr_group;
|
||||
struct list_head list;
|
||||
int locality;
|
||||
unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
|
||||
@@ -118,19 +96,13 @@ struct tpm_vendor_specific {
|
||||
|
||||
struct tpm_chip {
|
||||
struct device *dev; /* Device stuff */
|
||||
const struct tpm_class_ops *ops;
|
||||
|
||||
int dev_num; /* /dev/tpm# */
|
||||
char devname[7];
|
||||
unsigned long is_open; /* only one allowed */
|
||||
int time_expired;
|
||||
|
||||
/* Data passed to and from the tpm via the read/write calls */
|
||||
u8 *data_buffer;
|
||||
atomic_t data_pending;
|
||||
struct mutex buffer_mutex;
|
||||
|
||||
struct timer_list user_read_timer; /* user needs to claim result */
|
||||
struct work_struct work;
|
||||
struct mutex tpm_mutex; /* tpm is processing */
|
||||
|
||||
struct tpm_vendor_specific vendor;
|
||||
@@ -171,6 +143,8 @@ struct tpm_output_header {
|
||||
__be32 return_code;
|
||||
} __packed;
|
||||
|
||||
#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
|
||||
|
||||
struct stclear_flags_t {
|
||||
__be16 tag;
|
||||
u8 deactivated;
|
||||
@@ -244,6 +218,24 @@ typedef union {
|
||||
struct duration_t duration;
|
||||
} cap_t;
|
||||
|
||||
enum tpm_capabilities {
|
||||
TPM_CAP_FLAG = cpu_to_be32(4),
|
||||
TPM_CAP_PROP = cpu_to_be32(5),
|
||||
CAP_VERSION_1_1 = cpu_to_be32(0x06),
|
||||
CAP_VERSION_1_2 = cpu_to_be32(0x1A)
|
||||
};
|
||||
|
||||
enum tpm_sub_capabilities {
|
||||
TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
|
||||
TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
|
||||
TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
|
||||
TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
|
||||
TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
|
||||
TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
|
||||
TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
|
||||
|
||||
};
|
||||
|
||||
struct tpm_getcap_params_in {
|
||||
__be32 cap;
|
||||
__be32 subcap_size;
|
||||
@@ -323,25 +315,28 @@ struct tpm_cmd_t {
|
||||
|
||||
ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
|
||||
|
||||
ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
|
||||
size_t bufsiz);
|
||||
extern int tpm_get_timeouts(struct tpm_chip *);
|
||||
extern void tpm_gen_interrupt(struct tpm_chip *);
|
||||
extern int tpm_do_selftest(struct tpm_chip *);
|
||||
extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
|
||||
extern struct tpm_chip* tpm_register_hardware(struct device *,
|
||||
const struct tpm_vendor_specific *);
|
||||
extern int tpm_open(struct inode *, struct file *);
|
||||
extern int tpm_release(struct inode *, struct file *);
|
||||
extern void tpm_dev_release(struct device *dev);
|
||||
const struct tpm_class_ops *ops);
|
||||
extern void tpm_dev_vendor_release(struct tpm_chip *);
|
||||
extern ssize_t tpm_write(struct file *, const char __user *, size_t,
|
||||
loff_t *);
|
||||
extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
|
||||
extern void tpm_remove_hardware(struct device *);
|
||||
extern int tpm_pm_suspend(struct device *);
|
||||
extern int tpm_pm_resume(struct device *);
|
||||
extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
|
||||
wait_queue_head_t *, bool);
|
||||
|
||||
int tpm_dev_add_device(struct tpm_chip *chip);
|
||||
void tpm_dev_del_device(struct tpm_chip *chip);
|
||||
int tpm_sysfs_add_device(struct tpm_chip *chip);
|
||||
void tpm_sysfs_del_device(struct tpm_chip *chip);
|
||||
|
||||
int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
extern int tpm_add_ppi(struct kobject *);
|
||||
extern void tpm_remove_ppi(struct kobject *);
|
||||
|
||||
@@ -121,31 +121,7 @@ static bool tpm_atml_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return (status == ATML_STATUS_READY);
|
||||
}
|
||||
|
||||
static const struct file_operations atmel_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
|
||||
|
||||
static struct attribute* atmel_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
|
||||
|
||||
static const struct tpm_vendor_specific tpm_atmel = {
|
||||
static const struct tpm_class_ops tpm_atmel = {
|
||||
.recv = tpm_atml_recv,
|
||||
.send = tpm_atml_send,
|
||||
.cancel = tpm_atml_cancel,
|
||||
@@ -153,8 +129,6 @@ static const struct tpm_vendor_specific tpm_atmel = {
|
||||
.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
|
||||
.req_complete_val = ATML_STATUS_DATA_AVAIL,
|
||||
.req_canceled = tpm_atml_req_canceled,
|
||||
.attr_group = &atmel_attr_grp,
|
||||
.miscdev = { .fops = &atmel_ops, },
|
||||
};
|
||||
|
||||
static struct platform_device *pdev;
|
||||
|
||||
@@ -135,50 +135,12 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip)
|
||||
return ATMEL_STS_OK;
|
||||
}
|
||||
|
||||
static const struct file_operations i2c_atmel_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
|
||||
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
|
||||
|
||||
static struct attribute *i2c_atmel_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group i2c_atmel_attr_grp = {
|
||||
.attrs = i2c_atmel_attrs
|
||||
};
|
||||
|
||||
static bool i2c_atmel_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct tpm_vendor_specific i2c_atmel = {
|
||||
static const struct tpm_class_ops i2c_atmel = {
|
||||
.status = i2c_atmel_read_status,
|
||||
.recv = i2c_atmel_recv,
|
||||
.send = i2c_atmel_send,
|
||||
@@ -186,8 +148,6 @@ static const struct tpm_vendor_specific i2c_atmel = {
|
||||
.req_complete_mask = ATMEL_STS_OK,
|
||||
.req_complete_val = ATMEL_STS_OK,
|
||||
.req_canceled = i2c_atmel_req_canceled,
|
||||
.attr_group = &i2c_atmel_attr_grp,
|
||||
.miscdev.fops = &i2c_atmel_ops,
|
||||
};
|
||||
|
||||
static int i2c_atmel_probe(struct i2c_client *client,
|
||||
|
||||
@@ -566,45 +566,7 @@ static bool tpm_tis_i2c_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return (status == TPM_STS_COMMAND_READY);
|
||||
}
|
||||
|
||||
static const struct file_operations tis_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
|
||||
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
|
||||
|
||||
static struct attribute *tis_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group tis_attr_grp = {
|
||||
.attrs = tis_attrs
|
||||
};
|
||||
|
||||
static struct tpm_vendor_specific tpm_tis_i2c = {
|
||||
static const struct tpm_class_ops tpm_tis_i2c = {
|
||||
.status = tpm_tis_i2c_status,
|
||||
.recv = tpm_tis_i2c_recv,
|
||||
.send = tpm_tis_i2c_send,
|
||||
@@ -612,8 +574,6 @@ static struct tpm_vendor_specific tpm_tis_i2c = {
|
||||
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_canceled = tpm_tis_i2c_req_canceled,
|
||||
.attr_group = &tis_attr_grp,
|
||||
.miscdev.fops = &tis_ops,
|
||||
};
|
||||
|
||||
static int tpm_tis_i2c_init(struct device *dev)
|
||||
|
||||
@@ -178,7 +178,6 @@ static int i2c_nuvoton_wait_for_stat(struct tpm_chip *chip, u8 mask, u8 value,
|
||||
{
|
||||
if (chip->vendor.irq && queue) {
|
||||
s32 rc;
|
||||
DEFINE_WAIT(wait);
|
||||
struct priv_data *priv = chip->vendor.priv;
|
||||
unsigned int cur_intrs = priv->intrs;
|
||||
|
||||
@@ -456,45 +455,7 @@ static bool i2c_nuvoton_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return (status == TPM_STS_COMMAND_READY);
|
||||
}
|
||||
|
||||
static const struct file_operations i2c_nuvoton_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
|
||||
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
|
||||
|
||||
static struct attribute *i2c_nuvoton_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group i2c_nuvoton_attr_grp = {
|
||||
.attrs = i2c_nuvoton_attrs
|
||||
};
|
||||
|
||||
static const struct tpm_vendor_specific tpm_i2c = {
|
||||
static const struct tpm_class_ops tpm_i2c = {
|
||||
.status = i2c_nuvoton_read_status,
|
||||
.recv = i2c_nuvoton_recv,
|
||||
.send = i2c_nuvoton_send,
|
||||
@@ -502,8 +463,6 @@ static const struct tpm_vendor_specific tpm_i2c = {
|
||||
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_canceled = i2c_nuvoton_req_canceled,
|
||||
.attr_group = &i2c_nuvoton_attr_grp,
|
||||
.miscdev.fops = &i2c_nuvoton_ops,
|
||||
};
|
||||
|
||||
/* The only purpose for the handler is to signal to any waiting threads that
|
||||
|
||||
@@ -410,6 +410,8 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
&chip->vendor.read_queue)
|
||||
== 0) {
|
||||
burstcnt = get_burstcount(chip);
|
||||
if (burstcnt < 0)
|
||||
return burstcnt;
|
||||
len = min_t(int, burstcnt, count - size);
|
||||
I2C_READ_DATA(client, TPM_DATA_FIFO, buf + size, len);
|
||||
size += len;
|
||||
@@ -451,7 +453,8 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
|
||||
static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
|
||||
size_t len)
|
||||
{
|
||||
u32 status, burstcnt = 0, i, size;
|
||||
u32 status, i, size;
|
||||
int burstcnt = 0;
|
||||
int ret;
|
||||
u8 data;
|
||||
struct i2c_client *client;
|
||||
@@ -482,6 +485,8 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
|
||||
|
||||
for (i = 0; i < len - 1;) {
|
||||
burstcnt = get_burstcount(chip);
|
||||
if (burstcnt < 0)
|
||||
return burstcnt;
|
||||
size = min_t(int, len - i - 1, burstcnt);
|
||||
ret = I2C_WRITE_DATA(client, TPM_DATA_FIFO, buf, size);
|
||||
if (ret < 0)
|
||||
@@ -559,7 +564,7 @@ static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf,
|
||||
}
|
||||
|
||||
out:
|
||||
chip->vendor.cancel(chip);
|
||||
chip->ops->cancel(chip);
|
||||
release_locality(chip);
|
||||
return size;
|
||||
}
|
||||
@@ -569,40 +574,7 @@ static bool tpm_st33_i2c_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return (status == TPM_STS_COMMAND_READY);
|
||||
}
|
||||
|
||||
static const struct file_operations tpm_st33_i2c_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.open = tpm_open,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
|
||||
static struct attribute *stm_tpm_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr, NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group stm_tpm_attr_grp = {
|
||||
.attrs = stm_tpm_attrs
|
||||
};
|
||||
|
||||
static struct tpm_vendor_specific st_i2c_tpm = {
|
||||
static const struct tpm_class_ops st_i2c_tpm = {
|
||||
.send = tpm_stm_i2c_send,
|
||||
.recv = tpm_stm_i2c_recv,
|
||||
.cancel = tpm_stm_i2c_cancel,
|
||||
@@ -610,8 +582,6 @@ static struct tpm_vendor_specific st_i2c_tpm = {
|
||||
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_canceled = tpm_st33_i2c_req_canceled,
|
||||
.attr_group = &stm_tpm_attr_grp,
|
||||
.miscdev = {.fops = &tpm_st33_i2c_fops,},
|
||||
};
|
||||
|
||||
static int interrupts;
|
||||
@@ -837,7 +807,7 @@ static int tpm_st33_i2c_pm_resume(struct device *dev)
|
||||
if (power_mgt) {
|
||||
gpio_set_value(pin_infos->io_lpcpd, 1);
|
||||
ret = wait_for_serirq_timeout(chip,
|
||||
(chip->vendor.status(chip) &
|
||||
(chip->ops->status(chip) &
|
||||
TPM_STS_VALID) == TPM_STS_VALID,
|
||||
chip->vendor.timeout_b);
|
||||
} else {
|
||||
|
||||
@@ -403,43 +403,7 @@ static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return (status == 0);
|
||||
}
|
||||
|
||||
static const struct file_operations ibmvtpm_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
|
||||
NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
|
||||
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
|
||||
|
||||
static struct attribute *ibmvtpm_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr, NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group ibmvtpm_attr_grp = { .attrs = ibmvtpm_attrs };
|
||||
|
||||
static const struct tpm_vendor_specific tpm_ibmvtpm = {
|
||||
static const struct tpm_class_ops tpm_ibmvtpm = {
|
||||
.recv = tpm_ibmvtpm_recv,
|
||||
.send = tpm_ibmvtpm_send,
|
||||
.cancel = tpm_ibmvtpm_cancel,
|
||||
@@ -447,8 +411,6 @@ static const struct tpm_vendor_specific tpm_ibmvtpm = {
|
||||
.req_complete_mask = 0,
|
||||
.req_complete_val = 0,
|
||||
.req_canceled = tpm_ibmvtpm_req_canceled,
|
||||
.attr_group = &ibmvtpm_attr_grp,
|
||||
.miscdev = { .fops = &ibmvtpm_ops, },
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops tpm_ibmvtpm_pm_ops = {
|
||||
@@ -507,7 +469,6 @@ static void ibmvtpm_crq_process(struct ibmvtpm_crq *crq,
|
||||
dev_err(ibmvtpm->dev, "Unknown crq message type: %d\n", crq->msg);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case IBMVTPM_VALID_CMD:
|
||||
switch (crq->msg) {
|
||||
case VTPM_GET_RTCE_BUFFER_SIZE_RES:
|
||||
|
||||
@@ -371,39 +371,13 @@ static u8 tpm_inf_status(struct tpm_chip *chip)
|
||||
return tpm_data_in(STAT);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
|
||||
static struct attribute *inf_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
|
||||
|
||||
static const struct file_operations inf_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static const struct tpm_vendor_specific tpm_inf = {
|
||||
static const struct tpm_class_ops tpm_inf = {
|
||||
.recv = tpm_inf_recv,
|
||||
.send = tpm_inf_send,
|
||||
.cancel = tpm_inf_cancel,
|
||||
.status = tpm_inf_status,
|
||||
.req_complete_mask = 0,
|
||||
.req_complete_val = 0,
|
||||
.attr_group = &inf_attr_grp,
|
||||
.miscdev = {.fops = &inf_ops,},
|
||||
};
|
||||
|
||||
static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
|
||||
|
||||
@@ -232,31 +232,7 @@ static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return (status == NSC_STATUS_RDY);
|
||||
}
|
||||
|
||||
static const struct file_operations nsc_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel);
|
||||
|
||||
static struct attribute * nsc_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
|
||||
|
||||
static const struct tpm_vendor_specific tpm_nsc = {
|
||||
static const struct tpm_class_ops tpm_nsc = {
|
||||
.recv = tpm_nsc_recv,
|
||||
.send = tpm_nsc_send,
|
||||
.cancel = tpm_nsc_cancel,
|
||||
@@ -264,8 +240,6 @@ static const struct tpm_vendor_specific tpm_nsc = {
|
||||
.req_complete_mask = NSC_STATUS_OBF,
|
||||
.req_complete_val = NSC_STATUS_OBF,
|
||||
.req_canceled = tpm_nsc_req_canceled,
|
||||
.attr_group = &nsc_attr_grp,
|
||||
.miscdev = { .fops = &nsc_ops, },
|
||||
};
|
||||
|
||||
static struct platform_device *pdev = NULL;
|
||||
|
||||
@@ -172,7 +172,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev,
|
||||
* is updated with function index from SUBREQ to SUBREQ2 since PPI
|
||||
* version 1.1
|
||||
*/
|
||||
if (strcmp(version, "1.1") == -1)
|
||||
if (strcmp(version, "1.1") < 0)
|
||||
params[2].integer.value = TPM_PPI_FN_SUBREQ;
|
||||
else
|
||||
params[2].integer.value = TPM_PPI_FN_SUBREQ2;
|
||||
@@ -182,7 +182,7 @@ static ssize_t tpm_store_ppi_request(struct device *dev,
|
||||
* string/package type. For PPI version 1.0 and 1.1, use buffer type
|
||||
* for compatibility, and use package type since 1.2 according to spec.
|
||||
*/
|
||||
if (strcmp(version, "1.2") == -1) {
|
||||
if (strcmp(version, "1.2") < 0) {
|
||||
params[3].type = ACPI_TYPE_BUFFER;
|
||||
params[3].buffer.length = sizeof(req);
|
||||
sscanf(buf, "%d", &req);
|
||||
@@ -248,7 +248,7 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev,
|
||||
* (e.g. Capella with PPI 1.0) need integer/string/buffer type, so for
|
||||
* compatibility, define params[3].type as buffer, if PPI version < 1.2
|
||||
*/
|
||||
if (strcmp(version, "1.2") == -1) {
|
||||
if (strcmp(version, "1.2") < 0) {
|
||||
params[3].type = ACPI_TYPE_BUFFER;
|
||||
params[3].buffer.length = 0;
|
||||
params[3].buffer.pointer = NULL;
|
||||
@@ -390,7 +390,7 @@ static ssize_t show_ppi_operations(char *buf, u32 start, u32 end)
|
||||
kfree(output.pointer);
|
||||
output.length = ACPI_ALLOCATE_BUFFER;
|
||||
output.pointer = NULL;
|
||||
if (strcmp(version, "1.2") == -1)
|
||||
if (strcmp(version, "1.2") < 0)
|
||||
return -EPERM;
|
||||
|
||||
params[2].integer.value = TPM_PPI_FN_GETOPR;
|
||||
|
||||
@@ -432,45 +432,7 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct file_operations tis_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
|
||||
NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
|
||||
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
|
||||
|
||||
static struct attribute *tis_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr, NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group tis_attr_grp = {
|
||||
.attrs = tis_attrs
|
||||
};
|
||||
|
||||
static struct tpm_vendor_specific tpm_tis = {
|
||||
static const struct tpm_class_ops tpm_tis = {
|
||||
.status = tpm_tis_status,
|
||||
.recv = tpm_tis_recv,
|
||||
.send = tpm_tis_send,
|
||||
@@ -478,9 +440,6 @@ static struct tpm_vendor_specific tpm_tis = {
|
||||
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
|
||||
.req_canceled = tpm_tis_req_canceled,
|
||||
.attr_group = &tis_attr_grp,
|
||||
.miscdev = {
|
||||
.fops = &tis_ops,},
|
||||
};
|
||||
|
||||
static irqreturn_t tis_int_probe(int irq, void *dev_id)
|
||||
@@ -743,7 +702,7 @@ out_err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PNP) || defined(CONFIG_PM_SLEEP)
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
|
||||
{
|
||||
u32 intmask;
|
||||
@@ -764,9 +723,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
|
||||
iowrite32(intmask,
|
||||
chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int tpm_tis_resume(struct device *dev)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
@@ -835,11 +792,9 @@ static struct pnp_driver tis_pnp_driver = {
|
||||
.id_table = tpm_pnp_tbl,
|
||||
.probe = tpm_tis_pnp_init,
|
||||
.remove = tpm_tis_pnp_remove,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.driver = {
|
||||
.pm = &tpm_tis_pm,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
|
||||
|
||||
@@ -143,46 +143,7 @@ static int vtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
return length;
|
||||
}
|
||||
|
||||
static const struct file_operations vtpm_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = tpm_open,
|
||||
.read = tpm_read,
|
||||
.write = tpm_write,
|
||||
.release = tpm_release,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
|
||||
static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
|
||||
static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
|
||||
static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
|
||||
static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
|
||||
NULL);
|
||||
static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
|
||||
static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
|
||||
static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
|
||||
static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
|
||||
|
||||
static struct attribute *vtpm_attrs[] = {
|
||||
&dev_attr_pubek.attr,
|
||||
&dev_attr_pcrs.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_active.attr,
|
||||
&dev_attr_owned.attr,
|
||||
&dev_attr_temp_deactivated.attr,
|
||||
&dev_attr_caps.attr,
|
||||
&dev_attr_cancel.attr,
|
||||
&dev_attr_durations.attr,
|
||||
&dev_attr_timeouts.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group vtpm_attr_grp = {
|
||||
.attrs = vtpm_attrs,
|
||||
};
|
||||
|
||||
static const struct tpm_vendor_specific tpm_vtpm = {
|
||||
static const struct tpm_class_ops tpm_vtpm = {
|
||||
.status = vtpm_status,
|
||||
.recv = vtpm_recv,
|
||||
.send = vtpm_send,
|
||||
@@ -190,10 +151,6 @@ static const struct tpm_vendor_specific tpm_vtpm = {
|
||||
.req_complete_mask = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT,
|
||||
.req_complete_val = VTPM_STATUS_IDLE | VTPM_STATUS_RESULT,
|
||||
.req_canceled = vtpm_req_canceled,
|
||||
.attr_group = &vtpm_attr_grp,
|
||||
.miscdev = {
|
||||
.fops = &vtpm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static irqreturn_t tpmif_interrupt(int dummy, void *dev_id)
|
||||
|
||||
Reference in New Issue
Block a user