debuggers.hg
changeset 6939: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>
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 */