// SPDX-License-Identifier: GPL-2.0-only /* * dmi-sysfs.c * * This module exports the DMI tables read-only to userspace through the * sysfs file system. * * Data is currently found below * /sys/firmware/dmi/... * * DMI attributes are presented in attribute files with names * formatted using %d-%d, so that the first integer indicates the * structure type (0-255), and the second field is the instance of that * entry. * * Copyright 2011 Google, Inc.
*/
#define MAX_ENTRY_TYPE 255 /* Most of these aren't used, but we consider
the top entry type is only 8 bits */
struct dmi_sysfs_entry { struct dmi_header dh; struct kobject kobj; int instance; int position; struct list_head list; struct kobject *child;
};
/* * Global list of dmi_sysfs_entry. Even though this should only be * manipulated at setup and teardown, the lazy nature of the kobject * system means we get lazy removes.
*/ static LIST_HEAD(entry_list); static DEFINE_SPINLOCK(entry_list_lock);
/* dmi_sysfs_attribute - Top level attribute. used by all entries. */ struct dmi_sysfs_attribute { struct attribute attr;
ssize_t (*show)(struct dmi_sysfs_entry *entry, char *buf);
};
/* * dmi_sysfs_mapped_attribute - Attribute where we require the entry be * mapped in. Use in conjunction with dmi_sysfs_specialize_attr_ops.
*/ struct dmi_sysfs_mapped_attribute { struct attribute attr;
ssize_t (*show)(struct dmi_sysfs_entry *entry, conststruct dmi_header *dh, char *buf);
};
/* Is this the entry we want? */ if (dh->type != entry->dh.type) return;
if (data->instance_countdown != 0) { /* try the next instance? */
data->instance_countdown--; return;
}
/* * Don't ever revisit the instance. Short circuit later * instances by letting the instance_countdown run negative
*/
data->instance_countdown--;
/* Found the entry */
data->ret = data->callback(entry, dh, data->private);
}
/* State for passing the read parameters through dmi_find_entry() */ struct dmi_read_state { char *buf;
loff_t pos;
size_t count;
};
static ssize_t find_dmi_entry(struct dmi_sysfs_entry *entry,
dmi_callback callback, void *private)
{ struct find_dmi_data data = {
.entry = entry,
.callback = callback,
.private = private,
.instance_countdown = entry->instance,
.ret = -EIO, /* To signal the entry disappeared */
}; int ret;
ret = dmi_walk(find_dmi_entry_helper, &data); /* This shouldn't happen, but just in case. */ if (ret) return -EINVAL; return data.ret;
}
/* * Calculate and return the byte length of the dmi entry identified by * dh. This includes both the formatted portion as well as the * unformatted string space, including the two trailing nul characters.
*/ static size_t dmi_entry_length(conststruct dmi_header *dh)
{ constchar *p = (constchar *)dh;
p += dh->length;
while (p[0] || p[1])
p++;
return 2 + p - (constchar *)dh;
}
/************************************************* * Support bits for specialized DMI entry support
*************************************************/ struct dmi_entry_attr_show_data { struct attribute *attr; char *buf;
};
static ssize_t dmi_entry_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
{ struct dmi_entry_attr_show_data data = {
.attr = attr,
.buf = buf,
}; /* Find the entry according to our parent and call the
* normalized show method hanging off of the attribute */ return find_dmi_entry(to_entry(kobj->parent),
dmi_entry_attr_show_helper, &data);
}
/* No locks, we are on our way out */
list_for_each_entry_safe(entry, next, &entry_list, list) {
kobject_put(entry->child);
kobject_put(&entry->kobj);
}
}
staticint __init dmi_sysfs_init(void)
{ int error; int val;
if (!dmi_kobj) {
pr_debug("dmi-sysfs: dmi entry is absent.\n");
error = -ENODATA; goto err;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.2Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.