linux统计代码注释率,Linux可信计算机制模块详细分析之核心文件分析(9)tpm.c核心代码注释(下)...

/*设备文件系统调用tpm_open()打开TPM设备实例*/

int tpm_open(struct inode *inode, struct file *file)

{

int minor = iminor(inode);

struct tpm_chip *chip = NULL, *pos;

rcu_read_lock();

list_for_each_entry_rcu(pos, &tpm_chip_list, list) {

if (pos->vendor.miscdev.minor == minor) {

chip = pos;

get_device(chip->dev);

break;

}

}

rcu_read_unlock();

if (!chip)

return -ENODEV;

/*检测chip结构体中is_open字段的值,确定此TPM设备只能打开一次*/

if (test_and_set_bit(0, &chip->is_open)) {

dev_dbg(chip->dev, "Another process owns this TPM\n");

put_device(chip->dev);

return -EBUSY;

}

/*分配TPM驱动程序的数据缓存区空间*/

chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL);

if (chip->data_buffer == NULL) {

/*设置tpm_chip结构体is_open字段值为0*/

clear_bit(0, &chip->is_open);

put_device(chip->dev);

return -ENOMEM;

}

atomic_set(&chip->data_pending, 0);

/将TPM设备实例放在文件结构的私有数据成员上*/

file->private_data = chip;

return 0;

}

/*设备文件系统调用tpm_release()释放tpm设备实例*/

int tpm_release(struct inode *inode, struct file *file)

{

struct tpm_chip *chip = file->private_data;

del_singleshot_timer_sync(&chip->user_read_timer);

flush_work_sync(&chip->work);

/*设置文件结构的私有数据成员值为NULL*/

file->private_data = NULL;

/*原子设置,使读写缓存区的互斥锁为0*/

atomic_set(&chip->data_pending, 0);

/*释放读写缓存区*/

kfree(chip->data_buffer);

/*设置TPM设备打开次数为0,tpm_chip结构体中的is_open字段表示TPM设备打开的次数*/

clear_bit(0, &chip->is_open);

/*将设备引用计算器的值减1*/

put_device(chip->dev);

return 0;

}

/*向TPM设备中发送数据,此函数通过TPM设备驱动程序库TDDL(TPM Device Driver Library)调用*/

ssize_t tpm_write(struct file *file, const char __user *buf,

size_t size, loff_t *off)

{

struct tpm_chip *chip = file->private_data;

size_t in_size = size, out_size;

/*当有TPM设备执行读操作时,不能有写操作*/

while (atomic_read(&chip->data_pending) != 0)

/*有读操作时,让写操作睡眠*/

msleep(TPM_TIMEOUT);

mutex_lock(&chip->buffer_mutex);

if (in_size > TPM_BUFSIZE)

in_size = TPM_BUFSIZE;

/*将TPM命令从用户空间拷贝到设备驱动程序数据的缓存区中,即chip->data_buffer中*/

if (copy_from_user

(chip->data_buffer, (void __user *) buf, in_size)) {

mutex_unlock(&chip->buffer_mutex);

return -EFAULT;

}

/*发送命令给对应的TPM设备执行,等待TPM设备执行完成,返回执行结果,发送命令和返回结果都是原子操作*/

out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);

atomic_set(&chip->data_pending, out_size);

mutex_unlock(&chip->buffer_mutex);

/*设定读的定时,读操作需在此时间内读取命令执行结果*/

mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));

return in_size;

}

/*从驱动程序数据缓存区读取命令执行的结果返回给用户,此函数也是由TPM设备驱动程序库TDDL调用*/

ssize_t tpm_read(struct file *file, char __user *buf,

size_t size, loff_t *off)

{

struct tpm_chip *chip = file->private_data;

ssize_t ret_size;

int rc;

del_singleshot_timer_sync(&chip->user_read_timer);

flush_work_sync(&chip->work);

/*原子操作,读取data_pending字段大小*/

ret_size = atomic_read(&chip->data_pending);

/*原子操作,设子data_pending字段中的值为0*/

atomic_set(&chip->data_pending, 0);

if (ret_size > 0) {

ssize_t orig_ret_size = ret_size;

if (size < ret_size)

ret_size = size;

mutex_lock(&chip->buffer_mutex);

/*将执行结果data_buffer中的值返回到用户空间的buf中*/

rc = copy_to_user(buf, chip->data_buffer, ret_size);

/*用0初始化data_buffer中的数据*/

memset(chip->data_buffer, 0, orig_ret_size);

if (rc)

ret_size = -EFAULT;

mutex_unlock(&chip->buffer_mutex);

}

/*返回命令执行结果的字节数*/

return ret_size;

}

