Commit fd048866 authored by Rajiv Andrade's avatar Rajiv Andrade

TPM: Export wait_for_stat for other vendor specific drivers

Moved wait_for_stat to tpm.c so that other drivers can use it.
Also renamed it to avoid future namespace conflicts.
Signed-off-by: default avatarRajiv Andrade <srajiv@linux.vnet.ibm.com>
parent 9efa54f0
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/freezer.h>
#include "tpm.h" #include "tpm.h"
...@@ -1057,6 +1058,46 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, ...@@ -1057,6 +1058,46 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
} }
EXPORT_SYMBOL_GPL(tpm_store_cancel); EXPORT_SYMBOL_GPL(tpm_store_cancel);
int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
wait_queue_head_t *queue)
{
unsigned long stop;
long rc;
u8 status;
/* check current status */
status = chip->vendor.status(chip);
if ((status & mask) == mask)
return 0;
stop = jiffies + timeout;
if (chip->vendor.irq) {
again:
timeout = stop - jiffies;
if ((long)timeout <= 0)
return -ETIME;
rc = wait_event_interruptible_timeout(*queue,
((chip->vendor.status(chip)
& mask) == mask),
timeout);
if (rc > 0)
return 0;
if (rc == -ERESTARTSYS && freezing(current)) {
clear_thread_flag(TIF_SIGPENDING);
goto again;
}
} else {
do {
msleep(TPM_TIMEOUT);
status = chip->vendor.status(chip);
if ((status & mask) == mask)
return 0;
} while (time_before(jiffies, stop));
}
return -ETIME;
}
EXPORT_SYMBOL_GPL(wait_for_tpm_stat);
/* /*
* Device file system interface to the TPM * Device file system interface to the TPM
* *
......
...@@ -296,7 +296,8 @@ extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); ...@@ -296,7 +296,8 @@ extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
extern void tpm_remove_hardware(struct device *); extern void tpm_remove_hardware(struct device *);
extern int tpm_pm_suspend(struct device *, pm_message_t); extern int tpm_pm_suspend(struct device *, pm_message_t);
extern int tpm_pm_resume(struct device *); extern int tpm_pm_resume(struct device *);
extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
wait_queue_head_t *);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
extern struct dentry ** tpm_bios_log_setup(char *); extern struct dentry ** tpm_bios_log_setup(char *);
extern void tpm_bios_log_teardown(struct dentry **); extern void tpm_bios_log_teardown(struct dentry **);
......
...@@ -193,54 +193,14 @@ static int get_burstcount(struct tpm_chip *chip) ...@@ -193,54 +193,14 @@ static int get_burstcount(struct tpm_chip *chip)
return -EBUSY; return -EBUSY;
} }
static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
wait_queue_head_t *queue)
{
unsigned long stop;
long rc;
u8 status;
/* check current status */
status = chip->vendor.status(chip);
if ((status & mask) == mask)
return 0;
stop = jiffies + timeout;
if (chip->vendor.irq) {
again:
timeout = stop - jiffies;
if ((long)timeout <= 0)
return -ETIME;
rc = wait_event_interruptible_timeout(*queue,
((chip->vendor.status(chip)
& mask) == mask),
timeout);
if (rc > 0)
return 0;
if (rc == -ERESTARTSYS && freezing(current)) {
clear_thread_flag(TIF_SIGPENDING);
goto again;
}
} else {
do {
msleep(TPM_TIMEOUT);
status = chip->vendor.status(chip);
if ((status & mask) == mask)
return 0;
} while (time_before(jiffies, stop));
}
return -ETIME;
}
static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
{ {
int size = 0, burstcnt; int size = 0, burstcnt;
while (size < count && while (size < count &&
wait_for_stat(chip, wait_for_tpm_stat(chip,
TPM_STS_DATA_AVAIL | TPM_STS_VALID, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
chip->vendor.timeout_c, chip->vendor.timeout_c,
&chip->vendor.read_queue) &chip->vendor.read_queue)
== 0) { == 0) {
burstcnt = get_burstcount(chip); burstcnt = get_burstcount(chip);
for (; burstcnt > 0 && size < count; burstcnt--) for (; burstcnt > 0 && size < count; burstcnt--)
...@@ -282,8 +242,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -282,8 +242,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
goto out; goto out;
} }
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, wait_for_tpm_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
&chip->vendor.int_queue); &chip->vendor.int_queue);
status = tpm_tis_status(chip); status = tpm_tis_status(chip);
if (status & TPM_STS_DATA_AVAIL) { /* retry? */ if (status & TPM_STS_DATA_AVAIL) { /* retry? */
dev_err(chip->dev, "Error left over data\n"); dev_err(chip->dev, "Error left over data\n");
...@@ -317,7 +277,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) ...@@ -317,7 +277,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
status = tpm_tis_status(chip); status = tpm_tis_status(chip);
if ((status & TPM_STS_COMMAND_READY) == 0) { if ((status & TPM_STS_COMMAND_READY) == 0) {
tpm_tis_ready(chip); tpm_tis_ready(chip);
if (wait_for_stat if (wait_for_tpm_stat
(chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b, (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
&chip->vendor.int_queue) < 0) { &chip->vendor.int_queue) < 0) {
rc = -ETIME; rc = -ETIME;
...@@ -333,8 +293,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) ...@@ -333,8 +293,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
count++; count++;
} }
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, wait_for_tpm_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
&chip->vendor.int_queue); &chip->vendor.int_queue);
status = tpm_tis_status(chip); status = tpm_tis_status(chip);
if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
rc = -EIO; rc = -EIO;
...@@ -345,8 +305,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) ...@@ -345,8 +305,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
/* write last byte */ /* write last byte */
iowrite8(buf[count], iowrite8(buf[count],
chip->vendor.iobase + TPM_DATA_FIFO(chip->vendor.locality)); chip->vendor.iobase + TPM_DATA_FIFO(chip->vendor.locality));
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, wait_for_tpm_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
&chip->vendor.int_queue); &chip->vendor.int_queue);
status = tpm_tis_status(chip); status = tpm_tis_status(chip);
if ((status & TPM_STS_DATA_EXPECT) != 0) { if ((status & TPM_STS_DATA_EXPECT) != 0) {
rc = -EIO; rc = -EIO;
...@@ -381,7 +341,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) ...@@ -381,7 +341,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
if (chip->vendor.irq) { if (chip->vendor.irq) {
ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
if (wait_for_stat if (wait_for_tpm_stat
(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
tpm_calc_ordinal_duration(chip, ordinal), tpm_calc_ordinal_duration(chip, ordinal),
&chip->vendor.read_queue) < 0) { &chip->vendor.read_queue) < 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment