14f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering/* 24f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * Export SMBIOS/DMI info via sysfs to userspace 34f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * 44f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * Copyright 2007, Lennart Poettering 54f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * 64f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * Licensed under GPLv2 74f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering */ 84f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 94f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering#include <linux/module.h> 104f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering#include <linux/kernel.h> 114f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering#include <linux/init.h> 124f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering#include <linux/dmi.h> 134f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering#include <linux/device.h> 145a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 154f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 166374475661172d508a9b93a2740a3fdc9d899756Jean Delvarestruct dmi_device_attribute{ 176374475661172d508a9b93a2740a3fdc9d899756Jean Delvare struct device_attribute dev_attr; 186374475661172d508a9b93a2740a3fdc9d899756Jean Delvare int field; 196374475661172d508a9b93a2740a3fdc9d899756Jean Delvare}; 206374475661172d508a9b93a2740a3fdc9d899756Jean Delvare#define to_dmi_dev_attr(_dev_attr) \ 216374475661172d508a9b93a2740a3fdc9d899756Jean Delvare container_of(_dev_attr, struct dmi_device_attribute, dev_attr) 226374475661172d508a9b93a2740a3fdc9d899756Jean Delvare 236374475661172d508a9b93a2740a3fdc9d899756Jean Delvarestatic ssize_t sys_dmi_field_show(struct device *dev, 246374475661172d508a9b93a2740a3fdc9d899756Jean Delvare struct device_attribute *attr, 256374475661172d508a9b93a2740a3fdc9d899756Jean Delvare char *page) 266374475661172d508a9b93a2740a3fdc9d899756Jean Delvare{ 276374475661172d508a9b93a2740a3fdc9d899756Jean Delvare int field = to_dmi_dev_attr(attr)->field; 286374475661172d508a9b93a2740a3fdc9d899756Jean Delvare ssize_t len; 296374475661172d508a9b93a2740a3fdc9d899756Jean Delvare len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(field)); 306374475661172d508a9b93a2740a3fdc9d899756Jean Delvare page[len-1] = '\n'; 316374475661172d508a9b93a2740a3fdc9d899756Jean Delvare return len; 326374475661172d508a9b93a2740a3fdc9d899756Jean Delvare} 336374475661172d508a9b93a2740a3fdc9d899756Jean Delvare 346374475661172d508a9b93a2740a3fdc9d899756Jean Delvare#define DMI_ATTR(_name, _mode, _show, _field) \ 356374475661172d508a9b93a2740a3fdc9d899756Jean Delvare { .dev_attr = __ATTR(_name, _mode, _show, NULL), \ 366374475661172d508a9b93a2740a3fdc9d899756Jean Delvare .field = _field } 376374475661172d508a9b93a2740a3fdc9d899756Jean Delvare 386374475661172d508a9b93a2740a3fdc9d899756Jean Delvare#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field) \ 396374475661172d508a9b93a2740a3fdc9d899756Jean Delvarestatic struct dmi_device_attribute sys_dmi_##_name##_attr = \ 406374475661172d508a9b93a2740a3fdc9d899756Jean Delvare DMI_ATTR(_name, _mode, sys_dmi_field_show, _field); 414f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 424f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(bios_vendor, 0444, DMI_BIOS_VENDOR); 434f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(bios_version, 0444, DMI_BIOS_VERSION); 444f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(bios_date, 0444, DMI_BIOS_DATE); 454f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(sys_vendor, 0444, DMI_SYS_VENDOR); 464f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(product_name, 0444, DMI_PRODUCT_NAME); 474f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(product_version, 0444, DMI_PRODUCT_VERSION); 484f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(product_serial, 0400, DMI_PRODUCT_SERIAL); 494f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(product_uuid, 0400, DMI_PRODUCT_UUID); 504f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(board_vendor, 0444, DMI_BOARD_VENDOR); 514f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(board_name, 0444, DMI_BOARD_NAME); 524f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(board_version, 0444, DMI_BOARD_VERSION); 534f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(board_serial, 0400, DMI_BOARD_SERIAL); 544f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(board_asset_tag, 0444, DMI_BOARD_ASSET_TAG); 554f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(chassis_vendor, 0444, DMI_CHASSIS_VENDOR); 564f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(chassis_type, 0444, DMI_CHASSIS_TYPE); 574f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(chassis_version, 0444, DMI_CHASSIS_VERSION); 584f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(chassis_serial, 0400, DMI_CHASSIS_SERIAL); 594f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart PoetteringDEFINE_DMI_ATTR_WITH_SHOW(chassis_asset_tag, 0444, DMI_CHASSIS_ASSET_TAG); 604f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 614f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic void ascii_filter(char *d, const char *s) 624f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering{ 634f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering /* Filter out characters we don't want to see in the modalias string */ 644f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering for (; *s; s++) 654f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (*s > ' ' && *s < 127 && *s != ':') 664f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering *(d++) = *s; 674f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 684f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering *d = 0; 694f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering} 704f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 714f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic ssize_t get_modalias(char *buffer, size_t buffer_size) 724f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering{ 734f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering static const struct mafield { 744f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering const char *prefix; 754f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering int field; 764f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering } fields[] = { 774f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "bvn", DMI_BIOS_VENDOR }, 784f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "bvr", DMI_BIOS_VERSION }, 794f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "bd", DMI_BIOS_DATE }, 804f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "svn", DMI_SYS_VENDOR }, 814f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "pn", DMI_PRODUCT_NAME }, 824f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "pvr", DMI_PRODUCT_VERSION }, 834f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "rvn", DMI_BOARD_VENDOR }, 844f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "rn", DMI_BOARD_NAME }, 854f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "rvr", DMI_BOARD_VERSION }, 864f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "cvn", DMI_CHASSIS_VENDOR }, 874f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "ct", DMI_CHASSIS_TYPE }, 884f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { "cvr", DMI_CHASSIS_VERSION }, 894f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering { NULL, DMI_NONE } 904f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering }; 914f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 924f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ssize_t l, left; 934f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering char *p; 944f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering const struct mafield *f; 954f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 964f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering strcpy(buffer, "dmi"); 974f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering p = buffer + 3; left = buffer_size - 4; 984f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 994f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering for (f = fields; f->prefix && left > 0; f++) { 1004f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering const char *c; 1014f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering char *t; 1024f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1034f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering c = dmi_get_system_info(f->field); 1044f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (!c) 1054f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering continue; 1064f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1074f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering t = kmalloc(strlen(c) + 1, GFP_KERNEL); 1084f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (!t) 1094f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering break; 1104f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ascii_filter(t, c); 1114f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering l = scnprintf(p, left, ":%s%s", f->prefix, t); 1124f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering kfree(t); 1134f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1144f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering p += l; 1154f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering left -= l; 1164f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering } 1174f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1184f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering p[0] = ':'; 1194f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering p[1] = 0; 1204f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1214f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering return p - buffer + 1; 1224f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering} 1234f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1244f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic ssize_t sys_dmi_modalias_show(struct device *dev, 1254f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering struct device_attribute *attr, char *page) 1264f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering{ 1274f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ssize_t r; 1284f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering r = get_modalias(page, PAGE_SIZE-1); 1294f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering page[r] = '\n'; 1304f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering page[r+1] = 0; 1314f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering return r+1; 1324f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering} 1334f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 13434b51f39e23bc9e529830ddf6108381d4bab95a6Jean Delvarestatic struct device_attribute sys_dmi_modalias_attr = 13534b51f39e23bc9e529830ddf6108381d4bab95a6Jean Delvare __ATTR(modalias, 0444, sys_dmi_modalias_show, NULL); 1364f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1374f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2]; 1384f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1394f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic struct attribute_group sys_dmi_attribute_group = { 1404f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering .attrs = sys_dmi_attributes, 1414f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering}; 1424f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 143a4dbd6740df0872cdf0a86841f75beec8381964dDavid Brownellstatic const struct attribute_group* sys_dmi_attribute_groups[] = { 1444f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering &sys_dmi_attribute_group, 1454f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering NULL 1464f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering}; 1474f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1487eff2e7a8b65c25920207324e56611150eb1cd9aKay Sieversstatic int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) 1494f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering{ 1507eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers ssize_t len; 1517eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers 1527eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers if (add_uevent_var(env, "MODALIAS=")) 1537eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers return -ENOMEM; 1547eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers len = get_modalias(&env->buf[env->buflen - 1], 1557eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers sizeof(env->buf) - env->buflen); 1567eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers if (len >= (sizeof(env->buf) - env->buflen)) 1577eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers return -ENOMEM; 1587eff2e7a8b65c25920207324e56611150eb1cd9aKay Sievers env->buflen += len; 1594f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering return 0; 1604f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering} 1614f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1624f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic struct class dmi_class = { 1634f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering .name = "dmi", 1644f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering .dev_release = (void(*)(struct device *)) kfree, 1654f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering .dev_uevent = dmi_dev_uevent, 1664f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering}; 1674f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1684f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringstatic struct device *dmi_dev; 1694f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1704f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering/* Initialization */ 1714f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1724f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering#define ADD_DMI_ATTR(_name, _field) \ 1734f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (dmi_get_system_info(_field)) \ 1746374475661172d508a9b93a2740a3fdc9d899756Jean Delvare sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr; 1754f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 176ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare/* In a separate function to keep gcc 3.2 happy - do NOT merge this in 177ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare dmi_id_init! */ 178ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvarestatic void __init dmi_id_init_attr_table(void) 1794f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering{ 180ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare int i; 1814f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 1824f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering /* Not necessarily all DMI fields are available on all 1834f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * systems, hence let's built an attribute table of just 1844f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering * what's available */ 1854f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering i = 0; 1864f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(bios_vendor, DMI_BIOS_VENDOR); 1874f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(bios_version, DMI_BIOS_VERSION); 1884f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(bios_date, DMI_BIOS_DATE); 1894f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(sys_vendor, DMI_SYS_VENDOR); 1904f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(product_name, DMI_PRODUCT_NAME); 1914f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(product_version, DMI_PRODUCT_VERSION); 1924f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(product_serial, DMI_PRODUCT_SERIAL); 1934f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(product_uuid, DMI_PRODUCT_UUID); 1944f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(board_vendor, DMI_BOARD_VENDOR); 1954f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(board_name, DMI_BOARD_NAME); 1964f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(board_version, DMI_BOARD_VERSION); 1974f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(board_serial, DMI_BOARD_SERIAL); 1984f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(board_asset_tag, DMI_BOARD_ASSET_TAG); 1994f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(chassis_vendor, DMI_CHASSIS_VENDOR); 2004f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(chassis_type, DMI_CHASSIS_TYPE); 2014f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(chassis_version, DMI_CHASSIS_VERSION); 2024f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(chassis_serial, DMI_CHASSIS_SERIAL); 2034f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ADD_DMI_ATTR(chassis_asset_tag, DMI_CHASSIS_ASSET_TAG); 2044f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering sys_dmi_attributes[i++] = &sys_dmi_modalias_attr.attr; 205ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare} 206ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare 207ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvarestatic int __init dmi_id_init(void) 208ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare{ 209ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare int ret; 210ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare 211ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare if (!dmi_available) 212ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare return -ENODEV; 213ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare 214ce8c628abadaf16a44953301c68b9f54cf6898ccJean Delvare dmi_id_init_attr_table(); 2154f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2164f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ret = class_register(&dmi_class); 2174f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (ret) 2184f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering return ret; 2194f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2204f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering dmi_dev = kzalloc(sizeof(*dmi_dev), GFP_KERNEL); 2214f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (!dmi_dev) { 2224f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ret = -ENOMEM; 2234f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering goto fail_class_unregister; 2244f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering } 2254f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2264f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering dmi_dev->class = &dmi_class; 2276ff4dd36d6386f6fb3e1e4eac56f0d22d59a1d5cKay Sievers dev_set_name(dmi_dev, "id"); 2284f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering dmi_dev->groups = sys_dmi_attribute_groups; 2294f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2304f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering ret = device_register(dmi_dev); 2314f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering if (ret) 2325b232f753a842fa66eab86e51dc76e3929d853afAxel Lin goto fail_free_dmi_dev; 2334f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2344f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering return 0; 2354f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2365b232f753a842fa66eab86e51dc76e3929d853afAxel Linfail_free_dmi_dev: 2375b232f753a842fa66eab86e51dc76e3929d853afAxel Lin kfree(dmi_dev); 2384f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringfail_class_unregister: 2394f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2404f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering class_unregister(&dmi_class); 2414f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2424f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering return ret; 2434f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering} 2444f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poettering 2454f5c791a850e5305a5b1b48d0e4b4de248dc96f9Lennart Poetteringarch_initcall(dmi_id_init); 246