proxy_dev
rc = copy_to_user(buf, proxy_dev->buffer, len);
memset(proxy_dev->buffer, 0, len);
proxy_dev->req_len = 0;
proxy_dev->state |= STATE_WAIT_RESPONSE_FLAG;
mutex_unlock(&proxy_dev->buf_lock);
struct proxy_dev *proxy_dev = filp->private_data;
mutex_lock(&proxy_dev->buf_lock);
if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
mutex_unlock(&proxy_dev->buf_lock);
if (count > sizeof(proxy_dev->buffer) ||
!(proxy_dev->state & STATE_WAIT_RESPONSE_FLAG)) {
mutex_unlock(&proxy_dev->buf_lock);
proxy_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
proxy_dev->req_len = 0;
if (copy_from_user(proxy_dev->buffer, buf, count)) {
mutex_unlock(&proxy_dev->buf_lock);
proxy_dev->resp_len = count;
mutex_unlock(&proxy_dev->buf_lock);
wake_up_interruptible(&proxy_dev->wq);
struct proxy_dev *proxy_dev = filp->private_data;
poll_wait(filp, &proxy_dev->wq, wait);
mutex_lock(&proxy_dev->buf_lock);
if (proxy_dev->req_len)
if (!(proxy_dev->state & STATE_OPENED_FLAG))
mutex_unlock(&proxy_dev->buf_lock);
struct proxy_dev *proxy_dev = filp->private_data;
proxy_dev->state |= STATE_OPENED_FLAG;
static void vtpm_proxy_fops_undo_open(struct proxy_dev *proxy_dev)
mutex_lock(&proxy_dev->buf_lock);
proxy_dev->state &= ~STATE_OPENED_FLAG;
mutex_unlock(&proxy_dev->buf_lock);
wake_up_interruptible(&proxy_dev->wq);
struct proxy_dev *proxy_dev = filp->private_data;
vtpm_proxy_delete_device(proxy_dev);
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
mutex_lock(&proxy_dev->buf_lock);
if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
mutex_unlock(&proxy_dev->buf_lock);
len = proxy_dev->resp_len;
memcpy(buf, proxy_dev->buffer, len);
proxy_dev->resp_len = 0;
mutex_unlock(&proxy_dev->buf_lock);
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
if (count > sizeof(proxy_dev->buffer)) {
count, sizeof(proxy_dev->buffer));
if (!(proxy_dev->state & STATE_DRIVER_COMMAND) &&
mutex_lock(&proxy_dev->buf_lock);
if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
mutex_unlock(&proxy_dev->buf_lock);
proxy_dev->resp_len = 0;
proxy_dev->req_len = count;
memcpy(proxy_dev->buffer, buf, count);
proxy_dev->state &= ~STATE_WAIT_RESPONSE_FLAG;
mutex_unlock(&proxy_dev->buf_lock);
wake_up_interruptible(&proxy_dev->wq);
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
if (proxy_dev->resp_len)
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
mutex_lock(&proxy_dev->buf_lock);
ret = !(proxy_dev->state & STATE_OPENED_FLAG);
mutex_unlock(&proxy_dev->buf_lock);
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
proxy_dev->state |= STATE_DRIVER_COMMAND;
proxy_dev->state &= ~STATE_DRIVER_COMMAND;
struct proxy_dev *proxy_dev = container_of(work, struct proxy_dev,
rc = tpm_chip_register(proxy_dev->chip);
vtpm_proxy_fops_undo_open(proxy_dev);
proxy_dev->state |= STATE_REGISTERED_FLAG;
static void vtpm_proxy_work_stop(struct proxy_dev *proxy_dev)
vtpm_proxy_fops_undo_open(proxy_dev);
flush_work(&proxy_dev->work);
static inline void vtpm_proxy_work_start(struct proxy_dev *proxy_dev)
queue_work(workqueue, &proxy_dev->work);
static struct proxy_dev *vtpm_proxy_create_proxy_dev(void)
struct proxy_dev *proxy_dev;
proxy_dev = kzalloc_obj(*proxy_dev);
if (proxy_dev == NULL)
init_waitqueue_head(&proxy_dev->wq);
mutex_init(&proxy_dev->buf_lock);
INIT_WORK(&proxy_dev->work, vtpm_proxy_work);
dev_set_drvdata(&chip->dev, proxy_dev);
proxy_dev->chip = chip;
return proxy_dev;
kfree(proxy_dev);
static inline void vtpm_proxy_delete_proxy_dev(struct proxy_dev *proxy_dev)
put_device(&proxy_dev->chip->dev); /* frees chip */
kfree(proxy_dev);
struct proxy_dev *proxy_dev;
proxy_dev = vtpm_proxy_create_proxy_dev();
if (IS_ERR(proxy_dev))
return ERR_CAST(proxy_dev);
proxy_dev->flags = vtpm_new_dev->flags;
static void vtpm_proxy_delete_device(struct proxy_dev *proxy_dev);
file = anon_inode_getfile("[vtpms]", &vtpm_proxy_fops, proxy_dev,
if (proxy_dev->flags & VTPM_PROXY_FLAG_TPM2)
proxy_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
vtpm_proxy_work_start(proxy_dev);
vtpm_new_dev->major = MAJOR(proxy_dev->chip->dev.devt);
vtpm_new_dev->minor = MINOR(proxy_dev->chip->dev.devt);
vtpm_new_dev->tpm_num = proxy_dev->chip->dev_num;
vtpm_proxy_delete_proxy_dev(proxy_dev);
static void vtpm_proxy_delete_device(struct proxy_dev *proxy_dev)
vtpm_proxy_work_stop(proxy_dev);
vtpm_proxy_fops_undo_open(proxy_dev);
if (proxy_dev->state & STATE_REGISTERED_FLAG)
tpm_chip_unregister(proxy_dev->chip);
vtpm_proxy_delete_proxy_dev(proxy_dev);
struct proxy_dev *proxy_dev = filp->private_data;
sig = wait_event_interruptible(proxy_dev->wq,
proxy_dev->req_len != 0 ||
!(proxy_dev->state & STATE_OPENED_FLAG));
mutex_lock(&proxy_dev->buf_lock);
if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
mutex_unlock(&proxy_dev->buf_lock);
len = proxy_dev->req_len;
if (count < len || len > sizeof(proxy_dev->buffer)) {
mutex_unlock(&proxy_dev->buf_lock);