diff options
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r-- | drivers/char/tpm/tpm.c | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ff170963c641..7b1f67d9f301 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -489,29 +489,19 @@ ssize_t tpm_read(struct file * file, char __user * buf, | |||
489 | size_t size, loff_t * off) | 489 | size_t size, loff_t * off) |
490 | { | 490 | { |
491 | struct tpm_chip *chip = file->private_data; | 491 | struct tpm_chip *chip = file->private_data; |
492 | int ret_size = -ENODATA; | 492 | int ret_size; |
493 | 493 | ||
494 | if (atomic_read(&chip->data_pending) != 0) { /* Result available */ | 494 | del_singleshot_timer_sync(&chip->user_read_timer); |
495 | down(&chip->timer_manipulation_mutex); | 495 | ret_size = atomic_read(&chip->data_pending); |
496 | del_singleshot_timer_sync(&chip->user_read_timer); | 496 | atomic_set(&chip->data_pending, 0); |
497 | up(&chip->timer_manipulation_mutex); | 497 | if (ret_size > 0) { /* relay data */ |
498 | if (size < ret_size) | ||
499 | ret_size = size; | ||
498 | 500 | ||
499 | down(&chip->buffer_mutex); | 501 | down(&chip->buffer_mutex); |
500 | 502 | if (copy_to_user | |
501 | ret_size = atomic_read(&chip->data_pending); | 503 | ((void __user *) buf, chip->data_buffer, ret_size)) |
502 | atomic_set(&chip->data_pending, 0); | 504 | ret_size = -EFAULT; |
503 | |||
504 | if (ret_size == 0) /* timeout just occurred */ | ||
505 | ret_size = -ETIME; | ||
506 | else if (ret_size > 0) { /* relay data */ | ||
507 | if (size < ret_size) | ||
508 | ret_size = size; | ||
509 | |||
510 | if (copy_to_user((void __user *) buf, | ||
511 | chip->data_buffer, ret_size)) { | ||
512 | ret_size = -EFAULT; | ||
513 | } | ||
514 | } | ||
515 | up(&chip->buffer_mutex); | 505 | up(&chip->buffer_mutex); |
516 | } | 506 | } |
517 | 507 | ||