direct-io.hg

view patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch @ 11522:1fae74cd3963

[POWERPC][XEN] Fix infinite loop caused by hdec storm

This was the cause of the periodic hang on secondary processors that has
been holding back the submission of the SMP patch.

Signed-off-by: Amos Waterland <apw@us.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Thu Sep 14 22:06:15 2006 -0400 (2006-09-14)
parents e3ad9b9c95ee
children
line source
1 diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c ./drivers/char/tpm/tpm_atmel.c
2 --- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c 2006-06-26 18:05:03.000000000 -0400
3 +++ ./drivers/char/tpm/tpm_atmel.c 2006-06-26 18:16:33.000000000 -0400
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 ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h ./drivers/char/tpm/tpm_atmel.h
155 --- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h 2006-06-26 18:05:03.000000000 -0400
156 +++ ./drivers/char/tpm/tpm_atmel.h 2006-06-26 18:16:33.000000000 -0400
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 ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c ./drivers/char/tpm/tpm_bios.c
218 --- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c 2006-06-26 18:05:03.000000000 -0400
219 +++ ./drivers/char/tpm/tpm_bios.c 2006-06-26 18:16:33.000000000 -0400
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 ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c ./drivers/char/tpm/tpm_infineon.c
473 --- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c 2006-06-26 18:05:03.000000000 -0400
474 +++ ./drivers/char/tpm/tpm_infineon.c 2006-06-26 18:16:33.000000000 -0400
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 ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c ./drivers/char/tpm/tpm_nsc.c
688 --- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c 2006-06-26 18:05:03.000000000 -0400
689 +++ ./drivers/char/tpm/tpm_nsc.c 2006-06-26 18:16:33.000000000 -0400
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 ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c ./drivers/char/tpm/tpm_tis.c
878 --- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c 1969-12-31 19:00:00.000000000 -0500
879 +++ ./drivers/char/tpm/tpm_tis.c 2006-06-26 18:16:33.000000000 -0400
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");