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;
}