direct-io.hg

changeset 10523:da8da6e1e1d6

[TPM] Update the TPM drivers in the repository to a newer version
and also fixes the following:

- a problem introduced by a recent change to the xenbus_driver structure
requires driver-specific data to be stored in another data structures
- removes the #define'd MIN by min/min_t
- moves the sysfs entry to /sys/devices/xen/<vtpm-%d>
- fixes a bug occurring during cancellation of requests
- updates the default configuration to also compile the TPM V1.2 driver
submitted in part 2 of this patch
- all changes made to the generic TPM driver are surrounded by #ifdef
CONFIG_XEN's.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Jun 28 16:20:29 2006 +0100 (2006-06-28)
parents 1d17ddd9e45d
children e3ad9b9c95ee
files buildconfigs/linux-defconfig_xen_x86_32 buildconfigs/linux-defconfig_xen_x86_64 linux-2.6-xen-sparse/drivers/char/tpm/Kconfig linux-2.6-xen-sparse/drivers/char/tpm/Makefile linux-2.6-xen-sparse/drivers/char/tpm/tpm.c linux-2.6-xen-sparse/drivers/char/tpm/tpm.h linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
line diff
     1.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Wed Jun 28 16:15:36 2006 +0100
     1.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Wed Jun 28 16:20:29 2006 +0100
     1.3 @@ -1902,6 +1902,7 @@ CONFIG_HANGCHECK_TIMER=m
     1.4  # TPM devices
     1.5  #
     1.6  CONFIG_TCG_TPM=m
     1.7 +CONFIG_TCG_TIS=m
     1.8  CONFIG_TCG_NSC=m
     1.9  CONFIG_TCG_ATMEL=m
    1.10  CONFIG_TCG_INFINEON=m
     2.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Wed Jun 28 16:15:36 2006 +0100
     2.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Wed Jun 28 16:20:29 2006 +0100
     2.3 @@ -1765,6 +1765,7 @@ CONFIG_HANGCHECK_TIMER=m
     2.4  # TPM devices
     2.5  #
     2.6  CONFIG_TCG_TPM=m
     2.7 +CONFIG_TCG_TIS=m
     2.8  CONFIG_TCG_NSC=m
     2.9  CONFIG_TCG_ATMEL=m
    2.10  CONFIG_TCG_INFINEON=m
     3.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Wed Jun 28 16:15:36 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig	Wed Jun 28 16:20:29 2006 +0100
     3.3 @@ -20,9 +20,18 @@ config TCG_TPM
     3.4  	  Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
     3.5  	  and CONFIG_PNPACPI.
     3.6  
     3.7 +config TCG_TIS
     3.8 +	tristate "TPM Interface Specification 1.2 Interface"
     3.9 +	depends on TCG_TPM
    3.10 +	---help---
    3.11 +	  If you have a TPM security chip that is compliant with the
    3.12 +	  TCG TIS 1.2 TPM specification say Yes and it will be accessible
    3.13 +	  from within Linux.  To compile this driver as a module, choose
    3.14 +	  M here; the module will be called tpm_tis.
    3.15 +
    3.16  config TCG_NSC
    3.17  	tristate "National Semiconductor TPM Interface"
    3.18 -	depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
    3.19 +	depends on TCG_TPM && PNPACPI
    3.20  	---help---
    3.21  	  If you have a TPM security chip from National Semicondutor 
    3.22  	  say Yes and it will be accessible from within Linux.  To 
    3.23 @@ -31,7 +40,7 @@ config TCG_NSC
    3.24  
    3.25  config TCG_ATMEL
    3.26  	tristate "Atmel TPM Interface"
    3.27 -	depends on TCG_TPM && !XEN_UNPRIVILEGED_GUEST
    3.28 +	depends on TCG_TPM
    3.29  	---help---
    3.30  	  If you have a TPM security chip from Atmel say Yes and it 
    3.31  	  will be accessible from within Linux.  To compile this driver 
     4.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Wed Jun 28 16:15:36 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/Makefile	Wed Jun 28 16:20:29 2006 +0100
     4.3 @@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o
     4.4  ifdef CONFIG_ACPI
     4.5  	obj-$(CONFIG_TCG_TPM) += tpm_bios.o
     4.6  endif
     4.7 +obj-$(CONFIG_TCG_TIS) += tpm_tis.o
     4.8  obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
     4.9  obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
    4.10  obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
     5.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Wed Jun 28 16:15:36 2006 +0100
     5.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Wed Jun 28 16:20:29 2006 +0100
     5.3 @@ -30,15 +30,295 @@
     5.4  
     5.5  enum tpm_const {
     5.6  	TPM_MINOR = 224,	/* officially assigned */
     5.7 -	TPM_MIN_BUFSIZE = 2048,
     5.8 -	TPM_MAX_BUFSIZE = 64 * 1024,
     5.9 +#ifndef CONFIG_XEN
    5.10 +	TPM_BUFSIZE = 2048,
    5.11 +#endif
    5.12  	TPM_NUM_DEVICES = 256,
    5.13 -	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
    5.14  };
    5.15  
    5.16 +enum tpm_duration {
    5.17 +	TPM_SHORT = 0,
    5.18 +	TPM_MEDIUM = 1,
    5.19 +	TPM_LONG = 2,
    5.20 +	TPM_UNDEFINED,
    5.21 +};
    5.22 +
    5.23 +#define TPM_MAX_ORDINAL 243
    5.24 +#define TPM_MAX_PROTECTED_ORDINAL 12
    5.25 +#define TPM_PROTECTED_ORDINAL_MASK 0xFF
    5.26 +
    5.27  static LIST_HEAD(tpm_chip_list);
    5.28  static DEFINE_SPINLOCK(driver_lock);
    5.29 -static int dev_mask[TPM_NUM_MASK_ENTRIES];
    5.30 +static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
    5.31 +
    5.32 +/*
    5.33 + * Array with one entry per ordinal defining the maximum amount
    5.34 + * of time the chip could take to return the result.  The ordinal
    5.35 + * designation of short, medium or long is defined in a table in
    5.36 + * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
    5.37 + * values of the SHORT, MEDIUM, and LONG durations are retrieved
    5.38 + * from the chip during initialization with a call to tpm_get_timeouts.
    5.39 + */
    5.40 +static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
    5.41 +	TPM_UNDEFINED,		/* 0 */
    5.42 +	TPM_UNDEFINED,
    5.43 +	TPM_UNDEFINED,
    5.44 +	TPM_UNDEFINED,
    5.45 +	TPM_UNDEFINED,
    5.46 +	TPM_UNDEFINED,		/* 5 */
    5.47 +	TPM_UNDEFINED,
    5.48 +	TPM_UNDEFINED,
    5.49 +	TPM_UNDEFINED,
    5.50 +	TPM_UNDEFINED,
    5.51 +	TPM_SHORT,		/* 10 */
    5.52 +	TPM_SHORT,
    5.53 +};
    5.54 +
    5.55 +static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
    5.56 +	TPM_UNDEFINED,		/* 0 */
    5.57 +	TPM_UNDEFINED,
    5.58 +	TPM_UNDEFINED,
    5.59 +	TPM_UNDEFINED,
    5.60 +	TPM_UNDEFINED,
    5.61 +	TPM_UNDEFINED,		/* 5 */
    5.62 +	TPM_UNDEFINED,
    5.63 +	TPM_UNDEFINED,
    5.64 +	TPM_UNDEFINED,
    5.65 +	TPM_UNDEFINED,
    5.66 +	TPM_SHORT,		/* 10 */
    5.67 +	TPM_SHORT,
    5.68 +	TPM_MEDIUM,
    5.69 +	TPM_LONG,
    5.70 +	TPM_LONG,
    5.71 +	TPM_MEDIUM,		/* 15 */
    5.72 +	TPM_SHORT,
    5.73 +	TPM_SHORT,
    5.74 +	TPM_MEDIUM,
    5.75 +	TPM_LONG,
    5.76 +	TPM_SHORT,		/* 20 */
    5.77 +	TPM_SHORT,
    5.78 +	TPM_MEDIUM,
    5.79 +	TPM_MEDIUM,
    5.80 +	TPM_MEDIUM,
    5.81 +	TPM_SHORT,		/* 25 */
    5.82 +	TPM_SHORT,
    5.83 +	TPM_MEDIUM,
    5.84 +	TPM_SHORT,
    5.85 +	TPM_SHORT,
    5.86 +	TPM_MEDIUM,		/* 30 */
    5.87 +	TPM_LONG,
    5.88 +	TPM_MEDIUM,
    5.89 +	TPM_SHORT,
    5.90 +	TPM_SHORT,
    5.91 +	TPM_SHORT,		/* 35 */
    5.92 +	TPM_MEDIUM,
    5.93 +	TPM_MEDIUM,
    5.94 +	TPM_UNDEFINED,
    5.95 +	TPM_UNDEFINED,
    5.96 +	TPM_MEDIUM,		/* 40 */
    5.97 +	TPM_LONG,
    5.98 +	TPM_MEDIUM,
    5.99 +	TPM_SHORT,
   5.100 +	TPM_SHORT,
   5.101 +	TPM_SHORT,		/* 45 */
   5.102 +	TPM_SHORT,
   5.103 +	TPM_SHORT,
   5.104 +	TPM_SHORT,
   5.105 +	TPM_LONG,
   5.106 +	TPM_MEDIUM,		/* 50 */
   5.107 +	TPM_MEDIUM,
   5.108 +	TPM_UNDEFINED,
   5.109 +	TPM_UNDEFINED,
   5.110 +	TPM_UNDEFINED,
   5.111 +	TPM_UNDEFINED,		/* 55 */
   5.112 +	TPM_UNDEFINED,
   5.113 +	TPM_UNDEFINED,
   5.114 +	TPM_UNDEFINED,
   5.115 +	TPM_UNDEFINED,
   5.116 +	TPM_MEDIUM,		/* 60 */
   5.117 +	TPM_MEDIUM,
   5.118 +	TPM_MEDIUM,
   5.119 +	TPM_SHORT,
   5.120 +	TPM_SHORT,
   5.121 +	TPM_MEDIUM,		/* 65 */
   5.122 +	TPM_UNDEFINED,
   5.123 +	TPM_UNDEFINED,
   5.124 +	TPM_UNDEFINED,
   5.125 +	TPM_UNDEFINED,
   5.126 +	TPM_SHORT,		/* 70 */
   5.127 +	TPM_SHORT,
   5.128 +	TPM_UNDEFINED,
   5.129 +	TPM_UNDEFINED,
   5.130 +	TPM_UNDEFINED,
   5.131 +	TPM_UNDEFINED,		/* 75 */
   5.132 +	TPM_UNDEFINED,
   5.133 +	TPM_UNDEFINED,
   5.134 +	TPM_UNDEFINED,
   5.135 +	TPM_UNDEFINED,
   5.136 +	TPM_LONG,		/* 80 */
   5.137 +	TPM_UNDEFINED,
   5.138 +	TPM_MEDIUM,
   5.139 +	TPM_LONG,
   5.140 +	TPM_SHORT,
   5.141 +	TPM_UNDEFINED,		/* 85 */
   5.142 +	TPM_UNDEFINED,
   5.143 +	TPM_UNDEFINED,
   5.144 +	TPM_UNDEFINED,
   5.145 +	TPM_UNDEFINED,
   5.146 +	TPM_SHORT,		/* 90 */
   5.147 +	TPM_SHORT,
   5.148 +	TPM_SHORT,
   5.149 +	TPM_SHORT,
   5.150 +	TPM_SHORT,
   5.151 +	TPM_UNDEFINED,		/* 95 */
   5.152 +	TPM_UNDEFINED,
   5.153 +	TPM_UNDEFINED,
   5.154 +	TPM_UNDEFINED,
   5.155 +	TPM_UNDEFINED,
   5.156 +	TPM_MEDIUM,		/* 100 */
   5.157 +	TPM_SHORT,
   5.158 +	TPM_SHORT,
   5.159 +	TPM_UNDEFINED,
   5.160 +	TPM_UNDEFINED,
   5.161 +	TPM_UNDEFINED,		/* 105 */
   5.162 +	TPM_UNDEFINED,
   5.163 +	TPM_UNDEFINED,
   5.164 +	TPM_UNDEFINED,
   5.165 +	TPM_UNDEFINED,
   5.166 +	TPM_SHORT,		/* 110 */
   5.167 +	TPM_SHORT,
   5.168 +	TPM_SHORT,
   5.169 +	TPM_SHORT,
   5.170 +	TPM_SHORT,
   5.171 +	TPM_SHORT,		/* 115 */
   5.172 +	TPM_SHORT,
   5.173 +	TPM_SHORT,
   5.174 +	TPM_UNDEFINED,
   5.175 +	TPM_UNDEFINED,
   5.176 +	TPM_LONG,		/* 120 */
   5.177 +	TPM_LONG,
   5.178 +	TPM_MEDIUM,
   5.179 +	TPM_UNDEFINED,
   5.180 +	TPM_SHORT,
   5.181 +	TPM_SHORT,		/* 125 */
   5.182 +	TPM_SHORT,
   5.183 +	TPM_LONG,
   5.184 +	TPM_SHORT,
   5.185 +	TPM_SHORT,
   5.186 +	TPM_SHORT,		/* 130 */
   5.187 +	TPM_MEDIUM,
   5.188 +	TPM_UNDEFINED,
   5.189 +	TPM_SHORT,
   5.190 +	TPM_MEDIUM,
   5.191 +	TPM_UNDEFINED,		/* 135 */
   5.192 +	TPM_UNDEFINED,
   5.193 +	TPM_UNDEFINED,
   5.194 +	TPM_UNDEFINED,
   5.195 +	TPM_UNDEFINED,
   5.196 +	TPM_SHORT,		/* 140 */
   5.197 +	TPM_SHORT,
   5.198 +	TPM_UNDEFINED,
   5.199 +	TPM_UNDEFINED,
   5.200 +	TPM_UNDEFINED,
   5.201 +	TPM_UNDEFINED,		/* 145 */
   5.202 +	TPM_UNDEFINED,
   5.203 +	TPM_UNDEFINED,
   5.204 +	TPM_UNDEFINED,
   5.205 +	TPM_UNDEFINED,
   5.206 +	TPM_SHORT,		/* 150 */
   5.207 +	TPM_MEDIUM,
   5.208 +	TPM_MEDIUM,
   5.209 +	TPM_SHORT,
   5.210 +	TPM_SHORT,
   5.211 +	TPM_UNDEFINED,		/* 155 */
   5.212 +	TPM_UNDEFINED,
   5.213 +	TPM_UNDEFINED,
   5.214 +	TPM_UNDEFINED,
   5.215 +	TPM_UNDEFINED,
   5.216 +	TPM_SHORT,		/* 160 */
   5.217 +	TPM_SHORT,
   5.218 +	TPM_SHORT,
   5.219 +	TPM_SHORT,
   5.220 +	TPM_UNDEFINED,
   5.221 +	TPM_UNDEFINED,		/* 165 */
   5.222 +	TPM_UNDEFINED,
   5.223 +	TPM_UNDEFINED,
   5.224 +	TPM_UNDEFINED,
   5.225 +	TPM_UNDEFINED,
   5.226 +	TPM_LONG,		/* 170 */
   5.227 +	TPM_UNDEFINED,
   5.228 +	TPM_UNDEFINED,
   5.229 +	TPM_UNDEFINED,
   5.230 +	TPM_UNDEFINED,
   5.231 +	TPM_UNDEFINED,		/* 175 */
   5.232 +	TPM_UNDEFINED,
   5.233 +	TPM_UNDEFINED,
   5.234 +	TPM_UNDEFINED,
   5.235 +	TPM_UNDEFINED,
   5.236 +	TPM_MEDIUM,		/* 180 */
   5.237 +	TPM_SHORT,
   5.238 +	TPM_MEDIUM,
   5.239 +	TPM_MEDIUM,
   5.240 +	TPM_MEDIUM,
   5.241 +	TPM_MEDIUM,		/* 185 */
   5.242 +	TPM_SHORT,
   5.243 +	TPM_UNDEFINED,
   5.244 +	TPM_UNDEFINED,
   5.245 +	TPM_UNDEFINED,
   5.246 +	TPM_UNDEFINED,		/* 190 */
   5.247 +	TPM_UNDEFINED,
   5.248 +	TPM_UNDEFINED,
   5.249 +	TPM_UNDEFINED,
   5.250 +	TPM_UNDEFINED,
   5.251 +	TPM_UNDEFINED,		/* 195 */
   5.252 +	TPM_UNDEFINED,
   5.253 +	TPM_UNDEFINED,
   5.254 +	TPM_UNDEFINED,
   5.255 +	TPM_UNDEFINED,
   5.256 +	TPM_SHORT,		/* 200 */
   5.257 +	TPM_UNDEFINED,
   5.258 +	TPM_UNDEFINED,
   5.259 +	TPM_UNDEFINED,
   5.260 +	TPM_SHORT,
   5.261 +	TPM_SHORT,		/* 205 */
   5.262 +	TPM_SHORT,
   5.263 +	TPM_SHORT,
   5.264 +	TPM_SHORT,
   5.265 +	TPM_SHORT,
   5.266 +	TPM_MEDIUM,		/* 210 */
   5.267 +	TPM_UNDEFINED,
   5.268 +	TPM_MEDIUM,
   5.269 +	TPM_MEDIUM,
   5.270 +	TPM_MEDIUM,
   5.271 +	TPM_UNDEFINED,		/* 215 */
   5.272 +	TPM_MEDIUM,
   5.273 +	TPM_UNDEFINED,
   5.274 +	TPM_UNDEFINED,
   5.275 +	TPM_SHORT,
   5.276 +	TPM_SHORT,		/* 220 */
   5.277 +	TPM_SHORT,
   5.278 +	TPM_SHORT,
   5.279 +	TPM_SHORT,
   5.280 +	TPM_SHORT,
   5.281 +	TPM_UNDEFINED,		/* 225 */
   5.282 +	TPM_UNDEFINED,
   5.283 +	TPM_UNDEFINED,
   5.284 +	TPM_UNDEFINED,
   5.285 +	TPM_UNDEFINED,
   5.286 +	TPM_SHORT,		/* 230 */
   5.287 +	TPM_LONG,
   5.288 +	TPM_MEDIUM,
   5.289 +	TPM_UNDEFINED,
   5.290 +	TPM_UNDEFINED,
   5.291 +	TPM_UNDEFINED,		/* 235 */
   5.292 +	TPM_UNDEFINED,
   5.293 +	TPM_UNDEFINED,
   5.294 +	TPM_UNDEFINED,
   5.295 +	TPM_UNDEFINED,
   5.296 +	TPM_SHORT,		/* 240 */
   5.297 +	TPM_UNDEFINED,
   5.298 +	TPM_MEDIUM,
   5.299 +};
   5.300  
   5.301  static void user_reader_timeout(unsigned long ptr)
   5.302  {
   5.303 @@ -47,28 +327,58 @@ static void user_reader_timeout(unsigned
   5.304  	schedule_work(&chip->work);
   5.305  }
   5.306  
   5.307 -static void timeout_work(void * ptr)
   5.308 +static void timeout_work(void *ptr)
   5.309  {
   5.310  	struct tpm_chip *chip = ptr;
   5.311  
   5.312  	down(&chip->buffer_mutex);
   5.313  	atomic_set(&chip->data_pending, 0);
   5.314 +#ifndef CONFIG_XEN
   5.315 +	memset(chip->data_buffer, 0, TPM_BUFSIZE);
   5.316 +#else
   5.317  	memset(chip->data_buffer, 0, get_chip_buffersize(chip));
   5.318 +#endif
   5.319  	up(&chip->buffer_mutex);
   5.320  }
   5.321  
   5.322  /*
   5.323 + * Returns max number of jiffies to wait
   5.324 + */
   5.325 +unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
   5.326 +					   u32 ordinal)
   5.327 +{
   5.328 +	int duration_idx = TPM_UNDEFINED;
   5.329 +	int duration = 0;
   5.330 +
   5.331 +	if (ordinal < TPM_MAX_ORDINAL)
   5.332 +		duration_idx = tpm_ordinal_duration[ordinal];
   5.333 +	else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
   5.334 +		 TPM_MAX_PROTECTED_ORDINAL)
   5.335 +		duration_idx =
   5.336 +		    tpm_protected_ordinal_duration[ordinal &
   5.337 +						   TPM_PROTECTED_ORDINAL_MASK];
   5.338 +
   5.339 +	if (duration_idx != TPM_UNDEFINED)
   5.340 +		duration = chip->vendor.duration[duration_idx];
   5.341 +	if (duration <= 0)
   5.342 +		return 2 * 60 * HZ;
   5.343 +	else
   5.344 +		return duration;
   5.345 +}
   5.346 +EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
   5.347 +
   5.348 +/*
   5.349   * Internal kernel interface to transmit TPM commands
   5.350   */
   5.351 -static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
   5.352 +static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
   5.353  			    size_t bufsiz)
   5.354  {
   5.355  	ssize_t rc;
   5.356 -	u32 count;
   5.357 +	u32 count, ordinal;
   5.358  	unsigned long stop;
   5.359  
   5.360  	count = be32_to_cpu(*((__be32 *) (buf + 2)));
   5.361 -
   5.362 +	ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
   5.363  	if (count == 0)
   5.364  		return -ENODATA;
   5.365  	if (count > bufsiz) {
   5.366 @@ -79,21 +389,23 @@ static ssize_t tpm_transmit(struct tpm_c
   5.367  
   5.368  	down(&chip->tpm_mutex);
   5.369  
   5.370 -	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
   5.371 +	if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
   5.372  		dev_err(chip->dev,
   5.373  			"tpm_transmit: tpm_send: error %zd\n", rc);
   5.374  		goto out;
   5.375  	}
   5.376  
   5.377 -	stop = jiffies + 2 * 60 * HZ;
   5.378 +	if (chip->vendor.irq)
   5.379 +		goto out_recv;
   5.380 +
   5.381 +	stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
   5.382  	do {
   5.383 -		u8 status = chip->vendor->status(chip);
   5.384 -		if ((status & chip->vendor->req_complete_mask) ==
   5.385 -		    chip->vendor->req_complete_val) {
   5.386 +		u8 status = chip->vendor.status(chip);
   5.387 +		if ((status & chip->vendor.req_complete_mask) ==
   5.388 +		    chip->vendor.req_complete_val)
   5.389  			goto out_recv;
   5.390 -		}
   5.391  
   5.392 -		if ((status == chip->vendor->req_canceled)) {
   5.393 +		if ((status == chip->vendor.req_canceled)) {
   5.394  			dev_err(chip->dev, "Operation Canceled\n");
   5.395  			rc = -ECANCELED;
   5.396  			goto out;
   5.397 @@ -103,14 +415,13 @@ static ssize_t tpm_transmit(struct tpm_c
   5.398  		rmb();
   5.399  	} while (time_before(jiffies, stop));
   5.400  
   5.401 -
   5.402 -	chip->vendor->cancel(chip);
   5.403 +	chip->vendor.cancel(chip);
   5.404  	dev_err(chip->dev, "Operation Timed out\n");
   5.405  	rc = -ETIME;
   5.406  	goto out;
   5.407  
   5.408  out_recv:
   5.409 -	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
   5.410 +	rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
   5.411  	if (rc < 0)
   5.412  		dev_err(chip->dev,
   5.413  			"tpm_transmit: tpm_recv: error %zd\n", rc);
   5.414 @@ -120,17 +431,247 @@ out:
   5.415  }
   5.416  
   5.417  #define TPM_DIGEST_SIZE 20
   5.418 -#define CAP_PCR_RESULT_SIZE 18
   5.419 -static const u8 cap_pcr[] = {
   5.420 +#define TPM_ERROR_SIZE 10
   5.421 +#define TPM_RET_CODE_IDX 6
   5.422 +#define TPM_GET_CAP_RET_SIZE_IDX 10
   5.423 +#define TPM_GET_CAP_RET_UINT32_1_IDX 14
   5.424 +#define TPM_GET_CAP_RET_UINT32_2_IDX 18
   5.425 +#define TPM_GET_CAP_RET_UINT32_3_IDX 22
   5.426 +#define TPM_GET_CAP_RET_UINT32_4_IDX 26
   5.427 +#define TPM_GET_CAP_PERM_DISABLE_IDX 16
   5.428 +#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
   5.429 +#define TPM_GET_CAP_RET_BOOL_1_IDX 14
   5.430 +#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
   5.431 +
   5.432 +#define TPM_CAP_IDX 13
   5.433 +#define TPM_CAP_SUBCAP_IDX 21
   5.434 +
   5.435 +enum tpm_capabilities {
   5.436 +	TPM_CAP_FLAG = 4,
   5.437 +	TPM_CAP_PROP = 5,
   5.438 +};
   5.439 +
   5.440 +enum tpm_sub_capabilities {
   5.441 +	TPM_CAP_PROP_PCR = 0x1,
   5.442 +	TPM_CAP_PROP_MANUFACTURER = 0x3,
   5.443 +	TPM_CAP_FLAG_PERM = 0x8,
   5.444 +	TPM_CAP_FLAG_VOL = 0x9,
   5.445 +	TPM_CAP_PROP_OWNER = 0x11,
   5.446 +	TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
   5.447 +	TPM_CAP_PROP_TIS_DURATION = 0x20,
   5.448 +};
   5.449 +
   5.450 +/*
   5.451 + * This is a semi generic GetCapability command for use
   5.452 + * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
   5.453 + * and their associated sub_capabilities.
   5.454 + */
   5.455 +
   5.456 +static const u8 tpm_cap[] = {
   5.457  	0, 193,			/* TPM_TAG_RQU_COMMAND */
   5.458  	0, 0, 0, 22,		/* length */
   5.459  	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
   5.460 -	0, 0, 0, 5,
   5.461 -	0, 0, 0, 4,
   5.462 -	0, 0, 1, 1
   5.463 +	0, 0, 0, 0,		/* TPM_CAP_<TYPE> */
   5.464 +	0, 0, 0, 4,		/* TPM_CAP_SUB_<TYPE> size */
   5.465 +	0, 0, 1, 0		/* TPM_CAP_SUB_<TYPE> */
   5.466  };
   5.467  
   5.468 -#define READ_PCR_RESULT_SIZE 30
   5.469 +static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
   5.470 +			    char *desc)
   5.471 +{
   5.472 +	int err;
   5.473 +
   5.474 +	len = tpm_transmit(chip, data, len);
   5.475 +	if (len <  0)
   5.476 +		return len;
   5.477 +	if (len == TPM_ERROR_SIZE) {
   5.478 +		err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
   5.479 +		dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
   5.480 +		return err;
   5.481 +	}
   5.482 +	return 0;
   5.483 +}
   5.484 +
   5.485 +void tpm_gen_interrupt(struct tpm_chip *chip)
   5.486 +{
   5.487 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
   5.488 +	ssize_t rc;
   5.489 +
   5.490 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.491 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.492 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
   5.493 +
   5.494 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.495 +			"attempting to determine the timeouts");
   5.496 +}
   5.497 +EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
   5.498 +
   5.499 +void tpm_get_timeouts(struct tpm_chip *chip)
   5.500 +{
   5.501 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
   5.502 +	ssize_t rc;
   5.503 +	u32 timeout;
   5.504 +
   5.505 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.506 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.507 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
   5.508 +
   5.509 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.510 +			"attempting to determine the timeouts");
   5.511 +	if (rc)
   5.512 +		goto duration;
   5.513 +
   5.514 +	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
   5.515 +	    != 4 * sizeof(u32))
   5.516 +		goto duration;
   5.517 +
   5.518 +	/* Don't overwrite default if value is 0 */
   5.519 +	timeout =
   5.520 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
   5.521 +	if (timeout)
   5.522 +		chip->vendor.timeout_a = msecs_to_jiffies(timeout);
   5.523 +	timeout =
   5.524 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
   5.525 +	if (timeout)
   5.526 +		chip->vendor.timeout_b = msecs_to_jiffies(timeout);
   5.527 +	timeout =
   5.528 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
   5.529 +	if (timeout)
   5.530 +		chip->vendor.timeout_c = msecs_to_jiffies(timeout);
   5.531 +	timeout =
   5.532 +	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
   5.533 +	if (timeout)
   5.534 +		chip->vendor.timeout_d = msecs_to_jiffies(timeout);
   5.535 +
   5.536 +duration:
   5.537 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.538 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.539 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
   5.540 +
   5.541 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.542 +			"attempting to determine the durations");
   5.543 +	if (rc)
   5.544 +		return;
   5.545 +
   5.546 +	if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
   5.547 +	    != 3 * sizeof(u32))
   5.548 +		return;
   5.549 +
   5.550 +	chip->vendor.duration[TPM_SHORT] =
   5.551 +	    msecs_to_jiffies(be32_to_cpu
   5.552 +			     (*((__be32 *) (data +
   5.553 +					    TPM_GET_CAP_RET_UINT32_1_IDX))));
   5.554 +	chip->vendor.duration[TPM_MEDIUM] =
   5.555 +	    msecs_to_jiffies(be32_to_cpu
   5.556 +			     (*((__be32 *) (data +
   5.557 +					    TPM_GET_CAP_RET_UINT32_2_IDX))));
   5.558 +	chip->vendor.duration[TPM_LONG] =
   5.559 +	    msecs_to_jiffies(be32_to_cpu
   5.560 +			     (*((__be32 *) (data +
   5.561 +					    TPM_GET_CAP_RET_UINT32_3_IDX))));
   5.562 +}
   5.563 +EXPORT_SYMBOL_GPL(tpm_get_timeouts);
   5.564 +
   5.565 +void tpm_continue_selftest(struct tpm_chip *chip)
   5.566 +{
   5.567 +	u8 data[] = {
   5.568 +		0, 193,			/* TPM_TAG_RQU_COMMAND */
   5.569 +		0, 0, 0, 10,		/* length */
   5.570 +		0, 0, 0, 83,		/* TPM_ORD_GetCapability */
   5.571 +	};
   5.572 +
   5.573 +	tpm_transmit(chip, data, sizeof(data));
   5.574 +}
   5.575 +EXPORT_SYMBOL_GPL(tpm_continue_selftest);
   5.576 +
   5.577 +ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
   5.578 +			char *buf)
   5.579 +{
   5.580 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
   5.581 +	ssize_t rc;
   5.582 +
   5.583 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   5.584 +	if (chip == NULL)
   5.585 +		return -ENODEV;
   5.586 +
   5.587 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.588 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
   5.589 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
   5.590 +
   5.591 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.592 +			"attemtping to determine the permanent state");
   5.593 +	if (rc)
   5.594 +		return 0;
   5.595 +	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
   5.596 +}
   5.597 +EXPORT_SYMBOL_GPL(tpm_show_enabled);
   5.598 +
   5.599 +ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
   5.600 +			char *buf)
   5.601 +{
   5.602 +	u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
   5.603 +	ssize_t rc;
   5.604 +
   5.605 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   5.606 +	if (chip == NULL)
   5.607 +		return -ENODEV;
   5.608 +
   5.609 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.610 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
   5.611 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
   5.612 +
   5.613 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.614 +			"attemtping to determine the permanent state");
   5.615 +	if (rc)
   5.616 +		return 0;
   5.617 +	return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
   5.618 +}
   5.619 +EXPORT_SYMBOL_GPL(tpm_show_active);
   5.620 +
   5.621 +ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
   5.622 +			char *buf)
   5.623 +{
   5.624 +	u8 data[sizeof(tpm_cap)];
   5.625 +	ssize_t rc;
   5.626 +
   5.627 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   5.628 +	if (chip == NULL)
   5.629 +		return -ENODEV;
   5.630 +
   5.631 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.632 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.633 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
   5.634 +
   5.635 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.636 +			"attempting to determine the owner state");
   5.637 +	if (rc)
   5.638 +		return 0;
   5.639 +	return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
   5.640 +}
   5.641 +EXPORT_SYMBOL_GPL(tpm_show_owned);
   5.642 +
   5.643 +ssize_t tpm_show_temp_deactivated(struct device * dev,
   5.644 +				struct device_attribute * attr, char *buf)
   5.645 +{
   5.646 +	u8 data[sizeof(tpm_cap)];
   5.647 +	ssize_t rc;
   5.648 +
   5.649 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   5.650 +	if (chip == NULL)
   5.651 +		return -ENODEV;
   5.652 +
   5.653 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.654 +	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
   5.655 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
   5.656 +
   5.657 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.658 +			"attempting to determine the temporary state");
   5.659 +	if (rc)
   5.660 +		return 0;
   5.661 +	return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
   5.662 +}
   5.663 +EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
   5.664 +
   5.665  static const u8 pcrread[] = {
   5.666  	0, 193,			/* TPM_TAG_RQU_COMMAND */
   5.667  	0, 0, 0, 14,		/* length */
   5.668 @@ -141,8 +682,8 @@ static const u8 pcrread[] = {
   5.669  ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
   5.670  		      char *buf)
   5.671  {
   5.672 -	u8 data[READ_PCR_RESULT_SIZE];
   5.673 -	ssize_t len;
   5.674 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
   5.675 +	ssize_t rc;
   5.676  	int i, j, num_pcrs;
   5.677  	__be32 index;
   5.678  	char *str = buf;
   5.679 @@ -151,29 +692,24 @@ ssize_t tpm_show_pcrs(struct device *dev
   5.680  	if (chip == NULL)
   5.681  		return -ENODEV;
   5.682  
   5.683 -	memcpy(data, cap_pcr, sizeof(cap_pcr));
   5.684 -	if ((len = tpm_transmit(chip, data, sizeof(data)))
   5.685 -	    < CAP_PCR_RESULT_SIZE) {
   5.686 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
   5.687 -				"attempting to determine the number of PCRS\n",
   5.688 -			be32_to_cpu(*((__be32 *) (data + 6))));
   5.689 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.690 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.691 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
   5.692 +
   5.693 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.694 +			"attempting to determine the number of PCRS");
   5.695 +	if (rc)
   5.696  		return 0;
   5.697 -	}
   5.698  
   5.699  	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
   5.700 -
   5.701  	for (i = 0; i < num_pcrs; i++) {
   5.702  		memcpy(data, pcrread, sizeof(pcrread));
   5.703  		index = cpu_to_be32(i);
   5.704  		memcpy(data + 10, &index, 4);
   5.705 -		if ((len = tpm_transmit(chip, data, sizeof(data)))
   5.706 -		    < READ_PCR_RESULT_SIZE){
   5.707 -			dev_dbg(chip->dev, "A TPM error (%d) occurred"
   5.708 -				" attempting to read PCR %d of %d\n",
   5.709 -				be32_to_cpu(*((__be32 *) (data + 6))),
   5.710 -				i, num_pcrs);
   5.711 +		rc = transmit_cmd(chip, data, sizeof(data),
   5.712 +				"attempting to read a PCR");
   5.713 +		if (rc)
   5.714  			goto out;
   5.715 -		}
   5.716  		str += sprintf(str, "PCR-%02d: ", i);
   5.717  		for (j = 0; j < TPM_DIGEST_SIZE; j++)
   5.718  			str += sprintf(str, "%02X ", *(data + 10 + j));
   5.719 @@ -195,7 +731,7 @@ ssize_t tpm_show_pubek(struct device *de
   5.720  		       char *buf)
   5.721  {
   5.722  	u8 *data;
   5.723 -	ssize_t len;
   5.724 +	ssize_t err;
   5.725  	int i, rc;
   5.726  	char *str = buf;
   5.727  
   5.728 @@ -209,14 +745,10 @@ ssize_t tpm_show_pubek(struct device *de
   5.729  
   5.730  	memcpy(data, readpubek, sizeof(readpubek));
   5.731  
   5.732 -	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
   5.733 -	    READ_PUBEK_RESULT_SIZE) {
   5.734 -		dev_dbg(chip->dev, "A TPM error (%d) occurred "
   5.735 -				"attempting to read the PUBEK\n",
   5.736 -			    be32_to_cpu(*((__be32 *) (data + 6))));
   5.737 -		rc = 0;
   5.738 +	err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
   5.739 +			"attempting to read the PUBEK");
   5.740 +	if (err)
   5.741  		goto out;
   5.742 -	}
   5.743  
   5.744  	/* 
   5.745  	   ignore header 10 bytes
   5.746 @@ -246,36 +778,68 @@ ssize_t tpm_show_pubek(struct device *de
   5.747  		if ((i + 1) % 16 == 0)
   5.748  			str += sprintf(str, "\n");
   5.749  	}
   5.750 +out:
   5.751  	rc = str - buf;
   5.752 -out:
   5.753  	kfree(data);
   5.754  	return rc;
   5.755  }
   5.756  EXPORT_SYMBOL_GPL(tpm_show_pubek);
   5.757  
   5.758 -#define CAP_VER_RESULT_SIZE 18
   5.759 +#define CAP_VERSION_1_1 6
   5.760 +#define CAP_VERSION_1_2 0x1A
   5.761 +#define CAP_VERSION_IDX 13
   5.762  static const u8 cap_version[] = {
   5.763  	0, 193,			/* TPM_TAG_RQU_COMMAND */
   5.764  	0, 0, 0, 18,		/* length */
   5.765  	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
   5.766 -	0, 0, 0, 6,
   5.767 +	0, 0, 0, 0,
   5.768  	0, 0, 0, 0
   5.769  };
   5.770  
   5.771 -#define CAP_MANUFACTURER_RESULT_SIZE 18
   5.772 -static const u8 cap_manufacturer[] = {
   5.773 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   5.774 -	0, 0, 0, 22,		/* length */
   5.775 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
   5.776 -	0, 0, 0, 5,
   5.777 -	0, 0, 0, 4,
   5.778 -	0, 0, 1, 3
   5.779 -};
   5.780 -
   5.781  ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
   5.782  		      char *buf)
   5.783  {
   5.784 -	u8 data[sizeof(cap_manufacturer)];
   5.785 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
   5.786 +	ssize_t rc;
   5.787 +	char *str = buf;
   5.788 +
   5.789 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   5.790 +	if (chip == NULL)
   5.791 +		return -ENODEV;
   5.792 +
   5.793 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.794 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.795 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
   5.796 +
   5.797 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.798 +			"attempting to determine the manufacturer");
   5.799 +	if (rc)
   5.800 +		return 0;
   5.801 +
   5.802 +	str += sprintf(str, "Manufacturer: 0x%x\n",
   5.803 +		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
   5.804 +
   5.805 +	memcpy(data, cap_version, sizeof(cap_version));
   5.806 +	data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
   5.807 +	rc = transmit_cmd(chip, data, sizeof(data),
   5.808 +			"attempting to determine the 1.1 version");
   5.809 +	if (rc)
   5.810 +		goto out;
   5.811 +
   5.812 +	str += sprintf(str,
   5.813 +		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
   5.814 +		       (int) data[14], (int) data[15], (int) data[16],
   5.815 +		       (int) data[17]);
   5.816 +
   5.817 +out:
   5.818 +	return str - buf;
   5.819 +}
   5.820 +EXPORT_SYMBOL_GPL(tpm_show_caps);
   5.821 +
   5.822 +ssize_t tpm_show_caps_1_2(struct device * dev,
   5.823 +			  struct device_attribute * attr, char *buf)
   5.824 +{
   5.825 +	u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
   5.826  	ssize_t len;
   5.827  	char *str = buf;
   5.828  
   5.829 @@ -283,29 +847,40 @@ ssize_t tpm_show_caps(struct device *dev
   5.830  	if (chip == NULL)
   5.831  		return -ENODEV;
   5.832  
   5.833 -	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
   5.834 +	memcpy(data, tpm_cap, sizeof(tpm_cap));
   5.835 +	data[TPM_CAP_IDX] = TPM_CAP_PROP;
   5.836 +	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
   5.837  
   5.838 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
   5.839 -	    CAP_MANUFACTURER_RESULT_SIZE)
   5.840 -		return len;
   5.841 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
   5.842 +	    TPM_ERROR_SIZE) {
   5.843 +		dev_dbg(chip->dev, "A TPM error (%d) occurred "
   5.844 +			"attempting to determine the manufacturer\n",
   5.845 +			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
   5.846 +		return 0;
   5.847 +	}
   5.848  
   5.849  	str += sprintf(str, "Manufacturer: 0x%x\n",
   5.850 -		       be32_to_cpu(*((__be32 *) (data + 14))));
   5.851 +		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
   5.852  
   5.853  	memcpy(data, cap_version, sizeof(cap_version));
   5.854 -
   5.855 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
   5.856 -	    CAP_VER_RESULT_SIZE)
   5.857 -		return len;
   5.858 +	data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
   5.859  
   5.860 -	str +=
   5.861 -	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
   5.862 -		    (int) data[14], (int) data[15], (int) data[16],
   5.863 -		    (int) data[17]);
   5.864 +	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
   5.865 +	    TPM_ERROR_SIZE) {
   5.866 +		dev_err(chip->dev, "A TPM error (%d) occurred "
   5.867 +			"attempting to determine the 1.2 version\n",
   5.868 +			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
   5.869 +		goto out;
   5.870 +	}
   5.871 +	str += sprintf(str,
   5.872 +		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
   5.873 +		       (int) data[16], (int) data[17], (int) data[18],
   5.874 +		       (int) data[19]);
   5.875  
   5.876 +out:
   5.877  	return str - buf;
   5.878  }
   5.879 -EXPORT_SYMBOL_GPL(tpm_show_caps);
   5.880 +EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
   5.881  
   5.882  ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
   5.883  			const char *buf, size_t count)
   5.884 @@ -314,7 +889,7 @@ ssize_t tpm_store_cancel(struct device *
   5.885  	if (chip == NULL)
   5.886  		return 0;
   5.887  
   5.888 -	chip->vendor->cancel(chip);
   5.889 +	chip->vendor.cancel(chip);
   5.890  	return count;
   5.891  }
   5.892  EXPORT_SYMBOL_GPL(tpm_store_cancel);
   5.893 @@ -330,7 +905,7 @@ int tpm_open(struct inode *inode, struct
   5.894  	spin_lock(&driver_lock);
   5.895  
   5.896  	list_for_each_entry(pos, &tpm_chip_list, list) {
   5.897 -		if (pos->vendor->miscdev.minor == minor) {
   5.898 +		if (pos->vendor.miscdev.minor == minor) {
   5.899  			chip = pos;
   5.900  			break;
   5.901  		}
   5.902 @@ -352,7 +927,12 @@ int tpm_open(struct inode *inode, struct
   5.903  
   5.904  	spin_unlock(&driver_lock);
   5.905  
   5.906 -	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8), GFP_KERNEL);
   5.907 +#ifndef CONFIG_XEN
   5.908 +	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
   5.909 +#else
   5.910 +	chip->data_buffer = kmalloc(get_chip_buffersize(chip) * sizeof(u8),
   5.911 +	                            GFP_KERNEL);
   5.912 +#endif
   5.913  	if (chip->data_buffer == NULL) {
   5.914  		chip->num_opens--;
   5.915  		put_device(chip->dev);
   5.916 @@ -388,7 +968,7 @@ int tpm_release(struct inode *inode, str
   5.917  EXPORT_SYMBOL_GPL(tpm_release);
   5.918  
   5.919  ssize_t tpm_write(struct file *file, const char __user *buf,
   5.920 -		  size_t size, loff_t * off)
   5.921 +		  size_t size, loff_t *off)
   5.922  {
   5.923  	struct tpm_chip *chip = file->private_data;
   5.924  	int in_size = size, out_size;
   5.925 @@ -400,8 +980,13 @@ ssize_t tpm_write(struct file *file, con
   5.926  
   5.927  	down(&chip->buffer_mutex);
   5.928  
   5.929 +#ifndef CONFIG_XEN
   5.930 +	if (in_size > TPM_BUFSIZE)
   5.931 +		in_size = TPM_BUFSIZE;
   5.932 +#else
   5.933  	if (in_size > get_chip_buffersize(chip))
   5.934  		in_size = get_chip_buffersize(chip);
   5.935 +#endif
   5.936  
   5.937  	if (copy_from_user
   5.938  	    (chip->data_buffer, (void __user *) buf, in_size)) {
   5.939 @@ -410,11 +995,17 @@ ssize_t tpm_write(struct file *file, con
   5.940  	}
   5.941  
   5.942  	/* atomic tpm command send and result receive */
   5.943 -	out_size = tpm_transmit(chip, chip->data_buffer, 
   5.944 +#ifndef CONFIG_XEN
   5.945 +	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
   5.946 +#else
   5.947 +	out_size = tpm_transmit(chip, chip->data_buffer,
   5.948  	                        get_chip_buffersize(chip));
   5.949 +#endif
   5.950  
   5.951  	atomic_set(&chip->data_pending, out_size);
   5.952 +#ifdef CONFIG_XEN
   5.953  	atomic_set(&chip->data_position, 0);
   5.954 +#endif
   5.955  	up(&chip->buffer_mutex);
   5.956  
   5.957  	/* Set a timeout by which the reader must come claim the result */
   5.958 @@ -422,42 +1013,59 @@ ssize_t tpm_write(struct file *file, con
   5.959  
   5.960  	return in_size;
   5.961  }
   5.962 -
   5.963  EXPORT_SYMBOL_GPL(tpm_write);
   5.964  
   5.965 -ssize_t tpm_read(struct file * file, char __user *buf,
   5.966 -		 size_t size, loff_t * off)
   5.967 +ssize_t tpm_read(struct file *file, char __user *buf,
   5.968 +		 size_t size, loff_t *off)
   5.969  {
   5.970  	struct tpm_chip *chip = file->private_data;
   5.971  	int ret_size;
   5.972 +#ifdef CONFIG_XEN
   5.973  	int pos, pending = 0;
   5.974 +#endif
   5.975  
   5.976 +#ifndef CONFIG_XEN
   5.977 +	del_singleshot_timer_sync(&chip->user_read_timer);
   5.978 +	flush_scheduled_work();
   5.979 +#endif
   5.980  	ret_size = atomic_read(&chip->data_pending);
   5.981 +#ifndef CONFIG_XEN
   5.982 +	atomic_set(&chip->data_pending, 0);
   5.983 +#endif
   5.984  	if (ret_size > 0) {	/* relay data */
   5.985  		if (size < ret_size)
   5.986  			ret_size = size;
   5.987  
   5.988 +#ifdef CONFIG_XEN
   5.989  		pos = atomic_read(&chip->data_position);
   5.990 -
   5.991 +#endif
   5.992  		down(&chip->buffer_mutex);
   5.993 +#ifndef CONFIG_XEN
   5.994 +		if (copy_to_user(buf, chip->data_buffer, ret_size))
   5.995 +#else
   5.996  		if (copy_to_user(buf, &chip->data_buffer[pos], ret_size)) {
   5.997 +#endif
   5.998  			ret_size = -EFAULT;
   5.999 +#ifdef CONFIG_XEN
  5.1000  		} else {
  5.1001  			pending = atomic_read(&chip->data_pending) - ret_size;
  5.1002  			if ( pending ) {
  5.1003 -				atomic_set( &chip->data_pending, pending );
  5.1004 -				atomic_set( &chip->data_position, pos+ret_size );
  5.1005 +				atomic_set(&chip->data_pending, pending);
  5.1006 +				atomic_set(&chip->data_position,
  5.1007 +				           pos+ret_size);
  5.1008  			}
  5.1009  		}
  5.1010 +#endif
  5.1011  		up(&chip->buffer_mutex);
  5.1012  	}
  5.1013 -	
  5.1014 -	if ( ret_size <= 0 || pending == 0 ) {
  5.1015 -		atomic_set( &chip->data_pending, 0 );
  5.1016 +
  5.1017 +#ifdef CONFIG_XEN
  5.1018 + 	if ( ret_size <= 0 || pending == 0 ) {
  5.1019 +		atomic_set(&chip->data_pending, 0);
  5.1020  		del_singleshot_timer_sync(&chip->user_read_timer);
  5.1021  		flush_scheduled_work();
  5.1022  	}
  5.1023 -
  5.1024 +#endif
  5.1025  	return ret_size;
  5.1026  }
  5.1027  EXPORT_SYMBOL_GPL(tpm_read);
  5.1028 @@ -478,14 +1086,13 @@ void tpm_remove_hardware(struct device *
  5.1029  	spin_unlock(&driver_lock);
  5.1030  
  5.1031  	dev_set_drvdata(dev, NULL);
  5.1032 -	misc_deregister(&chip->vendor->miscdev);
  5.1033 -	kfree(chip->vendor->miscdev.name);
  5.1034 +	misc_deregister(&chip->vendor.miscdev);
  5.1035 +	kfree(chip->vendor.miscdev.name);
  5.1036  
  5.1037 -	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
  5.1038 +	sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
  5.1039  	tpm_bios_log_teardown(chip->bios_dir);
  5.1040  
  5.1041 -	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
  5.1042 -		~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
  5.1043 +	clear_bit(chip->dev_num, dev_mask);
  5.1044  
  5.1045  	kfree(chip);
  5.1046  
  5.1047 @@ -536,18 +1143,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
  5.1048   * upon errant exit from this function specific probe function should call
  5.1049   * pci_disable_device
  5.1050   */
  5.1051 -int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
  5.1052 +struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
  5.1053 +				       *entry)
  5.1054  {
  5.1055  #define DEVNAME_SIZE 7
  5.1056  
  5.1057  	char *devname;
  5.1058  	struct tpm_chip *chip;
  5.1059 -	int i, j;
  5.1060  
  5.1061  	/* Driver specific per-device data */
  5.1062  	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
  5.1063  	if (chip == NULL)
  5.1064 -		return -ENOMEM;
  5.1065 +		return NULL;
  5.1066  
  5.1067  	init_MUTEX(&chip->buffer_mutex);
  5.1068  	init_MUTEX(&chip->tpm_mutex);
  5.1069 @@ -559,51 +1166,37 @@ int tpm_register_hardware(struct device 
  5.1070  	chip->user_read_timer.function = user_reader_timeout;
  5.1071  	chip->user_read_timer.data = (unsigned long) chip;
  5.1072  
  5.1073 -	chip->vendor = entry;
  5.1074 -	
  5.1075 -	if (entry->buffersize < TPM_MIN_BUFSIZE) {
  5.1076 -		entry->buffersize = TPM_MIN_BUFSIZE;
  5.1077 -	} else if (entry->buffersize > TPM_MAX_BUFSIZE) {
  5.1078 -		entry->buffersize = TPM_MAX_BUFSIZE;
  5.1079 -	}
  5.1080 -
  5.1081 -	chip->dev_num = -1;
  5.1082 +	memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
  5.1083  
  5.1084 -	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
  5.1085 -		for (j = 0; j < 8 * sizeof(int); j++)
  5.1086 -			if ((dev_mask[i] & (1 << j)) == 0) {
  5.1087 -				chip->dev_num =
  5.1088 -				    i * TPM_NUM_MASK_ENTRIES + j;
  5.1089 -				dev_mask[i] |= 1 << j;
  5.1090 -				goto dev_num_search_complete;
  5.1091 -			}
  5.1092 +	chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
  5.1093  
  5.1094 -dev_num_search_complete:
  5.1095 -	if (chip->dev_num < 0) {
  5.1096 +	if (chip->dev_num >= TPM_NUM_DEVICES) {
  5.1097  		dev_err(dev, "No available tpm device numbers\n");
  5.1098  		kfree(chip);
  5.1099 -		return -ENODEV;
  5.1100 +		return NULL;
  5.1101  	} else if (chip->dev_num == 0)
  5.1102 -		chip->vendor->miscdev.minor = TPM_MINOR;
  5.1103 +		chip->vendor.miscdev.minor = TPM_MINOR;
  5.1104  	else
  5.1105 -		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
  5.1106 +		chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
  5.1107 +
  5.1108 +	set_bit(chip->dev_num, dev_mask);
  5.1109  
  5.1110  	devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
  5.1111  	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
  5.1112 -	chip->vendor->miscdev.name = devname;
  5.1113 +	chip->vendor.miscdev.name = devname;
  5.1114  
  5.1115 -	chip->vendor->miscdev.dev = dev;
  5.1116 +	chip->vendor.miscdev.dev = dev;
  5.1117  	chip->dev = get_device(dev);
  5.1118  
  5.1119 -	if (misc_register(&chip->vendor->miscdev)) {
  5.1120 +	if (misc_register(&chip->vendor.miscdev)) {
  5.1121  		dev_err(chip->dev,
  5.1122  			"unable to misc_register %s, minor %d\n",
  5.1123 -			chip->vendor->miscdev.name,
  5.1124 -			chip->vendor->miscdev.minor);
  5.1125 +			chip->vendor.miscdev.name,
  5.1126 +			chip->vendor.miscdev.minor);
  5.1127  		put_device(dev);
  5.1128 +		clear_bit(chip->dev_num, dev_mask);
  5.1129  		kfree(chip);
  5.1130 -		dev_mask[i] &= !(1 << j);
  5.1131 -		return -ENODEV;
  5.1132 +		return NULL;
  5.1133  	}
  5.1134  
  5.1135  	spin_lock(&driver_lock);
  5.1136 @@ -614,11 +1207,11 @@ dev_num_search_complete:
  5.1137  
  5.1138  	spin_unlock(&driver_lock);
  5.1139  
  5.1140 -	sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
  5.1141 +	sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
  5.1142  
  5.1143  	chip->bios_dir = tpm_bios_log_setup(devname);
  5.1144  
  5.1145 -	return 0;
  5.1146 +	return chip;
  5.1147  }
  5.1148  EXPORT_SYMBOL_GPL(tpm_register_hardware);
  5.1149  
     6.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Wed Jun 28 16:15:36 2006 +0100
     6.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Wed Jun 28 16:20:29 2006 +0100
     6.3 @@ -24,6 +24,14 @@
     6.4  #include <linux/fs.h>
     6.5  #include <linux/miscdevice.h>
     6.6  #include <linux/platform_device.h>
     6.7 +#include <linux/io.h>
     6.8 +
     6.9 +#ifdef CONFIG_XEN
    6.10 +enum tpm_bufsize {
    6.11 +	TPM_MIN_BUFFERSIZE = 2048,
    6.12 +	TPM_MAX_BUFFERSIZE = 64 * 1024,
    6.13 +};
    6.14 +#endif
    6.15  
    6.16  enum tpm_timeout {
    6.17  	TPM_TIMEOUT = 5,	/* msecs */
    6.18 @@ -41,19 +49,33 @@ extern ssize_t tpm_show_pcrs(struct devi
    6.19  				char *);
    6.20  extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
    6.21  				char *);
    6.22 +extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
    6.23 +				char *);
    6.24  extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
    6.25  				const char *, size_t);
    6.26 +extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
    6.27 +				char *);
    6.28 +extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
    6.29 +				char *);
    6.30 +extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
    6.31 +				char *);
    6.32 +extern ssize_t tpm_show_temp_deactivated(struct device *,
    6.33 +					 struct device_attribute *attr, char *);
    6.34  
    6.35  struct tpm_chip;
    6.36  
    6.37  struct tpm_vendor_specific {
    6.38 -	u8 req_complete_mask;
    6.39 -	u8 req_complete_val;
    6.40 -	u8 req_canceled;
    6.41 +	const u8 req_complete_mask;
    6.42 +	const u8 req_complete_val;
    6.43 +	const u8 req_canceled;
    6.44 +#ifdef CONFIG_XEN
    6.45  	u32 buffersize;
    6.46 +#endif
    6.47  	void __iomem *iobase;		/* ioremapped address */
    6.48  	unsigned long base;		/* TPM base address */
    6.49  
    6.50 +	int irq;
    6.51 +
    6.52  	int region_size;
    6.53  	int have_region;
    6.54  
    6.55 @@ -63,6 +85,13 @@ struct tpm_vendor_specific {
    6.56  	u8 (*status) (struct tpm_chip *);
    6.57  	struct miscdevice miscdev;
    6.58  	struct attribute_group *attr_group;
    6.59 +	struct list_head list;
    6.60 +	int locality;
    6.61 +	unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
    6.62 +	unsigned long duration[3]; /* jiffies */
    6.63 +
    6.64 +	wait_queue_head_t read_queue;
    6.65 +	wait_queue_head_t int_queue;
    6.66  };
    6.67  
    6.68  struct tpm_chip {
    6.69 @@ -75,20 +104,27 @@ struct tpm_chip {
    6.70  	/* Data passed to and from the tpm via the read/write calls */
    6.71  	u8 *data_buffer;
    6.72  	atomic_t data_pending;
    6.73 +#ifdef CONFIG_XEN
    6.74  	atomic_t data_position;
    6.75 +#endif
    6.76  	struct semaphore buffer_mutex;
    6.77  
    6.78  	struct timer_list user_read_timer;	/* user needs to claim result */
    6.79  	struct work_struct work;
    6.80  	struct semaphore tpm_mutex;	/* tpm is processing */
    6.81  
    6.82 -	struct tpm_vendor_specific *vendor;
    6.83 +	struct tpm_vendor_specific vendor;
    6.84  
    6.85  	struct dentry **bios_dir;
    6.86  
    6.87  	struct list_head list;
    6.88 +#ifdef CONFIG_XEN
    6.89 +	void *priv;
    6.90 +#endif
    6.91  };
    6.92  
    6.93 +#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
    6.94 +
    6.95  static inline int tpm_read_index(int base, int index)
    6.96  {
    6.97  	outb(index, base);
    6.98 @@ -101,13 +137,35 @@ static inline void tpm_write_index(int b
    6.99  	outb(value & 0xFF, base+1);
   6.100  }
   6.101  
   6.102 +#ifdef CONFIG_XEN
   6.103  static inline u32 get_chip_buffersize(struct tpm_chip *chip)
   6.104  {
   6.105 -	return chip->vendor->buffersize;
   6.106 +	u32 size = chip->vendor.buffersize;
   6.107 +	if (size > TPM_MAX_BUFFERSIZE) {
   6.108 +		return TPM_MAX_BUFFERSIZE;
   6.109 +	} else if (size < TPM_MIN_BUFFERSIZE) {
   6.110 +		return TPM_MIN_BUFFERSIZE;
   6.111 +	}
   6.112 +	return size;
   6.113  }
   6.114  
   6.115 -extern int tpm_register_hardware(struct device *,
   6.116 -				 struct tpm_vendor_specific *);
   6.117 +static inline void *chip_get_private(const struct tpm_chip *chip)
   6.118 +{
   6.119 +	return chip->priv;
   6.120 +}
   6.121 +
   6.122 +static inline void chip_set_private(struct tpm_chip *chip, void *priv)
   6.123 +{
   6.124 +	chip->priv = priv;
   6.125 +}
   6.126 +#endif
   6.127 +
   6.128 +extern void tpm_get_timeouts(struct tpm_chip *);
   6.129 +extern void tpm_gen_interrupt(struct tpm_chip *);
   6.130 +extern void tpm_continue_selftest(struct tpm_chip *);
   6.131 +extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
   6.132 +extern struct tpm_chip* tpm_register_hardware(struct device *,
   6.133 +				 const struct tpm_vendor_specific *);
   6.134  extern int tpm_open(struct inode *, struct file *);
   6.135  extern int tpm_release(struct inode *, struct file *);
   6.136  extern ssize_t tpm_write(struct file *, const char __user *, size_t,
   6.137 @@ -121,7 +179,7 @@ extern int tpm_pm_resume(struct device *
   6.138  extern struct dentry ** tpm_bios_log_setup(char *);
   6.139  extern void tpm_bios_log_teardown(struct dentry **);
   6.140  #else
   6.141 -static inline struct dentry* tpm_bios_log_setup(char *name)
   6.142 +static inline struct dentry ** tpm_bios_log_setup(char *name)
   6.143  {
   6.144  	return NULL;
   6.145  }
     7.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Jun 28 16:15:36 2006 +0100
     7.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.c	Wed Jun 28 16:20:29 2006 +0100
     7.3 @@ -29,8 +29,6 @@ enum {
     7.4  	STATUS_READY = 0x04
     7.5  };
     7.6  
     7.7 -#define MIN(x,y)  ((x) < (y)) ? (x) : (y)
     7.8 -
     7.9  struct transmission {
    7.10  	struct list_head next;
    7.11  
    7.12 @@ -49,26 +47,6 @@ enum {
    7.13  	TRANSMISSION_FLAG_WAS_QUEUED = 0x1
    7.14  };
    7.15  
    7.16 -struct vtpm_state {
    7.17 -	struct transmission *current_request;
    7.18 -	spinlock_t           req_list_lock;
    7.19 -	wait_queue_head_t    req_wait_queue;
    7.20 -
    7.21 -	struct list_head     queued_requests;
    7.22 -
    7.23 -	struct transmission *current_response;
    7.24 -	spinlock_t           resp_list_lock;
    7.25 -	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
    7.26 -
    7.27 -	struct transmission *req_cancelled;       // if a cancellation was encounterd
    7.28 -
    7.29 -	u8                   vd_status;
    7.30 -	u8                   flags;
    7.31 -
    7.32 -	unsigned long        disconnect_time;
    7.33 -
    7.34 -	struct tpm_virtual_device *tpmvd;
    7.35 -};
    7.36  
    7.37  enum {
    7.38  	DATAEX_FLAG_QUEUED_ONLY = 0x1
    7.39 @@ -76,7 +54,6 @@ enum {
    7.40  
    7.41  
    7.42  /* local variables */
    7.43 -static struct vtpm_state *vtpms;
    7.44  
    7.45  /* local function prototypes */
    7.46  static int _vtpm_send_queued(struct tpm_chip *chip);
    7.47 @@ -160,11 +137,16 @@ static inline void transmission_free(str
    7.48  /*
    7.49   * Lower layer uses this function to make a response available.
    7.50   */
    7.51 -int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr)
    7.52 +int vtpm_vd_recv(const struct tpm_chip *chip,
    7.53 +                 const unsigned char *buffer, size_t count,
    7.54 +                 void *ptr)
    7.55  {
    7.56  	unsigned long flags;
    7.57  	int ret_size = 0;
    7.58  	struct transmission *t;
    7.59 +	struct vtpm_state *vtpms;
    7.60 +
    7.61 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
    7.62  
    7.63  	/*
    7.64  	 * The list with requests must contain one request
    7.65 @@ -173,26 +155,11 @@ int vtpm_vd_recv(const unsigned char *bu
    7.66  	 */
    7.67  	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
    7.68  	if (vtpms->current_request != ptr) {
    7.69 -		printk("WARNING: The request pointer is different than the "
    7.70 -		       "pointer the shared memory driver returned to me. "
    7.71 -		       "%p != %p\n",
    7.72 -		       vtpms->current_request, ptr);
    7.73 -	}
    7.74 -
    7.75 -	/*
    7.76 -	 * If the request has been cancelled, just quit here
    7.77 -	 */
    7.78 -	if (vtpms->req_cancelled == (struct transmission *)ptr) {
    7.79 -		if (vtpms->current_request == vtpms->req_cancelled) {
    7.80 -			vtpms->current_request = NULL;
    7.81 -		}
    7.82 -		transmission_free(vtpms->req_cancelled);
    7.83 -		vtpms->req_cancelled = NULL;
    7.84  		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
    7.85  		return 0;
    7.86  	}
    7.87  
    7.88 -	if (NULL != (t = vtpms->current_request)) {
    7.89 +	if ((t = vtpms->current_request)) {
    7.90  		transmission_free(t);
    7.91  		vtpms->current_request = NULL;
    7.92  	}
    7.93 @@ -217,8 +184,12 @@ int vtpm_vd_recv(const unsigned char *bu
    7.94  /*
    7.95   * Lower layer indicates its status (connected/disconnected)
    7.96   */
    7.97 -void vtpm_vd_status(u8 vd_status)
    7.98 +void vtpm_vd_status(const struct tpm_chip *chip, u8 vd_status)
    7.99  {
   7.100 +	struct vtpm_state *vtpms;
   7.101 +
   7.102 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   7.103 +
   7.104  	vtpms->vd_status = vd_status;
   7.105  	if ((vtpms->vd_status & TPM_VD_STATUS_CONNECTED) == 0) {
   7.106  		vtpms->disconnect_time = jiffies;
   7.107 @@ -233,6 +204,9 @@ static int vtpm_recv(struct tpm_chip *ch
   7.108  {
   7.109  	int rc = 0;
   7.110  	unsigned long flags;
   7.111 +	struct vtpm_state *vtpms;
   7.112 +
   7.113 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   7.114  
   7.115  	/*
   7.116  	 * Check if the previous operation only queued the command
   7.117 @@ -251,7 +225,7 @@ static int vtpm_recv(struct tpm_chip *ch
   7.118  		 * Return a response of up to 30 '0's.
   7.119  		 */
   7.120  
   7.121 -		count = MIN(count, 30);
   7.122 +		count = min_t(size_t, count, 30);
   7.123  		memset(buf, 0x0, count);
   7.124  		return count;
   7.125  	}
   7.126 @@ -270,7 +244,7 @@ static int vtpm_recv(struct tpm_chip *ch
   7.127  	if (vtpms->current_response) {
   7.128  		struct transmission *t = vtpms->current_response;
   7.129  		vtpms->current_response = NULL;
   7.130 -		rc = MIN(count, t->response_len);
   7.131 +		rc = min(count, t->response_len);
   7.132  		memcpy(buf, t->response, rc);
   7.133  		transmission_free(t);
   7.134  	}
   7.135 @@ -284,6 +258,9 @@ static int vtpm_send(struct tpm_chip *ch
   7.136  	int rc = 0;
   7.137  	unsigned long flags;
   7.138  	struct transmission *t = transmission_alloc();
   7.139 +	struct vtpm_state *vtpms;
   7.140 +
   7.141 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   7.142  
   7.143  	if (!t)
   7.144  		return -ENOMEM;
   7.145 @@ -327,8 +304,7 @@ static int vtpm_send(struct tpm_chip *ch
   7.146  
   7.147  			vtpms->current_request = t;
   7.148  
   7.149 -			rc = vtpm_vd_send(chip,
   7.150 -			                  vtpms->tpmvd->tpm_private,
   7.151 +			rc = vtpm_vd_send(vtpms->tpm_private,
   7.152  			                  buf,
   7.153  			                  count,
   7.154  			                  t);
   7.155 @@ -373,6 +349,8 @@ static int _vtpm_send_queued(struct tpm_
   7.156  	int error = 0;
   7.157  	long flags;
   7.158  	unsigned char buffer[1];
   7.159 +	struct vtpm_state *vtpms;
   7.160 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   7.161  
   7.162  	spin_lock_irqsave(&vtpms->req_list_lock, flags);
   7.163  
   7.164 @@ -387,8 +365,7 @@ static int _vtpm_send_queued(struct tpm_
   7.165  		vtpms->current_request = qt;
   7.166  		spin_unlock_irqrestore(&vtpms->req_list_lock, flags);
   7.167  
   7.168 -		rc = vtpm_vd_send(chip,
   7.169 -		                  vtpms->tpmvd->tpm_private,
   7.170 +		rc = vtpm_vd_send(vtpms->tpm_private,
   7.171  		                  qt->request,
   7.172  		                  qt->request_len,
   7.173  		                  qt);
   7.174 @@ -427,9 +404,21 @@ static int _vtpm_send_queued(struct tpm_
   7.175  static void vtpm_cancel(struct tpm_chip *chip)
   7.176  {
   7.177  	unsigned long flags;
   7.178 +	struct vtpm_state *vtpms = (struct vtpm_state *)chip_get_private(chip);
   7.179 +
   7.180  	spin_lock_irqsave(&vtpms->resp_list_lock,flags);
   7.181  
   7.182 -	vtpms->req_cancelled = vtpms->current_request;
   7.183 +	if (!vtpms->current_response && vtpms->current_request) {
   7.184 +		spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
   7.185 +		interruptible_sleep_on(&vtpms->resp_wait_queue);
   7.186 +		spin_lock_irqsave(&vtpms->resp_list_lock,flags);
   7.187 +	}
   7.188 +
   7.189 +	if (vtpms->current_response) {
   7.190 +		struct transmission *t = vtpms->current_response;
   7.191 +		vtpms->current_response = NULL;
   7.192 +		transmission_free(t);
   7.193 +	}
   7.194  
   7.195  	spin_unlock_irqrestore(&vtpms->resp_list_lock,flags);
   7.196  }
   7.197 @@ -438,6 +427,9 @@ static u8 vtpm_status(struct tpm_chip *c
   7.198  {
   7.199  	u8 rc = 0;
   7.200  	unsigned long flags;
   7.201 +	struct vtpm_state *vtpms;
   7.202 +
   7.203 +	vtpms = (struct vtpm_state *)chip_get_private(chip);
   7.204  
   7.205  	spin_lock_irqsave(&vtpms->resp_list_lock, flags);
   7.206  	/*
   7.207 @@ -449,7 +441,10 @@ static u8 vtpm_status(struct tpm_chip *c
   7.208  	if (vtpms->current_response ||
   7.209  	    0 != (vtpms->flags & DATAEX_FLAG_QUEUED_ONLY)) {
   7.210  		rc = STATUS_DATA_AVAIL;
   7.211 +	} else if (!vtpms->current_response && !vtpms->current_request) {
   7.212 +		rc = STATUS_READY;
   7.213  	}
   7.214 +
   7.215  	spin_unlock_irqrestore(&vtpms->resp_list_lock, flags);
   7.216  	return rc;
   7.217  }
   7.218 @@ -465,12 +460,21 @@ static struct file_operations vtpm_ops =
   7.219  
   7.220  static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
   7.221  static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
   7.222 +static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
   7.223 +static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
   7.224 +static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
   7.225 +static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
   7.226 +		   NULL);
   7.227  static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
   7.228  static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
   7.229  
   7.230  static struct attribute *vtpm_attrs[] = {
   7.231  	&dev_attr_pubek.attr,
   7.232  	&dev_attr_pcrs.attr,
   7.233 +	&dev_attr_enabled.attr,
   7.234 +	&dev_attr_active.attr,
   7.235 +	&dev_attr_owned.attr,
   7.236 +	&dev_attr_temp_deactivated.attr,
   7.237  	&dev_attr_caps.attr,
   7.238  	&dev_attr_cancel.attr,
   7.239  	NULL,
   7.240 @@ -478,6 +482,8 @@ static struct attribute *vtpm_attrs[] = 
   7.241  
   7.242  static struct attribute_group vtpm_attr_grp = { .attrs = vtpm_attrs };
   7.243  
   7.244 +#define TPM_LONG_TIMEOUT   (10 * 60 * HZ)
   7.245 +
   7.246  static struct tpm_vendor_specific tpm_vtpm = {
   7.247  	.recv = vtpm_recv,
   7.248  	.send = vtpm_send,
   7.249 @@ -486,61 +492,56 @@ static struct tpm_vendor_specific tpm_vt
   7.250  	.req_complete_mask = STATUS_BUSY | STATUS_DATA_AVAIL,
   7.251  	.req_complete_val  = STATUS_DATA_AVAIL,
   7.252  	.req_canceled = STATUS_READY,
   7.253 -	.base = 0,
   7.254  	.attr_group = &vtpm_attr_grp,
   7.255  	.miscdev = {
   7.256  		.fops = &vtpm_ops,
   7.257  	},
   7.258 +	.duration = {
   7.259 +		TPM_LONG_TIMEOUT,
   7.260 +		TPM_LONG_TIMEOUT,
   7.261 +		TPM_LONG_TIMEOUT,
   7.262 +	},
   7.263  };
   7.264  
   7.265 -static struct platform_device *pdev;
   7.266 -
   7.267 -int __init init_vtpm(struct tpm_virtual_device *tvd)
   7.268 +struct tpm_chip *init_vtpm(struct device *dev,
   7.269 +                           struct tpm_virtual_device *tvd,
   7.270 +                           struct tpm_private *tp)
   7.271  {
   7.272 -	int rc;
   7.273 -
   7.274 -	/* vtpms is global - only allow one user */
   7.275 -	if (vtpms)
   7.276 -		return -EBUSY;
   7.277 +	long rc;
   7.278 +	struct tpm_chip *chip;
   7.279 +	struct vtpm_state *vtpms;
   7.280  
   7.281  	vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
   7.282  	if (!vtpms)
   7.283 -		return -ENOMEM;
   7.284 +		return ERR_PTR(-ENOMEM);
   7.285  
   7.286  	vtpm_state_init(vtpms);
   7.287  	vtpms->tpmvd = tvd;
   7.288 -
   7.289 -	pdev = platform_device_register_simple("tpm_vtpm", -1, NULL, 0);
   7.290 -	if (IS_ERR(pdev)) {
   7.291 -		rc = PTR_ERR(pdev);
   7.292 -		goto err_free_mem;
   7.293 -	}
   7.294 +	vtpms->tpm_private = tp;
   7.295  
   7.296  	if (tvd)
   7.297  		tpm_vtpm.buffersize = tvd->max_tx_size;
   7.298  
   7.299 -	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_vtpm)) < 0) {
   7.300 -		goto err_unreg_pdev;
   7.301 +	chip = tpm_register_hardware(dev, &tpm_vtpm);
   7.302 +	if (!chip) {
   7.303 +		rc = -ENODEV;
   7.304 +		goto err_free_mem;
   7.305  	}
   7.306  
   7.307 -	return 0;
   7.308 +	chip_set_private(chip, vtpms);
   7.309  
   7.310 -err_unreg_pdev:
   7.311 -	platform_device_unregister(pdev);
   7.312 +	return chip;
   7.313 +
   7.314  err_free_mem:
   7.315  	kfree(vtpms);
   7.316 -	vtpms = NULL;
   7.317  
   7.318 -	return rc;
   7.319 +	return ERR_PTR(rc);
   7.320  }
   7.321  
   7.322 -void __exit cleanup_vtpm(void)
   7.323 +void cleanup_vtpm(struct device *dev)
   7.324  {
   7.325 -	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
   7.326 -	if (chip) {
   7.327 -		tpm_remove_hardware(chip->dev);
   7.328 -		platform_device_unregister(pdev);
   7.329 -	}
   7.330 +	struct tpm_chip *chip = dev_get_drvdata(dev);
   7.331 +	struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip);
   7.332 +	tpm_remove_hardware(dev);
   7.333  	kfree(vtpms);
   7.334 -	vtpms = NULL;
   7.335  }
     8.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Jun 28 16:15:36 2006 +0100
     8.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_vtpm.h	Wed Jun 28 16:20:29 2006 +0100
     8.3 @@ -12,6 +12,26 @@ struct tpm_virtual_device {
     8.4  	 * for allocation of buffers.
     8.5  	 */
     8.6  	unsigned int max_tx_size;
     8.7 +};
     8.8 +
     8.9 +struct vtpm_state {
    8.10 +	struct transmission *current_request;
    8.11 +	spinlock_t           req_list_lock;
    8.12 +	wait_queue_head_t    req_wait_queue;
    8.13 +
    8.14 +	struct list_head     queued_requests;
    8.15 +
    8.16 +	struct transmission *current_response;
    8.17 +	spinlock_t           resp_list_lock;
    8.18 +	wait_queue_head_t    resp_wait_queue;     // processes waiting for responses
    8.19 +
    8.20 +	u8                   vd_status;
    8.21 +	u8                   flags;
    8.22 +
    8.23 +	unsigned long        disconnect_time;
    8.24 +
    8.25 +	struct tpm_virtual_device *tpmvd;
    8.26 +
    8.27  	/*
    8.28  	 * The following is a private structure of the underlying
    8.29  	 * driver. It is passed as parameter in the send function.
    8.30 @@ -19,20 +39,30 @@ struct tpm_virtual_device {
    8.31  	struct tpm_private *tpm_private;
    8.32  };
    8.33  
    8.34 +
    8.35  enum vdev_status {
    8.36  	TPM_VD_STATUS_DISCONNECTED = 0x0,
    8.37  	TPM_VD_STATUS_CONNECTED = 0x1
    8.38  };
    8.39  
    8.40  /* this function is called from tpm_vtpm.c */
    8.41 -int vtpm_vd_send(struct tpm_chip *tc,
    8.42 -                 struct tpm_private * tp,
    8.43 +int vtpm_vd_send(struct tpm_private * tp,
    8.44                   const u8 * buf, size_t count, void *ptr);
    8.45  
    8.46  /* these functions are offered by tpm_vtpm.c */
    8.47 -int __init init_vtpm(struct tpm_virtual_device *);
    8.48 -void __exit cleanup_vtpm(void);
    8.49 -int vtpm_vd_recv(const unsigned char *buffer, size_t count, const void *ptr);
    8.50 -void vtpm_vd_status(u8 status);
    8.51 +struct tpm_chip *init_vtpm(struct device *,
    8.52 +                           struct tpm_virtual_device *,
    8.53 +                           struct tpm_private *);
    8.54 +void cleanup_vtpm(struct device *);
    8.55 +int vtpm_vd_recv(const struct tpm_chip* chip,
    8.56 +                 const unsigned char *buffer, size_t count, void *ptr);
    8.57 +void vtpm_vd_status(const struct tpm_chip *, u8 status);
    8.58 +
    8.59 +static inline struct tpm_private *tpm_private_from_dev(struct device *dev)
    8.60 +{
    8.61 +	struct tpm_chip *chip = dev_get_drvdata(dev);
    8.62 +	struct vtpm_state *vtpms = chip_get_private(chip);
    8.63 +	return vtpms->tpm_private;
    8.64 +}
    8.65  
    8.66  #endif
     9.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Jun 28 16:15:36 2006 +0100
     9.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Wed Jun 28 16:20:29 2006 +0100
     9.3 @@ -34,6 +34,7 @@
     9.4   */
     9.5  
     9.6  #include <linux/errno.h>
     9.7 +#include <linux/err.h>
     9.8  #include <linux/interrupt.h>
     9.9  #include <linux/mutex.h>
    9.10  #include <asm/uaccess.h>
    9.11 @@ -41,12 +42,15 @@
    9.12  #include <xen/interface/grant_table.h>
    9.13  #include <xen/interface/io/tpmif.h>
    9.14  #include <xen/xenbus.h>
    9.15 +#include "tpm.h"
    9.16  #include "tpm_vtpm.h"
    9.17  
    9.18  #undef DEBUG
    9.19  
    9.20  /* local structures */
    9.21  struct tpm_private {
    9.22 +	struct tpm_chip *chip;
    9.23 +
    9.24  	tpmif_tx_interface_t *tx;
    9.25  	atomic_t refcnt;
    9.26  	unsigned int evtchn;
    9.27 @@ -60,6 +64,7 @@ struct tpm_private {
    9.28  
    9.29  	atomic_t tx_busy;
    9.30  	void *tx_remember;
    9.31 +
    9.32  	domid_t backend_id;
    9.33  	wait_queue_head_t wait_q;
    9.34  
    9.35 @@ -95,6 +100,7 @@ static int tpm_xmit(struct tpm_private *
    9.36                      const u8 * buf, size_t count, int userbuffer,
    9.37                      void *remember);
    9.38  static void destroy_tpmring(struct tpm_private *tp);
    9.39 +void __exit tpmif_exit(void);
    9.40  
    9.41  #define DPRINTK(fmt, args...) \
    9.42      pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
    9.43 @@ -199,8 +205,7 @@ static DEFINE_MUTEX(suspend_lock);
    9.44  /*
    9.45   * Send data via this module by calling this function
    9.46   */
    9.47 -int vtpm_vd_send(struct tpm_chip *chip,
    9.48 -                 struct tpm_private *tp,
    9.49 +int vtpm_vd_send(struct tpm_private *tp,
    9.50                   const u8 * buf, size_t count, void *ptr)
    9.51  {
    9.52  	int sent;
    9.53 @@ -331,7 +336,7 @@ out:
    9.54  static void backend_changed(struct xenbus_device *dev,
    9.55  			    enum xenbus_state backend_state)
    9.56  {
    9.57 -	struct tpm_private *tp = dev->dev.driver_data;
    9.58 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
    9.59  	DPRINTK("\n");
    9.60  
    9.61  	switch (backend_state) {
    9.62 @@ -358,6 +363,9 @@ static void backend_changed(struct xenbu
    9.63  	}
    9.64  }
    9.65  
    9.66 +struct tpm_virtual_device tvd = {
    9.67 +	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
    9.68 +};
    9.69  
    9.70  static int tpmfront_probe(struct xenbus_device *dev,
    9.71                            const struct xenbus_device_id *id)
    9.72 @@ -369,6 +377,12 @@ static int tpmfront_probe(struct xenbus_
    9.73  	if (!tp)
    9.74  		return -ENOMEM;
    9.75  
    9.76 +	tp->chip = init_vtpm(&dev->dev, &tvd, tp);
    9.77 +
    9.78 +	if (IS_ERR(tp->chip)) {
    9.79 +		return PTR_ERR(tp->chip);
    9.80 +	}
    9.81 +
    9.82  	err = xenbus_scanf(XBT_NIL, dev->nodename,
    9.83  	                   "handle", "%i", &handle);
    9.84  	if (XENBUS_EXIST_ERR(err))
    9.85 @@ -380,12 +394,10 @@ static int tpmfront_probe(struct xenbus_
    9.86  	}
    9.87  
    9.88  	tp->dev = dev;
    9.89 -	dev->dev.driver_data = tp;
    9.90  
    9.91  	err = talk_to_backend(dev, tp);
    9.92  	if (err) {
    9.93  		tpm_private_put();
    9.94 -		dev->dev.driver_data = NULL;
    9.95  		return err;
    9.96  	}
    9.97  	return 0;
    9.98 @@ -394,16 +406,16 @@ static int tpmfront_probe(struct xenbus_
    9.99  
   9.100  static int tpmfront_remove(struct xenbus_device *dev)
   9.101  {
   9.102 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
   9.103 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   9.104  	destroy_tpmring(tp);
   9.105 +	cleanup_vtpm(&dev->dev);
   9.106  	return 0;
   9.107  }
   9.108  
   9.109  static int tpmfront_suspend(struct xenbus_device *dev)
   9.110  {
   9.111 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
   9.112 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   9.113  	u32 ctr;
   9.114 -
   9.115  	/* lock, so no app can send */
   9.116  	mutex_lock(&suspend_lock);
   9.117  	tp->is_suspended = 1;
   9.118 @@ -431,7 +443,7 @@ static int tpmfront_suspend(struct xenbu
   9.119  
   9.120  static int tpmfront_resume(struct xenbus_device *dev)
   9.121  {
   9.122 -	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
   9.123 +	struct tpm_private *tp = tpm_private_from_dev(&dev->dev);
   9.124  	destroy_tpmring(tp);
   9.125  	return talk_to_backend(dev, tp);
   9.126  }
   9.127 @@ -548,7 +560,7 @@ static void tpmif_rx_action(unsigned lon
   9.128  		offset += tocopy;
   9.129  	}
   9.130  
   9.131 -	vtpm_vd_recv(buffer, received, tp->tx_remember);
   9.132 +	vtpm_vd_recv(tp->chip, buffer, received, tp->tx_remember);
   9.133  	kfree(buffer);
   9.134  
   9.135  exit:
   9.136 @@ -638,6 +650,7 @@ static int tpm_xmit(struct tpm_private *
   9.137  
   9.138  	atomic_set(&tp->tx_busy, 1);
   9.139  	tp->tx_remember = remember;
   9.140 +
   9.141  	mb();
   9.142  
   9.143  	DPRINTK("Notifying backend via event channel %d\n",
   9.144 @@ -657,9 +670,9 @@ static void tpmif_notify_upperlayer(stru
   9.145  	 * to the BE.
   9.146  	 */
   9.147  	if (tp->is_connected) {
   9.148 -		vtpm_vd_status(TPM_VD_STATUS_CONNECTED);
   9.149 +		vtpm_vd_status(tp->chip, TPM_VD_STATUS_CONNECTED);
   9.150  	} else {
   9.151 -		vtpm_vd_status(TPM_VD_STATUS_DISCONNECTED);
   9.152 +		vtpm_vd_status(tp->chip, TPM_VD_STATUS_DISCONNECTED);
   9.153  	}
   9.154  }
   9.155  
   9.156 @@ -699,13 +712,10 @@ static void tpmif_set_connected_state(st
   9.157   * =================================================================
   9.158   */
   9.159  
   9.160 -struct tpm_virtual_device tvd = {
   9.161 -	.max_tx_size = PAGE_SIZE * TPMIF_TX_RING_SIZE,
   9.162 -};
   9.163  
   9.164  static int __init tpmif_init(void)
   9.165  {
   9.166 -	int rc;
   9.167 +	long rc = 0;
   9.168  	struct tpm_private *tp;
   9.169  
   9.170  	if ((xen_start_info->flags & SIF_INITDOMAIN)) {
   9.171 @@ -718,11 +728,6 @@ static int __init tpmif_init(void)
   9.172  		goto failexit;
   9.173  	}
   9.174  
   9.175 -	tvd.tpm_private = tp;
   9.176 -	rc = init_vtpm(&tvd);
   9.177 -	if (rc)
   9.178 -		goto init_vtpm_failed;
   9.179 -
   9.180  	IPRINTK("Initialising the vTPM driver.\n");
   9.181  	if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
   9.182  	                                     &gref_head ) < 0) {
   9.183 @@ -734,19 +739,16 @@ static int __init tpmif_init(void)
   9.184  	return 0;
   9.185  
   9.186  gnttab_alloc_failed:
   9.187 -	cleanup_vtpm();
   9.188 -init_vtpm_failed:
   9.189  	tpm_private_put();
   9.190  failexit:
   9.191  
   9.192 -	return rc;
   9.193 +	return (int)rc;
   9.194  }
   9.195  
   9.196  
   9.197 -static void __exit tpmif_exit(void)
   9.198 +void __exit tpmif_exit(void)
   9.199  {
   9.200  	exit_tpm_xenbus();
   9.201 -	cleanup_vtpm();
   9.202  	tpm_private_put();
   9.203  	gnttab_free_grant_references(gref_head);
   9.204  }