2013-11-27 00:30:40 +04:00
/*
* Copyright ( C ) 2004 IBM Corporation
* Authors :
* Leendert van Doorn < leendert @ watson . ibm . com >
* Dave Safford < safford @ watson . ibm . com >
* Reiner Sailer < sailer @ watson . ibm . com >
* Kylene Hall < kjhall @ us . ibm . com >
*
* Copyright ( C ) 2013 Obsidian Research Corp
* Jason Gunthorpe < jgunthorpe @ obsidianresearch . com >
*
* Device file system interface to the TPM
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation , version 2 of the
* License .
*
*/
# include <linux/slab.h>
2017-01-11 06:08:53 +03:00
# include "tpm-dev.h"
2013-11-27 00:30:40 +04:00
static int tpm_open ( struct inode * inode , struct file * file )
{
2017-01-11 06:08:53 +03:00
struct tpm_chip * chip ;
2013-11-27 00:30:45 +04:00
struct file_priv * priv ;
2013-11-27 00:30:40 +04:00
2017-01-11 06:08:53 +03:00
chip = container_of ( inode - > i_cdev , struct tpm_chip , cdev ) ;
2013-11-27 00:30:40 +04:00
/* It's assured that the chip will be opened just once,
* by the check of is_open variable , which is protected
* by driver_lock . */
if ( test_and_set_bit ( 0 , & chip - > is_open ) ) {
2016-02-29 20:29:47 +03:00
dev_dbg ( & chip - > dev , " Another process owns this TPM \n " ) ;
2013-11-27 00:30:40 +04:00
return - EBUSY ;
}
2013-11-27 00:30:45 +04:00
priv = kzalloc ( sizeof ( * priv ) , GFP_KERNEL ) ;
2017-01-11 06:08:53 +03:00
if ( priv = = NULL )
goto out ;
2013-11-27 00:30:40 +04:00
2017-01-11 06:08:53 +03:00
tpm_common_open ( file , chip , priv ) ;
2013-11-27 00:30:40 +04:00
return 0 ;
2017-01-11 06:08:53 +03:00
out :
clear_bit ( 0 , & chip - > is_open ) ;
return - ENOMEM ;
2013-11-27 00:30:40 +04:00
}
static ssize_t tpm_write ( struct file * file , const char __user * buf ,
size_t size , loff_t * off )
{
2017-01-11 06:08:53 +03:00
return tpm_common_write ( file , buf , size , off , NULL ) ;
2013-11-27 00:30:40 +04:00
}
/*
* Called on file close
*/
static int tpm_release ( struct inode * inode , struct file * file )
{
2013-11-27 00:30:45 +04:00
struct file_priv * priv = file - > private_data ;
2013-11-27 00:30:40 +04:00
2017-01-11 06:08:53 +03:00
tpm_common_release ( file , priv ) ;
2013-11-27 00:30:45 +04:00
clear_bit ( 0 , & priv - > chip - > is_open ) ;
kfree ( priv ) ;
2017-01-11 06:08:53 +03:00
2013-11-27 00:30:40 +04:00
return 0 ;
}
2014-12-12 22:46:37 +03:00
const struct file_operations tpm_fops = {
2013-11-27 00:30:40 +04:00
. owner = THIS_MODULE ,
. llseek = no_llseek ,
. open = tpm_open ,
2017-01-11 06:08:53 +03:00
. read = tpm_common_read ,
2013-11-27 00:30:40 +04:00
. write = tpm_write ,
. release = tpm_release ,
} ;