diff options
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r-- | drivers/char/tpm/tpm.c | 104 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 11 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_atmel.c | 146 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 179 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_nsc.c | 164 |
5 files changed, 300 insertions, 304 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 049d128ae7f0..303f15880466 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -64,7 +64,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
64 | if (count == 0) | 64 | if (count == 0) |
65 | return -ENODATA; | 65 | return -ENODATA; |
66 | if (count > bufsiz) { | 66 | if (count > bufsiz) { |
67 | dev_err(&chip->pci_dev->dev, | 67 | dev_err(chip->dev, |
68 | "invalid count value %x %zx \n", count, bufsiz); | 68 | "invalid count value %x %zx \n", count, bufsiz); |
69 | return -E2BIG; | 69 | return -E2BIG; |
70 | } | 70 | } |
@@ -72,21 +72,21 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
72 | down(&chip->tpm_mutex); | 72 | down(&chip->tpm_mutex); |
73 | 73 | ||
74 | if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { | 74 | if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { |
75 | dev_err(&chip->pci_dev->dev, | 75 | dev_err(chip->dev, |
76 | "tpm_transmit: tpm_send: error %zd\n", rc); | 76 | "tpm_transmit: tpm_send: error %zd\n", rc); |
77 | goto out; | 77 | goto out; |
78 | } | 78 | } |
79 | 79 | ||
80 | stop = jiffies + 2 * 60 * HZ; | 80 | stop = jiffies + 2 * 60 * HZ; |
81 | do { | 81 | do { |
82 | u8 status = inb(chip->vendor->base + 1); | 82 | u8 status = chip->vendor->status(chip); |
83 | if ((status & chip->vendor->req_complete_mask) == | 83 | if ((status & chip->vendor->req_complete_mask) == |
84 | chip->vendor->req_complete_val) { | 84 | chip->vendor->req_complete_val) { |
85 | goto out_recv; | 85 | goto out_recv; |
86 | } | 86 | } |
87 | 87 | ||
88 | if ((status == chip->vendor->req_canceled)) { | 88 | if ((status == chip->vendor->req_canceled)) { |
89 | dev_err(&chip->pci_dev->dev, "Operation Canceled\n"); | 89 | dev_err(chip->dev, "Operation Canceled\n"); |
90 | rc = -ECANCELED; | 90 | rc = -ECANCELED; |
91 | goto out; | 91 | goto out; |
92 | } | 92 | } |
@@ -97,14 +97,14 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
97 | 97 | ||
98 | 98 | ||
99 | chip->vendor->cancel(chip); | 99 | chip->vendor->cancel(chip); |
100 | dev_err(&chip->pci_dev->dev, "Operation Timed out\n"); | 100 | dev_err(chip->dev, "Operation Timed out\n"); |
101 | rc = -ETIME; | 101 | rc = -ETIME; |
102 | goto out; | 102 | goto out; |
103 | 103 | ||
104 | out_recv: | 104 | out_recv: |
105 | rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); | 105 | rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); |
106 | if (rc < 0) | 106 | if (rc < 0) |
107 | dev_err(&chip->pci_dev->dev, | 107 | dev_err(chip->dev, |
108 | "tpm_transmit: tpm_recv: error %zd\n", rc); | 108 | "tpm_transmit: tpm_recv: error %zd\n", rc); |
109 | out: | 109 | out: |
110 | up(&chip->tpm_mutex); | 110 | up(&chip->tpm_mutex); |
@@ -139,15 +139,14 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | |||
139 | __be32 index; | 139 | __be32 index; |
140 | char *str = buf; | 140 | char *str = buf; |
141 | 141 | ||
142 | struct tpm_chip *chip = | 142 | struct tpm_chip *chip = dev_get_drvdata(dev); |
143 | pci_get_drvdata(to_pci_dev(dev)); | ||
144 | if (chip == NULL) | 143 | if (chip == NULL) |
145 | return -ENODEV; | 144 | return -ENODEV; |
146 | 145 | ||
147 | memcpy(data, cap_pcr, sizeof(cap_pcr)); | 146 | memcpy(data, cap_pcr, sizeof(cap_pcr)); |
148 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 147 | if ((len = tpm_transmit(chip, data, sizeof(data))) |
149 | < CAP_PCR_RESULT_SIZE) { | 148 | < CAP_PCR_RESULT_SIZE) { |
150 | dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred " | 149 | dev_dbg(chip->dev, "A TPM error (%d) occurred " |
151 | "attempting to determine the number of PCRS\n", | 150 | "attempting to determine the number of PCRS\n", |
152 | be32_to_cpu(*((__be32 *) (data + 6)))); | 151 | be32_to_cpu(*((__be32 *) (data + 6)))); |
153 | return 0; | 152 | return 0; |
@@ -161,9 +160,10 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | |||
161 | memcpy(data + 10, &index, 4); | 160 | memcpy(data + 10, &index, 4); |
162 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 161 | if ((len = tpm_transmit(chip, data, sizeof(data))) |
163 | < READ_PCR_RESULT_SIZE){ | 162 | < READ_PCR_RESULT_SIZE){ |
164 | dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred" | 163 | dev_dbg(chip->dev, "A TPM error (%d) occurred" |
165 | " attempting to read PCR %d of %d\n", | 164 | " attempting to read PCR %d of %d\n", |
166 | be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs); | 165 | be32_to_cpu(*((__be32 *) (data + 6))), |
166 | i, num_pcrs); | ||
167 | goto out; | 167 | goto out; |
168 | } | 168 | } |
169 | str += sprintf(str, "PCR-%02d: ", i); | 169 | str += sprintf(str, "PCR-%02d: ", i); |
@@ -191,21 +191,19 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
191 | int i, rc; | 191 | int i, rc; |
192 | char *str = buf; | 192 | char *str = buf; |
193 | 193 | ||
194 | struct tpm_chip *chip = | 194 | struct tpm_chip *chip = dev_get_drvdata(dev); |
195 | pci_get_drvdata(to_pci_dev(dev)); | ||
196 | if (chip == NULL) | 195 | if (chip == NULL) |
197 | return -ENODEV; | 196 | return -ENODEV; |
198 | 197 | ||
199 | data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); | 198 | data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); |
200 | if (!data) | 199 | if (!data) |
201 | return -ENOMEM; | 200 | return -ENOMEM; |
202 | 201 | ||
203 | memcpy(data, readpubek, sizeof(readpubek)); | 202 | memcpy(data, readpubek, sizeof(readpubek)); |
204 | memset(data + sizeof(readpubek), 0, 20); /* zero nonce */ | ||
205 | 203 | ||
206 | if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < | 204 | if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < |
207 | READ_PUBEK_RESULT_SIZE) { | 205 | READ_PUBEK_RESULT_SIZE) { |
208 | dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred " | 206 | dev_dbg(chip->dev, "A TPM error (%d) occurred " |
209 | "attempting to read the PUBEK\n", | 207 | "attempting to read the PUBEK\n", |
210 | be32_to_cpu(*((__be32 *) (data + 6)))); | 208 | be32_to_cpu(*((__be32 *) (data + 6)))); |
211 | rc = 0; | 209 | rc = 0; |
@@ -245,7 +243,6 @@ out: | |||
245 | kfree(data); | 243 | kfree(data); |
246 | return rc; | 244 | return rc; |
247 | } | 245 | } |
248 | |||
249 | EXPORT_SYMBOL_GPL(tpm_show_pubek); | 246 | EXPORT_SYMBOL_GPL(tpm_show_pubek); |
250 | 247 | ||
251 | #define CAP_VER_RESULT_SIZE 18 | 248 | #define CAP_VER_RESULT_SIZE 18 |
@@ -274,8 +271,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, | |||
274 | ssize_t len; | 271 | ssize_t len; |
275 | char *str = buf; | 272 | char *str = buf; |
276 | 273 | ||
277 | struct tpm_chip *chip = | 274 | struct tpm_chip *chip = dev_get_drvdata(dev); |
278 | pci_get_drvdata(to_pci_dev(dev)); | ||
279 | if (chip == NULL) | 275 | if (chip == NULL) |
280 | return -ENODEV; | 276 | return -ENODEV; |
281 | 277 | ||
@@ -315,7 +311,6 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | |||
315 | } | 311 | } |
316 | EXPORT_SYMBOL_GPL(tpm_store_cancel); | 312 | EXPORT_SYMBOL_GPL(tpm_store_cancel); |
317 | 313 | ||
318 | |||
319 | /* | 314 | /* |
320 | * Device file system interface to the TPM | 315 | * Device file system interface to the TPM |
321 | */ | 316 | */ |
@@ -339,21 +334,20 @@ int tpm_open(struct inode *inode, struct file *file) | |||
339 | } | 334 | } |
340 | 335 | ||
341 | if (chip->num_opens) { | 336 | if (chip->num_opens) { |
342 | dev_dbg(&chip->pci_dev->dev, | 337 | dev_dbg(chip->dev, "Another process owns this TPM\n"); |
343 | "Another process owns this TPM\n"); | ||
344 | rc = -EBUSY; | 338 | rc = -EBUSY; |
345 | goto err_out; | 339 | goto err_out; |
346 | } | 340 | } |
347 | 341 | ||
348 | chip->num_opens++; | 342 | chip->num_opens++; |
349 | pci_dev_get(chip->pci_dev); | 343 | get_device(chip->dev); |
350 | 344 | ||
351 | spin_unlock(&driver_lock); | 345 | spin_unlock(&driver_lock); |
352 | 346 | ||
353 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); | 347 | chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); |
354 | if (chip->data_buffer == NULL) { | 348 | if (chip->data_buffer == NULL) { |
355 | chip->num_opens--; | 349 | chip->num_opens--; |
356 | pci_dev_put(chip->pci_dev); | 350 | put_device(chip->dev); |
357 | return -ENOMEM; | 351 | return -ENOMEM; |
358 | } | 352 | } |
359 | 353 | ||
@@ -366,7 +360,6 @@ err_out: | |||
366 | spin_unlock(&driver_lock); | 360 | spin_unlock(&driver_lock); |
367 | return rc; | 361 | return rc; |
368 | } | 362 | } |
369 | |||
370 | EXPORT_SYMBOL_GPL(tpm_open); | 363 | EXPORT_SYMBOL_GPL(tpm_open); |
371 | 364 | ||
372 | int tpm_release(struct inode *inode, struct file *file) | 365 | int tpm_release(struct inode *inode, struct file *file) |
@@ -378,15 +371,14 @@ int tpm_release(struct inode *inode, struct file *file) | |||
378 | chip->num_opens--; | 371 | chip->num_opens--; |
379 | del_singleshot_timer_sync(&chip->user_read_timer); | 372 | del_singleshot_timer_sync(&chip->user_read_timer); |
380 | atomic_set(&chip->data_pending, 0); | 373 | atomic_set(&chip->data_pending, 0); |
381 | pci_dev_put(chip->pci_dev); | 374 | put_device(chip->dev); |
382 | kfree(chip->data_buffer); | 375 | kfree(chip->data_buffer); |
383 | spin_unlock(&driver_lock); | 376 | spin_unlock(&driver_lock); |
384 | return 0; | 377 | return 0; |
385 | } | 378 | } |
386 | |||
387 | EXPORT_SYMBOL_GPL(tpm_release); | 379 | EXPORT_SYMBOL_GPL(tpm_release); |
388 | 380 | ||
389 | ssize_t tpm_write(struct file * file, const char __user * buf, | 381 | ssize_t tpm_write(struct file *file, const char __user *buf, |
390 | size_t size, loff_t * off) | 382 | size_t size, loff_t * off) |
391 | { | 383 | { |
392 | struct tpm_chip *chip = file->private_data; | 384 | struct tpm_chip *chip = file->private_data; |
@@ -422,7 +414,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf, | |||
422 | 414 | ||
423 | EXPORT_SYMBOL_GPL(tpm_write); | 415 | EXPORT_SYMBOL_GPL(tpm_write); |
424 | 416 | ||
425 | ssize_t tpm_read(struct file * file, char __user * buf, | 417 | ssize_t tpm_read(struct file * file, char __user *buf, |
426 | size_t size, loff_t * off) | 418 | size_t size, loff_t * off) |
427 | { | 419 | { |
428 | struct tpm_chip *chip = file->private_data; | 420 | struct tpm_chip *chip = file->private_data; |
@@ -444,15 +436,14 @@ ssize_t tpm_read(struct file * file, char __user * buf, | |||
444 | 436 | ||
445 | return ret_size; | 437 | return ret_size; |
446 | } | 438 | } |
447 | |||
448 | EXPORT_SYMBOL_GPL(tpm_read); | 439 | EXPORT_SYMBOL_GPL(tpm_read); |
449 | 440 | ||
450 | void __devexit tpm_remove(struct pci_dev *pci_dev) | 441 | void tpm_remove_hardware(struct device *dev) |
451 | { | 442 | { |
452 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 443 | struct tpm_chip *chip = dev_get_drvdata(dev); |
453 | 444 | ||
454 | if (chip == NULL) { | 445 | if (chip == NULL) { |
455 | dev_err(&pci_dev->dev, "No device data found\n"); | 446 | dev_err(dev, "No device data found\n"); |
456 | return; | 447 | return; |
457 | } | 448 | } |
458 | 449 | ||
@@ -462,22 +453,20 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) | |||
462 | 453 | ||
463 | spin_unlock(&driver_lock); | 454 | spin_unlock(&driver_lock); |
464 | 455 | ||
465 | pci_set_drvdata(pci_dev, NULL); | 456 | dev_set_drvdata(dev, NULL); |
466 | misc_deregister(&chip->vendor->miscdev); | 457 | misc_deregister(&chip->vendor->miscdev); |
467 | kfree(chip->vendor->miscdev.name); | 458 | kfree(chip->vendor->miscdev.name); |
468 | 459 | ||
469 | sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); | 460 | sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); |
470 | 461 | ||
471 | pci_disable_device(pci_dev); | 462 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= |
472 | 463 | !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); | |
473 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); | ||
474 | 464 | ||
475 | kfree(chip); | 465 | kfree(chip); |
476 | 466 | ||
477 | pci_dev_put(pci_dev); | 467 | put_device(dev); |
478 | } | 468 | } |
479 | 469 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); | |
480 | EXPORT_SYMBOL_GPL(tpm_remove); | ||
481 | 470 | ||
482 | static u8 savestate[] = { | 471 | static u8 savestate[] = { |
483 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 472 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
@@ -489,32 +478,30 @@ static u8 savestate[] = { | |||
489 | * We are about to suspend. Save the TPM state | 478 | * We are about to suspend. Save the TPM state |
490 | * so that it can be restored. | 479 | * so that it can be restored. |
491 | */ | 480 | */ |
492 | int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state) | 481 | int tpm_pm_suspend(struct device *dev, pm_message_t pm_state) |
493 | { | 482 | { |
494 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 483 | struct tpm_chip *chip = dev_get_drvdata(dev); |
495 | if (chip == NULL) | 484 | if (chip == NULL) |
496 | return -ENODEV; | 485 | return -ENODEV; |
497 | 486 | ||
498 | tpm_transmit(chip, savestate, sizeof(savestate)); | 487 | tpm_transmit(chip, savestate, sizeof(savestate)); |
499 | return 0; | 488 | return 0; |
500 | } | 489 | } |
501 | |||
502 | EXPORT_SYMBOL_GPL(tpm_pm_suspend); | 490 | EXPORT_SYMBOL_GPL(tpm_pm_suspend); |
503 | 491 | ||
504 | /* | 492 | /* |
505 | * Resume from a power safe. The BIOS already restored | 493 | * Resume from a power safe. The BIOS already restored |
506 | * the TPM state. | 494 | * the TPM state. |
507 | */ | 495 | */ |
508 | int tpm_pm_resume(struct pci_dev *pci_dev) | 496 | int tpm_pm_resume(struct device *dev) |
509 | { | 497 | { |
510 | struct tpm_chip *chip = pci_get_drvdata(pci_dev); | 498 | struct tpm_chip *chip = dev_get_drvdata(dev); |
511 | 499 | ||
512 | if (chip == NULL) | 500 | if (chip == NULL) |
513 | return -ENODEV; | 501 | return -ENODEV; |
514 | 502 | ||
515 | return 0; | 503 | return 0; |
516 | } | 504 | } |
517 | |||
518 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 505 | EXPORT_SYMBOL_GPL(tpm_pm_resume); |
519 | 506 | ||
520 | /* | 507 | /* |
@@ -524,8 +511,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume); | |||
524 | * upon errant exit from this function specific probe function should call | 511 | * upon errant exit from this function specific probe function should call |
525 | * pci_disable_device | 512 | * pci_disable_device |
526 | */ | 513 | */ |
527 | int tpm_register_hardware(struct pci_dev *pci_dev, | 514 | int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) |
528 | struct tpm_vendor_specific *entry) | ||
529 | { | 515 | { |
530 | #define DEVNAME_SIZE 7 | 516 | #define DEVNAME_SIZE 7 |
531 | 517 | ||
@@ -534,12 +520,10 @@ int tpm_register_hardware(struct pci_dev *pci_dev, | |||
534 | int i, j; | 520 | int i, j; |
535 | 521 | ||
536 | /* Driver specific per-device data */ | 522 | /* Driver specific per-device data */ |
537 | chip = kmalloc(sizeof(*chip), GFP_KERNEL); | 523 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
538 | if (chip == NULL) | 524 | if (chip == NULL) |
539 | return -ENOMEM; | 525 | return -ENOMEM; |
540 | 526 | ||
541 | memset(chip, 0, sizeof(struct tpm_chip)); | ||
542 | |||
543 | init_MUTEX(&chip->buffer_mutex); | 527 | init_MUTEX(&chip->buffer_mutex); |
544 | init_MUTEX(&chip->tpm_mutex); | 528 | init_MUTEX(&chip->tpm_mutex); |
545 | INIT_LIST_HEAD(&chip->list); | 529 | INIT_LIST_HEAD(&chip->list); |
@@ -563,8 +547,7 @@ int tpm_register_hardware(struct pci_dev *pci_dev, | |||
563 | 547 | ||
564 | dev_num_search_complete: | 548 | dev_num_search_complete: |
565 | if (chip->dev_num < 0) { | 549 | if (chip->dev_num < 0) { |
566 | dev_err(&pci_dev->dev, | 550 | dev_err(dev, "No available tpm device numbers\n"); |
567 | "No available tpm device numbers\n"); | ||
568 | kfree(chip); | 551 | kfree(chip); |
569 | return -ENODEV; | 552 | return -ENODEV; |
570 | } else if (chip->dev_num == 0) | 553 | } else if (chip->dev_num == 0) |
@@ -576,15 +559,15 @@ dev_num_search_complete: | |||
576 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 559 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); |
577 | chip->vendor->miscdev.name = devname; | 560 | chip->vendor->miscdev.name = devname; |
578 | 561 | ||
579 | chip->vendor->miscdev.dev = &(pci_dev->dev); | 562 | chip->vendor->miscdev.dev = dev; |
580 | chip->pci_dev = pci_dev_get(pci_dev); | 563 | chip->dev = get_device(dev); |
581 | 564 | ||
582 | if (misc_register(&chip->vendor->miscdev)) { | 565 | if (misc_register(&chip->vendor->miscdev)) { |
583 | dev_err(&chip->pci_dev->dev, | 566 | dev_err(chip->dev, |
584 | "unable to misc_register %s, minor %d\n", | 567 | "unable to misc_register %s, minor %d\n", |
585 | chip->vendor->miscdev.name, | 568 | chip->vendor->miscdev.name, |
586 | chip->vendor->miscdev.minor); | 569 | chip->vendor->miscdev.minor); |
587 | pci_dev_put(pci_dev); | 570 | put_device(dev); |
588 | kfree(chip); | 571 | kfree(chip); |
589 | dev_mask[i] &= !(1 << j); | 572 | dev_mask[i] &= !(1 << j); |
590 | return -ENODEV; | 573 | return -ENODEV; |
@@ -592,17 +575,16 @@ dev_num_search_complete: | |||
592 | 575 | ||
593 | spin_lock(&driver_lock); | 576 | spin_lock(&driver_lock); |
594 | 577 | ||
595 | pci_set_drvdata(pci_dev, chip); | 578 | dev_set_drvdata(dev, chip); |
596 | 579 | ||
597 | list_add(&chip->list, &tpm_chip_list); | 580 | list_add(&chip->list, &tpm_chip_list); |
598 | 581 | ||
599 | spin_unlock(&driver_lock); | 582 | spin_unlock(&driver_lock); |
600 | 583 | ||
601 | sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group); | 584 | sysfs_create_group(&dev->kobj, chip->vendor->attr_group); |
602 | 585 | ||
603 | return 0; | 586 | return 0; |
604 | } | 587 | } |
605 | |||
606 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | 588 | EXPORT_SYMBOL_GPL(tpm_register_hardware); |
607 | 589 | ||
608 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); | 590 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 373b41f6b460..024814b50c3c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -55,12 +55,13 @@ struct tpm_vendor_specific { | |||
55 | int (*recv) (struct tpm_chip *, u8 *, size_t); | 55 | int (*recv) (struct tpm_chip *, u8 *, size_t); |
56 | int (*send) (struct tpm_chip *, u8 *, size_t); | 56 | int (*send) (struct tpm_chip *, u8 *, size_t); |
57 | void (*cancel) (struct tpm_chip *); | 57 | void (*cancel) (struct tpm_chip *); |
58 | u8 (*status) (struct tpm_chip *); | ||
58 | struct miscdevice miscdev; | 59 | struct miscdevice miscdev; |
59 | struct attribute_group *attr_group; | 60 | struct attribute_group *attr_group; |
60 | }; | 61 | }; |
61 | 62 | ||
62 | struct tpm_chip { | 63 | struct tpm_chip { |
63 | struct pci_dev *pci_dev; /* PCI device stuff */ | 64 | struct device *dev; /* Device stuff */ |
64 | 65 | ||
65 | int dev_num; /* /dev/tpm# */ | 66 | int dev_num; /* /dev/tpm# */ |
66 | int num_opens; /* only one allowed */ | 67 | int num_opens; /* only one allowed */ |
@@ -91,13 +92,13 @@ static inline void tpm_write_index(int base, int index, int value) | |||
91 | outb(value & 0xFF, base+1); | 92 | outb(value & 0xFF, base+1); |
92 | } | 93 | } |
93 | 94 | ||
94 | extern int tpm_register_hardware(struct pci_dev *, | 95 | extern int tpm_register_hardware(struct device *, |
95 | struct tpm_vendor_specific *); | 96 | struct tpm_vendor_specific *); |
96 | extern int tpm_open(struct inode *, struct file *); | 97 | extern int tpm_open(struct inode *, struct file *); |
97 | extern int tpm_release(struct inode *, struct file *); | 98 | extern int tpm_release(struct inode *, struct file *); |
98 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | 99 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, |
99 | loff_t *); | 100 | loff_t *); |
100 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); | 101 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); |
101 | extern void __devexit tpm_remove(struct pci_dev *); | 102 | extern void tpm_remove_hardware(struct device *); |
102 | extern int tpm_pm_suspend(struct pci_dev *, pm_message_t); | 103 | extern int tpm_pm_suspend(struct device *, pm_message_t); |
103 | extern int tpm_pm_resume(struct pci_dev *); | 104 | extern int tpm_pm_resume(struct device *); |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index c0d64914595f..8cb42e84723c 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -40,7 +40,7 @@ enum tpm_atmel_read_status { | |||
40 | ATML_STATUS_READY = 0x08 | 40 | ATML_STATUS_READY = 0x08 |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | 43 | static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) |
44 | { | 44 | { |
45 | u8 status, *hdr = buf; | 45 | u8 status, *hdr = buf; |
46 | u32 size; | 46 | u32 size; |
@@ -54,7 +54,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
54 | for (i = 0; i < 6; i++) { | 54 | for (i = 0; i < 6; i++) { |
55 | status = inb(chip->vendor->base + 1); | 55 | status = inb(chip->vendor->base + 1); |
56 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 56 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
57 | dev_err(&chip->pci_dev->dev, | 57 | dev_err(chip->dev, |
58 | "error reading header\n"); | 58 | "error reading header\n"); |
59 | return -EIO; | 59 | return -EIO; |
60 | } | 60 | } |
@@ -66,12 +66,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
66 | size = be32_to_cpu(*native_size); | 66 | size = be32_to_cpu(*native_size); |
67 | 67 | ||
68 | if (count < size) { | 68 | if (count < size) { |
69 | dev_err(&chip->pci_dev->dev, | 69 | dev_err(chip->dev, |
70 | "Recv size(%d) less than available space\n", size); | 70 | "Recv size(%d) less than available space\n", size); |
71 | for (; i < size; i++) { /* clear the waiting data anyway */ | 71 | for (; i < size; i++) { /* clear the waiting data anyway */ |
72 | status = inb(chip->vendor->base + 1); | 72 | status = inb(chip->vendor->base + 1); |
73 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 73 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
74 | dev_err(&chip->pci_dev->dev, | 74 | dev_err(chip->dev, |
75 | "error reading data\n"); | 75 | "error reading data\n"); |
76 | return -EIO; | 76 | return -EIO; |
77 | } | 77 | } |
@@ -83,7 +83,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
83 | for (; i < size; i++) { | 83 | for (; i < size; i++) { |
84 | status = inb(chip->vendor->base + 1); | 84 | status = inb(chip->vendor->base + 1); |
85 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 85 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
86 | dev_err(&chip->pci_dev->dev, | 86 | dev_err(chip->dev, |
87 | "error reading data\n"); | 87 | "error reading data\n"); |
88 | return -EIO; | 88 | return -EIO; |
89 | } | 89 | } |
@@ -93,20 +93,20 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
93 | /* make sure data available is gone */ | 93 | /* make sure data available is gone */ |
94 | status = inb(chip->vendor->base + 1); | 94 | status = inb(chip->vendor->base + 1); |
95 | if (status & ATML_STATUS_DATA_AVAIL) { | 95 | if (status & ATML_STATUS_DATA_AVAIL) { |
96 | dev_err(&chip->pci_dev->dev, "data available is stuck\n"); | 96 | dev_err(chip->dev, "data available is stuck\n"); |
97 | return -EIO; | 97 | return -EIO; |
98 | } | 98 | } |
99 | 99 | ||
100 | return size; | 100 | return size; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count) | 103 | static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) |
104 | { | 104 | { |
105 | int i; | 105 | int i; |
106 | 106 | ||
107 | dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: "); | 107 | dev_dbg(chip->dev, "tpm_atml_send:\n"); |
108 | for (i = 0; i < count; i++) { | 108 | for (i = 0; i < count; i++) { |
109 | dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]); | 109 | dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); |
110 | outb(buf[i], chip->vendor->base); | 110 | outb(buf[i], chip->vendor->base); |
111 | } | 111 | } |
112 | 112 | ||
@@ -118,6 +118,11 @@ static void tpm_atml_cancel(struct tpm_chip *chip) | |||
118 | outb(ATML_STATUS_ABORT, chip->vendor->base + 1); | 118 | outb(ATML_STATUS_ABORT, chip->vendor->base + 1); |
119 | } | 119 | } |
120 | 120 | ||
121 | static u8 tpm_atml_status(struct tpm_chip *chip) | ||
122 | { | ||
123 | return inb(chip->vendor->base + 1); | ||
124 | } | ||
125 | |||
121 | static struct file_operations atmel_ops = { | 126 | static struct file_operations atmel_ops = { |
122 | .owner = THIS_MODULE, | 127 | .owner = THIS_MODULE, |
123 | .llseek = no_llseek, | 128 | .llseek = no_llseek, |
@@ -137,7 +142,7 @@ static struct attribute* atmel_attrs[] = { | |||
137 | &dev_attr_pcrs.attr, | 142 | &dev_attr_pcrs.attr, |
138 | &dev_attr_caps.attr, | 143 | &dev_attr_caps.attr, |
139 | &dev_attr_cancel.attr, | 144 | &dev_attr_cancel.attr, |
140 | 0, | 145 | NULL, |
141 | }; | 146 | }; |
142 | 147 | ||
143 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; | 148 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; |
@@ -146,6 +151,7 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
146 | .recv = tpm_atml_recv, | 151 | .recv = tpm_atml_recv, |
147 | .send = tpm_atml_send, | 152 | .send = tpm_atml_send, |
148 | .cancel = tpm_atml_cancel, | 153 | .cancel = tpm_atml_cancel, |
154 | .status = tpm_atml_status, | ||
149 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, | 155 | .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, |
150 | .req_complete_val = ATML_STATUS_DATA_AVAIL, | 156 | .req_complete_val = ATML_STATUS_DATA_AVAIL, |
151 | .req_canceled = ATML_STATUS_READY, | 157 | .req_canceled = ATML_STATUS_READY, |
@@ -153,86 +159,94 @@ static struct tpm_vendor_specific tpm_atmel = { | |||
153 | .miscdev = { .fops = &atmel_ops, }, | 159 | .miscdev = { .fops = &atmel_ops, }, |
154 | }; | 160 | }; |
155 | 161 | ||
156 | static int __devinit tpm_atml_init(struct pci_dev *pci_dev, | 162 | static struct platform_device *pdev; |
157 | const struct pci_device_id *pci_id) | 163 | |
164 | static void __devexit tpm_atml_remove(struct device *dev) | ||
165 | { | ||
166 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
167 | if (chip) { | ||
168 | release_region(chip->vendor->base, 2); | ||
169 | tpm_remove_hardware(chip->dev); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static struct device_driver atml_drv = { | ||
174 | .name = "tpm_atmel", | ||
175 | .bus = &platform_bus_type, | ||
176 | .owner = THIS_MODULE, | ||
177 | .suspend = tpm_pm_suspend, | ||
178 | .resume = tpm_pm_resume, | ||
179 | }; | ||
180 | |||
181 | static int __init init_atmel(void) | ||
158 | { | 182 | { |
159 | u8 version[4]; | ||
160 | int rc = 0; | 183 | int rc = 0; |
161 | int lo, hi; | 184 | int lo, hi; |
162 | 185 | ||
163 | if (pci_enable_device(pci_dev)) | 186 | driver_register(&atml_drv); |
164 | return -EIO; | ||
165 | 187 | ||
166 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); | 188 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); |
167 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); | 189 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); |
168 | 190 | ||
169 | tpm_atmel.base = (hi<<8)|lo; | 191 | tpm_atmel.base = (hi<<8)|lo; |
170 | dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); | ||
171 | 192 | ||
172 | /* verify that it is an Atmel part */ | 193 | /* verify that it is an Atmel part */ |
173 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' | 194 | if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T' |
174 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { | 195 | || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') { |
175 | rc = -ENODEV; | 196 | return -ENODEV; |
176 | goto out_err; | ||
177 | } | 197 | } |
178 | 198 | ||
179 | /* query chip for its version number */ | 199 | /* verify chip version number is 1.1 */ |
180 | if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) { | 200 | if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) || |
181 | version[1] = tpm_read_index(TPM_ADDR, 0x01); | 201 | (tpm_read_index(TPM_ADDR, 0x01) != 0x01 )) |
182 | version[2] = tpm_read_index(TPM_ADDR, 0x02); | 202 | return -ENODEV; |
183 | version[3] = tpm_read_index(TPM_ADDR, 0x03); | 203 | |
184 | } else { | 204 | pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); |
185 | dev_info(&pci_dev->dev, "version query failed\n"); | 205 | if ( !pdev ) |
186 | rc = -ENODEV; | 206 | return -ENOMEM; |
187 | goto out_err; | 207 | |
208 | pdev->name = "tpm_atmel0"; | ||
209 | pdev->id = -1; | ||
210 | pdev->num_resources = 0; | ||
211 | pdev->dev.release = tpm_atml_remove; | ||
212 | pdev->dev.driver = &atml_drv; | ||
213 | |||
214 | if ((rc = platform_device_register(pdev)) < 0) { | ||
215 | kfree(pdev); | ||
216 | pdev = NULL; | ||
217 | return rc; | ||
188 | } | 218 | } |
189 | 219 | ||
190 | if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0) | 220 | if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) { |
191 | goto out_err; | 221 | platform_device_unregister(pdev); |
222 | kfree(pdev); | ||
223 | pdev = NULL; | ||
224 | return -EBUSY; | ||
225 | } | ||
192 | 226 | ||
193 | dev_info(&pci_dev->dev, | 227 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) { |
194 | "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1], | 228 | release_region(tpm_atmel.base, 2); |
195 | version[2], version[3]); | 229 | platform_device_unregister(pdev); |
230 | kfree(pdev); | ||
231 | pdev = NULL; | ||
232 | return rc; | ||
233 | } | ||
196 | 234 | ||
235 | dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n", | ||
236 | tpm_atmel.base); | ||
197 | return 0; | 237 | return 0; |
198 | out_err: | ||
199 | pci_disable_device(pci_dev); | ||
200 | return rc; | ||
201 | } | ||
202 | |||
203 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | ||
204 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | ||
205 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | ||
206 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
207 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
208 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
209 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
210 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
211 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
212 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | ||
213 | {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)}, | ||
214 | {0,} | ||
215 | }; | ||
216 | |||
217 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | ||
218 | |||
219 | static struct pci_driver atmel_pci_driver = { | ||
220 | .name = "tpm_atmel", | ||
221 | .id_table = tpm_pci_tbl, | ||
222 | .probe = tpm_atml_init, | ||
223 | .remove = __devexit_p(tpm_remove), | ||
224 | .suspend = tpm_pm_suspend, | ||
225 | .resume = tpm_pm_resume, | ||
226 | }; | ||
227 | |||
228 | static int __init init_atmel(void) | ||
229 | { | ||
230 | return pci_register_driver(&atmel_pci_driver); | ||
231 | } | 238 | } |
232 | 239 | ||
233 | static void __exit cleanup_atmel(void) | 240 | static void __exit cleanup_atmel(void) |
234 | { | 241 | { |
235 | pci_unregister_driver(&atmel_pci_driver); | 242 | if (pdev) { |
243 | tpm_atml_remove(&pdev->dev); | ||
244 | platform_device_unregister(pdev); | ||
245 | kfree(pdev); | ||
246 | pdev = NULL; | ||
247 | } | ||
248 | |||
249 | driver_unregister(&atml_drv); | ||
236 | } | 250 | } |
237 | 251 | ||
238 | module_init(init_atmel); | 252 | module_init(init_atmel); |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 939e51e119e6..8198dbb7370f 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Specifications at www.trustedcomputinggroup.org | 5 | * Specifications at www.trustedcomputinggroup.org |
6 | * | 6 | * |
7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> | 7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> |
8 | * Sirrix AG - security technologies, http://www.sirrix.com and | ||
8 | * Applied Data Security Group, Ruhr-University Bochum, Germany | 9 | * Applied Data Security Group, Ruhr-University Bochum, Germany |
9 | * Project-Homepage: http://www.prosec.rub.de/tpm | 10 | * Project-Homepage: http://www.prosec.rub.de/tpm |
10 | * | 11 | * |
@@ -29,9 +30,10 @@ | |||
29 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 | 30 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
30 | 31 | ||
31 | /* These values will be filled after PnP-call */ | 32 | /* These values will be filled after PnP-call */ |
32 | static int TPM_INF_DATA = 0; | 33 | static int TPM_INF_DATA; |
33 | static int TPM_INF_ADDR = 0; | 34 | static int TPM_INF_ADDR; |
34 | static int pnp_registered = 0; | 35 | static int TPM_INF_BASE; |
36 | static int TPM_INF_PORT_LEN; | ||
35 | 37 | ||
36 | /* TPM header definitions */ | 38 | /* TPM header definitions */ |
37 | enum infineon_tpm_header { | 39 | enum infineon_tpm_header { |
@@ -143,11 +145,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
143 | } | 145 | } |
144 | if (i == TPM_MAX_TRIES) { /* timeout occurs */ | 146 | if (i == TPM_MAX_TRIES) { /* timeout occurs */ |
145 | if (wait_for_bit == STAT_XFE) | 147 | if (wait_for_bit == STAT_XFE) |
146 | dev_err(&chip->pci_dev->dev, | 148 | dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n"); |
147 | "Timeout in wait(STAT_XFE)\n"); | ||
148 | if (wait_for_bit == STAT_RDA) | 149 | if (wait_for_bit == STAT_RDA) |
149 | dev_err(&chip->pci_dev->dev, | 150 | dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n"); |
150 | "Timeout in wait(STAT_RDA)\n"); | ||
151 | return -EIO; | 151 | return -EIO; |
152 | } | 152 | } |
153 | return 0; | 153 | return 0; |
@@ -170,7 +170,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) | |||
170 | static void tpm_wtx(struct tpm_chip *chip) | 170 | static void tpm_wtx(struct tpm_chip *chip) |
171 | { | 171 | { |
172 | number_of_wtx++; | 172 | number_of_wtx++; |
173 | dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n", | 173 | dev_info(chip->dev, "Granting WTX (%02d / %02d)\n", |
174 | number_of_wtx, TPM_MAX_WTX_PACKAGES); | 174 | number_of_wtx, TPM_MAX_WTX_PACKAGES); |
175 | wait_and_send(chip, TPM_VL_VER); | 175 | wait_and_send(chip, TPM_VL_VER); |
176 | wait_and_send(chip, TPM_CTRL_WTX); | 176 | wait_and_send(chip, TPM_CTRL_WTX); |
@@ -181,7 +181,7 @@ static void tpm_wtx(struct tpm_chip *chip) | |||
181 | 181 | ||
182 | static void tpm_wtx_abort(struct tpm_chip *chip) | 182 | static void tpm_wtx_abort(struct tpm_chip *chip) |
183 | { | 183 | { |
184 | dev_info(&chip->pci_dev->dev, "Aborting WTX\n"); | 184 | dev_info(chip->dev, "Aborting WTX\n"); |
185 | wait_and_send(chip, TPM_VL_VER); | 185 | wait_and_send(chip, TPM_VL_VER); |
186 | wait_and_send(chip, TPM_CTRL_WTX_ABORT); | 186 | wait_and_send(chip, TPM_CTRL_WTX_ABORT); |
187 | wait_and_send(chip, 0x00); | 187 | wait_and_send(chip, 0x00); |
@@ -206,7 +206,7 @@ recv_begin: | |||
206 | } | 206 | } |
207 | 207 | ||
208 | if (buf[0] != TPM_VL_VER) { | 208 | if (buf[0] != TPM_VL_VER) { |
209 | dev_err(&chip->pci_dev->dev, | 209 | dev_err(chip->dev, |
210 | "Wrong transport protocol implementation!\n"); | 210 | "Wrong transport protocol implementation!\n"); |
211 | return -EIO; | 211 | return -EIO; |
212 | } | 212 | } |
@@ -221,8 +221,7 @@ recv_begin: | |||
221 | } | 221 | } |
222 | 222 | ||
223 | if ((size == 0x6D00) && (buf[1] == 0x80)) { | 223 | if ((size == 0x6D00) && (buf[1] == 0x80)) { |
224 | dev_err(&chip->pci_dev->dev, | 224 | dev_err(chip->dev, "Error handling on vendor layer!\n"); |
225 | "Error handling on vendor layer!\n"); | ||
226 | return -EIO; | 225 | return -EIO; |
227 | } | 226 | } |
228 | 227 | ||
@@ -234,7 +233,7 @@ recv_begin: | |||
234 | } | 233 | } |
235 | 234 | ||
236 | if (buf[1] == TPM_CTRL_WTX) { | 235 | if (buf[1] == TPM_CTRL_WTX) { |
237 | dev_info(&chip->pci_dev->dev, "WTX-package received\n"); | 236 | dev_info(chip->dev, "WTX-package received\n"); |
238 | if (number_of_wtx < TPM_MAX_WTX_PACKAGES) { | 237 | if (number_of_wtx < TPM_MAX_WTX_PACKAGES) { |
239 | tpm_wtx(chip); | 238 | tpm_wtx(chip); |
240 | goto recv_begin; | 239 | goto recv_begin; |
@@ -245,14 +244,14 @@ recv_begin: | |||
245 | } | 244 | } |
246 | 245 | ||
247 | if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) { | 246 | if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) { |
248 | dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n"); | 247 | dev_info(chip->dev, "WTX-abort acknowledged\n"); |
249 | return size; | 248 | return size; |
250 | } | 249 | } |
251 | 250 | ||
252 | if (buf[1] == TPM_CTRL_ERROR) { | 251 | if (buf[1] == TPM_CTRL_ERROR) { |
253 | dev_err(&chip->pci_dev->dev, "ERROR-package received:\n"); | 252 | dev_err(chip->dev, "ERROR-package received:\n"); |
254 | if (buf[4] == TPM_INF_NAK) | 253 | if (buf[4] == TPM_INF_NAK) |
255 | dev_err(&chip->pci_dev->dev, | 254 | dev_err(chip->dev, |
256 | "-> Negative acknowledgement" | 255 | "-> Negative acknowledgement" |
257 | " - retransmit command!\n"); | 256 | " - retransmit command!\n"); |
258 | return -EIO; | 257 | return -EIO; |
@@ -271,7 +270,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
271 | 270 | ||
272 | ret = empty_fifo(chip, 1); | 271 | ret = empty_fifo(chip, 1); |
273 | if (ret) { | 272 | if (ret) { |
274 | dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n"); | 273 | dev_err(chip->dev, "Timeout while clearing FIFO\n"); |
275 | return -EIO; | 274 | return -EIO; |
276 | } | 275 | } |
277 | 276 | ||
@@ -316,6 +315,11 @@ static void tpm_inf_cancel(struct tpm_chip *chip) | |||
316 | */ | 315 | */ |
317 | } | 316 | } |
318 | 317 | ||
318 | static u8 tpm_inf_status(struct tpm_chip *chip) | ||
319 | { | ||
320 | return inb(chip->vendor->base + STAT); | ||
321 | } | ||
322 | |||
319 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 323 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); |
320 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | 324 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); |
321 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); | 325 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL); |
@@ -344,6 +348,7 @@ static struct tpm_vendor_specific tpm_inf = { | |||
344 | .recv = tpm_inf_recv, | 348 | .recv = tpm_inf_recv, |
345 | .send = tpm_inf_send, | 349 | .send = tpm_inf_send, |
346 | .cancel = tpm_inf_cancel, | 350 | .cancel = tpm_inf_cancel, |
351 | .status = tpm_inf_status, | ||
347 | .req_complete_mask = 0, | 352 | .req_complete_mask = 0, |
348 | .req_complete_val = 0, | 353 | .req_complete_val = 0, |
349 | .attr_group = &inf_attr_grp, | 354 | .attr_group = &inf_attr_grp, |
@@ -356,30 +361,11 @@ static const struct pnp_device_id tpm_pnp_tbl[] = { | |||
356 | {"IFX0102", 0}, | 361 | {"IFX0102", 0}, |
357 | {"", 0} | 362 | {"", 0} |
358 | }; | 363 | }; |
364 | |||
359 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | 365 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); |
360 | 366 | ||
361 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | 367 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, |
362 | const struct pnp_device_id *dev_id) | 368 | const struct pnp_device_id *dev_id) |
363 | { | ||
364 | if (pnp_port_valid(dev, 0)) { | ||
365 | TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff); | ||
366 | TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff); | ||
367 | tpm_inf.base = pnp_port_start(dev, 1); | ||
368 | dev_info(&dev->dev, "Found %s with ID %s\n", | ||
369 | dev->name, dev_id->id); | ||
370 | return 0; | ||
371 | } | ||
372 | return -ENODEV; | ||
373 | } | ||
374 | |||
375 | static struct pnp_driver tpm_inf_pnp = { | ||
376 | .name = "tpm_inf_pnp", | ||
377 | .id_table = tpm_pnp_tbl, | ||
378 | .probe = tpm_inf_pnp_probe, | ||
379 | }; | ||
380 | |||
381 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | ||
382 | const struct pci_device_id *pci_id) | ||
383 | { | 369 | { |
384 | int rc = 0; | 370 | int rc = 0; |
385 | u8 iol, ioh; | 371 | u8 iol, ioh; |
@@ -388,30 +374,28 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
388 | int productid[2]; | 374 | int productid[2]; |
389 | char chipname[20]; | 375 | char chipname[20]; |
390 | 376 | ||
391 | rc = pci_enable_device(pci_dev); | 377 | /* read IO-ports through PnP */ |
392 | if (rc) | 378 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
393 | return rc; | 379 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
394 | 380 | TPM_INF_ADDR = pnp_port_start(dev, 0); | |
395 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); | 381 | TPM_INF_DATA = (TPM_INF_ADDR + 1); |
396 | 382 | TPM_INF_BASE = pnp_port_start(dev, 1); | |
397 | /* read IO-ports from PnP */ | 383 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); |
398 | rc = pnp_register_driver(&tpm_inf_pnp); | 384 | if (!TPM_INF_PORT_LEN) |
399 | if (rc < 0) { | 385 | return -EINVAL; |
400 | dev_err(&pci_dev->dev, | 386 | dev_info(&dev->dev, "Found %s with ID %s\n", |
401 | "Error %x from pnp_register_driver!\n",rc); | 387 | dev->name, dev_id->id); |
402 | goto error2; | 388 | if (!((TPM_INF_BASE >> 8) & 0xff)) |
403 | } | 389 | return -EINVAL; |
404 | if (!rc) { | 390 | /* publish my base address and request region */ |
405 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); | 391 | tpm_inf.base = TPM_INF_BASE; |
406 | goto error; | 392 | if (request_region |
393 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | ||
394 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | ||
395 | return -EINVAL; | ||
396 | } | ||
407 | } else { | 397 | } else { |
408 | pnp_registered = 1; | 398 | return -EINVAL; |
409 | } | ||
410 | |||
411 | /* Make sure, we have received valid config ports */ | ||
412 | if (!TPM_INF_ADDR) { | ||
413 | dev_err(&pci_dev->dev, "No valid IO-ports received!\n"); | ||
414 | goto error; | ||
415 | } | 399 | } |
416 | 400 | ||
417 | /* query chip for its vendor, its version number a.s.o. */ | 401 | /* query chip for its vendor, its version number a.s.o. */ |
@@ -443,10 +427,6 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
443 | 427 | ||
444 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | 428 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { |
445 | 429 | ||
446 | if (tpm_inf.base == 0) { | ||
447 | dev_err(&pci_dev->dev, "No IO-ports found!\n"); | ||
448 | goto error; | ||
449 | } | ||
450 | /* configure TPM with IO-ports */ | 430 | /* configure TPM with IO-ports */ |
451 | outb(IOLIMH, TPM_INF_ADDR); | 431 | outb(IOLIMH, TPM_INF_ADDR); |
452 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); | 432 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); |
@@ -460,10 +440,11 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
460 | iol = inb(TPM_INF_DATA); | 440 | iol = inb(TPM_INF_DATA); |
461 | 441 | ||
462 | if ((ioh << 8 | iol) != tpm_inf.base) { | 442 | if ((ioh << 8 | iol) != tpm_inf.base) { |
463 | dev_err(&pci_dev->dev, | 443 | dev_err(&dev->dev, |
464 | "Could not set IO-ports to %04x\n", | 444 | "Could not set IO-ports to %04x\n", |
465 | tpm_inf.base); | 445 | tpm_inf.base); |
466 | goto error; | 446 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); |
447 | return -EIO; | ||
467 | } | 448 | } |
468 | 449 | ||
469 | /* activate register */ | 450 | /* activate register */ |
@@ -475,7 +456,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
475 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); | 456 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); |
476 | 457 | ||
477 | /* Finally, we're done, print some infos */ | 458 | /* Finally, we're done, print some infos */ |
478 | dev_info(&pci_dev->dev, "TPM found: " | 459 | dev_info(&dev->dev, "TPM found: " |
479 | "config base 0x%x, " | 460 | "config base 0x%x, " |
480 | "io base 0x%x, " | 461 | "io base 0x%x, " |
481 | "chip version %02x%02x, " | 462 | "chip version %02x%02x, " |
@@ -483,59 +464,53 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
483 | "product id %02x%02x" | 464 | "product id %02x%02x" |
484 | "%s\n", | 465 | "%s\n", |
485 | TPM_INF_ADDR, | 466 | TPM_INF_ADDR, |
486 | tpm_inf.base, | 467 | TPM_INF_BASE, |
487 | version[0], version[1], | 468 | version[0], version[1], |
488 | vendorid[0], vendorid[1], | 469 | vendorid[0], vendorid[1], |
489 | productid[0], productid[1], chipname); | 470 | productid[0], productid[1], chipname); |
490 | 471 | ||
491 | rc = tpm_register_hardware(pci_dev, &tpm_inf); | 472 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); |
492 | if (rc < 0) | 473 | if (rc < 0) { |
493 | goto error; | 474 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); |
475 | return -ENODEV; | ||
476 | } | ||
494 | return 0; | 477 | return 0; |
495 | } else { | 478 | } else { |
496 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); | 479 | dev_info(&dev->dev, "No Infineon TPM found!\n"); |
497 | error: | ||
498 | pnp_unregister_driver(&tpm_inf_pnp); | ||
499 | error2: | ||
500 | pci_disable_device(pci_dev); | ||
501 | pnp_registered = 0; | ||
502 | return -ENODEV; | 480 | return -ENODEV; |
503 | } | 481 | } |
504 | } | 482 | } |
505 | 483 | ||
506 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | 484 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) |
507 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | 485 | { |
508 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | 486 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
509 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
510 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
511 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
512 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
513 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
514 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)}, | ||
515 | {0,} | ||
516 | }; | ||
517 | 487 | ||
518 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | 488 | if (chip) { |
489 | release_region(chip->vendor->base, TPM_INF_PORT_LEN); | ||
490 | tpm_remove_hardware(chip->dev); | ||
491 | } | ||
492 | } | ||
519 | 493 | ||
520 | static struct pci_driver inf_pci_driver = { | 494 | static struct pnp_driver tpm_inf_pnp = { |
521 | .name = "tpm_inf", | 495 | .name = "tpm_inf_pnp", |
522 | .id_table = tpm_pci_tbl, | 496 | .driver = { |
523 | .probe = tpm_inf_probe, | 497 | .owner = THIS_MODULE, |
524 | .remove = __devexit_p(tpm_remove), | 498 | .suspend = tpm_pm_suspend, |
525 | .suspend = tpm_pm_suspend, | 499 | .resume = tpm_pm_resume, |
526 | .resume = tpm_pm_resume, | 500 | }, |
501 | .id_table = tpm_pnp_tbl, | ||
502 | .probe = tpm_inf_pnp_probe, | ||
503 | .remove = tpm_inf_pnp_remove, | ||
527 | }; | 504 | }; |
528 | 505 | ||
529 | static int __init init_inf(void) | 506 | static int __init init_inf(void) |
530 | { | 507 | { |
531 | return pci_register_driver(&inf_pci_driver); | 508 | return pnp_register_driver(&tpm_inf_pnp); |
532 | } | 509 | } |
533 | 510 | ||
534 | static void __exit cleanup_inf(void) | 511 | static void __exit cleanup_inf(void) |
535 | { | 512 | { |
536 | if (pnp_registered) | 513 | pnp_unregister_driver(&tpm_inf_pnp); |
537 | pnp_unregister_driver(&tpm_inf_pnp); | ||
538 | pci_unregister_driver(&inf_pci_driver); | ||
539 | } | 514 | } |
540 | 515 | ||
541 | module_init(init_inf); | 516 | module_init(init_inf); |
@@ -543,5 +518,5 @@ module_exit(cleanup_inf); | |||
543 | 518 | ||
544 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 519 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
545 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 520 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
546 | MODULE_VERSION("1.5"); | 521 | MODULE_VERSION("1.6"); |
547 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index b4127348c063..253871b5b1e2 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -111,7 +111,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip) | |||
111 | } | 111 | } |
112 | while (time_before(jiffies, stop)); | 112 | while (time_before(jiffies, stop)); |
113 | 113 | ||
114 | dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); | 114 | dev_info(chip->dev, "wait for ready failed\n"); |
115 | return -EBUSY; | 115 | return -EBUSY; |
116 | } | 116 | } |
117 | 117 | ||
@@ -127,12 +127,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
127 | return -EIO; | 127 | return -EIO; |
128 | 128 | ||
129 | if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { | 129 | if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { |
130 | dev_err(&chip->pci_dev->dev, "F0 timeout\n"); | 130 | dev_err(chip->dev, "F0 timeout\n"); |
131 | return -EIO; | 131 | return -EIO; |
132 | } | 132 | } |
133 | if ((data = | 133 | if ((data = |
134 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { | 134 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { |
135 | dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n", | 135 | dev_err(chip->dev, "not in normal mode (0x%x)\n", |
136 | data); | 136 | data); |
137 | return -EIO; | 137 | return -EIO; |
138 | } | 138 | } |
@@ -141,7 +141,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
141 | for (p = buffer; p < &buffer[count]; p++) { | 141 | for (p = buffer; p < &buffer[count]; p++) { |
142 | if (wait_for_stat | 142 | if (wait_for_stat |
143 | (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { | 143 | (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { |
144 | dev_err(&chip->pci_dev->dev, | 144 | dev_err(chip->dev, |
145 | "OBF timeout (while reading data)\n"); | 145 | "OBF timeout (while reading data)\n"); |
146 | return -EIO; | 146 | return -EIO; |
147 | } | 147 | } |
@@ -152,11 +152,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
152 | 152 | ||
153 | if ((data & NSC_STATUS_F0) == 0 && | 153 | if ((data & NSC_STATUS_F0) == 0 && |
154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { | 154 | (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { |
155 | dev_err(&chip->pci_dev->dev, "F0 not set\n"); | 155 | dev_err(chip->dev, "F0 not set\n"); |
156 | return -EIO; | 156 | return -EIO; |
157 | } | 157 | } |
158 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { | 158 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { |
159 | dev_err(&chip->pci_dev->dev, | 159 | dev_err(chip->dev, |
160 | "expected end of command(0x%x)\n", data); | 160 | "expected end of command(0x%x)\n", data); |
161 | return -EIO; | 161 | return -EIO; |
162 | } | 162 | } |
@@ -187,19 +187,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
187 | return -EIO; | 187 | return -EIO; |
188 | 188 | ||
189 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 189 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
190 | dev_err(&chip->pci_dev->dev, "IBF timeout\n"); | 190 | dev_err(chip->dev, "IBF timeout\n"); |
191 | return -EIO; | 191 | return -EIO; |
192 | } | 192 | } |
193 | 193 | ||
194 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); | 194 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); |
195 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { | 195 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { |
196 | dev_err(&chip->pci_dev->dev, "IBR timeout\n"); | 196 | dev_err(chip->dev, "IBR timeout\n"); |
197 | return -EIO; | 197 | return -EIO; |
198 | } | 198 | } |
199 | 199 | ||
200 | for (i = 0; i < count; i++) { | 200 | for (i = 0; i < count; i++) { |
201 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 201 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
202 | dev_err(&chip->pci_dev->dev, | 202 | dev_err(chip->dev, |
203 | "IBF timeout (while writing data)\n"); | 203 | "IBF timeout (while writing data)\n"); |
204 | return -EIO; | 204 | return -EIO; |
205 | } | 205 | } |
@@ -207,7 +207,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
207 | } | 207 | } |
208 | 208 | ||
209 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 209 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
210 | dev_err(&chip->pci_dev->dev, "IBF timeout\n"); | 210 | dev_err(chip->dev, "IBF timeout\n"); |
211 | return -EIO; | 211 | return -EIO; |
212 | } | 212 | } |
213 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); | 213 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); |
@@ -220,6 +220,11 @@ static void tpm_nsc_cancel(struct tpm_chip *chip) | |||
220 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); | 220 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); |
221 | } | 221 | } |
222 | 222 | ||
223 | static u8 tpm_nsc_status(struct tpm_chip *chip) | ||
224 | { | ||
225 | return inb(chip->vendor->base + NSC_STATUS); | ||
226 | } | ||
227 | |||
223 | static struct file_operations nsc_ops = { | 228 | static struct file_operations nsc_ops = { |
224 | .owner = THIS_MODULE, | 229 | .owner = THIS_MODULE, |
225 | .llseek = no_llseek, | 230 | .llseek = no_llseek, |
@@ -239,7 +244,7 @@ static struct attribute * nsc_attrs[] = { | |||
239 | &dev_attr_pcrs.attr, | 244 | &dev_attr_pcrs.attr, |
240 | &dev_attr_caps.attr, | 245 | &dev_attr_caps.attr, |
241 | &dev_attr_cancel.attr, | 246 | &dev_attr_cancel.attr, |
242 | 0, | 247 | NULL, |
243 | }; | 248 | }; |
244 | 249 | ||
245 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; | 250 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; |
@@ -248,6 +253,7 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
248 | .recv = tpm_nsc_recv, | 253 | .recv = tpm_nsc_recv, |
249 | .send = tpm_nsc_send, | 254 | .send = tpm_nsc_send, |
250 | .cancel = tpm_nsc_cancel, | 255 | .cancel = tpm_nsc_cancel, |
256 | .status = tpm_nsc_status, | ||
251 | .req_complete_mask = NSC_STATUS_OBF, | 257 | .req_complete_mask = NSC_STATUS_OBF, |
252 | .req_complete_val = NSC_STATUS_OBF, | 258 | .req_complete_val = NSC_STATUS_OBF, |
253 | .req_canceled = NSC_STATUS_RDY, | 259 | .req_canceled = NSC_STATUS_RDY, |
@@ -255,16 +261,32 @@ static struct tpm_vendor_specific tpm_nsc = { | |||
255 | .miscdev = { .fops = &nsc_ops, }, | 261 | .miscdev = { .fops = &nsc_ops, }, |
256 | }; | 262 | }; |
257 | 263 | ||
258 | static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | 264 | static struct platform_device *pdev = NULL; |
259 | const struct pci_device_id *pci_id) | 265 | |
266 | static void __devexit tpm_nsc_remove(struct device *dev) | ||
267 | { | ||
268 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
269 | if ( chip ) { | ||
270 | release_region(chip->vendor->base, 2); | ||
271 | tpm_remove_hardware(chip->dev); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | static struct device_driver nsc_drv = { | ||
276 | .name = "tpm_nsc", | ||
277 | .bus = &platform_bus_type, | ||
278 | .owner = THIS_MODULE, | ||
279 | .suspend = tpm_pm_suspend, | ||
280 | .resume = tpm_pm_resume, | ||
281 | }; | ||
282 | |||
283 | static int __init init_nsc(void) | ||
260 | { | 284 | { |
261 | int rc = 0; | 285 | int rc = 0; |
262 | int lo, hi; | 286 | int lo, hi; |
263 | int nscAddrBase = TPM_ADDR; | 287 | int nscAddrBase = TPM_ADDR; |
264 | 288 | ||
265 | 289 | driver_register(&nsc_drv); | |
266 | if (pci_enable_device(pci_dev)) | ||
267 | return -EIO; | ||
268 | 290 | ||
269 | /* select PM channel 1 */ | 291 | /* select PM channel 1 */ |
270 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); | 292 | tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12); |
@@ -273,37 +295,71 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
273 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { | 295 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { |
274 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| | 296 | nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| |
275 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); | 297 | (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); |
276 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) { | 298 | if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) |
277 | rc = -ENODEV; | 299 | return -ENODEV; |
278 | goto out_err; | ||
279 | } | ||
280 | } | 300 | } |
281 | 301 | ||
282 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); | 302 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); |
283 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); | 303 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); |
284 | tpm_nsc.base = (hi<<8) | lo; | 304 | tpm_nsc.base = (hi<<8) | lo; |
285 | 305 | ||
286 | dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); | 306 | /* enable the DPM module */ |
287 | dev_dbg(&pci_dev->dev, | 307 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); |
308 | |||
309 | pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL); | ||
310 | if ( !pdev ) | ||
311 | return -ENOMEM; | ||
312 | |||
313 | memset(pdev, 0, sizeof(struct platform_device)); | ||
314 | |||
315 | pdev->name = "tpm_nscl0"; | ||
316 | pdev->id = -1; | ||
317 | pdev->num_resources = 0; | ||
318 | pdev->dev.release = tpm_nsc_remove; | ||
319 | pdev->dev.driver = &nsc_drv; | ||
320 | |||
321 | if ((rc=platform_device_register(pdev)) < 0) { | ||
322 | kfree(pdev); | ||
323 | pdev = NULL; | ||
324 | return rc; | ||
325 | } | ||
326 | |||
327 | if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { | ||
328 | platform_device_unregister(pdev); | ||
329 | kfree(pdev); | ||
330 | pdev = NULL; | ||
331 | return -EBUSY; | ||
332 | } | ||
333 | |||
334 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) { | ||
335 | release_region(tpm_nsc.base, 2); | ||
336 | platform_device_unregister(pdev); | ||
337 | kfree(pdev); | ||
338 | pdev = NULL; | ||
339 | return rc; | ||
340 | } | ||
341 | |||
342 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); | ||
343 | dev_dbg(&pdev->dev, | ||
288 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", | 344 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", |
289 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), | 345 | tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), |
290 | tpm_read_index(nscAddrBase,0x27)); | 346 | tpm_read_index(nscAddrBase,0x27)); |
291 | dev_dbg(&pci_dev->dev, | 347 | dev_dbg(&pdev->dev, |
292 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", | 348 | "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", |
293 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), | 349 | tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25), |
294 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); | 350 | tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28)); |
295 | dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", | 351 | dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n", |
296 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); | 352 | (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61)); |
297 | dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", | 353 | dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n", |
298 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); | 354 | (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63)); |
299 | dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", | 355 | dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n", |
300 | tpm_read_index(nscAddrBase,0x70)); | 356 | tpm_read_index(nscAddrBase,0x70)); |
301 | dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", | 357 | dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n", |
302 | tpm_read_index(nscAddrBase,0x71)); | 358 | tpm_read_index(nscAddrBase,0x71)); |
303 | dev_dbg(&pci_dev->dev, | 359 | dev_dbg(&pdev->dev, |
304 | "NSC DMA channel select0 0x%x, select1 0x%x\n", | 360 | "NSC DMA channel select0 0x%x, select1 0x%x\n", |
305 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); | 361 | tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75)); |
306 | dev_dbg(&pci_dev->dev, | 362 | dev_dbg(&pdev->dev, |
307 | "NSC Config " | 363 | "NSC Config " |
308 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 364 | "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
309 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), | 365 | tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1), |
@@ -312,55 +368,23 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, | |||
312 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), | 368 | tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), |
313 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); | 369 | tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); |
314 | 370 | ||
315 | dev_info(&pci_dev->dev, | 371 | dev_info(&pdev->dev, |
316 | "NSC TPM revision %d\n", | 372 | "NSC TPM revision %d\n", |
317 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); | 373 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); |
318 | 374 | ||
319 | /* enable the DPM module */ | ||
320 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); | ||
321 | |||
322 | if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) | ||
323 | goto out_err; | ||
324 | |||
325 | return 0; | 375 | return 0; |
326 | |||
327 | out_err: | ||
328 | pci_disable_device(pci_dev); | ||
329 | return rc; | ||
330 | } | ||
331 | |||
332 | static struct pci_device_id tpm_pci_tbl[] __devinitdata = { | ||
333 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)}, | ||
334 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)}, | ||
335 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, | ||
336 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, | ||
337 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, | ||
338 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)}, | ||
339 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)}, | ||
340 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)}, | ||
341 | {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, | ||
342 | {0,} | ||
343 | }; | ||
344 | |||
345 | MODULE_DEVICE_TABLE(pci, tpm_pci_tbl); | ||
346 | |||
347 | static struct pci_driver nsc_pci_driver = { | ||
348 | .name = "tpm_nsc", | ||
349 | .id_table = tpm_pci_tbl, | ||
350 | .probe = tpm_nsc_init, | ||
351 | .remove = __devexit_p(tpm_remove), | ||
352 | .suspend = tpm_pm_suspend, | ||
353 | .resume = tpm_pm_resume, | ||
354 | }; | ||
355 | |||
356 | static int __init init_nsc(void) | ||
357 | { | ||
358 | return pci_register_driver(&nsc_pci_driver); | ||
359 | } | 376 | } |
360 | 377 | ||
361 | static void __exit cleanup_nsc(void) | 378 | static void __exit cleanup_nsc(void) |
362 | { | 379 | { |
363 | pci_unregister_driver(&nsc_pci_driver); | 380 | if (pdev) { |
381 | tpm_nsc_remove(&pdev->dev); | ||
382 | platform_device_unregister(pdev); | ||
383 | kfree(pdev); | ||
384 | pdev = NULL; | ||
385 | } | ||
386 | |||
387 | driver_unregister(&nsc_drv); | ||
364 | } | 388 | } |
365 | 389 | ||
366 | module_init(init_nsc); | 390 | module_init(init_nsc); |