drivers/char/tpm/tpm_vtpm_proxy.c

Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_vtpm_proxy.c

File Facts

System
Linux kernel
Corpus path
drivers/char/tpm/tpm_vtpm_proxy.c
Extension
.c
Size
16350 bytes
Lines
719
Domain
Driver Families
Bucket
drivers/char
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations vtpm_proxy_fops = {
	.owner = THIS_MODULE,
	.read = vtpm_proxy_fops_read,
	.write = vtpm_proxy_fops_write,
	.poll = vtpm_proxy_fops_poll,
	.release = vtpm_proxy_fops_release,
};

/*
 * Functions invoked by the core TPM driver to send TPM commands to
 * 'server side' and receive responses from there.
 */

/*
 * Called when core TPM driver reads TPM responses from 'server side'
 *
 * @chip: tpm chip to use
 * @buf: receive buffer
 * @count: bytes to read
 * Return:
 *      Number of TPM response bytes read, negative error value otherwise
 */
static int vtpm_proxy_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
	struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
	size_t len;

	/* process gone ? */
	mutex_lock(&proxy_dev->buf_lock);

	if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
		mutex_unlock(&proxy_dev->buf_lock);
		return -EPIPE;
	}

	len = proxy_dev->resp_len;
	if (count < len) {
		dev_err(&chip->dev,
			"Invalid size in recv: count=%zd, resp_len=%zd\n",
			count, len);
		len = -EIO;
		goto out;
	}

	memcpy(buf, proxy_dev->buffer, len);
	proxy_dev->resp_len = 0;

out:
	mutex_unlock(&proxy_dev->buf_lock);

	return len;
}

static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
					u8 *buf, size_t count)
{
	struct tpm_header *hdr = (struct tpm_header *)buf;

	if (count < sizeof(struct tpm_header))
		return 0;

	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
		switch (be32_to_cpu(hdr->ordinal)) {
		case TPM2_CC_SET_LOCALITY:
			return 1;
		}
	} else {
		switch (be32_to_cpu(hdr->ordinal)) {
		case TPM_ORD_SET_LOCALITY:
			return 1;
		}
	}
	return 0;
}

/*
 * Called when core TPM driver forwards TPM requests to 'server side'.
 *
 * @chip: tpm chip to use
 * @buf: send buffer
 * @bufsiz: size of the buffer
 * @count: bytes to send
 *
 * Return:
 *      0 in case of success, negative error value otherwise.
 */
static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
				  size_t count)
{
	struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);

Annotation

Implementation Notes