⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmi-id.c

📁 linux 内核源代码
💻 C
字号:
/* * Export SMBIOS/DMI info via sysfs to userspace * * Copyright 2007, Lennart Poettering * * Licensed under GPLv2 */#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/dmi.h>#include <linux/device.h>#include <linux/autoconf.h>struct dmi_device_attribute{	struct device_attribute dev_attr;	int field;};#define to_dmi_dev_attr(_dev_attr) \	container_of(_dev_attr, struct dmi_device_attribute, dev_attr)static ssize_t sys_dmi_field_show(struct device *dev,				  struct device_attribute *attr,				  char *page){	int field = to_dmi_dev_attr(attr)->field;	ssize_t len;	len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(field));	page[len-1] = '\n';	return len;}#define DMI_ATTR(_name, _mode, _show, _field)			\	{ .dev_attr = __ATTR(_name, _mode, _show, NULL),	\	  .field = _field }#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field)		\static struct dmi_device_attribute sys_dmi_##_name##_attr =	\	DMI_ATTR(_name, _mode, sys_dmi_field_show, _field);DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,		0444, DMI_BIOS_VENDOR);DEFINE_DMI_ATTR_WITH_SHOW(bios_version,		0444, DMI_BIOS_VERSION);DEFINE_DMI_ATTR_WITH_SHOW(bios_date,		0444, DMI_BIOS_DATE);DEFINE_DMI_ATTR_WITH_SHOW(sys_vendor,		0444, DMI_SYS_VENDOR);DEFINE_DMI_ATTR_WITH_SHOW(product_name,		0444, DMI_PRODUCT_NAME);DEFINE_DMI_ATTR_WITH_SHOW(product_version,	0444, DMI_PRODUCT_VERSION);DEFINE_DMI_ATTR_WITH_SHOW(product_serial,	0400, DMI_PRODUCT_SERIAL);DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,		0400, DMI_PRODUCT_UUID);DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,		0444, DMI_BOARD_VENDOR);DEFINE_DMI_ATTR_WITH_SHOW(board_name,		0444, DMI_BOARD_NAME);DEFINE_DMI_ATTR_WITH_SHOW(board_version,	0444, DMI_BOARD_VERSION);DEFINE_DMI_ATTR_WITH_SHOW(board_serial,		0400, DMI_BOARD_SERIAL);DEFINE_DMI_ATTR_WITH_SHOW(board_asset_tag,	0444, DMI_BOARD_ASSET_TAG);DEFINE_DMI_ATTR_WITH_SHOW(chassis_vendor,	0444, DMI_CHASSIS_VENDOR);DEFINE_DMI_ATTR_WITH_SHOW(chassis_type,		0444, DMI_CHASSIS_TYPE);DEFINE_DMI_ATTR_WITH_SHOW(chassis_version,	0444, DMI_CHASSIS_VERSION);DEFINE_DMI_ATTR_WITH_SHOW(chassis_serial,	0400, DMI_CHASSIS_SERIAL);DEFINE_DMI_ATTR_WITH_SHOW(chassis_asset_tag,	0444, DMI_CHASSIS_ASSET_TAG);static void ascii_filter(char *d, const char *s){	/* Filter out characters we don't want to see in the modalias string */	for (; *s; s++)		if (*s > ' ' && *s < 127 && *s != ':')			*(d++) = *s;	*d = 0;}static ssize_t get_modalias(char *buffer, size_t buffer_size){	static const struct mafield {		const char *prefix;		int field;	} fields[] = {		{ "bvn", DMI_BIOS_VENDOR },		{ "bvr", DMI_BIOS_VERSION },		{ "bd",  DMI_BIOS_DATE },		{ "svn", DMI_SYS_VENDOR },		{ "pn",  DMI_PRODUCT_NAME },		{ "pvr", DMI_PRODUCT_VERSION },		{ "rvn", DMI_BOARD_VENDOR },		{ "rn",  DMI_BOARD_NAME },		{ "rvr", DMI_BOARD_VERSION },		{ "cvn", DMI_CHASSIS_VENDOR },		{ "ct",  DMI_CHASSIS_TYPE },		{ "cvr", DMI_CHASSIS_VERSION },		{ NULL,  DMI_NONE }	};	ssize_t l, left;	char *p;	const struct mafield *f;	strcpy(buffer, "dmi");	p = buffer + 3; left = buffer_size - 4;	for (f = fields; f->prefix && left > 0; f++) {		const char *c;		char *t;		c = dmi_get_system_info(f->field);		if (!c)			continue;		t = kmalloc(strlen(c) + 1, GFP_KERNEL);		if (!t)			break;		ascii_filter(t, c);		l = scnprintf(p, left, ":%s%s", f->prefix, t);		kfree(t);		p += l;		left -= l;	}	p[0] = ':';	p[1] = 0;	return p - buffer + 1;}static ssize_t sys_dmi_modalias_show(struct device *dev,				     struct device_attribute *attr, char *page){	ssize_t r;	r = get_modalias(page, PAGE_SIZE-1);	page[r] = '\n';	page[r+1] = 0;	return r+1;}static struct device_attribute sys_dmi_modalias_attr =	__ATTR(modalias, 0444, sys_dmi_modalias_show, NULL);static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2];static struct attribute_group sys_dmi_attribute_group = {	.attrs = sys_dmi_attributes,};static struct attribute_group* sys_dmi_attribute_groups[] = {	&sys_dmi_attribute_group,	NULL};static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env){	ssize_t len;	if (add_uevent_var(env, "MODALIAS="))		return -ENOMEM;	len = get_modalias(&env->buf[env->buflen - 1],			   sizeof(env->buf) - env->buflen);	if (len >= (sizeof(env->buf) - env->buflen))		return -ENOMEM;	env->buflen += len;	return 0;}static struct class dmi_class = {	.name = "dmi",	.dev_release = (void(*)(struct device *)) kfree,	.dev_uevent = dmi_dev_uevent,};static struct device *dmi_dev;/* Initialization */#define ADD_DMI_ATTR(_name, _field) \	if (dmi_get_system_info(_field)) \		sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr;/* In a separate function to keep gcc 3.2 happy - do NOT merge this in   dmi_id_init! */static void __init dmi_id_init_attr_table(void){	int i;	/* Not necessarily all DMI fields are available on all	 * systems, hence let's built an attribute table of just	 * what's available */	i = 0;	ADD_DMI_ATTR(bios_vendor,       DMI_BIOS_VENDOR);	ADD_DMI_ATTR(bios_version,      DMI_BIOS_VERSION);	ADD_DMI_ATTR(bios_date,         DMI_BIOS_DATE);	ADD_DMI_ATTR(sys_vendor,        DMI_SYS_VENDOR);	ADD_DMI_ATTR(product_name,      DMI_PRODUCT_NAME);	ADD_DMI_ATTR(product_version,   DMI_PRODUCT_VERSION);	ADD_DMI_ATTR(product_serial,    DMI_PRODUCT_SERIAL);	ADD_DMI_ATTR(product_uuid,      DMI_PRODUCT_UUID);	ADD_DMI_ATTR(board_vendor,      DMI_BOARD_VENDOR);	ADD_DMI_ATTR(board_name,        DMI_BOARD_NAME);	ADD_DMI_ATTR(board_version,     DMI_BOARD_VERSION);	ADD_DMI_ATTR(board_serial,      DMI_BOARD_SERIAL);	ADD_DMI_ATTR(board_asset_tag,   DMI_BOARD_ASSET_TAG);	ADD_DMI_ATTR(chassis_vendor,    DMI_CHASSIS_VENDOR);	ADD_DMI_ATTR(chassis_type,      DMI_CHASSIS_TYPE);	ADD_DMI_ATTR(chassis_version,   DMI_CHASSIS_VERSION);	ADD_DMI_ATTR(chassis_serial,    DMI_CHASSIS_SERIAL);	ADD_DMI_ATTR(chassis_asset_tag, DMI_CHASSIS_ASSET_TAG);	sys_dmi_attributes[i++] = &sys_dmi_modalias_attr.attr;}static int __init dmi_id_init(void){	int ret;	if (!dmi_available)		return -ENODEV;	dmi_id_init_attr_table();	ret = class_register(&dmi_class);	if (ret)		return ret;	dmi_dev = kzalloc(sizeof(*dmi_dev), GFP_KERNEL);	if (!dmi_dev) {		ret = -ENOMEM;		goto fail_class_unregister;	}	dmi_dev->class = &dmi_class;	strcpy(dmi_dev->bus_id, "id");	dmi_dev->groups = sys_dmi_attribute_groups;	ret = device_register(dmi_dev);	if (ret)		goto fail_class_unregister;	return 0;fail_class_unregister:	class_unregister(&dmi_class);	return ret;}arch_initcall(dmi_id_init);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -