| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  */ | 
 | 21 | #include <linux/module.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 22 | #include <linux/pci.h> | 
 | 23 | #include <linux/delay.h> | 
 | 24 | #include <linux/fs.h> | 
 | 25 | #include <linux/miscdevice.h> | 
| Al Viro | bbc5b21 | 2005-11-01 15:14:05 +0000 | [diff] [blame] | 26 | #include <linux/platform_device.h> | 
| Andrew Morton | 276ad0c | 2006-03-25 03:07:35 -0800 | [diff] [blame] | 27 | #include <linux/io.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 |  | 
| Kylene Hall | 3122a88 | 2005-06-23 22:01:48 -0700 | [diff] [blame] | 29 | enum tpm_timeout { | 
 | 30 | 	TPM_TIMEOUT = 5,	/* msecs */ | 
 | 31 | }; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 32 |  | 
 | 33 | /* TPM addresses */ | 
| Kylene Hall | 3122a88 | 2005-06-23 22:01:48 -0700 | [diff] [blame] | 34 | enum tpm_addr { | 
| Kylene Jo Hall | daacdfa | 2005-06-25 14:55:39 -0700 | [diff] [blame] | 35 | 	TPM_SUPERIO_ADDR = 0x2E, | 
| Kylene Hall | 3122a88 | 2005-06-23 22:01:48 -0700 | [diff] [blame] | 36 | 	TPM_ADDR = 0x4E, | 
| Kylene Hall | 3122a88 | 2005-06-23 22:01:48 -0700 | [diff] [blame] | 37 | }; | 
 | 38 |  | 
| Kylene Hall | 6659ca2 | 2005-06-23 22:02:00 -0700 | [diff] [blame] | 39 | extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, | 
 | 40 | 				char *); | 
 | 41 | extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, | 
 | 42 | 				char *); | 
 | 43 | extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, | 
 | 44 | 				char *); | 
 | 45 | extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, | 
 | 46 | 				const char *, size_t); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 |  | 
 | 48 | struct tpm_chip; | 
 | 49 |  | 
 | 50 | struct tpm_vendor_specific { | 
 | 51 | 	u8 req_complete_mask; | 
 | 52 | 	u8 req_complete_val; | 
| Kylene Hall | d9e5b6b | 2005-06-23 22:02:02 -0700 | [diff] [blame] | 53 | 	u8 req_canceled; | 
| Kylene Jo Hall | ad5ea3c | 2005-11-13 16:07:41 -0800 | [diff] [blame] | 54 | 	void __iomem *iobase;		/* ioremapped address */ | 
 | 55 | 	unsigned long base;		/* TPM base address */ | 
 | 56 |  | 
 | 57 | 	int region_size; | 
 | 58 | 	int have_region; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 |  | 
 | 60 | 	int (*recv) (struct tpm_chip *, u8 *, size_t); | 
 | 61 | 	int (*send) (struct tpm_chip *, u8 *, size_t); | 
 | 62 | 	void (*cancel) (struct tpm_chip *); | 
| Kylene Jo Hall | b4ed3e3 | 2005-10-30 15:03:23 -0800 | [diff] [blame] | 63 | 	u8 (*status) (struct tpm_chip *); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 64 | 	struct miscdevice miscdev; | 
| Kylene Hall | 6659ca2 | 2005-06-23 22:02:00 -0700 | [diff] [blame] | 65 | 	struct attribute_group *attr_group; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 66 | }; | 
 | 67 |  | 
 | 68 | struct tpm_chip { | 
| Kylene Jo Hall | e659a3f | 2005-10-30 15:03:24 -0800 | [diff] [blame] | 69 | 	struct device *dev;	/* Device stuff */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 70 |  | 
 | 71 | 	int dev_num;		/* /dev/tpm# */ | 
 | 72 | 	int num_opens;		/* only one allowed */ | 
 | 73 | 	int time_expired; | 
 | 74 |  | 
 | 75 | 	/* Data passed to and from the tpm via the read/write calls */ | 
 | 76 | 	u8 *data_buffer; | 
 | 77 | 	atomic_t data_pending; | 
 | 78 | 	struct semaphore buffer_mutex; | 
 | 79 |  | 
 | 80 | 	struct timer_list user_read_timer;	/* user needs to claim result */ | 
| Kylene Jo Hall | 09e12f9 | 2005-11-13 16:07:43 -0800 | [diff] [blame] | 81 | 	struct work_struct work; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 82 | 	struct semaphore tpm_mutex;	/* tpm is processing */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 83 |  | 
 | 84 | 	struct tpm_vendor_specific *vendor; | 
 | 85 |  | 
| Kylene Jo Hall | 55a82ab | 2006-01-08 01:03:15 -0800 | [diff] [blame] | 86 | 	struct dentry **bios_dir; | 
 | 87 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 | 	struct list_head list; | 
 | 89 | }; | 
 | 90 |  | 
| Kylene Jo Hall | daacdfa | 2005-06-25 14:55:39 -0700 | [diff] [blame] | 91 | static inline int tpm_read_index(int base, int index) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 92 | { | 
| Kylene Jo Hall | daacdfa | 2005-06-25 14:55:39 -0700 | [diff] [blame] | 93 | 	outb(index, base); | 
 | 94 | 	return inb(base+1) & 0xFF; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 95 | } | 
 | 96 |  | 
| Kylene Jo Hall | daacdfa | 2005-06-25 14:55:39 -0700 | [diff] [blame] | 97 | static inline void tpm_write_index(int base, int index, int value) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 98 | { | 
| Kylene Jo Hall | daacdfa | 2005-06-25 14:55:39 -0700 | [diff] [blame] | 99 | 	outb(index, base); | 
 | 100 | 	outb(value & 0xFF, base+1); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 101 | } | 
 | 102 |  | 
| Kylene Jo Hall | e659a3f | 2005-10-30 15:03:24 -0800 | [diff] [blame] | 103 | extern int tpm_register_hardware(struct device *, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 104 | 				 struct tpm_vendor_specific *); | 
 | 105 | extern int tpm_open(struct inode *, struct file *); | 
 | 106 | extern int tpm_release(struct inode *, struct file *); | 
 | 107 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | 
 | 108 | 			 loff_t *); | 
 | 109 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); | 
| Kylene Jo Hall | e659a3f | 2005-10-30 15:03:24 -0800 | [diff] [blame] | 110 | extern void tpm_remove_hardware(struct device *); | 
| Kylene Jo Hall | ce2c87d | 2005-10-30 15:03:25 -0800 | [diff] [blame] | 111 | extern int tpm_pm_suspend(struct device *, pm_message_t); | 
 | 112 | extern int tpm_pm_resume(struct device *); | 
| Kylene Jo Hall | 55a82ab | 2006-01-08 01:03:15 -0800 | [diff] [blame] | 113 |  | 
 | 114 | #ifdef CONFIG_ACPI | 
 | 115 | extern struct dentry ** tpm_bios_log_setup(char *); | 
 | 116 | extern void tpm_bios_log_teardown(struct dentry **); | 
 | 117 | #else | 
 | 118 | static inline struct dentry* tpm_bios_log_setup(char *name) | 
 | 119 | { | 
 | 120 | 	return NULL; | 
 | 121 | } | 
 | 122 | static inline void tpm_bios_log_teardown(struct dentry **dir) | 
 | 123 | { | 
 | 124 | } | 
 | 125 | #endif |