Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26114
b: refs/heads/master
c: 08e96e4
h: refs/heads/master
v: v3
  • Loading branch information
Kylene Jo Hall authored and Linus Torvalds committed Apr 22, 2006
1 parent a5b0f23 commit f4e2136
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e18ee19179a7742999d0e2d4bfcba75b5562439
refs/heads/master: 08e96e486dd1345ae0ad70247387d0d4fd346889
235 changes: 233 additions & 2 deletions trunk/drivers/char/tpm/tpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,17 +430,27 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
#define TPM_GET_CAP_RET_UINT32_2_IDX 18
#define TPM_GET_CAP_RET_UINT32_3_IDX 22
#define TPM_GET_CAP_RET_UINT32_4_IDX 26
#define TPM_GET_CAP_PERM_DISABLE_IDX 16
#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
#define TPM_GET_CAP_RET_BOOL_1_IDX 14
#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16

#define TPM_CAP_IDX 13
#define TPM_CAP_SUBCAP_IDX 21

enum tpm_capabilities {
TPM_CAP_FLAG = 4,
TPM_CAP_PROP = 5,
};

enum tpm_sub_capabilities {
TPM_CAP_PROP_PCR = 0x1,
TPM_CAP_PROP_MANUFACTURER = 0x3,
TPM_CAP_FLAG_PERM = 0x8,
TPM_CAP_FLAG_VOL = 0x9,
TPM_CAP_PROP_OWNER = 0x11,
TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
TPM_CAP_PROP_TIS_DURATION = 0x20,
};

/*
Expand Down Expand Up @@ -474,6 +484,180 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
return 0;
}

void tpm_gen_interrupt(struct tpm_chip *chip)
{
u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
ssize_t rc;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;

rc = transmit_cmd(chip, data, sizeof(data),
"attempting to determine the timeouts");
}
EXPORT_SYMBOL_GPL(tpm_gen_interrupt);

void tpm_get_timeouts(struct tpm_chip *chip)
{
u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
ssize_t rc;
u32 timeout;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;

rc = transmit_cmd(chip, data, sizeof(data),
"attempting to determine the timeouts");
if (rc)
goto duration;

if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
!= 4 * sizeof(u32))
goto duration;

/* Don't overwrite default if value is 0 */
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
if (timeout)
chip->vendor.timeout_a = timeout;
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
if (timeout)
chip->vendor.timeout_b = timeout;
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
if (timeout)
chip->vendor.timeout_c = timeout;
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
if (timeout)
chip->vendor.timeout_d = timeout;

duration:
memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;

rc = transmit_cmd(chip, data, sizeof(data),
"attempting to determine the durations");
if (rc)
return;

if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
!= 3 * sizeof(u32))
return;

chip->vendor.duration[TPM_SHORT] =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
chip->vendor.duration[TPM_MEDIUM] =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
chip->vendor.duration[TPM_LONG] =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
}
EXPORT_SYMBOL_GPL(tpm_get_timeouts);

void tpm_continue_selftest(struct tpm_chip *chip)
{
u8 data[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 10, /* length */
0, 0, 0, 83, /* TPM_ORD_GetCapability */
};

tpm_transmit(chip, data, sizeof(data));
}
EXPORT_SYMBOL_GPL(tpm_continue_selftest);

ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
char *buf)
{
u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
ssize_t rc;

struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_FLAG;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;

rc = transmit_cmd(chip, data, sizeof(data),
"attemtping to determine the permanent state");
if (rc)
return 0;
return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
}
EXPORT_SYMBOL_GPL(tpm_show_enabled);

ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
char *buf)
{
u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
ssize_t rc;

struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_FLAG;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;

rc = transmit_cmd(chip, data, sizeof(data),
"attemtping to determine the permanent state");
if (rc)
return 0;
return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
}
EXPORT_SYMBOL_GPL(tpm_show_active);

ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
char *buf)
{
u8 data[sizeof(tpm_cap)];
ssize_t rc;

struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;

rc = transmit_cmd(chip, data, sizeof(data),
"attempting to determine the owner state");
if (rc)
return 0;
return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
}
EXPORT_SYMBOL_GPL(tpm_show_owned);

ssize_t tpm_show_temp_deactivated(struct device * dev,
struct device_attribute * attr, char *buf)
{
u8 data[sizeof(tpm_cap)];
ssize_t rc;

struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_FLAG;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;

rc = transmit_cmd(chip, data, sizeof(data),
"attempting to determine the temporary state");
if (rc)
return 0;
return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
}
EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);

static const u8 pcrread[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 14, /* length */
Expand All @@ -484,7 +668,7 @@ static const u8 pcrread[] = {
ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
char *buf)
{
u8 data[30];
u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
ssize_t rc;
int i, j, num_pcrs;
__be32 index;
Expand Down Expand Up @@ -588,6 +772,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
EXPORT_SYMBOL_GPL(tpm_show_pubek);

#define CAP_VERSION_1_1 6
#define CAP_VERSION_1_2 0x1A
#define CAP_VERSION_IDX 13
static const u8 cap_version[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
Expand All @@ -600,7 +785,7 @@ static const u8 cap_version[] = {
ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
char *buf)
{
u8 data[30];
u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
ssize_t rc;
char *str = buf;

Expand Down Expand Up @@ -637,6 +822,52 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
}
EXPORT_SYMBOL_GPL(tpm_show_caps);

ssize_t tpm_show_caps_1_2(struct device * dev,
struct device_attribute * attr, char *buf)
{
u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
ssize_t len;
char *str = buf;

struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return -ENODEV;

memcpy(data, tpm_cap, sizeof(tpm_cap));
data[TPM_CAP_IDX] = TPM_CAP_PROP;
data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;

if ((len = tpm_transmit(chip, data, sizeof(data))) <=
TPM_ERROR_SIZE) {
dev_dbg(chip->dev, "A TPM error (%d) occurred "
"attempting to determine the manufacturer\n",
be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
return 0;
}

str += sprintf(str, "Manufacturer: 0x%x\n",
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));

memcpy(data, cap_version, sizeof(cap_version));
data[CAP_VERSION_IDX] = CAP_VERSION_1_2;

if ((len = tpm_transmit(chip, data, sizeof(data))) <=
TPM_ERROR_SIZE) {
dev_err(chip->dev, "A TPM error (%d) occurred "
"attempting to determine the 1.2 version\n",
be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
goto out;
}
str += sprintf(str,
"TCG version: %d.%d\nFirmware version: %d.%d\n",
(int) data[16], (int) data[17], (int) data[18],
(int) data[19]);

out:
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);

ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
Expand Down
14 changes: 14 additions & 0 deletions trunk/drivers/char/tpm/tpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,18 @@ 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_show_caps_1_2(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 *);

struct tpm_chip;

Expand All @@ -63,6 +73,7 @@ struct tpm_vendor_specific {
u8 (*status) (struct tpm_chip *);
struct miscdevice miscdev;
struct attribute_group *attr_group;
u32 timeout_a, timeout_b, timeout_c, timeout_d;
u32 duration[3];
};

Expand Down Expand Up @@ -101,6 +112,9 @@ static inline void tpm_write_index(int base, int index, int value)
outb(value & 0xFF, base+1);
}

extern void tpm_get_timeouts(struct tpm_chip *);
extern void tpm_gen_interrupt(struct tpm_chip *);
extern void tpm_continue_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 *);
Expand Down

0 comments on commit f4e2136

Please sign in to comment.