/*注销tpm_chip结构体实例,释放其占用空间*/

void tpm_remove_hardware(struct device *dev)

{

struct tpm_chip *chip = dev_get_drvdata(dev);

if (chip == NULL) {

dev_err(dev, "No device data found\n");

return;

}

spin_lock(&driver_lock);

list_del_rcu(&chip->list);

spin_unlock(&driver_lock);

synchronize_rcu();

misc_deregister(&chip->vendor.miscdev);

sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);

tpm_bios_log_teardown(chip->bios_dir);

/*device结构对象引用计数器减1*/

put_device(chip->dev);

}

/*保存TPM设备状态,以备需要时恢复*/

int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)

{

struct tpm_chip *chip = dev_get_drvdata(dev);

struct tpm_cmd_t cmd;

int rc;

u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };

if (chip == NULL)

return -ENODEV;

if (tpm_suspend_pcr) {

cmd.header.in = pcrextend_header;

cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);

memcpy(cmd.params.pcrextend_in.hash, dummy_hash,

TPM_DIGEST_SIZE);

rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,

"extending dummy pcr before suspend");

}

cmd.header.in = savestate_header;

rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE,

"sending savestate before suspend");

return rc;

}

/*恢复TPM状态*/

int tpm_pm_resume(struct device *dev)

{

struct tpm_chip *chip = dev_get_drvdata(dev);

if (chip == NULL)

return -ENODEV;

return 0;

}

/*tpm_vendor_specific结构体中提供的释放TPM结构实例的操作*/

void tpm_dev_vendor_release(struct tpm_chip *chip)

{

if (chip->vendor.release)

chip->vendor.release(chip->dev);

clear_bit(chip->dev_num, dev_mask);

kfree(chip->vendor.miscdev.name);

}

/*一次注销所有与TPM设备驱动有关的实例对象并释放其占有的空间*/

void tpm_dev_release(struct device *dev)

{

struct tpm_chip *chip = dev_get_drvdata(dev);

tpm_dev_vendor_release(chip);

chip->release(dev);

kfree(chip);

}

/*注册tpm结构体实例并初始化*/

struct tpm_chip *tpm_register_hardware(struct device *dev,

const struct tpm_vendor_specific *entry)

{

#define DEVNAME_SIZE 7

char *devname;

struct tpm_chip *chip;

/*分配内存空间*/

chip = kzalloc(sizeof(*chip), GFP_KERNEL);

devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);

if (chip == NULL || devname == NULL)

goto out_free;

/*初始化互斥量*/

mutex_init(&chip->buffer_mutex);

mutex_init(&chip->tpm_mutex);

/*初始化tpm_chip结构实例链表*/

INIT_LIST_HEAD(&chip->list);

/*初始化工作队列*/

INIT_WORK(&chip->work, timeout_work);

/*设定用户读定时器的值*/

setup_timer(&chip->user_read_timer, user_reader_timeout,

(unsigned long)chip);

/*设置tpm_chip实例中vendor字段的值*/

memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));

/*设定dev_num字段的值*/

chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);

if (chip->dev_num >= TPM_NUM_DEVICES) {

dev_err(dev, "No available tpm device numbers\n");

goto out_free;

} else if (chip->dev_num == 0)

chip->vendor.miscdev.minor = TPM_MINOR;

else

chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;

set_bit(chip->dev_num, dev_mask);

scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);

chip->vendor.miscdev.name = devname;

chip->vendor.miscdev.parent = dev;

chip->dev = get_device(dev);

chip->release = dev->release;

dev->release = tpm_dev_release;

dev_set_drvdata(dev, chip);

if (misc_register(&chip->vendor.miscdev)) {

dev_err(chip->dev,

"unable to misc_register %s, minor %d\n",

chip->vendor.miscdev.name,

chip->vendor.miscdev.minor);

put_device(chip->dev);

return NULL;

}

if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {

misc_deregister(&chip->vendor.miscdev);

put_device(chip->dev);

return NULL;

}

chip->bios_dir = tpm_bios_log_setup(devname);

/*确保tpm_chip设备实例有效*/

spin_lock(&driver_lock);

list_add_rcu(&chip->list, &tpm_chip_list);

spin_unlock(&driver_lock);

return chip;

out_free:

/*注册失败,释放已经分配的空间*/

kfree(chip);

kfree(devname);

return NULL;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值