direct-io.hg

view patches/linux-2.6.16.29/tpm_plugin_2.6.17.patch @ 11750:d845c9522d9e

[HVM][SVM] Check if SVM is disabled by the BIOS before enabling it.

Newer BIOS implementations will be able to disable the SVM feature,
although an additional test of an MSR (VMCR 0xC0010114 bit 4) is
necessary (set equals disabled). Bit 4 of MSR 0xc0010114 returns 0
(SVM enabled) on machines with older BIOS' without the SVM disable
feature support.

Signed-off-by: Wei Huang <wei.huang2@amd.com>=20
Signed-off-by: Tom Woller <thomas.woller@amd.com>=20
author kfraser@localhost.localdomain
date Thu Oct 12 16:12:10 2006 +0100 (2006-10-12)
parents 041be3f6b38e
children
line source
1 diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.c ./drivers/char/tpm/tpm_atmel.c
2 --- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.c 2006-09-12 19:02:10.000000000 +0100
3 +++ ./drivers/char/tpm/tpm_atmel.c 2006-09-19 14:05:52.000000000 +0100
4 @@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
5 return -EIO;
7 for (i = 0; i < 6; i++) {
8 - status = ioread8(chip->vendor->iobase + 1);
9 + status = ioread8(chip->vendor.iobase + 1);
10 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
11 dev_err(chip->dev, "error reading header\n");
12 return -EIO;
13 }
14 - *buf++ = ioread8(chip->vendor->iobase);
15 + *buf++ = ioread8(chip->vendor.iobase);
16 }
18 /* size of the data received */
19 @@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
20 dev_err(chip->dev,
21 "Recv size(%d) less than available space\n", size);
22 for (; i < size; i++) { /* clear the waiting data anyway */
23 - status = ioread8(chip->vendor->iobase + 1);
24 + status = ioread8(chip->vendor.iobase + 1);
25 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
26 dev_err(chip->dev, "error reading data\n");
27 return -EIO;
28 @@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
30 /* read all the data available */
31 for (; i < size; i++) {
32 - status = ioread8(chip->vendor->iobase + 1);
33 + status = ioread8(chip->vendor.iobase + 1);
34 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
35 dev_err(chip->dev, "error reading data\n");
36 return -EIO;
37 }
38 - *buf++ = ioread8(chip->vendor->iobase);
39 + *buf++ = ioread8(chip->vendor.iobase);
40 }
42 /* make sure data available is gone */
43 - status = ioread8(chip->vendor->iobase + 1);
44 + status = ioread8(chip->vendor.iobase + 1);
46 if (status & ATML_STATUS_DATA_AVAIL) {
47 dev_err(chip->dev, "data available is stuck\n");
48 @@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
49 dev_dbg(chip->dev, "tpm_atml_send:\n");
50 for (i = 0; i < count; i++) {
51 dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
52 - iowrite8(buf[i], chip->vendor->iobase);
53 + iowrite8(buf[i], chip->vendor.iobase);
54 }
56 return count;
57 @@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
59 static void tpm_atml_cancel(struct tpm_chip *chip)
60 {
61 - iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
62 + iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
63 }
65 static u8 tpm_atml_status(struct tpm_chip *chip)
66 {
67 - return ioread8(chip->vendor->iobase + 1);
68 + return ioread8(chip->vendor.iobase + 1);
69 }
71 static struct file_operations atmel_ops = {
72 @@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
74 static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
76 -static struct tpm_vendor_specific tpm_atmel = {
77 +static const struct tpm_vendor_specific tpm_atmel = {
78 .recv = tpm_atml_recv,
79 .send = tpm_atml_send,
80 .cancel = tpm_atml_cancel,
81 @@ -159,10 +159,10 @@ static void atml_plat_remove(void)
82 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
84 if (chip) {
85 - if (chip->vendor->have_region)
86 - atmel_release_region(chip->vendor->base,
87 - chip->vendor->region_size);
88 - atmel_put_base_addr(chip->vendor);
89 + if (chip->vendor.have_region)
90 + atmel_release_region(chip->vendor.base,
91 + chip->vendor.region_size);
92 + atmel_put_base_addr(chip->vendor.iobase);
93 tpm_remove_hardware(chip->dev);
94 platform_device_unregister(pdev);
95 }
96 @@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
97 static int __init init_atmel(void)
98 {
99 int rc = 0;
100 + void __iomem *iobase = NULL;
101 + int have_region, region_size;
102 + unsigned long base;
103 + struct tpm_chip *chip;
105 driver_register(&atml_drv);
107 - if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
108 + if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
109 rc = -ENODEV;
110 goto err_unreg_drv;
111 }
113 - tpm_atmel.have_region =
114 + have_region =
115 (atmel_request_region
116 - (tpm_atmel.base, tpm_atmel.region_size,
117 - "tpm_atmel0") == NULL) ? 0 : 1;
118 + (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
119 +
121 if (IS_ERR
122 (pdev =
123 @@ -199,17 +203,25 @@ static int __init init_atmel(void)
124 goto err_rel_reg;
125 }
127 - if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
128 + if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
129 + rc = -ENODEV;
130 goto err_unreg_dev;
131 + }
132 +
133 + chip->vendor.iobase = iobase;
134 + chip->vendor.base = base;
135 + chip->vendor.have_region = have_region;
136 + chip->vendor.region_size = region_size;
137 +
138 return 0;
140 err_unreg_dev:
141 platform_device_unregister(pdev);
142 err_rel_reg:
143 - atmel_put_base_addr(&tpm_atmel);
144 - if (tpm_atmel.have_region)
145 - atmel_release_region(tpm_atmel.base,
146 - tpm_atmel.region_size);
147 + atmel_put_base_addr(iobase);
148 + if (have_region)
149 + atmel_release_region(base,
150 + region_size);
151 err_unreg_drv:
152 driver_unregister(&atml_drv);
153 return rc;
154 diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.h ./drivers/char/tpm/tpm_atmel.h
155 --- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.h 2006-09-12 19:02:10.000000000 +0100
156 +++ ./drivers/char/tpm/tpm_atmel.h 2006-09-19 14:05:52.000000000 +0100
157 @@ -28,13 +28,12 @@
158 #define atmel_request_region request_mem_region
159 #define atmel_release_region release_mem_region
161 -static inline void atmel_put_base_addr(struct tpm_vendor_specific
162 - *vendor)
163 +static inline void atmel_put_base_addr(void __iomem *iobase)
164 {
165 - iounmap(vendor->iobase);
166 + iounmap(iobase);
167 }
169 -static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
170 +static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
171 {
172 struct device_node *dn;
173 unsigned long address, size;
174 @@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
175 else
176 size = reg[naddrc];
178 - vendor->base = address;
179 - vendor->region_size = size;
180 - return ioremap(vendor->base, vendor->region_size);
181 + *base = address;
182 + *region_size = size;
183 + return ioremap(*base, *region_size);
184 }
185 #else
186 #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
187 @@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
188 return 0;
189 }
191 -static inline void atmel_put_base_addr(struct tpm_vendor_specific
192 - *vendor)
193 +static inline void atmel_put_base_addr(void __iomem *iobase)
194 {
195 }
197 /* Determine where to talk to device */
198 -static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
199 - *vendor)
200 +static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
201 {
202 int lo, hi;
204 @@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
205 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
206 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
208 - vendor->base = (hi << 8) | lo;
209 - vendor->region_size = 2;
210 + *base = (hi << 8) | lo;
211 + *region_size = 2;
213 - return ioport_map(vendor->base, vendor->region_size);
214 + return ioport_map(*base, *region_size);
215 }
216 #endif
217 diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_bios.c ./drivers/char/tpm/tpm_bios.c
218 --- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_bios.c 2006-09-12 19:02:10.000000000 +0100
219 +++ ./drivers/char/tpm/tpm_bios.c 2006-09-19 14:05:52.000000000 +0100
220 @@ -29,6 +29,11 @@
221 #define MAX_TEXT_EVENT 1000 /* Max event string length */
222 #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
224 +enum bios_platform_class {
225 + BIOS_CLIENT = 0x00,
226 + BIOS_SERVER = 0x01,
227 +};
228 +
229 struct tpm_bios_log {
230 void *bios_event_log;
231 void *bios_event_log_end;
232 @@ -36,9 +41,18 @@ struct tpm_bios_log {
234 struct acpi_tcpa {
235 struct acpi_table_header hdr;
236 - u16 reserved;
237 - u32 log_max_len __attribute__ ((packed));
238 - u32 log_start_addr __attribute__ ((packed));
239 + u16 platform_class;
240 + union {
241 + struct client_hdr {
242 + u32 log_max_len __attribute__ ((packed));
243 + u64 log_start_addr __attribute__ ((packed));
244 + } client;
245 + struct server_hdr {
246 + u16 reserved;
247 + u64 log_max_len __attribute__ ((packed));
248 + u64 log_start_addr __attribute__ ((packed));
249 + } server;
250 + };
251 };
253 struct tcpa_event {
254 @@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
255 "Non-Host Info"
256 };
258 +struct tcpa_pc_event {
259 + u32 event_id;
260 + u32 event_size;
261 + u8 event_data[0];
262 +};
263 +
264 enum tcpa_pc_event_ids {
265 SMBIOS = 1,
266 BIS_CERT,
267 @@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
268 NVRAM,
269 OPTION_ROM_EXEC,
270 OPTION_ROM_CONFIG,
271 - OPTION_ROM_MICROCODE,
272 + OPTION_ROM_MICROCODE = 10,
273 S_CRTM_VERSION,
274 S_CRTM_CONTENTS,
275 POST_CONTENTS,
276 + HOST_TABLE_OF_DEVICES,
277 };
279 static const char* tcpa_pc_event_id_strings[] = {
280 - ""
281 + "",
282 "SMBIOS",
283 "BIS Certificate",
284 "POST BIOS ",
285 @@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
286 "NVRAM",
287 "Option ROM",
288 "Option ROM config",
289 - "Option ROM microcode",
290 + "",
291 + "Option ROM microcode ",
292 "S-CRTM Version",
293 - "S-CRTM Contents",
294 - "S-CRTM POST Contents",
295 + "S-CRTM Contents ",
296 + "POST Contents ",
297 + "Table of Devices",
298 };
300 /* returns pointer to start of pos. entry of tcg log */
301 @@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
302 const char *name = "";
303 char data[40] = "";
304 int i, n_len = 0, d_len = 0;
305 - u32 event_id;
306 + struct tcpa_pc_event *pc_event;
308 switch(event->event_type) {
309 case PREBOOT:
310 @@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
311 }
312 break;
313 case EVENT_TAG:
314 - event_id = be32_to_cpu(*((u32 *)event_entry));
315 + pc_event = (struct tcpa_pc_event *)event_entry;
317 /* ToDo Row data -> Base64 */
319 - switch (event_id) {
320 + switch (pc_event->event_id) {
321 case SMBIOS:
322 case BIS_CERT:
323 case CMOS:
324 case NVRAM:
325 case OPTION_ROM_EXEC:
326 case OPTION_ROM_CONFIG:
327 - case OPTION_ROM_MICROCODE:
328 case S_CRTM_VERSION:
329 - case S_CRTM_CONTENTS:
330 - case POST_CONTENTS:
331 - name = tcpa_pc_event_id_strings[event_id];
332 + name = tcpa_pc_event_id_strings[pc_event->event_id];
333 n_len = strlen(name);
334 break;
335 + /* hash data */
336 case POST_BIOS_ROM:
337 case ESCD:
338 - name = tcpa_pc_event_id_strings[event_id];
339 + case OPTION_ROM_MICROCODE:
340 + case S_CRTM_CONTENTS:
341 + case POST_CONTENTS:
342 + name = tcpa_pc_event_id_strings[pc_event->event_id];
343 n_len = strlen(name);
344 for (i = 0; i < 20; i++)
345 - d_len += sprintf(data, "%02x",
346 - event_entry[8 + i]);
347 + d_len += sprintf(&data[2*i], "%02x",
348 + pc_event->event_data[i]);
349 break;
350 default:
351 break;
352 @@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
354 static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
355 {
356 + struct tcpa_event *event = v;
357 + char *data = v;
358 + int i;
360 - char *eventname;
361 - char data[4];
362 - u32 help;
363 - int i, len;
364 - struct tcpa_event *event = (struct tcpa_event *) v;
365 - unsigned char *event_entry =
366 - (unsigned char *) (v + sizeof(struct tcpa_event));
367 -
368 - eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
369 - if (!eventname) {
370 - printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
371 - __func__);
372 - return -ENOMEM;
373 - }
374 -
375 - /* 1st: PCR used is in little-endian format (4 bytes) */
376 - help = le32_to_cpu(event->pcr_index);
377 - memcpy(data, &help, 4);
378 - for (i = 0; i < 4; i++)
379 - seq_putc(m, data[i]);
380 -
381 - /* 2nd: SHA1 (20 bytes) */
382 - for (i = 0; i < 20; i++)
383 - seq_putc(m, event->pcr_value[i]);
384 -
385 - /* 3rd: event type identifier (4 bytes) */
386 - help = le32_to_cpu(event->event_type);
387 - memcpy(data, &help, 4);
388 - for (i = 0; i < 4; i++)
389 + for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
390 seq_putc(m, data[i]);
392 - len = 0;
393 -
394 - len += get_event_name(eventname, event, event_entry);
395 -
396 - /* 4th: filename <= 255 + \'0' delimiter */
397 - if (len > TCG_EVENT_NAME_LEN_MAX)
398 - len = TCG_EVENT_NAME_LEN_MAX;
399 -
400 - for (i = 0; i < len; i++)
401 - seq_putc(m, eventname[i]);
402 -
403 - /* 5th: delimiter */
404 - seq_putc(m, '\0');
405 -
406 return 0;
407 }
409 @@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
410 /* 4th: eventname <= max + \'0' delimiter */
411 seq_printf(m, " %s\n", eventname);
413 + kfree(eventname);
414 return 0;
415 }
417 @@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log
418 struct acpi_tcpa *buff;
419 acpi_status status;
420 struct acpi_table_header *virt;
421 + u64 len, start;
423 if (log->bios_event_log != NULL) {
424 printk(KERN_ERR
425 @@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log
426 return -EIO;
427 }
429 - if (buff->log_max_len == 0) {
430 + switch(buff->platform_class) {
431 + case BIOS_SERVER:
432 + len = buff->server.log_max_len;
433 + start = buff->server.log_start_addr;
434 + break;
435 + case BIOS_CLIENT:
436 + default:
437 + len = buff->client.log_max_len;
438 + start = buff->client.log_start_addr;
439 + break;
440 + }
441 + if (!len) {
442 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
443 return -EIO;
444 }
446 /* malloc EventLog space */
447 - log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
448 + log->bios_event_log = kmalloc(len, GFP_KERNEL);
449 if (!log->bios_event_log) {
450 - printk
451 - ("%s: ERROR - Not enough Memory for BIOS measurements\n",
452 - __func__);
453 + printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
454 + __func__);
455 return -ENOMEM;
456 }
458 - log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
459 + log->bios_event_log_end = log->bios_event_log + len;
461 - acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
462 + acpi_os_map_memory(start, len, (void *) &virt);
464 - memcpy(log->bios_event_log, virt, buff->log_max_len);
465 + memcpy(log->bios_event_log, virt, len);
467 - acpi_os_unmap_memory(virt, buff->log_max_len);
468 + acpi_os_unmap_memory(virt, len);
469 return 0;
470 }
472 diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_infineon.c ./drivers/char/tpm/tpm_infineon.c
473 --- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_infineon.c 2006-09-12 19:02:10.000000000 +0100
474 +++ ./drivers/char/tpm/tpm_infineon.c 2006-09-19 14:05:52.000000000 +0100
475 @@ -15,6 +15,7 @@
476 * License.
477 */
479 +#include <linux/init.h>
480 #include <linux/pnp.h>
481 #include "tpm.h"
483 @@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
485 if (clear_wrfifo) {
486 for (i = 0; i < 4096; i++) {
487 - status = inb(chip->vendor->base + WRFIFO);
488 + status = inb(chip->vendor.base + WRFIFO);
489 if (status == 0xff) {
490 if (check == 5)
491 break;
492 @@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
493 */
494 i = 0;
495 do {
496 - status = inb(chip->vendor->base + RDFIFO);
497 - status = inb(chip->vendor->base + STAT);
498 + status = inb(chip->vendor.base + RDFIFO);
499 + status = inb(chip->vendor.base + STAT);
500 i++;
501 if (i == TPM_MAX_TRIES)
502 return -EIO;
503 @@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
504 int status;
505 int i;
506 for (i = 0; i < TPM_MAX_TRIES; i++) {
507 - status = inb(chip->vendor->base + STAT);
508 + status = inb(chip->vendor.base + STAT);
509 /* check the status-register if wait_for_bit is set */
510 if (status & 1 << wait_for_bit)
511 break;
512 @@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
513 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
514 {
515 wait(chip, STAT_XFE);
516 - outb(sendbyte, chip->vendor->base + WRFIFO);
517 + outb(sendbyte, chip->vendor.base + WRFIFO);
518 }
520 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
521 @@ -204,7 +205,7 @@ recv_begin:
522 ret = wait(chip, STAT_RDA);
523 if (ret)
524 return -EIO;
525 - buf[i] = inb(chip->vendor->base + RDFIFO);
526 + buf[i] = inb(chip->vendor.base + RDFIFO);
527 }
529 if (buf[0] != TPM_VL_VER) {
530 @@ -219,7 +220,7 @@ recv_begin:
532 for (i = 0; i < size; i++) {
533 wait(chip, STAT_RDA);
534 - buf[i] = inb(chip->vendor->base + RDFIFO);
535 + buf[i] = inb(chip->vendor.base + RDFIFO);
536 }
538 if ((size == 0x6D00) && (buf[1] == 0x80)) {
539 @@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip
540 u8 count_high, count_low, count_4, count_3, count_2, count_1;
542 /* Disabling Reset, LP and IRQC */
543 - outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
544 + outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
546 ret = empty_fifo(chip, 1);
547 if (ret) {
548 @@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
550 static u8 tpm_inf_status(struct tpm_chip *chip)
551 {
552 - return inb(chip->vendor->base + STAT);
553 + return inb(chip->vendor.base + STAT);
554 }
556 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
557 @@ -346,7 +347,7 @@ static struct file_operations inf_ops =
558 .release = tpm_release,
559 };
561 -static struct tpm_vendor_specific tpm_inf = {
562 +static const struct tpm_vendor_specific tpm_inf = {
563 .recv = tpm_inf_recv,
564 .send = tpm_inf_send,
565 .cancel = tpm_inf_cancel,
566 @@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
567 int version[2];
568 int productid[2];
569 char chipname[20];
570 + struct tpm_chip *chip;
572 /* read IO-ports through PnP */
573 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
574 @@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
575 goto err_last;
576 }
577 /* publish my base address and request region */
578 - tpm_inf.base = TPM_INF_BASE;
579 if (request_region
580 - (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
581 + (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
582 rc = -EINVAL;
583 goto err_last;
584 }
585 - if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
586 - "tpm_infineon0") == NULL) {
587 + if (request_region
588 + (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
589 rc = -EINVAL;
590 goto err_last;
591 }
592 @@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
594 /* configure TPM with IO-ports */
595 outb(IOLIMH, TPM_INF_ADDR);
596 - outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
597 + outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
598 outb(IOLIML, TPM_INF_ADDR);
599 - outb((tpm_inf.base & 0xff), TPM_INF_DATA);
600 + outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
602 /* control if IO-ports are set correctly */
603 outb(IOLIMH, TPM_INF_ADDR);
604 @@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
605 outb(IOLIML, TPM_INF_ADDR);
606 iol = inb(TPM_INF_DATA);
608 - if ((ioh << 8 | iol) != tpm_inf.base) {
609 + if ((ioh << 8 | iol) != TPM_INF_BASE) {
610 dev_err(&dev->dev,
611 - "Could not set IO-ports to 0x%lx\n",
612 - tpm_inf.base);
613 + "Could not set IO-ports to 0x%x\n",
614 + TPM_INF_BASE);
615 rc = -EIO;
616 goto err_release_region;
617 }
618 @@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
619 outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
621 /* disable RESET, LP and IRQC */
622 - outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
623 + outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
625 /* Finally, we're done, print some infos */
626 dev_info(&dev->dev, "TPM found: "
627 "config base 0x%x, "
628 "io base 0x%x, "
629 - "chip version %02x%02x, "
630 - "vendor id %x%x (Infineon), "
631 - "product id %02x%02x"
632 + "chip version 0x%02x%02x, "
633 + "vendor id 0x%x%x (Infineon), "
634 + "product id 0x%02x%02x"
635 "%s\n",
636 TPM_INF_ADDR,
637 TPM_INF_BASE,
638 @@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
639 vendorid[0], vendorid[1],
640 productid[0], productid[1], chipname);
642 - rc = tpm_register_hardware(&dev->dev, &tpm_inf);
643 - if (rc < 0) {
644 - rc = -ENODEV;
645 + if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
646 goto err_release_region;
647 }
648 + chip->vendor.base = TPM_INF_BASE;
649 return 0;
650 } else {
651 rc = -ENODEV;
652 @@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
653 }
655 err_release_region:
656 - release_region(tpm_inf.base, TPM_INF_PORT_LEN);
657 + release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
658 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
660 err_last:
661 @@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
662 struct tpm_chip *chip = pnp_get_drvdata(dev);
664 if (chip) {
665 - release_region(chip->vendor->base, TPM_INF_PORT_LEN);
666 + release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
667 + release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
668 tpm_remove_hardware(chip->dev);
669 }
670 }
671 @@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
672 },
673 .id_table = tpm_pnp_tbl,
674 .probe = tpm_inf_pnp_probe,
675 - .remove = tpm_inf_pnp_remove,
676 + .remove = __devexit_p(tpm_inf_pnp_remove),
677 };
679 static int __init init_inf(void)
680 @@ -538,5 +539,5 @@ module_exit(cleanup_inf);
682 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
683 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
684 -MODULE_VERSION("1.7");
685 +MODULE_VERSION("1.8");
686 MODULE_LICENSE("GPL");
687 diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_nsc.c ./drivers/char/tpm/tpm_nsc.c
688 --- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_nsc.c 2006-09-12 19:02:10.000000000 +0100
689 +++ ./drivers/char/tpm/tpm_nsc.c 2006-09-19 14:05:52.000000000 +0100
690 @@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
691 unsigned long stop;
693 /* status immediately available check */
694 - *data = inb(chip->vendor->base + NSC_STATUS);
695 + *data = inb(chip->vendor.base + NSC_STATUS);
696 if ((*data & mask) == val)
697 return 0;
699 @@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
700 stop = jiffies + 10 * HZ;
701 do {
702 msleep(TPM_TIMEOUT);
703 - *data = inb(chip->vendor->base + 1);
704 + *data = inb(chip->vendor.base + 1);
705 if ((*data & mask) == val)
706 return 0;
707 }
708 @@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
709 unsigned long stop;
711 /* status immediately available check */
712 - status = inb(chip->vendor->base + NSC_STATUS);
713 + status = inb(chip->vendor.base + NSC_STATUS);
714 if (status & NSC_STATUS_OBF)
715 - status = inb(chip->vendor->base + NSC_DATA);
716 + status = inb(chip->vendor.base + NSC_DATA);
717 if (status & NSC_STATUS_RDY)
718 return 0;
720 @@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
721 stop = jiffies + 100;
722 do {
723 msleep(TPM_TIMEOUT);
724 - status = inb(chip->vendor->base + NSC_STATUS);
725 + status = inb(chip->vendor.base + NSC_STATUS);
726 if (status & NSC_STATUS_OBF)
727 - status = inb(chip->vendor->base + NSC_DATA);
728 + status = inb(chip->vendor.base + NSC_DATA);
729 if (status & NSC_STATUS_RDY)
730 return 0;
731 }
732 @@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip
733 return -EIO;
734 }
735 if ((data =
736 - inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
737 + inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
738 dev_err(chip->dev, "not in normal mode (0x%x)\n",
739 data);
740 return -EIO;
741 @@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip
742 }
743 if (data & NSC_STATUS_F0)
744 break;
745 - *p = inb(chip->vendor->base + NSC_DATA);
746 + *p = inb(chip->vendor.base + NSC_DATA);
747 }
749 if ((data & NSC_STATUS_F0) == 0 &&
750 @@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip
751 dev_err(chip->dev, "F0 not set\n");
752 return -EIO;
753 }
754 - if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
755 + if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
756 dev_err(chip->dev,
757 "expected end of command(0x%x)\n", data);
758 return -EIO;
759 @@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip
760 * fix it. Not sure why this is needed, we followed the flow
761 * chart in the manual to the letter.
762 */
763 - outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
764 + outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
766 if (nsc_wait_for_ready(chip) != 0)
767 return -EIO;
768 @@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip
769 return -EIO;
770 }
772 - outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
773 + outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
774 if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
775 dev_err(chip->dev, "IBR timeout\n");
776 return -EIO;
777 @@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip
778 "IBF timeout (while writing data)\n");
779 return -EIO;
780 }
781 - outb(buf[i], chip->vendor->base + NSC_DATA);
782 + outb(buf[i], chip->vendor.base + NSC_DATA);
783 }
785 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
786 dev_err(chip->dev, "IBF timeout\n");
787 return -EIO;
788 }
789 - outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
790 + outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
792 return count;
793 }
795 static void tpm_nsc_cancel(struct tpm_chip *chip)
796 {
797 - outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
798 + outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
799 }
801 static u8 tpm_nsc_status(struct tpm_chip *chip)
802 {
803 - return inb(chip->vendor->base + NSC_STATUS);
804 + return inb(chip->vendor.base + NSC_STATUS);
805 }
807 static struct file_operations nsc_ops = {
808 @@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] =
810 static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
812 -static struct tpm_vendor_specific tpm_nsc = {
813 +static const struct tpm_vendor_specific tpm_nsc = {
814 .recv = tpm_nsc_recv,
815 .send = tpm_nsc_send,
816 .cancel = tpm_nsc_cancel,
817 @@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
818 {
819 struct tpm_chip *chip = dev_get_drvdata(dev);
820 if ( chip ) {
821 - release_region(chip->vendor->base, 2);
822 + release_region(chip->vendor.base, 2);
823 tpm_remove_hardware(chip->dev);
824 }
825 }
826 @@ -286,7 +286,8 @@ static int __init init_nsc(void)
827 int rc = 0;
828 int lo, hi;
829 int nscAddrBase = TPM_ADDR;
830 -
831 + struct tpm_chip *chip;
832 + unsigned long base;
834 /* verify that it is a National part (SID) */
835 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
836 @@ -300,7 +301,7 @@ static int __init init_nsc(void)
838 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
839 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
840 - tpm_nsc.base = (hi<<8) | lo;
841 + base = (hi<<8) | lo;
843 /* enable the DPM module */
844 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
845 @@ -320,13 +321,15 @@ static int __init init_nsc(void)
846 if ((rc = platform_device_register(pdev)) < 0)
847 goto err_free_dev;
849 - if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
850 + if (request_region(base, 2, "tpm_nsc0") == NULL ) {
851 rc = -EBUSY;
852 goto err_unreg_dev;
853 }
855 - if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
856 + if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
857 + rc = -ENODEV;
858 goto err_rel_reg;
859 + }
861 dev_dbg(&pdev->dev, "NSC TPM detected\n");
862 dev_dbg(&pdev->dev,
863 @@ -361,10 +364,12 @@ static int __init init_nsc(void)
864 "NSC TPM revision %d\n",
865 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
867 + chip->vendor.base = base;
868 +
869 return 0;
871 err_rel_reg:
872 - release_region(tpm_nsc.base, 2);
873 + release_region(base, 2);
874 err_unreg_dev:
875 platform_device_unregister(pdev);
876 err_free_dev:
877 diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_tis.c ./drivers/char/tpm/tpm_tis.c
878 --- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_tis.c 1970-01-01 01:00:00.000000000 +0100
879 +++ ./drivers/char/tpm/tpm_tis.c 2006-09-19 14:05:52.000000000 +0100
880 @@ -0,0 +1,665 @@
881 +/*
882 + * Copyright (C) 2005, 2006 IBM Corporation
883 + *
884 + * Authors:
885 + * Leendert van Doorn <leendert@watson.ibm.com>
886 + * Kylene Hall <kjhall@us.ibm.com>
887 + *
888 + * Device driver for TCG/TCPA TPM (trusted platform module).
889 + * Specifications at www.trustedcomputinggroup.org
890 + *
891 + * This device driver implements the TPM interface as defined in
892 + * the TCG TPM Interface Spec version 1.2, revision 1.0.
893 + *
894 + * This program is free software; you can redistribute it and/or
895 + * modify it under the terms of the GNU General Public License as
896 + * published by the Free Software Foundation, version 2 of the
897 + * License.
898 + */
899 +#include <linux/init.h>
900 +#include <linux/module.h>
901 +#include <linux/moduleparam.h>
902 +#include <linux/pnp.h>
903 +#include <linux/interrupt.h>
904 +#include <linux/wait.h>
905 +#include "tpm.h"
906 +
907 +#define TPM_HEADER_SIZE 10
908 +
909 +enum tis_access {
910 + TPM_ACCESS_VALID = 0x80,
911 + TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
912 + TPM_ACCESS_REQUEST_PENDING = 0x04,
913 + TPM_ACCESS_REQUEST_USE = 0x02,
914 +};
915 +
916 +enum tis_status {
917 + TPM_STS_VALID = 0x80,
918 + TPM_STS_COMMAND_READY = 0x40,
919 + TPM_STS_GO = 0x20,
920 + TPM_STS_DATA_AVAIL = 0x10,
921 + TPM_STS_DATA_EXPECT = 0x08,
922 +};
923 +
924 +enum tis_int_flags {
925 + TPM_GLOBAL_INT_ENABLE = 0x80000000,
926 + TPM_INTF_BURST_COUNT_STATIC = 0x100,
927 + TPM_INTF_CMD_READY_INT = 0x080,
928 + TPM_INTF_INT_EDGE_FALLING = 0x040,
929 + TPM_INTF_INT_EDGE_RISING = 0x020,
930 + TPM_INTF_INT_LEVEL_LOW = 0x010,
931 + TPM_INTF_INT_LEVEL_HIGH = 0x008,
932 + TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
933 + TPM_INTF_STS_VALID_INT = 0x002,
934 + TPM_INTF_DATA_AVAIL_INT = 0x001,
935 +};
936 +
937 +enum tis_defaults {
938 + TIS_MEM_BASE = 0xFED40000,
939 + TIS_MEM_LEN = 0x5000,
940 + TIS_SHORT_TIMEOUT = 750, /* ms */
941 + TIS_LONG_TIMEOUT = 2000, /* 2 sec */
942 +};
943 +
944 +#define TPM_ACCESS(l) (0x0000 | ((l) << 12))
945 +#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12))
946 +#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12))
947 +#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12))
948 +#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12))
949 +#define TPM_STS(l) (0x0018 | ((l) << 12))
950 +#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12))
951 +
952 +#define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
953 +#define TPM_RID(l) (0x0F04 | ((l) << 12))
954 +
955 +static LIST_HEAD(tis_chips);
956 +static DEFINE_SPINLOCK(tis_lock);
957 +
958 +static int check_locality(struct tpm_chip *chip, int l)
959 +{
960 + if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
961 + (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
962 + (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
963 + return chip->vendor.locality = l;
964 +
965 + return -1;
966 +}
967 +
968 +static void release_locality(struct tpm_chip *chip, int l, int force)
969 +{
970 + if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
971 + (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
972 + (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
973 + iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
974 + chip->vendor.iobase + TPM_ACCESS(l));
975 +}
976 +
977 +static int request_locality(struct tpm_chip *chip, int l)
978 +{
979 + unsigned long stop;
980 + long rc;
981 +
982 + if (check_locality(chip, l) >= 0)
983 + return l;
984 +
985 + iowrite8(TPM_ACCESS_REQUEST_USE,
986 + chip->vendor.iobase + TPM_ACCESS(l));
987 +
988 + if (chip->vendor.irq) {
989 + rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
990 + (check_locality
991 + (chip, l) >= 0),
992 + chip->vendor.timeout_a);
993 + if (rc > 0)
994 + return l;
995 +
996 + } else {
997 + /* wait for burstcount */
998 + stop = jiffies + chip->vendor.timeout_a;
999 + do {
1000 + if (check_locality(chip, l) >= 0)
1001 + return l;
1002 + msleep(TPM_TIMEOUT);
1003 + }
1004 + while (time_before(jiffies, stop));
1005 + }
1006 + return -1;
1007 +}
1009 +static u8 tpm_tis_status(struct tpm_chip *chip)
1010 +{
1011 + return ioread8(chip->vendor.iobase +
1012 + TPM_STS(chip->vendor.locality));
1013 +}
1015 +static void tpm_tis_ready(struct tpm_chip *chip)
1016 +{
1017 + /* this causes the current command to be aborted */
1018 + iowrite8(TPM_STS_COMMAND_READY,
1019 + chip->vendor.iobase + TPM_STS(chip->vendor.locality));
1020 +}
1022 +static int get_burstcount(struct tpm_chip *chip)
1023 +{
1024 + unsigned long stop;
1025 + int burstcnt;
1027 + /* wait for burstcount */
1028 + /* which timeout value, spec has 2 answers (c & d) */
1029 + stop = jiffies + chip->vendor.timeout_d;
1030 + do {
1031 + burstcnt = ioread8(chip->vendor.iobase +
1032 + TPM_STS(chip->vendor.locality) + 1);
1033 + burstcnt += ioread8(chip->vendor.iobase +
1034 + TPM_STS(chip->vendor.locality) +
1035 + 2) << 8;
1036 + if (burstcnt)
1037 + return burstcnt;
1038 + msleep(TPM_TIMEOUT);
1039 + } while (time_before(jiffies, stop));
1040 + return -EBUSY;
1041 +}
1043 +static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
1044 + wait_queue_head_t *queue)
1045 +{
1046 + unsigned long stop;
1047 + long rc;
1048 + u8 status;
1050 + /* check current status */
1051 + status = tpm_tis_status(chip);
1052 + if ((status & mask) == mask)
1053 + return 0;
1055 + if (chip->vendor.irq) {
1056 + rc = wait_event_interruptible_timeout(*queue,
1057 + ((tpm_tis_status
1058 + (chip) & mask) ==
1059 + mask), timeout);
1060 + if (rc > 0)
1061 + return 0;
1062 + } else {
1063 + stop = jiffies + timeout;
1064 + do {
1065 + msleep(TPM_TIMEOUT);
1066 + status = tpm_tis_status(chip);
1067 + if ((status & mask) == mask)
1068 + return 0;
1069 + } while (time_before(jiffies, stop));
1070 + }
1071 + return -ETIME;
1072 +}
1074 +static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
1075 +{
1076 + int size = 0, burstcnt;
1077 + while (size < count &&
1078 + wait_for_stat(chip,
1079 + TPM_STS_DATA_AVAIL | TPM_STS_VALID,
1080 + chip->vendor.timeout_c,
1081 + &chip->vendor.read_queue)
1082 + == 0) {
1083 + burstcnt = get_burstcount(chip);
1084 + for (; burstcnt > 0 && size < count; burstcnt--)
1085 + buf[size++] = ioread8(chip->vendor.iobase +
1086 + TPM_DATA_FIFO(chip->vendor.
1087 + locality));
1088 + }
1089 + return size;
1090 +}
1092 +static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
1093 +{
1094 + int size = 0;
1095 + int expected, status;
1097 + if (count < TPM_HEADER_SIZE) {
1098 + size = -EIO;
1099 + goto out;
1100 + }
1102 + /* read first 10 bytes, including tag, paramsize, and result */
1103 + if ((size =
1104 + recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
1105 + dev_err(chip->dev, "Unable to read header\n");
1106 + goto out;
1107 + }
1109 + expected = be32_to_cpu(*(__be32 *) (buf + 2));
1110 + if (expected > count) {
1111 + size = -EIO;
1112 + goto out;
1113 + }
1115 + if ((size +=
1116 + recv_data(chip, &buf[TPM_HEADER_SIZE],
1117 + expected - TPM_HEADER_SIZE)) < expected) {
1118 + dev_err(chip->dev, "Unable to read remainder of result\n");
1119 + size = -ETIME;
1120 + goto out;
1121 + }
1123 + wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
1124 + &chip->vendor.int_queue);
1125 + status = tpm_tis_status(chip);
1126 + if (status & TPM_STS_DATA_AVAIL) { /* retry? */
1127 + dev_err(chip->dev, "Error left over data\n");
1128 + size = -EIO;
1129 + goto out;
1130 + }
1132 +out:
1133 + tpm_tis_ready(chip);
1134 + release_locality(chip, chip->vendor.locality, 0);
1135 + return size;
1136 +}
1138 +/*
1139 + * If interrupts are used (signaled by an irq set in the vendor structure)
1140 + * tpm.c can skip polling for the data to be available as the interrupt is
1141 + * waited for here
1142 + */
1143 +static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
1144 +{
1145 + int rc, status, burstcnt;
1146 + size_t count = 0;
1147 + u32 ordinal;
1149 + if (request_locality(chip, 0) < 0)
1150 + return -EBUSY;
1152 + status = tpm_tis_status(chip);
1153 + if ((status & TPM_STS_COMMAND_READY) == 0) {
1154 + tpm_tis_ready(chip);
1155 + if (wait_for_stat
1156 + (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
1157 + &chip->vendor.int_queue) < 0) {
1158 + rc = -ETIME;
1159 + goto out_err;
1160 + }
1161 + }
1163 + while (count < len - 1) {
1164 + burstcnt = get_burstcount(chip);
1165 + for (; burstcnt > 0 && count < len - 1; burstcnt--) {
1166 + iowrite8(buf[count], chip->vendor.iobase +
1167 + TPM_DATA_FIFO(chip->vendor.locality));
1168 + count++;
1169 + }
1171 + wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
1172 + &chip->vendor.int_queue);
1173 + status = tpm_tis_status(chip);
1174 + if ((status & TPM_STS_DATA_EXPECT) == 0) {
1175 + rc = -EIO;
1176 + goto out_err;
1177 + }
1178 + }
1180 + /* write last byte */
1181 + iowrite8(buf[count],
1182 + chip->vendor.iobase +
1183 + TPM_DATA_FIFO(chip->vendor.locality));
1184 + wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
1185 + &chip->vendor.int_queue);
1186 + status = tpm_tis_status(chip);
1187 + if ((status & TPM_STS_DATA_EXPECT) != 0) {
1188 + rc = -EIO;
1189 + goto out_err;
1190 + }
1192 + /* go and do it */
1193 + iowrite8(TPM_STS_GO,
1194 + chip->vendor.iobase + TPM_STS(chip->vendor.locality));
1196 + if (chip->vendor.irq) {
1197 + ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
1198 + if (wait_for_stat
1199 + (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
1200 + tpm_calc_ordinal_duration(chip, ordinal),
1201 + &chip->vendor.read_queue) < 0) {
1202 + rc = -ETIME;
1203 + goto out_err;
1204 + }
1205 + }
1206 + return len;
1207 +out_err:
1208 + tpm_tis_ready(chip);
1209 + release_locality(chip, chip->vendor.locality, 0);
1210 + return rc;
1211 +}
1213 +static struct file_operations tis_ops = {
1214 + .owner = THIS_MODULE,
1215 + .llseek = no_llseek,
1216 + .open = tpm_open,
1217 + .read = tpm_read,
1218 + .write = tpm_write,
1219 + .release = tpm_release,
1220 +};
1222 +static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
1223 +static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
1224 +static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
1225 +static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
1226 +static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
1227 +static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
1228 + NULL);
1229 +static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
1230 +static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
1232 +static struct attribute *tis_attrs[] = {
1233 + &dev_attr_pubek.attr,
1234 + &dev_attr_pcrs.attr,
1235 + &dev_attr_enabled.attr,
1236 + &dev_attr_active.attr,
1237 + &dev_attr_owned.attr,
1238 + &dev_attr_temp_deactivated.attr,
1239 + &dev_attr_caps.attr,
1240 + &dev_attr_cancel.attr, NULL,
1241 +};
1243 +static struct attribute_group tis_attr_grp = {
1244 + .attrs = tis_attrs
1245 +};
1247 +static struct tpm_vendor_specific tpm_tis = {
1248 + .status = tpm_tis_status,
1249 + .recv = tpm_tis_recv,
1250 + .send = tpm_tis_send,
1251 + .cancel = tpm_tis_ready,
1252 + .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
1253 + .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
1254 + .req_canceled = TPM_STS_COMMAND_READY,
1255 + .attr_group = &tis_attr_grp,
1256 + .miscdev = {
1257 + .fops = &tis_ops,},
1258 +};
1260 +static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
1261 +{
1262 + struct tpm_chip *chip = (struct tpm_chip *) dev_id;
1263 + u32 interrupt;
1265 + interrupt = ioread32(chip->vendor.iobase +
1266 + TPM_INT_STATUS(chip->vendor.locality));
1268 + if (interrupt == 0)
1269 + return IRQ_NONE;
1271 + chip->vendor.irq = irq;
1273 + /* Clear interrupts handled with TPM_EOI */
1274 + iowrite32(interrupt,
1275 + chip->vendor.iobase +
1276 + TPM_INT_STATUS(chip->vendor.locality));
1277 + return IRQ_HANDLED;
1278 +}
1280 +static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
1281 +{
1282 + struct tpm_chip *chip = (struct tpm_chip *) dev_id;
1283 + u32 interrupt;
1284 + int i;
1286 + interrupt = ioread32(chip->vendor.iobase +
1287 + TPM_INT_STATUS(chip->vendor.locality));
1289 + if (interrupt == 0)
1290 + return IRQ_NONE;
1292 + if (interrupt & TPM_INTF_DATA_AVAIL_INT)
1293 + wake_up_interruptible(&chip->vendor.read_queue);
1294 + if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
1295 + for (i = 0; i < 5; i++)
1296 + if (check_locality(chip, i) >= 0)
1297 + break;
1298 + if (interrupt &
1299 + (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
1300 + TPM_INTF_CMD_READY_INT))
1301 + wake_up_interruptible(&chip->vendor.int_queue);
1303 + /* Clear interrupts handled with TPM_EOI */
1304 + iowrite32(interrupt,
1305 + chip->vendor.iobase +
1306 + TPM_INT_STATUS(chip->vendor.locality));
1307 + return IRQ_HANDLED;
1308 +}
1310 +static int interrupts = 1;
1311 +module_param(interrupts, bool, 0444);
1312 +MODULE_PARM_DESC(interrupts, "Enable interrupts");
1314 +static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
1315 + const struct pnp_device_id *pnp_id)
1316 +{
1317 + u32 vendor, intfcaps, intmask;
1318 + int rc, i;
1319 + unsigned long start, len;
1320 + struct tpm_chip *chip;
1322 + start = pnp_mem_start(pnp_dev, 0);
1323 + len = pnp_mem_len(pnp_dev, 0);
1325 + if (!start)
1326 + start = TIS_MEM_BASE;
1327 + if (!len)
1328 + len = TIS_MEM_LEN;
1330 + if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
1331 + return -ENODEV;
1333 + chip->vendor.iobase = ioremap(start, len);
1334 + if (!chip->vendor.iobase) {
1335 + rc = -EIO;
1336 + goto out_err;
1337 + }
1339 + vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
1341 + /* Default timeouts */
1342 + chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
1343 + chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
1344 + chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
1345 + chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
1347 + dev_info(&pnp_dev->dev,
1348 + "1.2 TPM (device-id 0x%X, rev-id %d)\n",
1349 + vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
1351 + /* Figure out the capabilities */
1352 + intfcaps =
1353 + ioread32(chip->vendor.iobase +
1354 + TPM_INTF_CAPS(chip->vendor.locality));
1355 + dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
1356 + intfcaps);
1357 + if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
1358 + dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
1359 + if (intfcaps & TPM_INTF_CMD_READY_INT)
1360 + dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
1361 + if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
1362 + dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
1363 + if (intfcaps & TPM_INTF_INT_EDGE_RISING)
1364 + dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
1365 + if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
1366 + dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
1367 + if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
1368 + dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
1369 + if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
1370 + dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
1371 + if (intfcaps & TPM_INTF_STS_VALID_INT)
1372 + dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
1373 + if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
1374 + dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
1376 + if (request_locality(chip, 0) != 0) {
1377 + rc = -ENODEV;
1378 + goto out_err;
1379 + }
1381 + /* INTERRUPT Setup */
1382 + init_waitqueue_head(&chip->vendor.read_queue);
1383 + init_waitqueue_head(&chip->vendor.int_queue);
1385 + intmask =
1386 + ioread32(chip->vendor.iobase +
1387 + TPM_INT_ENABLE(chip->vendor.locality));
1389 + intmask |= TPM_INTF_CMD_READY_INT
1390 + | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
1391 + | TPM_INTF_STS_VALID_INT;
1393 + iowrite32(intmask,
1394 + chip->vendor.iobase +
1395 + TPM_INT_ENABLE(chip->vendor.locality));
1396 + if (interrupts) {
1397 + chip->vendor.irq =
1398 + ioread8(chip->vendor.iobase +
1399 + TPM_INT_VECTOR(chip->vendor.locality));
1401 + for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
1402 + iowrite8(i, chip->vendor.iobase +
1403 + TPM_INT_VECTOR(chip->vendor.locality));
1404 + if (request_irq
1405 + (i, tis_int_probe, SA_SHIRQ,
1406 + chip->vendor.miscdev.name, chip) != 0) {
1407 + dev_info(chip->dev,
1408 + "Unable to request irq: %d for probe\n",
1409 + i);
1410 + continue;
1411 + }
1413 + /* Clear all existing */
1414 + iowrite32(ioread32
1415 + (chip->vendor.iobase +
1416 + TPM_INT_STATUS(chip->vendor.locality)),
1417 + chip->vendor.iobase +
1418 + TPM_INT_STATUS(chip->vendor.locality));
1420 + /* Turn on */
1421 + iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
1422 + chip->vendor.iobase +
1423 + TPM_INT_ENABLE(chip->vendor.locality));
1425 + /* Generate Interrupts */
1426 + tpm_gen_interrupt(chip);
1428 + /* Turn off */
1429 + iowrite32(intmask,
1430 + chip->vendor.iobase +
1431 + TPM_INT_ENABLE(chip->vendor.locality));
1432 + free_irq(i, chip);
1433 + }
1434 + }
1435 + if (chip->vendor.irq) {
1436 + iowrite8(chip->vendor.irq,
1437 + chip->vendor.iobase +
1438 + TPM_INT_VECTOR(chip->vendor.locality));
1439 + if (request_irq
1440 + (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
1441 + chip->vendor.miscdev.name, chip) != 0) {
1442 + dev_info(chip->dev,
1443 + "Unable to request irq: %d for use\n",
1444 + chip->vendor.irq);
1445 + chip->vendor.irq = 0;
1446 + } else {
1447 + /* Clear all existing */
1448 + iowrite32(ioread32
1449 + (chip->vendor.iobase +
1450 + TPM_INT_STATUS(chip->vendor.locality)),
1451 + chip->vendor.iobase +
1452 + TPM_INT_STATUS(chip->vendor.locality));
1454 + /* Turn on */
1455 + iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
1456 + chip->vendor.iobase +
1457 + TPM_INT_ENABLE(chip->vendor.locality));
1458 + }
1459 + }
1461 + INIT_LIST_HEAD(&chip->vendor.list);
1462 + spin_lock(&tis_lock);
1463 + list_add(&chip->vendor.list, &tis_chips);
1464 + spin_unlock(&tis_lock);
1466 + tpm_get_timeouts(chip);
1467 + tpm_continue_selftest(chip);
1469 + return 0;
1470 +out_err:
1471 + if (chip->vendor.iobase)
1472 + iounmap(chip->vendor.iobase);
1473 + tpm_remove_hardware(chip->dev);
1474 + return rc;
1475 +}
1477 +static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
1478 +{
1479 + return tpm_pm_suspend(&dev->dev, msg);
1480 +}
1482 +static int tpm_tis_pnp_resume(struct pnp_dev *dev)
1483 +{
1484 + return tpm_pm_resume(&dev->dev);
1485 +}
1487 +static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
1488 + {"PNP0C31", 0}, /* TPM */
1489 + {"ATM1200", 0}, /* Atmel */
1490 + {"IFX0102", 0}, /* Infineon */
1491 + {"BCM0101", 0}, /* Broadcom */
1492 + {"NSC1200", 0}, /* National */
1493 + /* Add new here */
1494 + {"", 0}, /* User Specified */
1495 + {"", 0} /* Terminator */
1496 +};
1498 +static struct pnp_driver tis_pnp_driver = {
1499 + .name = "tpm_tis",
1500 + .id_table = tpm_pnp_tbl,
1501 + .probe = tpm_tis_pnp_init,
1502 + .suspend = tpm_tis_pnp_suspend,
1503 + .resume = tpm_tis_pnp_resume,
1504 +};
1506 +#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
1507 +module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
1508 + sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
1509 +MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
1511 +static int __init init_tis(void)
1512 +{
1513 + return pnp_register_driver(&tis_pnp_driver);
1514 +}
1516 +static void __exit cleanup_tis(void)
1517 +{
1518 + struct tpm_vendor_specific *i, *j;
1519 + struct tpm_chip *chip;
1520 + spin_lock(&tis_lock);
1521 + list_for_each_entry_safe(i, j, &tis_chips, list) {
1522 + chip = to_tpm_chip(i);
1523 + iowrite32(~TPM_GLOBAL_INT_ENABLE &
1524 + ioread32(chip->vendor.iobase +
1525 + TPM_INT_ENABLE(chip->vendor.
1526 + locality)),
1527 + chip->vendor.iobase +
1528 + TPM_INT_ENABLE(chip->vendor.locality));
1529 + release_locality(chip, chip->vendor.locality, 1);
1530 + if (chip->vendor.irq)
1531 + free_irq(chip->vendor.irq, chip);
1532 + iounmap(i->iobase);
1533 + list_del(&i->list);
1534 + tpm_remove_hardware(chip->dev);
1535 + }
1536 + spin_unlock(&tis_lock);
1537 + pnp_unregister_driver(&tis_pnp_driver);
1538 +}
1540 +module_init(init_tis);
1541 +module_exit(cleanup_tis);
1542 +MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
1543 +MODULE_DESCRIPTION("TPM Driver");
1544 +MODULE_VERSION("2.0");
1545 +MODULE_LICENSE("GPL");