linux的模块机制简析,Linux可信计算机制模块详细分析之核心文件分析(7)tpm.c核心代码注释(上)...

2.4.2.6 核心代码注释

/* tpm_chip_list 全局链表,用于存放多个tpm_chip对象实例*/

static LIST_HEAD(tpm_chip_list);

/*定义自旋锁*/

static DEFINE_SPINLOCK(driver_lock);

/*用户读取TPM命令执行结果超过设定时间时的操作*/

static void user_reader_timeout(unsigned long ptr)

{

struct tpm_chip *chip = (struct tpm_chip *) ptr;

/*调用执行任务,将任务加入工作队列*/

schedule_work(&chip->work);

}

/*TPM设备工作超过设定的时间时执行的操作:将数据缓存区读写互斥锁设置为0,清空数据缓存区的值*/

static void timeout_work(struct work_struct *work)

{/*通过work字段的地址获得tpm_chip结构体的首地址*/

struct tpm_chip *chip = container_of(work, struct tpm_chip, work);

/加锁互斥量*/

mutex_lock(&chip->buffer_mutex);

/*原子操作,设值数据缓冲区互斥锁为0*/

atomic_set(&chip->data_pending, 0);

/*将数据缓存区data_buffer的值设为0*/

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

/解锁互斥量*/

mutex_unlock(&chip->buffer_mutex);

}

/*返回等待时间:单位jiffies*/

unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,

u32 ordinal)

{

int duration_idx = TPM_UNDEFINED;

int duration = 0;

if (ordinal < TPM_MAX_ORDINAL)

duration_idx = tpm_ordinal_duration[ordinal];

else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <

TPM_MAX_PROTECTED_ORDINAL)

duration_idx =

tpm_protected_ordinal_duration[ordinal &

TPM_PROTECTED_ORDINAL_MASK];

if (duration_idx != TPM_UNDEFINED)

duration = chip->vendor.duration[duration_idx];

if (duration <= 0)

return 2 * 60 * HZ;

else

return duration;

}

/*tpm_transmit()用于在内核中给TPM芯片通信,将命令发送给TPM设备,等待TPM设备执行完成,读取执行结果给对应的驱动程序*/

static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,

size_t bufsiz)

{

ssize_t rc;

u32 count, ordinal;

unsigned long stop;

/*设置数据缓存区的大小*/

if (bufsiz > TPM_BUFSIZE)

bufsiz = TPM_BUFSIZE;

/*将32位的字节序转换为CPU字节序*/

count = be32_to_cpu(*((__be32 *) (buf + 2)));

ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));

if (count == 0)

return -ENODATA;

if (count > bufsiz) {

dev_err(chip->dev,

"invalid count value %x %zx \n", count, bufsiz);

return -E2BIG;

}

/*加锁互斥量*/

mutex_lock(&chip->tpm_mutex);

/*发送TPM命令给TPM设备*/

if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {

dev_err(chip->dev,

"tpm_transmit: tpm_send: error %zd\n", rc);

goto out;

}

if (chip->vendor.irq)

goto out_recv;

/计算TPM设备执行命令停止的时间*/

stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);

/*执行下列循环直到jiffies值大于stop的值*/

do {

/* 获取TPM设备状态*/

u8 status = chip->vendor.status(chip);

if ((status & chip->vendor.req_complete_mask) ==

chip->vendor.req_complete_val)

goto out_recv;

if ((status == chip->vendor.req_canceled)) {

dev_err(chip->dev, "Operation Canceled\n");

rc = -ECANCELED;

goto out;

}

/*让进程睡眠TPM_TIMEOUT秒,TPM_TIMEOUT定义在tpm.h文件中*/

msleep(TPM_TIMEOUT);/* CHECK */

rmb();

} while (time_before(jiffies, stop));

/*取消TPM芯片的操作*/

chip->vendor.cancel(chip);

dev_err(chip->dev, "Operation Timed out\n");

rc = -ETIME;

goto out;

out_recv:

/*从TPM设备接收TPM命令执行结果*/

rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);

if (rc < 0)

dev_err(chip->dev,

"tpm_transmit: tpm_recv: error %zd\n", rc);

out:

/*解锁互斥量*/

mutex_unlock(&chip->tpm_mutex);

return rc;

}

/*执行TPM命令并检查执行结果*/

static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,

int len, const char *desc)

{

int err;

len = tpm_transmit(chip,(u8 *) cmd, len);

if (len <  0)

return len;

else if (len < TPM_HEADER_SIZE)

return -EFAULT;

err = be32_to_cpu(cmd->header.out.return_code);

if (err != 0)

dev_err(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);

return err;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值