diff options
Diffstat (limited to 'drivers/char/tpm/tpm.c')
-rw-r--r-- | drivers/char/tpm/tpm.c | 104 |
1 files changed, 43 insertions, 61 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)"); |