ia64/xen-unstable

changeset 6923:03b58a6f498e

Remove native tpm drivers from the linux sparse tree and replace
with minimal patch in the automatically-applied patches/ directory.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Sep 17 08:25:30 2005 +0000 (2005-09-17)
parents 8ff691d008f4
children 8bc44f718714
files patches/linux-2.6.12/tpm_partial_read.patch
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	Fri Sep 16 23:55:50 2005 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,627 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (C) 2004 IBM Corporation
     1.6 - *
     1.7 - * Authors:
     1.8 - * Leendert van Doorn <leendert@watson.ibm.com>
     1.9 - * Dave Safford <safford@watson.ibm.com>
    1.10 - * Reiner Sailer <sailer@watson.ibm.com>
    1.11 - * Kylene Hall <kjhall@us.ibm.com>
    1.12 - *
    1.13 - * Maintained by: <tpmdd_devel@lists.sourceforge.net>
    1.14 - *
    1.15 - * Device driver for TCG/TCPA TPM (trusted platform module).
    1.16 - * Specifications at www.trustedcomputinggroup.org
    1.17 - *
    1.18 - * This program is free software; you can redistribute it and/or
    1.19 - * modify it under the terms of the GNU General Public License as
    1.20 - * published by the Free Software Foundation, version 2 of the
    1.21 - * License.
    1.22 - *
    1.23 - * Note, the TPM chip is not interrupt driven (only polling)
    1.24 - * and can have very long timeouts (minutes!). Hence the unusual
    1.25 - * calls to schedule_timeout.
    1.26 - *
    1.27 - */
    1.28 -
    1.29 -#include <linux/sched.h>
    1.30 -#include <linux/poll.h>
    1.31 -#include <linux/spinlock.h>
    1.32 -#include "tpm.h"
    1.33 -
    1.34 -#define	TPM_MINOR			224	/* officially assigned */
    1.35 -
    1.36 -#define	TPM_BUFSIZE			2048
    1.37 -
    1.38 -static LIST_HEAD(tpm_chip_list);
    1.39 -static DEFINE_SPINLOCK(driver_lock);
    1.40 -static int dev_mask[32];
    1.41 -
    1.42 -static void user_reader_timeout(unsigned long ptr)
    1.43 -{
    1.44 -	struct tpm_chip *chip = (struct tpm_chip *) ptr;
    1.45 -
    1.46 -	down(&chip->buffer_mutex);
    1.47 -	atomic_set(&chip->data_pending, 0);
    1.48 -	memset(chip->data_buffer, 0, TPM_BUFSIZE);
    1.49 -	up(&chip->buffer_mutex);
    1.50 -}
    1.51 -
    1.52 -void tpm_time_expired(unsigned long ptr)
    1.53 -{
    1.54 -	int *exp = (int *) ptr;
    1.55 -	*exp = 1;
    1.56 -}
    1.57 -
    1.58 -EXPORT_SYMBOL_GPL(tpm_time_expired);
    1.59 -
    1.60 -/*
    1.61 - * Internal kernel interface to transmit TPM commands
    1.62 - */
    1.63 -static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
    1.64 -			    size_t bufsiz)
    1.65 -{
    1.66 -	ssize_t len;
    1.67 -	u32 count;
    1.68 -	__be32 *native_size;
    1.69 -
    1.70 -	native_size = (__force __be32 *) (buf + 2);
    1.71 -	count = be32_to_cpu(*native_size);
    1.72 -
    1.73 -	if (count == 0)
    1.74 -		return -ENODATA;
    1.75 -	if (count > bufsiz) {
    1.76 -		dev_err(&chip->pci_dev->dev,
    1.77 -			"invalid count value %x %zx \n", count, bufsiz);
    1.78 -		return -E2BIG;
    1.79 -	}
    1.80 -
    1.81 -	down(&chip->tpm_mutex);
    1.82 -
    1.83 -	if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
    1.84 -		dev_err(&chip->pci_dev->dev,
    1.85 -			"tpm_transmit: tpm_send: error %zd\n", len);
    1.86 -		return len;
    1.87 -	}
    1.88 -
    1.89 -	down(&chip->timer_manipulation_mutex);
    1.90 -	chip->time_expired = 0;
    1.91 -	init_timer(&chip->device_timer);
    1.92 -	chip->device_timer.function = tpm_time_expired;
    1.93 -	chip->device_timer.expires = jiffies + 2 * 60 * HZ;
    1.94 -	chip->device_timer.data = (unsigned long) &chip->time_expired;
    1.95 -	add_timer(&chip->device_timer);
    1.96 -	up(&chip->timer_manipulation_mutex);
    1.97 -
    1.98 -	do {
    1.99 -		u8 status = inb(chip->vendor->base + 1);
   1.100 -		if ((status & chip->vendor->req_complete_mask) ==
   1.101 -		    chip->vendor->req_complete_val) {
   1.102 -			down(&chip->timer_manipulation_mutex);
   1.103 -			del_singleshot_timer_sync(&chip->device_timer);
   1.104 -			up(&chip->timer_manipulation_mutex);
   1.105 -			goto out_recv;
   1.106 -		}
   1.107 -		set_current_state(TASK_UNINTERRUPTIBLE);
   1.108 -		schedule_timeout(TPM_TIMEOUT);
   1.109 -		rmb();
   1.110 -	} while (!chip->time_expired);
   1.111 -
   1.112 -
   1.113 -	chip->vendor->cancel(chip);
   1.114 -	dev_err(&chip->pci_dev->dev, "Time expired\n");
   1.115 -	up(&chip->tpm_mutex);
   1.116 -	return -EIO;
   1.117 -
   1.118 -out_recv:
   1.119 -	len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
   1.120 -	if (len < 0)
   1.121 -		dev_err(&chip->pci_dev->dev,
   1.122 -			"tpm_transmit: tpm_recv: error %zd\n", len);
   1.123 -	up(&chip->tpm_mutex);
   1.124 -	return len;
   1.125 -}
   1.126 -
   1.127 -#define TPM_DIGEST_SIZE 20
   1.128 -#define CAP_PCR_RESULT_SIZE 18
   1.129 -static u8 cap_pcr[] = {
   1.130 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   1.131 -	0, 0, 0, 22,		/* length */
   1.132 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
   1.133 -	0, 0, 0, 5,
   1.134 -	0, 0, 0, 4,
   1.135 -	0, 0, 1, 1
   1.136 -};
   1.137 -
   1.138 -#define READ_PCR_RESULT_SIZE 30
   1.139 -static u8 pcrread[] = {
   1.140 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   1.141 -	0, 0, 0, 14,		/* length */
   1.142 -	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
   1.143 -	0, 0, 0, 0		/* PCR index */
   1.144 -};
   1.145 -
   1.146 -static ssize_t show_pcrs(struct device *dev, char *buf)
   1.147 -{
   1.148 -	u8 data[READ_PCR_RESULT_SIZE];
   1.149 -	ssize_t len;
   1.150 -	int i, j, index, num_pcrs;
   1.151 -	char *str = buf;
   1.152 -
   1.153 -	struct tpm_chip *chip =
   1.154 -	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
   1.155 -	if (chip == NULL)
   1.156 -		return -ENODEV;
   1.157 -
   1.158 -	memcpy(data, cap_pcr, sizeof(cap_pcr));
   1.159 -	if ((len = tpm_transmit(chip, data, sizeof(data)))
   1.160 -	    < CAP_PCR_RESULT_SIZE)
   1.161 -		return len;
   1.162 -
   1.163 -	num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14)));
   1.164 -
   1.165 -	for (i = 0; i < num_pcrs; i++) {
   1.166 -		memcpy(data, pcrread, sizeof(pcrread));
   1.167 -		index = cpu_to_be32(i);
   1.168 -		memcpy(data + 10, &index, 4);
   1.169 -		if ((len = tpm_transmit(chip, data, sizeof(data)))
   1.170 -		    < READ_PCR_RESULT_SIZE)
   1.171 -			return len;
   1.172 -		str += sprintf(str, "PCR-%02d: ", i);
   1.173 -		for (j = 0; j < TPM_DIGEST_SIZE; j++)
   1.174 -			str += sprintf(str, "%02X ", *(data + 10 + j));
   1.175 -		str += sprintf(str, "\n");
   1.176 -	}
   1.177 -	return str - buf;
   1.178 -}
   1.179 -
   1.180 -static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
   1.181 -
   1.182 -#define  READ_PUBEK_RESULT_SIZE 314
   1.183 -static u8 readpubek[] = {
   1.184 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   1.185 -	0, 0, 0, 30,		/* length */
   1.186 -	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
   1.187 -};
   1.188 -
   1.189 -static ssize_t show_pubek(struct device *dev, char *buf)
   1.190 -{
   1.191 -	u8 data[READ_PUBEK_RESULT_SIZE];
   1.192 -	ssize_t len;
   1.193 -	__be32 *native_val;
   1.194 -	int i;
   1.195 -	char *str = buf;
   1.196 -
   1.197 -	struct tpm_chip *chip =
   1.198 -	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
   1.199 -	if (chip == NULL)
   1.200 -		return -ENODEV;
   1.201 -
   1.202 -	memcpy(data, readpubek, sizeof(readpubek));
   1.203 -	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
   1.204 -
   1.205 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
   1.206 -	    READ_PUBEK_RESULT_SIZE)
   1.207 -		return len;
   1.208 -
   1.209 -	/*
   1.210 -	   ignore header 10 bytes
   1.211 -	   algorithm 32 bits (1 == RSA )
   1.212 -	   encscheme 16 bits
   1.213 -	   sigscheme 16 bits
   1.214 -	   parameters (RSA 12->bytes: keybit, #primes, expbit)
   1.215 -	   keylenbytes 32 bits
   1.216 -	   256 byte modulus
   1.217 -	   ignore checksum 20 bytes
   1.218 -	 */
   1.219 -
   1.220 -	native_val = (__force __be32 *) (data + 34);
   1.221 -
   1.222 -	str +=
   1.223 -	    sprintf(str,
   1.224 -		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
   1.225 -		    "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
   1.226 -		    " %02X %02X %02X %02X %02X %02X %02X %02X\n"
   1.227 -		    "Modulus length: %d\nModulus: \n",
   1.228 -		    data[10], data[11], data[12], data[13], data[14],
   1.229 -		    data[15], data[16], data[17], data[22], data[23],
   1.230 -		    data[24], data[25], data[26], data[27], data[28],
   1.231 -		    data[29], data[30], data[31], data[32], data[33],
   1.232 -		    be32_to_cpu(*native_val)
   1.233 -	    );
   1.234 -
   1.235 -	for (i = 0; i < 256; i++) {
   1.236 -		str += sprintf(str, "%02X ", data[i + 39]);
   1.237 -		if ((i + 1) % 16 == 0)
   1.238 -			str += sprintf(str, "\n");
   1.239 -	}
   1.240 -	return str - buf;
   1.241 -}
   1.242 -
   1.243 -static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL);
   1.244 -
   1.245 -#define CAP_VER_RESULT_SIZE 18
   1.246 -static u8 cap_version[] = {
   1.247 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   1.248 -	0, 0, 0, 18,		/* length */
   1.249 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
   1.250 -	0, 0, 0, 6,
   1.251 -	0, 0, 0, 0
   1.252 -};
   1.253 -
   1.254 -#define CAP_MANUFACTURER_RESULT_SIZE 18
   1.255 -static u8 cap_manufacturer[] = {
   1.256 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   1.257 -	0, 0, 0, 22,		/* length */
   1.258 -	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
   1.259 -	0, 0, 0, 5,
   1.260 -	0, 0, 0, 4,
   1.261 -	0, 0, 1, 3
   1.262 -};
   1.263 -
   1.264 -static ssize_t show_caps(struct device *dev, char *buf)
   1.265 -{
   1.266 -	u8 data[READ_PUBEK_RESULT_SIZE];
   1.267 -	ssize_t len;
   1.268 -	char *str = buf;
   1.269 -
   1.270 -	struct tpm_chip *chip =
   1.271 -	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
   1.272 -	if (chip == NULL)
   1.273 -		return -ENODEV;
   1.274 -
   1.275 -	memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
   1.276 -
   1.277 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
   1.278 -	    CAP_MANUFACTURER_RESULT_SIZE)
   1.279 -		return len;
   1.280 -
   1.281 -	str += sprintf(str, "Manufacturer: 0x%x\n",
   1.282 -		       be32_to_cpu(*(data + 14)));
   1.283 -
   1.284 -	memcpy(data, cap_version, sizeof(cap_version));
   1.285 -
   1.286 -	if ((len = tpm_transmit(chip, data, sizeof(data))) <
   1.287 -	    CAP_VER_RESULT_SIZE)
   1.288 -		return len;
   1.289 -
   1.290 -	str +=
   1.291 -	    sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
   1.292 -		    (int) data[14], (int) data[15], (int) data[16],
   1.293 -		    (int) data[17]);
   1.294 -
   1.295 -	return str - buf;
   1.296 -}
   1.297 -
   1.298 -static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
   1.299 -
   1.300 -/*
   1.301 - * Device file system interface to the TPM
   1.302 - */
   1.303 -int tpm_open(struct inode *inode, struct file *file)
   1.304 -{
   1.305 -	int rc = 0, minor = iminor(inode);
   1.306 -	struct tpm_chip *chip = NULL, *pos;
   1.307 -
   1.308 -	spin_lock(&driver_lock);
   1.309 -
   1.310 -	list_for_each_entry(pos, &tpm_chip_list, list) {
   1.311 -		if (pos->vendor->miscdev.minor == minor) {
   1.312 -			chip = pos;
   1.313 -			break;
   1.314 -		}
   1.315 -	}
   1.316 -
   1.317 -	if (chip == NULL) {
   1.318 -		rc = -ENODEV;
   1.319 -		goto err_out;
   1.320 -	}
   1.321 -
   1.322 -	if (chip->num_opens) {
   1.323 -		dev_dbg(&chip->pci_dev->dev,
   1.324 -			"Another process owns this TPM\n");
   1.325 -		rc = -EBUSY;
   1.326 -		goto err_out;
   1.327 -	}
   1.328 -
   1.329 -	chip->num_opens++;
   1.330 -	pci_dev_get(chip->pci_dev);
   1.331 -
   1.332 -	spin_unlock(&driver_lock);
   1.333 -
   1.334 -	chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
   1.335 -	if (chip->data_buffer == NULL) {
   1.336 -		chip->num_opens--;
   1.337 -		pci_dev_put(chip->pci_dev);
   1.338 -		return -ENOMEM;
   1.339 -	}
   1.340 -
   1.341 -	atomic_set(&chip->data_pending, 0);
   1.342 -
   1.343 -	file->private_data = chip;
   1.344 -	return 0;
   1.345 -
   1.346 -err_out:
   1.347 -	spin_unlock(&driver_lock);
   1.348 -	return rc;
   1.349 -}
   1.350 -
   1.351 -EXPORT_SYMBOL_GPL(tpm_open);
   1.352 -
   1.353 -int tpm_release(struct inode *inode, struct file *file)
   1.354 -{
   1.355 -	struct tpm_chip *chip = file->private_data;
   1.356 -
   1.357 -	file->private_data = NULL;
   1.358 -
   1.359 -	spin_lock(&driver_lock);
   1.360 -	chip->num_opens--;
   1.361 -	spin_unlock(&driver_lock);
   1.362 -
   1.363 -	down(&chip->timer_manipulation_mutex);
   1.364 -	if (timer_pending(&chip->user_read_timer))
   1.365 -		del_singleshot_timer_sync(&chip->user_read_timer);
   1.366 -	else if (timer_pending(&chip->device_timer))
   1.367 -		del_singleshot_timer_sync(&chip->device_timer);
   1.368 -	up(&chip->timer_manipulation_mutex);
   1.369 -
   1.370 -	kfree(chip->data_buffer);
   1.371 -	atomic_set(&chip->data_pending, 0);
   1.372 -
   1.373 -	pci_dev_put(chip->pci_dev);
   1.374 -	return 0;
   1.375 -}
   1.376 -
   1.377 -EXPORT_SYMBOL_GPL(tpm_release);
   1.378 -
   1.379 -ssize_t tpm_write(struct file * file, const char __user * buf,
   1.380 -		  size_t size, loff_t * off)
   1.381 -{
   1.382 -	struct tpm_chip *chip = file->private_data;
   1.383 -	int in_size = size, out_size;
   1.384 -
   1.385 -	/* cannot perform a write until the read has cleared
   1.386 -	   either via tpm_read or a user_read_timer timeout */
   1.387 -	while (atomic_read(&chip->data_pending) != 0) {
   1.388 -		set_current_state(TASK_UNINTERRUPTIBLE);
   1.389 -		schedule_timeout(TPM_TIMEOUT);
   1.390 -	}
   1.391 -
   1.392 -	down(&chip->buffer_mutex);
   1.393 -
   1.394 -	if (in_size > TPM_BUFSIZE)
   1.395 -		in_size = TPM_BUFSIZE;
   1.396 -
   1.397 -	if (copy_from_user
   1.398 -	    (chip->data_buffer, (void __user *) buf, in_size)) {
   1.399 -		up(&chip->buffer_mutex);
   1.400 -		return -EFAULT;
   1.401 -	}
   1.402 -
   1.403 -	/* atomic tpm command send and result receive */
   1.404 -	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
   1.405 -
   1.406 -	atomic_set(&chip->data_pending, out_size);
   1.407 -	atomic_set(&chip->data_position, 0);
   1.408 -	up(&chip->buffer_mutex);
   1.409 -
   1.410 -	/* Set a timeout by which the reader must come claim the result */
   1.411 -	down(&chip->timer_manipulation_mutex);
   1.412 -	init_timer(&chip->user_read_timer);
   1.413 -	chip->user_read_timer.function = user_reader_timeout;
   1.414 -	chip->user_read_timer.data = (unsigned long) chip;
   1.415 -	chip->user_read_timer.expires = jiffies + (60 * HZ);
   1.416 -	add_timer(&chip->user_read_timer);
   1.417 -	up(&chip->timer_manipulation_mutex);
   1.418 -
   1.419 -	return in_size;
   1.420 -}
   1.421 -
   1.422 -EXPORT_SYMBOL_GPL(tpm_write);
   1.423 -
   1.424 -ssize_t tpm_read(struct file * file, char __user * buf,
   1.425 -		 size_t size, loff_t * off)
   1.426 -{
   1.427 -	struct tpm_chip *chip = file->private_data;
   1.428 -	int ret_size = -ENODATA;
   1.429 -	int pos, pending = 0;
   1.430 -
   1.431 -	down(&chip->buffer_mutex);
   1.432 -	ret_size = atomic_read(&chip->data_pending);
   1.433 -	if ( ret_size > 0 ) {	/* Result available */
   1.434 -		if (size < ret_size)
   1.435 -			ret_size = size;
   1.436 -
   1.437 -		pos = atomic_read(&chip->data_position);
   1.438 -
   1.439 -		if (copy_to_user((void __user *) buf,
   1.440 -				 &chip->data_buffer[pos], ret_size)) {
   1.441 -			ret_size = -EFAULT;
   1.442 -		} else {
   1.443 -			pending = atomic_read(&chip->data_pending) - ret_size;
   1.444 -			if ( pending ) {
   1.445 -				atomic_set( &chip->data_pending, pending );
   1.446 -				atomic_set( &chip->data_position, pos+ret_size );
   1.447 -			}
   1.448 -		}
   1.449 -	}
   1.450 -	up(&chip->buffer_mutex);
   1.451 -
   1.452 -	if ( ret_size <= 0 || pending == 0 ) {
   1.453 -		atomic_set( &chip->data_pending, 0 );
   1.454 -		down(&chip->timer_manipulation_mutex);
   1.455 -		del_singleshot_timer_sync(&chip->user_read_timer);
   1.456 -		up(&chip->timer_manipulation_mutex);
   1.457 -	}
   1.458 -
   1.459 -	return ret_size;
   1.460 -}
   1.461 -
   1.462 -EXPORT_SYMBOL_GPL(tpm_read);
   1.463 -
   1.464 -void __devexit tpm_remove(struct pci_dev *pci_dev)
   1.465 -{
   1.466 -	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
   1.467 -
   1.468 -	if (chip == NULL) {
   1.469 -		dev_err(&pci_dev->dev, "No device data found\n");
   1.470 -		return;
   1.471 -	}
   1.472 -
   1.473 -	spin_lock(&driver_lock);
   1.474 -
   1.475 -	list_del(&chip->list);
   1.476 -
   1.477 -	spin_unlock(&driver_lock);
   1.478 -
   1.479 -	pci_set_drvdata(pci_dev, NULL);
   1.480 -	misc_deregister(&chip->vendor->miscdev);
   1.481 -
   1.482 -	device_remove_file(&pci_dev->dev, &dev_attr_pubek);
   1.483 -	device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
   1.484 -	device_remove_file(&pci_dev->dev, &dev_attr_caps);
   1.485 -
   1.486 -	pci_disable_device(pci_dev);
   1.487 -
   1.488 -	dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
   1.489 -
   1.490 -	kfree(chip);
   1.491 -
   1.492 -	pci_dev_put(pci_dev);
   1.493 -}
   1.494 -
   1.495 -EXPORT_SYMBOL_GPL(tpm_remove);
   1.496 -
   1.497 -static u8 savestate[] = {
   1.498 -	0, 193,			/* TPM_TAG_RQU_COMMAND */
   1.499 -	0, 0, 0, 10,		/* blob length (in bytes) */
   1.500 -	0, 0, 0, 152		/* TPM_ORD_SaveState */
   1.501 -};
   1.502 -
   1.503 -/*
   1.504 - * We are about to suspend. Save the TPM state
   1.505 - * so that it can be restored.
   1.506 - */
   1.507 -int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
   1.508 -{
   1.509 -	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
   1.510 -	if (chip == NULL)
   1.511 -		return -ENODEV;
   1.512 -
   1.513 -	tpm_transmit(chip, savestate, sizeof(savestate));
   1.514 -	return 0;
   1.515 -}
   1.516 -
   1.517 -EXPORT_SYMBOL_GPL(tpm_pm_suspend);
   1.518 -
   1.519 -/*
   1.520 - * Resume from a power safe. The BIOS already restored
   1.521 - * the TPM state.
   1.522 - */
   1.523 -int tpm_pm_resume(struct pci_dev *pci_dev)
   1.524 -{
   1.525 -	struct tpm_chip *chip = pci_get_drvdata(pci_dev);
   1.526 -
   1.527 -	if (chip == NULL)
   1.528 -		return -ENODEV;
   1.529 -
   1.530 -	return 0;
   1.531 -}
   1.532 -
   1.533 -EXPORT_SYMBOL_GPL(tpm_pm_resume);
   1.534 -
   1.535 -/*
   1.536 - * Called from tpm_<specific>.c probe function only for devices
   1.537 - * the driver has determined it should claim.  Prior to calling
   1.538 - * this function the specific probe function has called pci_enable_device
   1.539 - * upon errant exit from this function specific probe function should call
   1.540 - * pci_disable_device
   1.541 - */
   1.542 -int tpm_register_hardware(struct pci_dev *pci_dev,
   1.543 -			  struct tpm_vendor_specific *entry)
   1.544 -{
   1.545 -	char devname[7];
   1.546 -	struct tpm_chip *chip;
   1.547 -	int i, j;
   1.548 -
   1.549 -	/* Driver specific per-device data */
   1.550 -	chip = kmalloc(sizeof(*chip), GFP_KERNEL);
   1.551 -	if (chip == NULL)
   1.552 -		return -ENOMEM;
   1.553 -
   1.554 -	memset(chip, 0, sizeof(struct tpm_chip));
   1.555 -
   1.556 -	init_MUTEX(&chip->buffer_mutex);
   1.557 -	init_MUTEX(&chip->tpm_mutex);
   1.558 -	init_MUTEX(&chip->timer_manipulation_mutex);
   1.559 -	INIT_LIST_HEAD(&chip->list);
   1.560 -
   1.561 -	chip->vendor = entry;
   1.562 -
   1.563 -	chip->dev_num = -1;
   1.564 -
   1.565 -	for (i = 0; i < 32; i++)
   1.566 -		for (j = 0; j < 8; j++)
   1.567 -			if ((dev_mask[i] & (1 << j)) == 0) {
   1.568 -				chip->dev_num = i * 32 + j;
   1.569 -				dev_mask[i] |= 1 << j;
   1.570 -				goto dev_num_search_complete;
   1.571 -			}
   1.572 -
   1.573 -dev_num_search_complete:
   1.574 -	if (chip->dev_num < 0) {
   1.575 -		dev_err(&pci_dev->dev,
   1.576 -			"No available tpm device numbers\n");
   1.577 -		kfree(chip);
   1.578 -		return -ENODEV;
   1.579 -	} else if (chip->dev_num == 0)
   1.580 -		chip->vendor->miscdev.minor = TPM_MINOR;
   1.581 -	else
   1.582 -		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
   1.583 -
   1.584 -	snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
   1.585 -	chip->vendor->miscdev.name = devname;
   1.586 -
   1.587 -	chip->vendor->miscdev.dev = &(pci_dev->dev);
   1.588 -	chip->pci_dev = pci_dev_get(pci_dev);
   1.589 -
   1.590 -	if (misc_register(&chip->vendor->miscdev)) {
   1.591 -		dev_err(&chip->pci_dev->dev,
   1.592 -			"unable to misc_register %s, minor %d\n",
   1.593 -			chip->vendor->miscdev.name,
   1.594 -			chip->vendor->miscdev.minor);
   1.595 -		pci_dev_put(pci_dev);
   1.596 -		kfree(chip);
   1.597 -		dev_mask[i] &= !(1 << j);
   1.598 -		return -ENODEV;
   1.599 -	}
   1.600 -
   1.601 -	pci_set_drvdata(pci_dev, chip);
   1.602 -
   1.603 -	list_add(&chip->list, &tpm_chip_list);
   1.604 -
   1.605 -	device_create_file(&pci_dev->dev, &dev_attr_pubek);
   1.606 -	device_create_file(&pci_dev->dev, &dev_attr_pcrs);
   1.607 -	device_create_file(&pci_dev->dev, &dev_attr_caps);
   1.608 -
   1.609 -	return 0;
   1.610 -}
   1.611 -
   1.612 -EXPORT_SYMBOL_GPL(tpm_register_hardware);
   1.613 -
   1.614 -static int __init init_tpm(void)
   1.615 -{
   1.616 -	return 0;
   1.617 -}
   1.618 -
   1.619 -static void __exit cleanup_tpm(void)
   1.620 -{
   1.621 -
   1.622 -}
   1.623 -
   1.624 -module_init(init_tpm);
   1.625 -module_exit(cleanup_tpm);
   1.626 -
   1.627 -MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
   1.628 -MODULE_DESCRIPTION("TPM Driver");
   1.629 -MODULE_VERSION("2.0");
   1.630 -MODULE_LICENSE("GPL");
     2.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	Fri Sep 16 23:55:50 2005 +0000
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,92 +0,0 @@
     2.4 -/*
     2.5 - * Copyright (C) 2004 IBM Corporation
     2.6 - *
     2.7 - * Authors:
     2.8 - * Leendert van Doorn <leendert@watson.ibm.com>
     2.9 - * Dave Safford <safford@watson.ibm.com>
    2.10 - * Reiner Sailer <sailer@watson.ibm.com>
    2.11 - * Kylene Hall <kjhall@us.ibm.com>
    2.12 - *
    2.13 - * Maintained by: <tpmdd_devel@lists.sourceforge.net>
    2.14 - *
    2.15 - * Device driver for TCG/TCPA TPM (trusted platform module).
    2.16 - * Specifications at www.trustedcomputinggroup.org
    2.17 - *
    2.18 - * This program is free software; you can redistribute it and/or
    2.19 - * modify it under the terms of the GNU General Public License as
    2.20 - * published by the Free Software Foundation, version 2 of the
    2.21 - * License.
    2.22 - *
    2.23 - */
    2.24 -#include <linux/module.h>
    2.25 -#include <linux/version.h>
    2.26 -#include <linux/pci.h>
    2.27 -#include <linux/delay.h>
    2.28 -#include <linux/fs.h>
    2.29 -#include <linux/miscdevice.h>
    2.30 -
    2.31 -#define TPM_TIMEOUT msecs_to_jiffies(5)
    2.32 -
    2.33 -/* TPM addresses */
    2.34 -#define	TPM_ADDR			0x4E
    2.35 -#define	TPM_DATA			0x4F
    2.36 -
    2.37 -struct tpm_chip;
    2.38 -
    2.39 -struct tpm_vendor_specific {
    2.40 -	u8 req_complete_mask;
    2.41 -	u8 req_complete_val;
    2.42 -	u16 base;		/* TPM base address */
    2.43 -
    2.44 -	int (*recv) (struct tpm_chip *, u8 *, size_t);
    2.45 -	int (*send) (struct tpm_chip *, u8 *, size_t);
    2.46 -	void (*cancel) (struct tpm_chip *);
    2.47 -	struct miscdevice miscdev;
    2.48 -};
    2.49 -
    2.50 -struct tpm_chip {
    2.51 -	struct pci_dev *pci_dev;	/* PCI device stuff */
    2.52 -
    2.53 -	int dev_num;		/* /dev/tpm# */
    2.54 -	int num_opens;		/* only one allowed */
    2.55 -	int time_expired;
    2.56 -
    2.57 -	/* Data passed to and from the tpm via the read/write calls */
    2.58 -	u8 *data_buffer;
    2.59 -	atomic_t data_pending;
    2.60 -	atomic_t data_position;
    2.61 -	struct semaphore buffer_mutex;
    2.62 -
    2.63 -	struct timer_list user_read_timer;	/* user needs to claim result */
    2.64 -	struct semaphore tpm_mutex;	/* tpm is processing */
    2.65 -	struct timer_list device_timer;	/* tpm is processing */
    2.66 -	struct semaphore timer_manipulation_mutex;
    2.67 -
    2.68 -	struct tpm_vendor_specific *vendor;
    2.69 -
    2.70 -	struct list_head list;
    2.71 -};
    2.72 -
    2.73 -static inline int tpm_read_index(int index)
    2.74 -{
    2.75 -	outb(index, TPM_ADDR);
    2.76 -	return inb(TPM_DATA) & 0xFF;
    2.77 -}
    2.78 -
    2.79 -static inline void tpm_write_index(int index, int value)
    2.80 -{
    2.81 -	outb(index, TPM_ADDR);
    2.82 -	outb(value & 0xFF, TPM_DATA);
    2.83 -}
    2.84 -
    2.85 -extern void tpm_time_expired(unsigned long);
    2.86 -extern int tpm_register_hardware(struct pci_dev *,
    2.87 -				 struct tpm_vendor_specific *);
    2.88 -extern int tpm_open(struct inode *, struct file *);
    2.89 -extern int tpm_release(struct inode *, struct file *);
    2.90 -extern ssize_t tpm_write(struct file *, const char __user *, size_t,
    2.91 -			 loff_t *);
    2.92 -extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
    2.93 -extern void __devexit tpm_remove(struct pci_dev *);
    2.94 -extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
    2.95 -extern int tpm_pm_resume(struct pci_dev *);
     3.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_atmel.c	Fri Sep 16 23:55:50 2005 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,220 +0,0 @@
     3.4 -/*
     3.5 - * Copyright (C) 2004 IBM Corporation
     3.6 - *
     3.7 - * Authors:
     3.8 - * Leendert van Doorn <leendert@watson.ibm.com>
     3.9 - * Dave Safford <safford@watson.ibm.com>
    3.10 - * Reiner Sailer <sailer@watson.ibm.com>
    3.11 - * Kylene Hall <kjhall@us.ibm.com>
    3.12 - *
    3.13 - * Maintained by: <tpmdd_devel@lists.sourceforge.net>
    3.14 - *
    3.15 - * Device driver for TCG/TCPA TPM (trusted platform module).
    3.16 - * Specifications at www.trustedcomputinggroup.org
    3.17 - *
    3.18 - * This program is free software; you can redistribute it and/or
    3.19 - * modify it under the terms of the GNU General Public License as
    3.20 - * published by the Free Software Foundation, version 2 of the
    3.21 - * License.
    3.22 - *
    3.23 - */
    3.24 -
    3.25 -#include "tpm.h"
    3.26 -
    3.27 -/* Atmel definitions */
    3.28 -enum tpm_atmel_addr {
    3.29 -	TPM_ATMEL_BASE_ADDR_LO = 0x08,
    3.30 -	TPM_ATMEL_BASE_ADDR_HI = 0x09
    3.31 -};
    3.32 -
    3.33 -/* write status bits */
    3.34 -#define	ATML_STATUS_ABORT		0x01
    3.35 -#define	ATML_STATUS_LASTBYTE		0x04
    3.36 -
    3.37 -/* read status bits */
    3.38 -#define	ATML_STATUS_BUSY		0x01
    3.39 -#define	ATML_STATUS_DATA_AVAIL		0x02
    3.40 -#define	ATML_STATUS_REWRITE		0x04
    3.41 -
    3.42 -
    3.43 -static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
    3.44 -{
    3.45 -	u8 status, *hdr = buf;
    3.46 -	u32 size;
    3.47 -	int i;
    3.48 -	__be32 *native_size;
    3.49 -
    3.50 -	/* start reading header */
    3.51 -	if (count < 6)
    3.52 -		return -EIO;
    3.53 -
    3.54 -	for (i = 0; i < 6; i++) {
    3.55 -		status = inb(chip->vendor->base + 1);
    3.56 -		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
    3.57 -			dev_err(&chip->pci_dev->dev,
    3.58 -				"error reading header\n");
    3.59 -			return -EIO;
    3.60 -		}
    3.61 -		*buf++ = inb(chip->vendor->base);
    3.62 -	}
    3.63 -
    3.64 -	/* size of the data received */
    3.65 -	native_size = (__force __be32 *) (hdr + 2);
    3.66 -	size = be32_to_cpu(*native_size);
    3.67 -
    3.68 -	if (count < size) {
    3.69 -		dev_err(&chip->pci_dev->dev,
    3.70 -			"Recv size(%d) less than available space\n", size);
    3.71 -		for (; i < size; i++) {	/* clear the waiting data anyway */
    3.72 -			status = inb(chip->vendor->base + 1);
    3.73 -			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
    3.74 -				dev_err(&chip->pci_dev->dev,
    3.75 -					"error reading data\n");
    3.76 -				return -EIO;
    3.77 -			}
    3.78 -		}
    3.79 -		return -EIO;
    3.80 -	}
    3.81 -
    3.82 -	/* read all the data available */
    3.83 -	for (; i < size; i++) {
    3.84 -		status = inb(chip->vendor->base + 1);
    3.85 -		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
    3.86 -			dev_err(&chip->pci_dev->dev,
    3.87 -				"error reading data\n");
    3.88 -			return -EIO;
    3.89 -		}
    3.90 -		*buf++ = inb(chip->vendor->base);
    3.91 -	}
    3.92 -
    3.93 -	/* make sure data available is gone */
    3.94 -	status = inb(chip->vendor->base + 1);
    3.95 -	if (status & ATML_STATUS_DATA_AVAIL) {
    3.96 -		dev_err(&chip->pci_dev->dev, "data available is stuck\n");
    3.97 -		return -EIO;
    3.98 -	}
    3.99 -
   3.100 -	return size;
   3.101 -}
   3.102 -
   3.103 -static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
   3.104 -{
   3.105 -	int i;
   3.106 -
   3.107 -	dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
   3.108 -	for (i = 0; i < count; i++) {
   3.109 -		dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
   3.110 -		outb(buf[i], chip->vendor->base);
   3.111 -	}
   3.112 -
   3.113 -	return count;
   3.114 -}
   3.115 -
   3.116 -static void tpm_atml_cancel(struct tpm_chip *chip)
   3.117 -{
   3.118 -	outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
   3.119 -}
   3.120 -
   3.121 -static struct file_operations atmel_ops = {
   3.122 -	.owner = THIS_MODULE,
   3.123 -	.llseek = no_llseek,
   3.124 -	.open = tpm_open,
   3.125 -	.read = tpm_read,
   3.126 -	.write = tpm_write,
   3.127 -	.release = tpm_release,
   3.128 -};
   3.129 -
   3.130 -static struct tpm_vendor_specific tpm_atmel = {
   3.131 -	.recv = tpm_atml_recv,
   3.132 -	.send = tpm_atml_send,
   3.133 -	.cancel = tpm_atml_cancel,
   3.134 -	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
   3.135 -	.req_complete_val = ATML_STATUS_DATA_AVAIL,
   3.136 -	.miscdev = { .fops = &atmel_ops, },
   3.137 -};
   3.138 -
   3.139 -static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
   3.140 -				   const struct pci_device_id *pci_id)
   3.141 -{
   3.142 -	u8 version[4];
   3.143 -	int rc = 0;
   3.144 -	int lo, hi;
   3.145 -
   3.146 -	if (pci_enable_device(pci_dev))
   3.147 -		return -EIO;
   3.148 -
   3.149 -	lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO );
   3.150 -	hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI );
   3.151 -
   3.152 -	tpm_atmel.base = (hi<<8)|lo;
   3.153 -	dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
   3.154 -
   3.155 -	/* verify that it is an Atmel part */
   3.156 -	if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
   3.157 -	    || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
   3.158 -		rc = -ENODEV;
   3.159 -		goto out_err;
   3.160 -	}
   3.161 -
   3.162 -	/* query chip for its version number */
   3.163 -	if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
   3.164 -		version[1] = tpm_read_index(0x01);
   3.165 -		version[2] = tpm_read_index(0x02);
   3.166 -		version[3] = tpm_read_index(0x03);
   3.167 -	} else {
   3.168 -		dev_info(&pci_dev->dev, "version query failed\n");
   3.169 -		rc = -ENODEV;
   3.170 -		goto out_err;
   3.171 -	}
   3.172 -
   3.173 -	if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
   3.174 -		goto out_err;
   3.175 -
   3.176 -	dev_info(&pci_dev->dev,
   3.177 -		 "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
   3.178 -		 version[2], version[3]);
   3.179 -
   3.180 -	return 0;
   3.181 -out_err:
   3.182 -	pci_disable_device(pci_dev);
   3.183 -	return rc;
   3.184 -}
   3.185 -
   3.186 -static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
   3.187 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
   3.188 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
   3.189 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
   3.190 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
   3.191 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
   3.192 -	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
   3.193 -	{0,}
   3.194 -};
   3.195 -
   3.196 -MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
   3.197 -
   3.198 -static struct pci_driver atmel_pci_driver = {
   3.199 -	.name = "tpm_atmel",
   3.200 -	.id_table = tpm_pci_tbl,
   3.201 -	.probe = tpm_atml_init,
   3.202 -	.remove = __devexit_p(tpm_remove),
   3.203 -	.suspend = tpm_pm_suspend,
   3.204 -	.resume = tpm_pm_resume,
   3.205 -};
   3.206 -
   3.207 -static int __init init_atmel(void)
   3.208 -{
   3.209 -	return pci_register_driver(&atmel_pci_driver);
   3.210 -}
   3.211 -
   3.212 -static void __exit cleanup_atmel(void)
   3.213 -{
   3.214 -	pci_unregister_driver(&atmel_pci_driver);
   3.215 -}
   3.216 -
   3.217 -module_init(init_atmel);
   3.218 -module_exit(cleanup_atmel);
   3.219 -
   3.220 -MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
   3.221 -MODULE_DESCRIPTION("TPM Driver");
   3.222 -MODULE_VERSION("2.0");
   3.223 -MODULE_LICENSE("GPL");
     4.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_nsc.c	Fri Sep 16 23:55:50 2005 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,377 +0,0 @@
     4.4 -/*
     4.5 - * Copyright (C) 2004 IBM Corporation
     4.6 - *
     4.7 - * Authors:
     4.8 - * Leendert van Doorn <leendert@watson.ibm.com>
     4.9 - * Dave Safford <safford@watson.ibm.com>
    4.10 - * Reiner Sailer <sailer@watson.ibm.com>
    4.11 - * Kylene Hall <kjhall@us.ibm.com>
    4.12 - *
    4.13 - * Maintained by: <tpmdd_devel@lists.sourceforge.net>
    4.14 - *
    4.15 - * Device driver for TCG/TCPA TPM (trusted platform module).
    4.16 - * Specifications at www.trustedcomputinggroup.org
    4.17 - *
    4.18 - * This program is free software; you can redistribute it and/or
    4.19 - * modify it under the terms of the GNU General Public License as
    4.20 - * published by the Free Software Foundation, version 2 of the
    4.21 - * License.
    4.22 - *
    4.23 - */
    4.24 -
    4.25 -#include "tpm.h"
    4.26 -
    4.27 -/* National definitions */
    4.28 -#define	TPM_NSC_BASE			0x360
    4.29 -#define	TPM_NSC_IRQ			0x07
    4.30 -#define	TPM_NSC_BASE0_HI		0x60
    4.31 -#define	TPM_NSC_BASE0_LO		0x61
    4.32 -#define	TPM_NSC_BASE1_HI		0x62
    4.33 -#define	TPM_NSC_BASE1_LO		0x63
    4.34 -
    4.35 -#define	NSC_LDN_INDEX			0x07
    4.36 -#define	NSC_SID_INDEX			0x20
    4.37 -#define	NSC_LDC_INDEX			0x30
    4.38 -#define	NSC_DIO_INDEX			0x60
    4.39 -#define	NSC_CIO_INDEX			0x62
    4.40 -#define	NSC_IRQ_INDEX			0x70
    4.41 -#define	NSC_ITS_INDEX			0x71
    4.42 -
    4.43 -#define	NSC_STATUS			0x01
    4.44 -#define	NSC_COMMAND			0x01
    4.45 -#define	NSC_DATA			0x00
    4.46 -
    4.47 -/* status bits */
    4.48 -#define	NSC_STATUS_OBF			0x01	/* output buffer full */
    4.49 -#define	NSC_STATUS_IBF			0x02	/* input buffer full */
    4.50 -#define	NSC_STATUS_F0			0x04	/* F0 */
    4.51 -#define	NSC_STATUS_A2			0x08	/* A2 */
    4.52 -#define	NSC_STATUS_RDY			0x10	/* ready to receive command */
    4.53 -#define	NSC_STATUS_IBR			0x20	/* ready to receive data */
    4.54 -
    4.55 -/* command bits */
    4.56 -#define	NSC_COMMAND_NORMAL		0x01	/* normal mode */
    4.57 -#define	NSC_COMMAND_EOC			0x03
    4.58 -#define	NSC_COMMAND_CANCEL		0x22
    4.59 -
    4.60 -/*
    4.61 - * Wait for a certain status to appear
    4.62 - */
    4.63 -static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
    4.64 -{
    4.65 -	int expired = 0;
    4.66 -	struct timer_list status_timer =
    4.67 -	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
    4.68 -			      (unsigned long) &expired);
    4.69 -
    4.70 -	/* status immediately available check */
    4.71 -	*data = inb(chip->vendor->base + NSC_STATUS);
    4.72 -	if ((*data & mask) == val)
    4.73 -		return 0;
    4.74 -
    4.75 -	/* wait for status */
    4.76 -	add_timer(&status_timer);
    4.77 -	do {
    4.78 -		set_current_state(TASK_UNINTERRUPTIBLE);
    4.79 -		schedule_timeout(TPM_TIMEOUT);
    4.80 -		*data = inb(chip->vendor->base + 1);
    4.81 -		if ((*data & mask) == val) {
    4.82 -			del_singleshot_timer_sync(&status_timer);
    4.83 -			return 0;
    4.84 -		}
    4.85 -	}
    4.86 -	while (!expired);
    4.87 -
    4.88 -	return -EBUSY;
    4.89 -}
    4.90 -
    4.91 -static int nsc_wait_for_ready(struct tpm_chip *chip)
    4.92 -{
    4.93 -	int status;
    4.94 -	int expired = 0;
    4.95 -	struct timer_list status_timer =
    4.96 -	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
    4.97 -			      (unsigned long) &expired);
    4.98 -
    4.99 -	/* status immediately available check */
   4.100 -	status = inb(chip->vendor->base + NSC_STATUS);
   4.101 -	if (status & NSC_STATUS_OBF)
   4.102 -		status = inb(chip->vendor->base + NSC_DATA);
   4.103 -	if (status & NSC_STATUS_RDY)
   4.104 -		return 0;
   4.105 -
   4.106 -	/* wait for status */
   4.107 -	add_timer(&status_timer);
   4.108 -	do {
   4.109 -		set_current_state(TASK_UNINTERRUPTIBLE);
   4.110 -		schedule_timeout(TPM_TIMEOUT);
   4.111 -		status = inb(chip->vendor->base + NSC_STATUS);
   4.112 -		if (status & NSC_STATUS_OBF)
   4.113 -			status = inb(chip->vendor->base + NSC_DATA);
   4.114 -		if (status & NSC_STATUS_RDY) {
   4.115 -			del_singleshot_timer_sync(&status_timer);
   4.116 -			return 0;
   4.117 -		}
   4.118 -	}
   4.119 -	while (!expired);
   4.120 -
   4.121 -	dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
   4.122 -	return -EBUSY;
   4.123 -}
   4.124 -
   4.125 -
   4.126 -static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
   4.127 -{
   4.128 -	u8 *buffer = buf;
   4.129 -	u8 data, *p;
   4.130 -	u32 size;
   4.131 -	__be32 *native_size;
   4.132 -
   4.133 -	if (count < 6)
   4.134 -		return -EIO;
   4.135 -
   4.136 -	if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
   4.137 -		dev_err(&chip->pci_dev->dev, "F0 timeout\n");
   4.138 -		return -EIO;
   4.139 -	}
   4.140 -	if ((data =
   4.141 -	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
   4.142 -		dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
   4.143 -			data);
   4.144 -		return -EIO;
   4.145 -	}
   4.146 -
   4.147 -	/* read the whole packet */
   4.148 -	for (p = buffer; p < &buffer[count]; p++) {
   4.149 -		if (wait_for_stat
   4.150 -		    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
   4.151 -			dev_err(&chip->pci_dev->dev,
   4.152 -				"OBF timeout (while reading data)\n");
   4.153 -			return -EIO;
   4.154 -		}
   4.155 -		if (data & NSC_STATUS_F0)
   4.156 -			break;
   4.157 -		*p = inb(chip->vendor->base + NSC_DATA);
   4.158 -	}
   4.159 -
   4.160 -	if ((data & NSC_STATUS_F0) == 0) {
   4.161 -		dev_err(&chip->pci_dev->dev, "F0 not set\n");
   4.162 -		return -EIO;
   4.163 -	}
   4.164 -	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
   4.165 -		dev_err(&chip->pci_dev->dev,
   4.166 -			"expected end of command(0x%x)\n", data);
   4.167 -		return -EIO;
   4.168 -	}
   4.169 -
   4.170 -	native_size = (__force __be32 *) (buf + 2);
   4.171 -	size = be32_to_cpu(*native_size);
   4.172 -
   4.173 -	if (count < size)
   4.174 -		return -EIO;
   4.175 -
   4.176 -	return size;
   4.177 -}
   4.178 -
   4.179 -static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
   4.180 -{
   4.181 -	u8 data;
   4.182 -	int i;
   4.183 -
   4.184 -	/*
   4.185 -	 * If we hit the chip with back to back commands it locks up
   4.186 -	 * and never set IBF. Hitting it with this "hammer" seems to
   4.187 -	 * fix it. Not sure why this is needed, we followed the flow
   4.188 -	 * chart in the manual to the letter.
   4.189 -	 */
   4.190 -	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
   4.191 -
   4.192 -	if (nsc_wait_for_ready(chip) != 0)
   4.193 -		return -EIO;
   4.194 -
   4.195 -	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
   4.196 -		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
   4.197 -		return -EIO;
   4.198 -	}
   4.199 -
   4.200 -	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
   4.201 -	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
   4.202 -		dev_err(&chip->pci_dev->dev, "IBR timeout\n");
   4.203 -		return -EIO;
   4.204 -	}
   4.205 -
   4.206 -	for (i = 0; i < count; i++) {
   4.207 -		if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
   4.208 -			dev_err(&chip->pci_dev->dev,
   4.209 -				"IBF timeout (while writing data)\n");
   4.210 -			return -EIO;
   4.211 -		}
   4.212 -		outb(buf[i], chip->vendor->base + NSC_DATA);
   4.213 -	}
   4.214 -
   4.215 -	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
   4.216 -		dev_err(&chip->pci_dev->dev, "IBF timeout\n");
   4.217 -		return -EIO;
   4.218 -	}
   4.219 -	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
   4.220 -
   4.221 -	return count;
   4.222 -}
   4.223 -
   4.224 -static void tpm_nsc_cancel(struct tpm_chip *chip)
   4.225 -{
   4.226 -	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
   4.227 -}
   4.228 -
   4.229 -static struct file_operations nsc_ops = {
   4.230 -	.owner = THIS_MODULE,
   4.231 -	.llseek = no_llseek,
   4.232 -	.open = tpm_open,
   4.233 -	.read = tpm_read,
   4.234 -	.write = tpm_write,
   4.235 -	.release = tpm_release,
   4.236 -};
   4.237 -
   4.238 -static struct tpm_vendor_specific tpm_nsc = {
   4.239 -	.recv = tpm_nsc_recv,
   4.240 -	.send = tpm_nsc_send,
   4.241 -	.cancel = tpm_nsc_cancel,
   4.242 -	.req_complete_mask = NSC_STATUS_OBF,
   4.243 -	.req_complete_val = NSC_STATUS_OBF,
   4.244 -	.miscdev = { .fops = &nsc_ops, },
   4.245 -
   4.246 -};
   4.247 -
   4.248 -static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
   4.249 -				  const struct pci_device_id *pci_id)
   4.250 -{
   4.251 -	int rc = 0;
   4.252 -	int lo, hi;
   4.253 -
   4.254 -	hi = tpm_read_index(TPM_NSC_BASE0_HI);
   4.255 -	lo = tpm_read_index(TPM_NSC_BASE0_LO);
   4.256 -
   4.257 -	tpm_nsc.base = (hi<<8) | lo;
   4.258 -
   4.259 -	if (pci_enable_device(pci_dev))
   4.260 -		return -EIO;
   4.261 -
   4.262 -	/* verify that it is a National part (SID) */
   4.263 -	if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
   4.264 -		rc = -ENODEV;
   4.265 -		goto out_err;
   4.266 -	}
   4.267 -
   4.268 -	dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
   4.269 -	dev_dbg(&pci_dev->dev,
   4.270 -		"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
   4.271 -		tpm_read_index(0x07), tpm_read_index(0x20),
   4.272 -		tpm_read_index(0x27));
   4.273 -	dev_dbg(&pci_dev->dev,
   4.274 -		"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
   4.275 -		tpm_read_index(0x21), tpm_read_index(0x25),
   4.276 -		tpm_read_index(0x26), tpm_read_index(0x28));
   4.277 -	dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
   4.278 -		(tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
   4.279 -	dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
   4.280 -		(tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
   4.281 -	dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
   4.282 -		tpm_read_index(0x70));
   4.283 -	dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
   4.284 -		tpm_read_index(0x71));
   4.285 -	dev_dbg(&pci_dev->dev,
   4.286 -		"NSC DMA channel select0 0x%x, select1 0x%x\n",
   4.287 -		tpm_read_index(0x74), tpm_read_index(0x75));
   4.288 -	dev_dbg(&pci_dev->dev,
   4.289 -		"NSC Config "
   4.290 -		"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
   4.291 -		tpm_read_index(0xF0), tpm_read_index(0xF1),
   4.292 -		tpm_read_index(0xF2), tpm_read_index(0xF3),
   4.293 -		tpm_read_index(0xF4), tpm_read_index(0xF5),
   4.294 -		tpm_read_index(0xF6), tpm_read_index(0xF7),
   4.295 -		tpm_read_index(0xF8), tpm_read_index(0xF9));
   4.296 -
   4.297 -	dev_info(&pci_dev->dev,
   4.298 -		 "NSC PC21100 TPM revision %d\n",
   4.299 -		 tpm_read_index(0x27) & 0x1F);
   4.300 -
   4.301 -	if (tpm_read_index(NSC_LDC_INDEX) == 0)
   4.302 -		dev_info(&pci_dev->dev, ": NSC TPM not active\n");
   4.303 -
   4.304 -	/* select PM channel 1 */
   4.305 -	tpm_write_index(NSC_LDN_INDEX, 0x12);
   4.306 -	tpm_read_index(NSC_LDN_INDEX);
   4.307 -
   4.308 -	/* disable the DPM module */
   4.309 -	tpm_write_index(NSC_LDC_INDEX, 0);
   4.310 -	tpm_read_index(NSC_LDC_INDEX);
   4.311 -
   4.312 -	/* set the data register base addresses */
   4.313 -	tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
   4.314 -	tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
   4.315 -	tpm_read_index(NSC_DIO_INDEX);
   4.316 -	tpm_read_index(NSC_DIO_INDEX + 1);
   4.317 -
   4.318 -	/* set the command register base addresses */
   4.319 -	tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
   4.320 -	tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
   4.321 -	tpm_read_index(NSC_DIO_INDEX);
   4.322 -	tpm_read_index(NSC_DIO_INDEX + 1);
   4.323 -
   4.324 -	/* set the interrupt number to be used for the host interface */
   4.325 -	tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
   4.326 -	tpm_write_index(NSC_ITS_INDEX, 0x00);
   4.327 -	tpm_read_index(NSC_IRQ_INDEX);
   4.328 -
   4.329 -	/* enable the DPM module */
   4.330 -	tpm_write_index(NSC_LDC_INDEX, 0x01);
   4.331 -	tpm_read_index(NSC_LDC_INDEX);
   4.332 -
   4.333 -	if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
   4.334 -		goto out_err;
   4.335 -
   4.336 -	return 0;
   4.337 -
   4.338 -out_err:
   4.339 -	pci_disable_device(pci_dev);
   4.340 -	return rc;
   4.341 -}
   4.342 -
   4.343 -static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
   4.344 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
   4.345 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
   4.346 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
   4.347 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
   4.348 -	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
   4.349 -	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
   4.350 -	{0,}
   4.351 -};
   4.352 -
   4.353 -MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
   4.354 -
   4.355 -static struct pci_driver nsc_pci_driver = {
   4.356 -	.name = "tpm_nsc",
   4.357 -	.id_table = tpm_pci_tbl,
   4.358 -	.probe = tpm_nsc_init,
   4.359 -	.remove = __devexit_p(tpm_remove),
   4.360 -	.suspend = tpm_pm_suspend,
   4.361 -	.resume = tpm_pm_resume,
   4.362 -};
   4.363 -
   4.364 -static int __init init_nsc(void)
   4.365 -{
   4.366 -	return pci_register_driver(&nsc_pci_driver);
   4.367 -}
   4.368 -
   4.369 -static void __exit cleanup_nsc(void)
   4.370 -{
   4.371 -	pci_unregister_driver(&nsc_pci_driver);
   4.372 -}
   4.373 -
   4.374 -module_init(init_nsc);
   4.375 -module_exit(cleanup_nsc);
   4.376 -
   4.377 -MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
   4.378 -MODULE_DESCRIPTION("TPM Driver");
   4.379 -MODULE_VERSION("2.0");
   4.380 -MODULE_LICENSE("GPL");
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/patches/linux-2.6.12/tpm_partial_read.patch	Sat Sep 17 08:25:30 2005 +0000
     5.3 @@ -0,0 +1,74 @@
     5.4 +--- ref-linux-2.6.12/drivers/char/tpm/tpm.c	2005-06-17 15:48:29.000000000 -0400
     5.5 ++++ linux-2.6-xen-sparse/drivers/char/tpm/tpm.c	2005-09-15 14:56:05.000000000 -0400
     5.6 +@@ -473,6 +401,7 @@ ssize_t tpm_write(struct file * file, co
     5.7 + 	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
     5.8 + 
     5.9 + 	atomic_set(&chip->data_pending, out_size);
    5.10 ++	atomic_set(&chip->data_position, 0);
    5.11 + 	up(&chip->buffer_mutex);
    5.12 + 
    5.13 + 	/* Set a timeout by which the reader must come claim the result */
    5.14 +@@ -494,29 +423,34 @@ ssize_t tpm_read(struct file * file, cha
    5.15 + {
    5.16 + 	struct tpm_chip *chip = file->private_data;
    5.17 + 	int ret_size = -ENODATA;
    5.18 ++	int pos, pending = 0;
    5.19 + 
    5.20 +-	if (atomic_read(&chip->data_pending) != 0) {	/* Result available */
    5.21 ++	down(&chip->buffer_mutex);
    5.22 ++	ret_size = atomic_read(&chip->data_pending);
    5.23 ++	if ( ret_size > 0 ) {	/* Result available */
    5.24 ++		if (size < ret_size)
    5.25 ++			ret_size = size;
    5.26 ++
    5.27 ++		pos = atomic_read(&chip->data_position);
    5.28 ++
    5.29 ++		if (copy_to_user((void __user *) buf,
    5.30 ++				 &chip->data_buffer[pos], ret_size)) {
    5.31 ++			ret_size = -EFAULT;
    5.32 ++		} else {
    5.33 ++			pending = atomic_read(&chip->data_pending) - ret_size;
    5.34 ++			if ( pending ) {
    5.35 ++				atomic_set( &chip->data_pending, pending );
    5.36 ++				atomic_set( &chip->data_position, pos+ret_size );
    5.37 ++			}
    5.38 ++		}
    5.39 ++	}
    5.40 ++	up(&chip->buffer_mutex);
    5.41 ++
    5.42 ++	if ( ret_size <= 0 || pending == 0 ) {
    5.43 ++		atomic_set( &chip->data_pending, 0 );
    5.44 + 		down(&chip->timer_manipulation_mutex);
    5.45 + 		del_singleshot_timer_sync(&chip->user_read_timer);
    5.46 + 		up(&chip->timer_manipulation_mutex);
    5.47 +-
    5.48 +-		down(&chip->buffer_mutex);
    5.49 +-
    5.50 +-		ret_size = atomic_read(&chip->data_pending);
    5.51 +-		atomic_set(&chip->data_pending, 0);
    5.52 +-
    5.53 +-		if (ret_size == 0)	/* timeout just occurred */
    5.54 +-			ret_size = -ETIME;
    5.55 +-		else if (ret_size > 0) {	/* relay data */
    5.56 +-			if (size < ret_size)
    5.57 +-				ret_size = size;
    5.58 +-
    5.59 +-			if (copy_to_user((void __user *) buf,
    5.60 +-					 chip->data_buffer, ret_size)) {
    5.61 +-				ret_size = -EFAULT;
    5.62 +-			}
    5.63 +-		}
    5.64 +-		up(&chip->buffer_mutex);
    5.65 + 	}
    5.66 + 
    5.67 + 	return ret_size;
    5.68 +--- ref-linux-2.6.12/drivers/char/tpm/tpm.h	2005-06-17 15:48:29.000000000 -0400
    5.69 ++++ linux-2.6-xen-sparse/drivers/char/tpm/tpm.h	2005-09-15 14:56:05.000000000 -0400
    5.70 +@@ -54,6 +54,7 @@ struct tpm_chip {
    5.71 + 	/* Data passed to and from the tpm via the read/write calls */
    5.72 + 	u8 *data_buffer;
    5.73 + 	atomic_t data_pending;
    5.74 ++	atomic_t data_position;
    5.75 + 	struct semaphore buffer_mutex;
    5.76 + 
    5.77 + 	struct timer_list user_read_timer;	/* user needs to claim result */