hwrng相关的sysfs

在driver/char/hwrng/core.c中会生成一个文件系统如下:
可以查询可以选择的hwrng,可以看当前选择的hwrng,以及手动选择hwrng
./sys/devices/virtual/misc/hw_random/rng_current
[root@ip134 /]# cd /sys/devices/virtual/misc/hw_random/
[root@ip134 hw_random]# ls
dev  power  rng_available  rng_current  rng_selected  subsystem  uevent
[root@ip134 hw_random]# cat rng_available

[root@ip134 hw_random]# cat rng_current
none
[root@ip134 hw_random]#
我们看看rng_available的实现
static ssize_t hwrng_attr_available_show(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{
	int err;
	struct hwrng *rng;

	err = mutex_lock_interruptible(&rng_mutex);
	if (err)
		return -ERESTARTSYS;
	buf[0] = '\0';
#可见这里所有的hwrng都是放在rng_list中,只要遍历这个就可以得到所有的hwrng
	list_for_each_entry(rng, &rng_list, list) {
		strlcat(buf, rng->name, PAGE_SIZE);
		strlcat(buf, " ", PAGE_SIZE);
	}
	strlcat(buf, "\n", PAGE_SIZE);
	mutex_unlock(&rng_mutex);

	return strlen(buf);
}
rng_selected 用于从rng_list中选择一个hwrng
static ssize_t hwrng_attr_selected_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
#就是设置cur_rng_set_by_user 为想要的hwrng就行,会有个现成自动切换到用户手动选择的hwrng
	return snprintf(buf, PAGE_SIZE, "%d\n", cur_rng_set_by_user);
}

而rng_current 则可以查询并设置hwrng
显示rng_current
static ssize_t hwrng_attr_current_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{
	ssize_t ret;
	struct hwrng *rng;
#得到当前的hwrng
	rng = get_current_rng();
	if (IS_ERR(rng))
		return PTR_ERR(rng);
#将当前hwrng的name打印出来
	ret = snprintf(buf, PAGE_SIZE, "%s\n", rng ? rng->name : "none");
	put_rng(rng);

	return ret;
}
设置rng_current

static ssize_t hwrng_attr_current_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t len)
{
	int err = -ENODEV;
	struct hwrng *rng, *old_rng, *new_rng;

	err = mutex_lock_interruptible(&rng_mutex);
	if (err)
		return -ERESTARTSYS;
#保存老的hwrng
	old_rng = current_rng;
#如果用户给的参数是空的,系统自动选择排名第一的rhwng
	if (sysfs_streq(buf, "")) {
		err = enable_best_rng();
	} else {
#比较用户设置的hwrng的name,如果确实存在着用用户设置的hwrng作为current hwrng,并设置标志cur_rng_set_by_user 
		list_for_each_entry(rng, &rng_list, list) {
			if (sysfs_streq(rng->name, buf)) {
				cur_rng_set_by_user = 1;
				err = set_current_rng(rng);
				break;
			}
		}
	}
#获得当前current的hwrng
	new_rng = get_current_rng_nolock();
	mutex_unlock(&rng_mutex);
#如果新的hwrng 不为null,且不等于老的hwrng,曾增加随机值
	if (new_rng) {
		if (new_rng != old_rng)
			add_early_randomness(new_rng);
		put_rng(new_rng);
	}

	return err ? : len;
}

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/113632532