From 87cdfdd19aefcf639507ce96ae8f403539a8ba29 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Tue, 17 Oct 2017 16:32:29 -0400 Subject: tpm: move wait_for_tpm_stat() to respective driver files The function wait_for_tpm_stat() is currently defined in tpm-interface file. It is a hardware specific function used only by tpm_tis and xen-tpmfront, so it is removed from tpm-interface.c and defined in respective driver files. Suggested-by: Jarkko Sakkinen Signed-off-by: Nayna Jain Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/xen-tpmfront.c | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'drivers/char/tpm/xen-tpmfront.c') diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 656e8af95d52..911475d36800 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,66 @@ enum status_bits { VTPM_STATUS_CANCELED = 0x8, }; +static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, + bool check_cancel, bool *canceled) +{ + u8 status = chip->ops->status(chip); + + *canceled = false; + if ((status & mask) == mask) + return true; + if (check_cancel && chip->ops->req_canceled(chip, status)) { + *canceled = true; + return true; + } + return false; +} + +static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, + unsigned long timeout, wait_queue_head_t *queue, + bool check_cancel) +{ + unsigned long stop; + long rc; + u8 status; + bool canceled = false; + + /* check current status */ + status = chip->ops->status(chip); + if ((status & mask) == mask) + return 0; + + stop = jiffies + timeout; + + if (chip->flags & TPM_CHIP_FLAG_IRQ) { +again: + timeout = stop - jiffies; + if ((long)timeout <= 0) + return -ETIME; + rc = wait_event_interruptible_timeout(*queue, + wait_for_tpm_stat_cond(chip, mask, check_cancel, + &canceled), + timeout); + if (rc > 0) { + if (canceled) + return -ECANCELED; + return 0; + } + if (rc == -ERESTARTSYS && freezing(current)) { + clear_thread_flag(TIF_SIGPENDING); + goto again; + } + } else { + do { + tpm_msleep(TPM_TIMEOUT); + status = chip->ops->status(chip); + if ((status & mask) == mask) + return 0; + } while (time_before(jiffies, stop)); + } + return -ETIME; +} + static u8 vtpm_status(struct tpm_chip *chip) { struct tpm_private *priv = dev_get_drvdata(&chip->dev); -- cgit v1.2.3