ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/char/tpm/tpm_nopci.c @ 7169:dd87869f877c

Allow adjustment of the size of TPM transfer buffers
to the size that a lower-layer driver supports.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Oct 03 15:05:37 2005 +0100 (2005-10-03)
parents 06d84bf87159
children
line source
1 /*
2 * Copyright (C) 2004 IBM Corporation
3 *
4 * Authors:
5 * Leendert van Doorn <leendert@watson.ibm.com>
6 * Dave Safford <safford@watson.ibm.com>
7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com>
9 *
10 * Maintained by: <tpmdd_devel@lists.sourceforge.net>
11 *
12 * Device driver for TCG/TCPA TPM (trusted platform module).
13 * Specifications at www.trustedcomputinggroup.org
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation, version 2 of the
18 * License.
19 *
20 * Note, the TPM chip is not interrupt driven (only polling)
21 * and can have very long timeouts (minutes!). Hence the unusual
22 * calls to schedule_timeout.
23 *
24 */
26 #include <linux/sched.h>
27 #include <linux/poll.h>
28 #include <linux/spinlock.h>
29 #include "tpm_nopci.h"
31 enum {
32 TPM_MINOR = 224, /* officially assigned */
33 TPM_MIN_BUFSIZE = 2048,
34 TPM_MAX_BUFSIZE = 65536,
35 TPM_NUM_DEVICES = 256,
36 TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
37 };
39 /* PCI configuration addresses */
40 enum {
41 PCI_GEN_PMCON_1 = 0xA0,
42 PCI_GEN1_DEC = 0xE4,
43 PCI_LPC_EN = 0xE6,
44 PCI_GEN2_DEC = 0xEC
45 };
47 enum {
48 TPM_LOCK_REG = 0x0D,
49 TPM_INTERUPT_REG = 0x0A,
50 TPM_BASE_ADDR_LO = 0x08,
51 TPM_BASE_ADDR_HI = 0x09,
52 TPM_UNLOCK_VALUE = 0x55,
53 TPM_LOCK_VALUE = 0xAA,
54 TPM_DISABLE_INTERUPT_VALUE = 0x00
55 };
57 static LIST_HEAD(tpm_chip_list);
58 static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
59 static int dev_mask[32];
61 static void user_reader_timeout(unsigned long ptr)
62 {
63 struct tpm_chip *chip = (struct tpm_chip *) ptr;
65 down(&chip->buffer_mutex);
66 atomic_set(&chip->data_pending, 0);
67 memset(chip->data_buffer, 0, chip->vendor->buffersize);
68 up(&chip->buffer_mutex);
69 }
71 void tpm_time_expired(unsigned long ptr)
72 {
73 int *exp = (int *) ptr;
74 *exp = 1;
75 }
77 EXPORT_SYMBOL_GPL(tpm_time_expired);
80 /*
81 * This function should be used by other kernel subsystems attempting to use the tpm through the tpm_transmit interface.
82 * A call to this function will return the chip structure corresponding to the TPM you are looking for that can then be sent with your command to tpm_transmit.
83 * Passing 0 as the argument corresponds to /dev/tpm0 and thus the first and probably primary TPM on the system. Passing 1 corresponds to /dev/tpm1 and the next TPM discovered. If a TPM with the given chip_num does not exist NULL will be returned.
84 */
85 struct tpm_chip* tpm_chip_lookup(int chip_num)
86 {
88 struct tpm_chip *pos;
89 list_for_each_entry(pos, &tpm_chip_list, list)
90 if (pos->dev_num == chip_num ||
91 chip_num == TPM_ANY_NUM)
92 return pos;
94 return NULL;
96 }
98 /*
99 * Internal kernel interface to transmit TPM commands
100 */
101 ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
102 size_t bufsiz)
103 {
104 ssize_t rc;
105 u32 count;
106 unsigned long stop;
108 count = be32_to_cpu(*((__be32 *) (buf + 2)));
110 if (count == 0)
111 return -ENODATA;
112 if (count > bufsiz) {
113 dev_err(chip->dev,
114 "invalid count value %x %x \n", count, bufsiz);
115 return -E2BIG;
116 }
118 dev_dbg(chip->dev, "TPM Ordinal: %d\n",
119 be32_to_cpu(*((__be32 *) (buf + 6))));
120 dev_dbg(chip->dev, "Chip Status: %x\n",
121 inb(chip->vendor->base + 1));
123 down(&chip->tpm_mutex);
125 if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
126 dev_err(chip->dev,
127 "tpm_transmit: tpm_send: error %d\n", rc);
128 goto out;
129 }
131 stop = jiffies + 2 * 60 * HZ;
132 do {
133 u8 status = chip->vendor->status(chip);
134 if ((status & chip->vendor->req_complete_mask) ==
135 chip->vendor->req_complete_val) {
136 goto out_recv;
137 }
139 if ((status == chip->vendor->req_canceled)) {
140 dev_err(chip->dev, "Operation Canceled\n");
141 rc = -ECANCELED;
142 goto out;
143 }
145 msleep(TPM_TIMEOUT); /* CHECK */
146 rmb();
147 }
148 while (time_before(jiffies, stop));
151 chip->vendor->cancel(chip);
152 dev_err(chip->dev, "Operation Timed out\n");
153 rc = -ETIME;
154 goto out;
156 out_recv:
157 rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
158 if (rc < 0)
159 dev_err(chip->dev,
160 "tpm_transmit: tpm_recv: error %d\n", rc);
161 atomic_set(&chip->data_position, 0);
163 out:
164 up(&chip->tpm_mutex);
165 return rc;
166 }
168 EXPORT_SYMBOL_GPL(tpm_transmit);
170 #define TPM_DIGEST_SIZE 20
171 #define CAP_PCR_RESULT_SIZE 18
172 static const u8 cap_pcr[] = {
173 0, 193, /* TPM_TAG_RQU_COMMAND */
174 0, 0, 0, 22, /* length */
175 0, 0, 0, 101, /* TPM_ORD_GetCapability */
176 0, 0, 0, 5,
177 0, 0, 0, 4,
178 0, 0, 1, 1
179 };
181 #define READ_PCR_RESULT_SIZE 30
182 static const u8 pcrread[] = {
183 0, 193, /* TPM_TAG_RQU_COMMAND */
184 0, 0, 0, 14, /* length */
185 0, 0, 0, 21, /* TPM_ORD_PcrRead */
186 0, 0, 0, 0 /* PCR index */
187 };
189 ssize_t tpm_show_pcrs(struct device *dev, char *buf)
190 {
191 u8 data[READ_PCR_RESULT_SIZE];
192 ssize_t len;
193 int i, j, num_pcrs;
194 __be32 index;
195 char *str = buf;
197 struct tpm_chip *chip = dev_get_drvdata(dev);
198 if (chip == NULL)
199 return -ENODEV;
201 memcpy(data, cap_pcr, sizeof(cap_pcr));
202 if ((len = tpm_transmit(chip, data, sizeof(data)))
203 < CAP_PCR_RESULT_SIZE)
204 return len;
206 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
208 for (i = 0; i < num_pcrs; i++) {
209 memcpy(data, pcrread, sizeof(pcrread));
210 index = cpu_to_be32(i);
211 memcpy(data + 10, &index, 4);
212 if ((len = tpm_transmit(chip, data, sizeof(data)))
213 < READ_PCR_RESULT_SIZE)
214 return len;
215 str += sprintf(str, "PCR-%02d: ", i);
216 for (j = 0; j < TPM_DIGEST_SIZE; j++)
217 str += sprintf(str, "%02X ", *(data + 10 + j));
218 str += sprintf(str, "\n");
219 }
220 return str - buf;
221 }
223 EXPORT_SYMBOL_GPL(tpm_show_pcrs);
225 /*
226 * Return 0 on success. On error pass along error code.
227 * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
228 * Lower 2 bytes equal tpm idx # or AN&
229 * res_buf must fit a TPM_PCR (20 bytes) or NULL if you don't care
230 */
231 int tpm_pcr_read( u32 chip_id, int pcr_idx, u8* res_buf, int res_buf_size )
232 {
233 u8 data[READ_PCR_RESULT_SIZE];
234 int rc;
235 __be32 index;
236 int chip_num = chip_id & TPM_CHIP_NUM_MASK;
237 struct tpm_chip* chip;
239 if ( res_buf && res_buf_size < TPM_DIGEST_SIZE )
240 return -ENOSPC;
241 if ( (chip = tpm_chip_lookup( chip_num /*,
242 chip_id >> TPM_CHIP_TYPE_SHIFT*/ ) ) == NULL ) {
243 printk("chip %d not found.\n",chip_num);
244 return -ENODEV;
245 }
246 memcpy(data, pcrread, sizeof(pcrread));
247 index = cpu_to_be32(pcr_idx);
248 memcpy(data + 10, &index, 4);
249 if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
250 rc = be32_to_cpu(*((u32*)(data+6)));
252 if ( rc == 0 && res_buf )
253 memcpy(res_buf, data+10, TPM_DIGEST_SIZE);
254 return rc;
255 }
256 EXPORT_SYMBOL_GPL(tpm_pcr_read);
258 #define EXTEND_PCR_SIZE 34
259 static const u8 pcrextend[] = {
260 0, 193, /* TPM_TAG_RQU_COMMAND */
261 0, 0, 0, 34, /* length */
262 0, 0, 0, 20, /* TPM_ORD_Extend */
263 0, 0, 0, 0 /* PCR index */
264 };
266 /*
267 * Return 0 on success. On error pass along error code.
268 * chip_id Upper 2 bytes equal ANY, HW_ONLY or SW_ONLY
269 * Lower 2 bytes equal tpm idx # or ANY
270 */
271 int tpm_pcr_extend(u32 chip_id, int pcr_idx, const u8* hash)
272 {
273 u8 data[EXTEND_PCR_SIZE];
274 int rc;
275 __be32 index;
276 int chip_num = chip_id & TPM_CHIP_NUM_MASK;
277 struct tpm_chip* chip;
279 if ( (chip = tpm_chip_lookup( chip_num /*,
280 chip_id >> TPM_CHIP_TYPE_SHIFT */)) == NULL )
281 return -ENODEV;
283 memcpy(data, pcrextend, sizeof(pcrextend));
284 index = cpu_to_be32(pcr_idx);
285 memcpy(data + 10, &index, 4);
286 memcpy( data + 14, hash, TPM_DIGEST_SIZE );
287 if ((rc = tpm_transmit(chip, data, sizeof(data))) > 0 )
288 rc = be32_to_cpu(*((u32*)(data+6)));
289 return rc;
290 }
291 EXPORT_SYMBOL_GPL(tpm_pcr_extend);
295 #define READ_PUBEK_RESULT_SIZE 314
296 static const u8 readpubek[] = {
297 0, 193, /* TPM_TAG_RQU_COMMAND */
298 0, 0, 0, 30, /* length */
299 0, 0, 0, 124, /* TPM_ORD_ReadPubek */
300 };
302 ssize_t tpm_show_pubek(struct device *dev, char *buf)
303 {
304 u8 *data;
305 ssize_t len;
306 int i, rc;
307 char *str = buf;
309 struct tpm_chip *chip = dev_get_drvdata(dev);
310 if (chip == NULL)
311 return -ENODEV;
313 data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
314 if (!data)
315 return -ENOMEM;
317 memcpy(data, readpubek, sizeof(readpubek));
318 memset(data + sizeof(readpubek), 0, 20); /* zero nonce */
320 if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
321 READ_PUBEK_RESULT_SIZE) {
322 rc = len;
323 goto out;
324 }
326 /*
327 ignore header 10 bytes
328 algorithm 32 bits (1 == RSA )
329 encscheme 16 bits
330 sigscheme 16 bits
331 parameters (RSA 12->bytes: keybit, #primes, expbit)
332 keylenbytes 32 bits
333 256 byte modulus
334 ignore checksum 20 bytes
335 */
337 str +=
338 sprintf(str,
339 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
340 "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
341 " %02X %02X %02X %02X %02X %02X %02X %02X\n"
342 "Modulus length: %d\nModulus: \n",
343 data[10], data[11], data[12], data[13], data[14],
344 data[15], data[16], data[17], data[22], data[23],
345 data[24], data[25], data[26], data[27], data[28],
346 data[29], data[30], data[31], data[32], data[33],
347 be32_to_cpu(*((__be32 *) (data + 32))));
349 for (i = 0; i < 256; i++) {
350 str += sprintf(str, "%02X ", data[i + 39]);
351 if ((i + 1) % 16 == 0)
352 str += sprintf(str, "\n");
353 }
354 rc = str - buf;
355 out:
356 kfree(data);
357 return rc;
358 }
360 EXPORT_SYMBOL_GPL(tpm_show_pubek);
362 #define CAP_VER_RESULT_SIZE 18
363 static const u8 cap_version[] = {
364 0, 193, /* TPM_TAG_RQU_COMMAND */
365 0, 0, 0, 18, /* length */
366 0, 0, 0, 101, /* TPM_ORD_GetCapability */
367 0, 0, 0, 6,
368 0, 0, 0, 0
369 };
371 #define CAP_MANUFACTURER_RESULT_SIZE 18
372 static const u8 cap_manufacturer[] = {
373 0, 193, /* TPM_TAG_RQU_COMMAND */
374 0, 0, 0, 22, /* length */
375 0, 0, 0, 101, /* TPM_ORD_GetCapability */
376 0, 0, 0, 5,
377 0, 0, 0, 4,
378 0, 0, 1, 3
379 };
381 ssize_t tpm_show_caps(struct device *dev, char *buf)
382 {
383 u8 data[sizeof(cap_manufacturer)];
384 ssize_t len;
385 char *str = buf;
387 struct tpm_chip *chip = dev_get_drvdata(dev);
388 if (chip == NULL)
389 return -ENODEV;
391 memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
393 if ((len = tpm_transmit(chip, data, sizeof(data))) <
394 CAP_MANUFACTURER_RESULT_SIZE)
395 return len;
397 str += sprintf(str, "Manufacturer: 0x%x\n",
398 be32_to_cpu(*((__be32 *)(data + 14))));
400 memcpy(data, cap_version, sizeof(cap_version));
402 if ((len = tpm_transmit(chip, data, sizeof(data))) <
403 CAP_VER_RESULT_SIZE)
404 return len;
406 str +=
407 sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
408 (int) data[14], (int) data[15], (int) data[16],
409 (int) data[17]);
411 return str - buf;
412 }
414 EXPORT_SYMBOL_GPL(tpm_show_caps);
416 ssize_t tpm_store_cancel(struct device * dev, const char *buf,
417 size_t count)
418 {
419 struct tpm_chip *chip = dev_get_drvdata(dev);
420 if (chip == NULL)
421 return 0;
423 chip->vendor->cancel(chip);
424 return count;
425 }
427 EXPORT_SYMBOL_GPL(tpm_store_cancel);
429 /*
430 * Device file system interface to the TPM
431 */
432 int tpm_open(struct inode *inode, struct file *file)
433 {
434 int rc = 0, minor = iminor(inode);
435 struct tpm_chip *chip = NULL, *pos;
437 spin_lock(&driver_lock);
439 list_for_each_entry(pos, &tpm_chip_list, list) {
440 if (pos->vendor->miscdev.minor == minor) {
441 chip = pos;
442 break;
443 }
444 }
446 if (chip == NULL) {
447 rc = -ENODEV;
448 goto err_out;
449 }
451 if (chip->num_opens) {
452 dev_dbg(chip->dev, "Another process owns this TPM\n");
453 rc = -EBUSY;
454 goto err_out;
455 }
457 chip->num_opens++;
458 get_device(chip->dev);
460 spin_unlock(&driver_lock);
462 chip->data_buffer = kmalloc(chip->vendor->buffersize * sizeof(u8),
463 GFP_KERNEL);
464 if (chip->data_buffer == NULL) {
465 chip->num_opens--;
466 put_device(chip->dev);
467 return -ENOMEM;
468 }
470 atomic_set(&chip->data_pending, 0);
472 file->private_data = chip;
473 return 0;
475 err_out:
476 spin_unlock(&driver_lock);
477 return rc;
478 }
480 EXPORT_SYMBOL_GPL(tpm_open);
482 int tpm_release(struct inode *inode, struct file *file)
483 {
484 struct tpm_chip *chip = file->private_data;
486 spin_lock(&driver_lock);
487 file->private_data = NULL;
488 chip->num_opens--;
489 del_singleshot_timer_sync(&chip->user_read_timer);
490 atomic_set(&chip->data_pending, 0);
491 put_device(chip->dev);
492 kfree(chip->data_buffer);
493 spin_unlock(&driver_lock);
494 return 0;
495 }
497 EXPORT_SYMBOL_GPL(tpm_release);
499 ssize_t tpm_write(struct file * file, const char __user * buf,
500 size_t size, loff_t * off)
501 {
502 struct tpm_chip *chip = file->private_data;
503 int in_size = size, out_size;
505 /* cannot perform a write until the read has cleared
506 either via tpm_read or a user_read_timer timeout */
507 while (atomic_read(&chip->data_pending) != 0)
508 msleep(TPM_TIMEOUT);
510 down(&chip->buffer_mutex);
512 if (in_size > chip->vendor->buffersize)
513 in_size = chip->vendor->buffersize;
515 if (copy_from_user
516 (chip->data_buffer, (void __user *) buf, in_size)) {
517 up(&chip->buffer_mutex);
518 return -EFAULT;
519 }
521 /* atomic tpm command send and result receive */
522 out_size = tpm_transmit(chip,
523 chip->data_buffer,
524 chip->vendor->buffersize);
526 atomic_set(&chip->data_pending, out_size);
527 up(&chip->buffer_mutex);
529 /* Set a timeout by which the reader must come claim the result */
530 mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
532 return in_size;
533 }
535 EXPORT_SYMBOL_GPL(tpm_write);
537 ssize_t tpm_read(struct file * file, char __user * buf,
538 size_t size, loff_t * off)
539 {
540 struct tpm_chip *chip = file->private_data;
541 int ret_size;
543 del_singleshot_timer_sync(&chip->user_read_timer);
544 ret_size = atomic_read(&chip->data_pending);
546 if (ret_size > 0) { /* relay data */
547 int position = atomic_read(&chip->data_position);
549 if (size < ret_size)
550 ret_size = size;
552 down(&chip->buffer_mutex);
554 if (copy_to_user((void __user *) buf,
555 &chip->data_buffer[position],
556 ret_size)) {
557 ret_size = -EFAULT;
558 } else {
559 int pending = atomic_read(&chip->data_pending) - ret_size;
560 atomic_set(&chip->data_pending,
561 pending);
562 atomic_set(&chip->data_position,
563 position + ret_size);
564 }
565 up(&chip->buffer_mutex);
566 }
568 return ret_size;
569 }
571 EXPORT_SYMBOL_GPL(tpm_read);
573 void tpm_remove_hardware(struct device *dev)
574 {
575 struct tpm_chip *chip = dev_get_drvdata(dev);
576 int i;
578 if (chip == NULL) {
579 dev_err(dev, "No device data found\n");
580 return;
581 }
583 spin_lock(&driver_lock);
585 list_del(&chip->list);
587 spin_unlock(&driver_lock);
589 dev_set_drvdata(dev, NULL);
590 misc_deregister(&chip->vendor->miscdev);
592 for (i = 0; i < TPM_NUM_ATTR; i++)
593 device_remove_file(dev, &chip->vendor->attr[i]);
595 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES] &=
596 !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
598 kfree(chip);
600 put_device(dev);
601 }
603 EXPORT_SYMBOL_GPL(tpm_remove_hardware);
605 static const u8 savestate[] = {
606 0, 193, /* TPM_TAG_RQU_COMMAND */
607 0, 0, 0, 10, /* blob length (in bytes) */
608 0, 0, 0, 152 /* TPM_ORD_SaveState */
609 };
611 /*
612 * We are about to suspend. Save the TPM state
613 * so that it can be restored.
614 */
615 int tpm_pm_suspend(struct pci_dev *pci_dev, u32 pm_state)
616 {
617 struct tpm_chip *chip = pci_get_drvdata(pci_dev);
618 if (chip == NULL)
619 return -ENODEV;
621 tpm_transmit(chip, savestate, sizeof(savestate));
622 return 0;
623 }
625 EXPORT_SYMBOL_GPL(tpm_pm_suspend);
627 /*
628 * Resume from a power safe. The BIOS already restored
629 * the TPM state.
630 */
631 int tpm_pm_resume(struct pci_dev *pci_dev)
632 {
633 struct tpm_chip *chip = pci_get_drvdata(pci_dev);
635 if (chip == NULL)
636 return -ENODEV;
638 return 0;
639 }
641 EXPORT_SYMBOL_GPL(tpm_pm_resume);
643 /*
644 * Called from tpm_<specific>.c probe function only for devices
645 * the driver has determined it should claim. Prior to calling
646 * this function the specific probe function has called pci_enable_device
647 * upon errant exit from this function specific probe function should call
648 * pci_disable_device
649 */
650 int tpm_register_hardware_nopci(struct device *dev,
651 struct tpm_vendor_specific *entry)
652 {
653 char devname[7];
654 struct tpm_chip *chip;
655 int i, j;
657 /* Driver specific per-device data */
658 chip = kmalloc(sizeof(*chip), GFP_KERNEL);
659 if (chip == NULL)
660 return -ENOMEM;
662 memset(chip, 0, sizeof(struct tpm_chip));
664 init_MUTEX(&chip->buffer_mutex);
665 init_MUTEX(&chip->tpm_mutex);
666 INIT_LIST_HEAD(&chip->list);
668 init_timer(&chip->user_read_timer);
669 chip->user_read_timer.function = user_reader_timeout;
670 chip->user_read_timer.data = (unsigned long) chip;
672 chip->vendor = entry;
674 if (entry->buffersize < TPM_MIN_BUFSIZE) {
675 entry->buffersize = TPM_MIN_BUFSIZE;
676 } else if (entry->buffersize > TPM_MAX_BUFSIZE) {
677 entry->buffersize = TPM_MAX_BUFSIZE;
678 }
680 chip->dev_num = -1;
682 for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
683 for (j = 0; j < 8 * sizeof(int); j++)
684 if ((dev_mask[i] & (1 << j)) == 0) {
685 chip->dev_num =
686 i * TPM_NUM_MASK_ENTRIES + j;
687 dev_mask[i] |= 1 << j;
688 goto dev_num_search_complete;
689 }
691 dev_num_search_complete:
692 if (chip->dev_num < 0) {
693 dev_err(dev, "No available tpm device numbers\n");
694 kfree(chip);
695 return -ENODEV;
696 } else if (chip->dev_num == 0)
697 chip->vendor->miscdev.minor = TPM_MINOR;
698 else
699 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
701 snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
702 chip->vendor->miscdev.name = devname;
704 chip->vendor->miscdev.dev = dev;
705 chip->dev = get_device(dev);
708 if (misc_register(&chip->vendor->miscdev)) {
709 dev_err(chip->dev,
710 "unable to misc_register %s, minor %d\n",
711 chip->vendor->miscdev.name,
712 chip->vendor->miscdev.minor);
713 put_device(dev);
714 kfree(chip);
715 dev_mask[i] &= !(1 << j);
716 return -ENODEV;
717 }
719 spin_lock(&driver_lock);
721 dev_set_drvdata(dev, chip);
723 list_add(&chip->list, &tpm_chip_list);
725 spin_unlock(&driver_lock);
727 for (i = 0; i < TPM_NUM_ATTR; i++)
728 device_create_file(dev, &chip->vendor->attr[i]);
730 return 0;
731 }
733 EXPORT_SYMBOL_GPL(tpm_register_hardware_nopci);
735 static int __init init_tpm(void)
736 {
737 return 0;
738 }
740 static void __exit cleanup_tpm(void)
741 {
743 }
745 module_init(init_tpm);
746 module_exit(cleanup_tpm);
748 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
749 MODULE_DESCRIPTION("TPM Driver");
750 MODULE_VERSION("2.0");
751 MODULE_LICENSE("GPL");