From 74880c063b06efd103c924abfe19d9d8fa4864c4 Mon Sep 17 00:00:00 2001 From: Yani Ioannou Date: Tue, 17 May 2005 06:41:12 -0400 Subject: [PATCH] Driver Core: drivers/base - drivers/i2c/chips/adm1026.c: update device attribute callbacks Signed-off-by: Yani Ioannou Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 87235330fdb..8ce508b2986 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -212,7 +212,7 @@ static u8 pcrread[] = { 0, 0, 0, 0 /* PCR index */ }; -static ssize_t show_pcrs(struct device *dev, char *buf) +static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) { u8 data[READ_PCR_RESULT_SIZE]; ssize_t len; @@ -255,7 +255,7 @@ static u8 readpubek[] = { 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ }; -static ssize_t show_pubek(struct device *dev, char *buf) +static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf) { u8 data[READ_PUBEK_RESULT_SIZE]; ssize_t len; @@ -330,7 +330,7 @@ static u8 cap_manufacturer[] = { 0, 0, 1, 3 }; -static ssize_t show_caps(struct device *dev, char *buf) +static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf) { u8 data[READ_PUBEK_RESULT_SIZE]; ssize_t len; -- cgit v1.2.3 From 700d8bdcd0fa815b08638b1e4d43b66d60cc6a8d Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Thu, 23 Jun 2005 22:01:47 -0700 Subject: [PATCH] char/tpm: use msleep(), clean-up timers, The TPM driver unnecessarily uses timers when it simply needs to maintain a maximum delay via time_before(). msleep() is used instead of schedule_timeout() to guarantee the task delays as expected. While compile-testing, I found a typo in the driver, using tpm_chp instead of tpm_chip. Remove the now unused timer callback function and change TPM_TIMEOUT's units to milliseconds. Patch is compile-tested. Signed-off-by: Nishanth Aravamudan Acked-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 8ce508b2986..c937ea2bcdb 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -19,7 +19,7 @@ * * Note, the TPM chip is not interrupt driven (only polling) * and can have very long timeouts (minutes!). Hence the unusual - * calls to schedule_timeout. + * calls to msleep. * */ @@ -52,14 +52,6 @@ static void user_reader_timeout(unsigned long ptr) up(&chip->buffer_mutex); } -void tpm_time_expired(unsigned long ptr) -{ - int *exp = (int *) ptr; - *exp = 1; -} - -EXPORT_SYMBOL_GPL(tpm_time_expired); - /* * Initialize the LPC bus and enable the TPM ports */ @@ -135,6 +127,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, ssize_t len; u32 count; __be32 *native_size; + unsigned long stop; native_size = (__force __be32 *) (buf + 2); count = be32_to_cpu(*native_size); @@ -155,28 +148,16 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, return len; } - down(&chip->timer_manipulation_mutex); - chip->time_expired = 0; - init_timer(&chip->device_timer); - chip->device_timer.function = tpm_time_expired; - chip->device_timer.expires = jiffies + 2 * 60 * HZ; - chip->device_timer.data = (unsigned long) &chip->time_expired; - add_timer(&chip->device_timer); - up(&chip->timer_manipulation_mutex); - + stop = jiffies + 2 * 60 * HZ; do { u8 status = inb(chip->vendor->base + 1); if ((status & chip->vendor->req_complete_mask) == chip->vendor->req_complete_val) { - down(&chip->timer_manipulation_mutex); - del_singleshot_timer_sync(&chip->device_timer); - up(&chip->timer_manipulation_mutex); goto out_recv; } - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(TPM_TIMEOUT); + msleep(TPM_TIMEOUT); /* CHECK */ rmb(); - } while (!chip->time_expired); + } while (time_before(jiffies, stop)); chip->vendor->cancel(chip); @@ -453,10 +434,8 @@ ssize_t tpm_write(struct file * file, const char __user * buf, /* cannot perform a write until the read has cleared either via tpm_read or a user_read_timer timeout */ - while (atomic_read(&chip->data_pending) != 0) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(TPM_TIMEOUT); - } + while (atomic_read(&chip->data_pending) != 0) + msleep(TPM_TIMEOUT); down(&chip->buffer_mutex); -- cgit v1.2.3 From 3122a88a242454efe72930e56a3e4d56ee534f3c Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:48 -0700 Subject: [PATCH] tpm: Fix concerns with TPM driver -- use enums Convert #defines to named enums where that preference has been indicated by other kernel developers. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index c937ea2bcdb..7da4fe92127 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -28,19 +28,35 @@ #include #include "tpm.h" -#define TPM_MINOR 224 /* officially assigned */ +enum tpm_const { + TPM_MINOR = 224, /* officially assigned */ + TPM_BUFSIZE = 2048, + TPM_NUM_DEVICES = 256, + TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int)) +}; -#define TPM_BUFSIZE 2048 + /* PCI configuration addresses */ +enum tpm_pci_config_addr { + PCI_GEN_PMCON_1 = 0xA0, + PCI_GEN1_DEC = 0xE4, + PCI_LPC_EN = 0xE6, + PCI_GEN2_DEC = 0xEC +}; + +enum tpm_config { + TPM_LOCK_REG = 0x0D, + TPM_INTERUPT_REG = 0x0A, + TPM_BASE_ADDR_LO = 0x08, + TPM_BASE_ADDR_HI = 0x09, + TPM_UNLOCK_VALUE = 0x55, + TPM_LOCK_VALUE = 0xAA, + TPM_DISABLE_INTERUPT_VALUE = 0x00 +}; -/* PCI configuration addresses */ -#define PCI_GEN_PMCON_1 0xA0 -#define PCI_GEN1_DEC 0xE4 -#define PCI_LPC_EN 0xE6 -#define PCI_GEN2_DEC 0xEC static LIST_HEAD(tpm_chip_list); static DEFINE_SPINLOCK(driver_lock); -static int dev_mask[32]; +static int dev_mask[TPM_NUM_MASK_ENTRIES]; static void user_reader_timeout(unsigned long ptr) { @@ -102,17 +118,18 @@ int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base) pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1, tmp); } - tpm_write_index(0x0D, 0x55); /* unlock 4F */ - tpm_write_index(0x0A, 0x00); /* int disable */ - tpm_write_index(0x08, base); /* base addr lo */ - tpm_write_index(0x09, (base & 0xFF00) >> 8); /* base addr hi */ - tpm_write_index(0x0D, 0xAA); /* lock 4F */ break; case PCI_VENDOR_ID_AMD: /* nothing yet */ break; } + tpm_write_index(TPM_LOCK_REG, TPM_UNLOCK_VALUE); + tpm_write_index(TPM_INTERUPT_REG, TPM_DISABLE_INTERUPT_VALUE); + tpm_write_index(TPM_BASE_ADDR_LO, base); + tpm_write_index(TPM_BASE_ADDR_HI, (base & 0xFF00) >> 8); + tpm_write_index(TPM_LOCK_REG, TPM_LOCK_VALUE); + return 0; } @@ -527,7 +544,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) pci_disable_device(pci_dev); - dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32)); + dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); kfree(chip); @@ -608,10 +625,11 @@ int tpm_register_hardware(struct pci_dev *pci_dev, chip->dev_num = -1; - for (i = 0; i < 32; i++) - for (j = 0; j < 8; j++) + for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++) + for (j = 0; j < 8 * sizeof(int); j++) if ((dev_mask[i] & (1 << j)) == 0) { - chip->dev_num = i * 32 + j; + chip->dev_num = + i * TPM_NUM_MASK_ENTRIES + j; dev_mask[i] |= 1 << j; goto dev_num_search_complete; } -- cgit v1.2.3 From dff37e4b0ad7bca3616f829c84bcf4ddd385d2c4 Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:50 -0700 Subject: [PATCH] tpm: address missing const defs Add "const" to several static arrays that were missing it in their definitions. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 7da4fe92127..9a5d46a3c17 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -193,7 +193,7 @@ out_recv: #define TPM_DIGEST_SIZE 20 #define CAP_PCR_RESULT_SIZE 18 -static u8 cap_pcr[] = { +static const u8 cap_pcr[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ 0, 0, 0, 22, /* length */ 0, 0, 0, 101, /* TPM_ORD_GetCapability */ @@ -203,7 +203,7 @@ static u8 cap_pcr[] = { }; #define READ_PCR_RESULT_SIZE 30 -static u8 pcrread[] = { +static const u8 pcrread[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ 0, 0, 0, 14, /* length */ 0, 0, 0, 21, /* TPM_ORD_PcrRead */ @@ -247,7 +247,7 @@ static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL); #define READ_PUBEK_RESULT_SIZE 314 -static u8 readpubek[] = { +static const u8 readpubek[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ 0, 0, 0, 30, /* length */ 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ @@ -310,7 +310,7 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL); #define CAP_VER_RESULT_SIZE 18 -static u8 cap_version[] = { +static const u8 cap_version[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ 0, 0, 0, 18, /* length */ 0, 0, 0, 101, /* TPM_ORD_GetCapability */ @@ -319,7 +319,7 @@ static u8 cap_version[] = { }; #define CAP_MANUFACTURER_RESULT_SIZE 18 -static u8 cap_manufacturer[] = { +static const u8 cap_manufacturer[] = { 0, 193, /* TPM_TAG_RQU_COMMAND */ 0, 0, 0, 22, /* length */ 0, 0, 0, 101, /* TPM_ORD_GetCapability */ -- cgit v1.2.3 From f87ea32ae2a986acc5258ad736ab0b55937c9489 Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:51 -0700 Subject: [PATCH] tpm: remove unnecessary module stuff Description: Remove unnecessary (empty) module definitions. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 9a5d46a3c17..ff170963c64 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -675,19 +675,6 @@ dev_num_search_complete: EXPORT_SYMBOL_GPL(tpm_register_hardware); -static int __init init_tpm(void) -{ - return 0; -} - -static void __exit cleanup_tpm(void) -{ - -} - -module_init(init_tpm); -module_exit(cleanup_tpm); - MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); MODULE_DESCRIPTION("TPM Driver"); MODULE_VERSION("2.0"); -- cgit v1.2.3 From 5b44bd58063f7839f42a4047843e93e1fbf73cda Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:53 -0700 Subject: [PATCH] tpm: read return code issue Replace an erroneous return code for the read function when no data is available. Signed-of-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ff170963c64..7b1f67d9f30 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -489,29 +489,19 @@ ssize_t tpm_read(struct file * file, char __user * buf, size_t size, loff_t * off) { struct tpm_chip *chip = file->private_data; - int ret_size = -ENODATA; + int ret_size; - if (atomic_read(&chip->data_pending) != 0) { /* Result available */ - down(&chip->timer_manipulation_mutex); - del_singleshot_timer_sync(&chip->user_read_timer); - up(&chip->timer_manipulation_mutex); + del_singleshot_timer_sync(&chip->user_read_timer); + ret_size = atomic_read(&chip->data_pending); + atomic_set(&chip->data_pending, 0); + if (ret_size > 0) { /* relay data */ + if (size < ret_size) + ret_size = size; down(&chip->buffer_mutex); - - ret_size = atomic_read(&chip->data_pending); - atomic_set(&chip->data_pending, 0); - - if (ret_size == 0) /* timeout just occurred */ - ret_size = -ETIME; - else if (ret_size > 0) { /* relay data */ - if (size < ret_size) - ret_size = size; - - if (copy_to_user((void __user *) buf, - chip->data_buffer, ret_size)) { - ret_size = -EFAULT; - } - } + if (copy_to_user + ((void __user *) buf, chip->data_buffer, ret_size)) + ret_size = -EFAULT; up(&chip->buffer_mutex); } -- cgit v1.2.3 From 2df7111fc6b0e050b06123379821ece2f8dd5bbc Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:54 -0700 Subject: [PATCH] tpm: large stack objects Remove some large objects be declared on the the stack. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 7b1f67d9f30..2035c15ffcc 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -255,7 +255,7 @@ static const u8 readpubek[] = { static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf) { - u8 data[READ_PUBEK_RESULT_SIZE]; + u8 *data; ssize_t len; __be32 *native_val; int i; @@ -266,12 +266,18 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha if (chip == NULL) return -ENODEV; + data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); + if (!data) + return -ENOMEM; + memcpy(data, readpubek, sizeof(readpubek)); memset(data + sizeof(readpubek), 0, 20); /* zero nonce */ - if ((len = tpm_transmit(chip, data, sizeof(data))) < - READ_PUBEK_RESULT_SIZE) - return len; + if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < + READ_PUBEK_RESULT_SIZE) { + rc = len; + goto out; + } /* ignore header 10 bytes @@ -304,7 +310,10 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha if ((i + 1) % 16 == 0) str += sprintf(str, "\n"); } - return str - buf; + rc = str - buf; +out: + kfree(data); + return rc; } static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL); @@ -330,7 +339,7 @@ static const u8 cap_manufacturer[] = { static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf) { - u8 data[READ_PUBEK_RESULT_SIZE]; + u8 data[sizeof(cap_manufacturer)]; ssize_t len; char *str = buf; -- cgit v1.2.3 From fe3fd48384af79e7619d3c6b0a020f801ef63c3b Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:56 -0700 Subject: [PATCH] tpm: fix timer initialization Fix the timer to be inited and modified properly. This work depends on the fixing of the msleep stuff which in patch 1 of this set. Signed-of-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 2035c15ffcc..f7fa3c3a51b 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -434,16 +434,7 @@ int tpm_release(struct inode *inode, struct file *file) spin_lock(&driver_lock); chip->num_opens--; - spin_unlock(&driver_lock); - - down(&chip->timer_manipulation_mutex); - if (timer_pending(&chip->user_read_timer)) - del_singleshot_timer_sync(&chip->user_read_timer); - else if (timer_pending(&chip->device_timer)) - del_singleshot_timer_sync(&chip->device_timer); - up(&chip->timer_manipulation_mutex); - - kfree(chip->data_buffer); + del_singleshot_timer_sync(&chip->user_read_timer); atomic_set(&chip->data_pending, 0); pci_dev_put(chip->pci_dev); @@ -481,13 +472,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf, up(&chip->buffer_mutex); /* Set a timeout by which the reader must come claim the result */ - down(&chip->timer_manipulation_mutex); - init_timer(&chip->user_read_timer); - chip->user_read_timer.function = user_reader_timeout; - chip->user_read_timer.data = (unsigned long) chip; - chip->user_read_timer.expires = jiffies + (60 * HZ); - add_timer(&chip->user_read_timer); - up(&chip->timer_manipulation_mutex); + mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); return in_size; } @@ -617,9 +602,12 @@ int tpm_register_hardware(struct pci_dev *pci_dev, init_MUTEX(&chip->buffer_mutex); init_MUTEX(&chip->tpm_mutex); - init_MUTEX(&chip->timer_manipulation_mutex); INIT_LIST_HEAD(&chip->list); + init_timer(&chip->user_read_timer); + chip->user_read_timer.function = user_reader_timeout; + chip->user_read_timer.data = (unsigned long) chip; + chip->vendor = entry; chip->dev_num = -1; -- cgit v1.2.3 From e2fe90666a84e6a11c541424dfa9eec20cfe5fc1 Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:57 -0700 Subject: [PATCH] tpm: use to_pci_dev Changes the container_of calls to 'to_pci_dev' as suggested previously. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index f7fa3c3a51b..39e82314d67 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -218,7 +218,7 @@ static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char char *str = buf; struct tpm_chip *chip = - pci_get_drvdata(container_of(dev, struct pci_dev, dev)); + pci_get_drvdata(to_pci_dev(dev)); if (chip == NULL) return -ENODEV; @@ -262,7 +262,7 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha char *str = buf; struct tpm_chip *chip = - pci_get_drvdata(container_of(dev, struct pci_dev, dev)); + pci_get_drvdata(to_pci_dev(dev)); if (chip == NULL) return -ENODEV; @@ -344,7 +344,7 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char char *str = buf; struct tpm_chip *chip = - pci_get_drvdata(container_of(dev, struct pci_dev, dev)); + pci_get_drvdata(to_pci_dev(dev)); if (chip == NULL) return -ENODEV; -- cgit v1.2.3 From 81179bb6a54c2c626b4cbcc084ca974bb2d7f2a3 Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:01:59 -0700 Subject: [PATCH] tpm: remove unnecessary __force Remove the unnecessary use of __force. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 39e82314d67..84b2d46e6ff 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -143,11 +143,9 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, { ssize_t len; u32 count; - __be32 *native_size; unsigned long stop; - native_size = (__force __be32 *) (buf + 2); - count = be32_to_cpu(*native_size); + count = be32_to_cpu(*((__be32 *) (buf + 2))); if (count == 0) return -ENODATA; @@ -214,7 +212,8 @@ static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char { u8 data[READ_PCR_RESULT_SIZE]; ssize_t len; - int i, j, index, num_pcrs; + int i, j, num_pcrs; + __be32 index; char *str = buf; struct tpm_chip *chip = @@ -227,7 +226,7 @@ static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char < CAP_PCR_RESULT_SIZE) return len; - num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14))); + num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); for (i = 0; i < num_pcrs; i++) { memcpy(data, pcrread, sizeof(pcrread)); @@ -257,8 +256,7 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha { u8 *data; ssize_t len; - __be32 *native_val; - int i; + int i, rc; char *str = buf; struct tpm_chip *chip = @@ -290,8 +288,6 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha ignore checksum 20 bytes */ - native_val = (__force __be32 *) (data + 34); - str += sprintf(str, "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n" @@ -302,8 +298,7 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha data[15], data[16], data[17], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], - be32_to_cpu(*native_val) - ); + be32_to_cpu(*((__be32 *) (data + 32)))); for (i = 0; i < 256; i++) { str += sprintf(str, "%02X ", data[i + 39]); @@ -355,7 +350,7 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char return len; str += sprintf(str, "Manufacturer: 0x%x\n", - be32_to_cpu(*(data + 14))); + be32_to_cpu(*((__be32 *) (data + 14)))); memcpy(data, cap_version, sizeof(cap_version)); -- cgit v1.2.3 From 6659ca2ab6730c3bbb9fa495f2327b95b955decd Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:02:00 -0700 Subject: [PATCH] tpm: sysfs owernship changes In the current driver all sysfs files end up owned by the base driver module rather than the module that actually owns the device this is a problem if the module is unloaded and the file is open. This patch fixes all that and lumps the files into an attribute_group. Signed-off-by: Kylene Hall Signed-off-by: Yani Ioannou Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 84b2d46e6ff..b72050c851d 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -208,7 +208,8 @@ static const u8 pcrread[] = { 0, 0, 0, 0 /* PCR index */ }; -static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) +ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, + char *buf) { u8 data[READ_PCR_RESULT_SIZE]; ssize_t len; @@ -243,7 +244,7 @@ static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char return str - buf; } -static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL); +EXPORT_SYMBOL_GPL(tpm_show_pcrs); #define READ_PUBEK_RESULT_SIZE 314 static const u8 readpubek[] = { @@ -252,7 +253,8 @@ static const u8 readpubek[] = { 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ }; -static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf) +ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, + char *buf) { u8 *data; ssize_t len; @@ -311,7 +313,7 @@ out: return rc; } -static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL); +EXPORT_SYMBOL_GPL(tpm_show_pubek); #define CAP_VER_RESULT_SIZE 18 static const u8 cap_version[] = { @@ -332,7 +334,8 @@ static const u8 cap_manufacturer[] = { 0, 0, 1, 3 }; -static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf) +ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, + char *buf) { u8 data[sizeof(cap_manufacturer)]; ssize_t len; @@ -365,8 +368,20 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char return str - buf; } +EXPORT_SYMBOL_GPL(tpm_show_caps); + +ssize_t tpm_store_cancel(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->vendor->cancel(chip); + return count; +} +EXPORT_SYMBOL_GPL(tpm_store_cancel); -static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL); /* * Device file system interface to the TPM @@ -517,9 +532,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) pci_set_drvdata(pci_dev, NULL); misc_deregister(&chip->vendor->miscdev); - device_remove_file(&pci_dev->dev, &dev_attr_pubek); - device_remove_file(&pci_dev->dev, &dev_attr_pcrs); - device_remove_file(&pci_dev->dev, &dev_attr_caps); + sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); pci_disable_device(pci_dev); @@ -648,9 +661,7 @@ dev_num_search_complete: list_add(&chip->list, &tpm_chip_list); - device_create_file(&pci_dev->dev, &dev_attr_pubek); - device_create_file(&pci_dev->dev, &dev_attr_pcrs); - device_create_file(&pci_dev->dev, &dev_attr_caps); + sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group); return 0; } -- cgit v1.2.3 From d9e5b6bf9cf19e6e9f2825228136ea17bc9a051a Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:02:02 -0700 Subject: [PATCH] tpm: add cancel function This patch provides the logic to check if an operation has been canceled while waiting for the response to arrive. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index b72050c851d..e7c1dedfe44 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -141,7 +141,7 @@ EXPORT_SYMBOL_GPL(tpm_lpc_bus_init); static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, size_t bufsiz) { - ssize_t len; + ssize_t rc; u32 count; unsigned long stop; @@ -157,10 +157,10 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, down(&chip->tpm_mutex); - if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { + if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { dev_err(&chip->pci_dev->dev, - "tpm_transmit: tpm_send: error %zd\n", len); - return len; + "tpm_transmit: tpm_send: error %zd\n", rc); + goto out; } stop = jiffies + 2 * 60 * HZ; @@ -170,23 +170,31 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, chip->vendor->req_complete_val) { goto out_recv; } - msleep(TPM_TIMEOUT); /* CHECK */ + + if ((status == chip->vendor->req_canceled)) { + dev_err(&chip->pci_dev->dev, "Operation Canceled\n"); + rc = -ECANCELED; + goto out; + } + + msleep(TPM_TIMEOUT); /* CHECK */ rmb(); } while (time_before(jiffies, stop)); chip->vendor->cancel(chip); - dev_err(&chip->pci_dev->dev, "Time expired\n"); - up(&chip->tpm_mutex); - return -EIO; + dev_err(&chip->pci_dev->dev, "Operation Timed out\n"); + rc = -ETIME; + goto out; out_recv: - len = chip->vendor->recv(chip, (u8 *) buf, bufsiz); - if (len < 0) + rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); + if (rc < 0) dev_err(&chip->pci_dev->dev, - "tpm_transmit: tpm_recv: error %zd\n", len); + "tpm_transmit: tpm_recv: error %zd\n", rc); +out: up(&chip->tpm_mutex); - return len; + return rc; } #define TPM_DIGEST_SIZE 20 -- cgit v1.2.3 From 5e976d5557d3dd1e835b8be52e6201556dcfa052 Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:02:03 -0700 Subject: [PATCH] tpm: locking fixes Add a missing lock in the register hardware and fix a misplaced lock release release. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index e7c1dedfe44..c6d985b04b6 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -447,15 +447,15 @@ EXPORT_SYMBOL_GPL(tpm_open); int tpm_release(struct inode *inode, struct file *file) { struct tpm_chip *chip = file->private_data; - - file->private_data = NULL; spin_lock(&driver_lock); + file->private_data = NULL; chip->num_opens--; del_singleshot_timer_sync(&chip->user_read_timer); atomic_set(&chip->data_pending, 0); - pci_dev_put(chip->pci_dev); + kfree(chip->data_buffer); + spin_unlock(&driver_lock); return 0; } @@ -665,10 +665,14 @@ dev_num_search_complete: return -ENODEV; } + spin_lock(&driver_lock); + pci_set_drvdata(pci_dev, chip); list_add(&chip->list, &tpm_chip_list); + spin_unlock(&driver_lock); + sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group); return 0; -- cgit v1.2.3 From e1a23c6671f2bfd6e5e112848f01334ca39ea2b1 Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:02:06 -0700 Subject: [PATCH] tpm: replace odd LPC init function Realized the tpm_lpc_init function isn't really necessary. Replaced it with vendor specific logic to find out the address the BIOS mapped the TPM to. This patch removes the tpm_lpc_init function, enums associated with it and calls to it. The patch also implements the replacement functionality. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 90 -------------------------------------------------- 1 file changed, 90 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index c6d985b04b6..726d1b5b33b 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -35,25 +35,6 @@ enum tpm_const { TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int)) }; - /* PCI configuration addresses */ -enum tpm_pci_config_addr { - PCI_GEN_PMCON_1 = 0xA0, - PCI_GEN1_DEC = 0xE4, - PCI_LPC_EN = 0xE6, - PCI_GEN2_DEC = 0xEC -}; - -enum tpm_config { - TPM_LOCK_REG = 0x0D, - TPM_INTERUPT_REG = 0x0A, - TPM_BASE_ADDR_LO = 0x08, - TPM_BASE_ADDR_HI = 0x09, - TPM_UNLOCK_VALUE = 0x55, - TPM_LOCK_VALUE = 0xAA, - TPM_DISABLE_INTERUPT_VALUE = 0x00 -}; - - static LIST_HEAD(tpm_chip_list); static DEFINE_SPINLOCK(driver_lock); static int dev_mask[TPM_NUM_MASK_ENTRIES]; @@ -68,73 +49,6 @@ static void user_reader_timeout(unsigned long ptr) up(&chip->buffer_mutex); } -/* - * Initialize the LPC bus and enable the TPM ports - */ -int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base) -{ - u32 lpcenable, tmp; - int is_lpcm = 0; - - switch (pci_dev->vendor) { - case PCI_VENDOR_ID_INTEL: - switch (pci_dev->device) { - case PCI_DEVICE_ID_INTEL_82801CA_12: - case PCI_DEVICE_ID_INTEL_82801DB_12: - is_lpcm = 1; - break; - } - /* init ICH (enable LPC) */ - pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable); - lpcenable |= 0x20000000; - pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable); - - if (is_lpcm) { - pci_read_config_dword(pci_dev, PCI_GEN1_DEC, - &lpcenable); - if ((lpcenable & 0x20000000) == 0) { - dev_err(&pci_dev->dev, - "cannot enable LPC\n"); - return -ENODEV; - } - } - - /* initialize TPM registers */ - pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp); - - if (!is_lpcm) - tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0); - else - tmp = - (tmp & 0xFFFF0000) | (base & 0xFFF0) | - 0x00000001; - - pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp); - - if (is_lpcm) { - pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1, - &tmp); - tmp |= 0x00000004; /* enable CLKRUN */ - pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1, - tmp); - } - break; - case PCI_VENDOR_ID_AMD: - /* nothing yet */ - break; - } - - tpm_write_index(TPM_LOCK_REG, TPM_UNLOCK_VALUE); - tpm_write_index(TPM_INTERUPT_REG, TPM_DISABLE_INTERUPT_VALUE); - tpm_write_index(TPM_BASE_ADDR_LO, base); - tpm_write_index(TPM_BASE_ADDR_HI, (base & 0xFF00) >> 8); - tpm_write_index(TPM_LOCK_REG, TPM_LOCK_VALUE); - - return 0; -} - -EXPORT_SYMBOL_GPL(tpm_lpc_bus_init); - /* * Internal kernel interface to transmit TPM commands */ @@ -586,10 +500,6 @@ int tpm_pm_resume(struct pci_dev *pci_dev) if (chip == NULL) return -ENODEV; - spin_lock(&driver_lock); - tpm_lpc_bus_init(pci_dev, chip->vendor->base); - spin_unlock(&driver_lock); - return 0; } -- cgit v1.2.3 From e234bc970451edc4021637fe2979b887da873f9a Mon Sep 17 00:00:00 2001 From: Kylene Hall Date: Thu, 23 Jun 2005 22:02:08 -0700 Subject: [PATCH] tpm: add debugging output Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 726d1b5b33b..785dce67942 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -146,8 +146,12 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, memcpy(data, cap_pcr, sizeof(cap_pcr)); if ((len = tpm_transmit(chip, data, sizeof(data))) - < CAP_PCR_RESULT_SIZE) - return len; + < CAP_PCR_RESULT_SIZE) { + dev_err(&chip->pci_dev->dev, "A TPM error (%d) occurred " + "attempting to determine the number of PCRS\n", + be32_to_cpu(*((__be32 *) (data + 6)))); + return 0; + } num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); @@ -156,16 +160,20 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, index = cpu_to_be32(i); memcpy(data + 10, &index, 4); if ((len = tpm_transmit(chip, data, sizeof(data))) - < READ_PCR_RESULT_SIZE) - return len; + < READ_PCR_RESULT_SIZE){ + dev_err(&chip->pci_dev->dev, "A TPM error (%d) occurred" + " attempting to read PCR %d of %d\n", + be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs); + goto out; + } str += sprintf(str, "PCR-%02d: ", i); for (j = 0; j < TPM_DIGEST_SIZE; j++) str += sprintf(str, "%02X ", *(data + 10 + j)); str += sprintf(str, "\n"); } +out: return str - buf; } - EXPORT_SYMBOL_GPL(tpm_show_pcrs); #define READ_PUBEK_RESULT_SIZE 314 @@ -197,8 +205,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < READ_PUBEK_RESULT_SIZE) { - rc = len; - goto out; + dev_err(&chip->pci_dev->dev, "A TPM error (%d) occurred " + "attempting to read the PUBEK\n", + be32_to_cpu(*((__be32 *) (data + 6)))); + return 0; } /* @@ -230,7 +240,6 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, str += sprintf(str, "\n"); } rc = str - buf; -out: kfree(data); return rc; } -- cgit v1.2.3 From 34d6e07570ef74b965131452a862b13dfa779188 Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Thu, 23 Jun 2005 22:02:10 -0700 Subject: [PATCH] tpm: improve output in sysfs files when the TPM fails Since after reconsideration this is more debug output than an error (the TPM is operating correctly given the current state) I have changed the statements to dbg rather than err. Also this patch corrects a memory leak if the error path is taken in the tpm_show_pubek function. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 785dce67942..5c843c9bf81 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -147,7 +147,7 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, memcpy(data, cap_pcr, sizeof(cap_pcr)); if ((len = tpm_transmit(chip, data, sizeof(data))) < CAP_PCR_RESULT_SIZE) { - dev_err(&chip->pci_dev->dev, "A TPM error (%d) occurred " + dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred " "attempting to determine the number of PCRS\n", be32_to_cpu(*((__be32 *) (data + 6)))); return 0; @@ -161,7 +161,7 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, memcpy(data + 10, &index, 4); if ((len = tpm_transmit(chip, data, sizeof(data))) < READ_PCR_RESULT_SIZE){ - dev_err(&chip->pci_dev->dev, "A TPM error (%d) occurred" + dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred" " attempting to read PCR %d of %d\n", be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs); goto out; @@ -205,10 +205,11 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < READ_PUBEK_RESULT_SIZE) { - dev_err(&chip->pci_dev->dev, "A TPM error (%d) occurred " + dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred " "attempting to read the PUBEK\n", be32_to_cpu(*((__be32 *) (data + 6)))); - return 0; + rc = 0; + goto out; } /* @@ -240,6 +241,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, str += sprintf(str, "\n"); } rc = str - buf; +out: kfree(data); return rc; } -- cgit v1.2.3 From 1dda8abe6feb906306a627b170654ddd8addcdac Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Sat, 25 Jun 2005 14:55:40 -0700 Subject: [PATCH] tpm: Fix pubek parsing Fix parsing of the PUBEK for display which was leading to showing the wrong modulus length and modulus. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 5c843c9bf81..1156d11f02d 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -233,10 +233,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, data[15], data[16], data[17], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], - be32_to_cpu(*((__be32 *) (data + 32)))); + be32_to_cpu(*((__be32 *) (data + 34)))); for (i = 0; i < 256; i++) { - str += sprintf(str, "%02X ", data[i + 39]); + str += sprintf(str, "%02X ", data[i + 38]); if ((i + 1) % 16 == 0) str += sprintf(str, "\n"); } -- cgit v1.2.3 From 6f9beccb95a47a15e446f64fbb7041dc6edce4d9 Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Sat, 25 Jun 2005 14:55:41 -0700 Subject: [PATCH] tpm: fix misc name memory problem I was using invalid memory for the miscdevice.name. This patch fixes the problem which was manifested by an ugly entry in /proc/misc. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/char/tpm/tpm.c') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 1156d11f02d..854475c54f0 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -464,6 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) pci_set_drvdata(pci_dev, NULL); misc_deregister(&chip->vendor->miscdev); + kfree(&chip->vendor->miscdev.name); sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); @@ -526,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume); int tpm_register_hardware(struct pci_dev *pci_dev, struct tpm_vendor_specific *entry) { - char devname[7]; +#define DEVNAME_SIZE 7 + + char *devname; struct tpm_chip *chip; int i, j; @@ -569,7 +572,8 @@ dev_num_search_complete: else chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; - snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num); + devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); + scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); chip->vendor->miscdev.name = devname; chip->vendor->miscdev.dev = &(pci_dev->dev); -- cgit v1.2.3