Exemple #1
0
/*
 * wait_for_stat wait for a TPM_STS value
 * @param: chip, the tpm chip description
 * @param: mask, the value mask to wait
 * @param: timeout, the timeout
 * @param: queue, the wait queue.
 * @param: check_cancel, does the command can be cancelled ?
 * @return: the tpm status, 0 if success, -ETIME if timeout is reached.
 */
static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
			wait_queue_head_t *queue, bool check_cancel)
{
	unsigned long stop;
	int ret;
	bool canceled = false;
	bool condition;
	u32 cur_intrs;
	u8 interrupt, status;
	struct tpm_stm_dev *tpm_dev;

	tpm_dev = (struct tpm_stm_dev *)TPM_VPRIV(chip);

	/* check current status */
	status = tpm_stm_i2c_status(chip);
	if ((status & mask) == mask)
		return 0;

	stop = jiffies + timeout;

	if (chip->vendor.irq) {
		cur_intrs = tpm_dev->intrs;
		interrupt = clear_interruption(tpm_dev);
		enable_irq(chip->vendor.irq);

again:
		timeout = stop - jiffies;
		if ((long) timeout <= 0)
			return -1;

		ret = wait_event_interruptible_timeout(*queue,
					cur_intrs != tpm_dev->intrs, timeout);

		interrupt |= clear_interruption(tpm_dev);
		status = interrupt_to_status(interrupt);
		condition = wait_for_tpm_stat_cond(chip, mask,
						   check_cancel, &canceled);

		if (ret >= 0 && condition) {
			if (canceled)
				return -ECANCELED;
			return 0;
		}
		if (ret == -ERESTARTSYS && freezing(current)) {
			clear_thread_flag(TIF_SIGPENDING);
			goto again;
		}
		disable_irq_nosync(chip->vendor.irq);

	} else {
		do {
			msleep(TPM_TIMEOUT);
			status = chip->ops->status(chip);
			if ((status & mask) == mask)
				return 0;
		} while (time_before(jiffies, stop));
	}

	return -ETIME;
} /* wait_for_stat() */
Exemple #2
0
/*
 * wait_for_stat wait for a TPM_STS value
 * @param: chip, the tpm chip description
 * @param: mask, the value mask to wait
 * @param: timeout, the timeout
 * @param: queue, the wait queue.
 * @param: check_cancel, does the command can be cancelled ?
 * @return: the tpm status, 0 if success, -ETIME if timeout is reached.
 */
static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
			wait_queue_head_t *queue, bool check_cancel)
{
	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
	unsigned long stop;
	int ret = 0;
	bool canceled = false;
	bool condition;
	u32 cur_intrs;
	u8 status;

	/* check current status */
	status = st33zp24_status(chip);
	if ((status & mask) == mask)
		return 0;

	stop = jiffies + timeout;

	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
		cur_intrs = tpm_dev->intrs;
		clear_interruption(tpm_dev);
		enable_irq(tpm_dev->irq);

		do {
			if (ret == -ERESTARTSYS && freezing(current))
				clear_thread_flag(TIF_SIGPENDING);

			timeout = stop - jiffies;
			if ((long) timeout <= 0)
				return -1;

			ret = wait_event_interruptible_timeout(*queue,
						cur_intrs != tpm_dev->intrs,
						timeout);
			clear_interruption(tpm_dev);
			condition = wait_for_tpm_stat_cond(chip, mask,
						check_cancel, &canceled);
			if (ret >= 0 && condition) {
				if (canceled)
					return -ECANCELED;
				return 0;
			}
		} while (ret == -ERESTARTSYS && freezing(current));

		disable_irq_nosync(tpm_dev->irq);

	} else {
		do {
			msleep(TPM_TIMEOUT);
			status = chip->ops->status(chip);
			if ((status & mask) == mask)
				return 0;
		} while (time_before(jiffies, stop));
	}

	return -ETIME;
} /* wait_for_stat() */
Exemple #3
0
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;
}