* [PATCH] [-mm]: ACPI: expose ACPI tables in sysfs
@ 2007-06-14 9:43 Zhang Rui
2007-06-14 11:31 ` Henrique de Moraes Holschuh
0 siblings, 1 reply; 3+ messages in thread
From: Zhang Rui @ 2007-06-14 9:43 UTC (permalink / raw)
To: linux-acpi; +Cc: lenb
From: Zhang Rui <rui.zhang@intel.com>
This is the basic functionality of exposing ACPI tables in sysfs.
Only static tables are exposed to user space in this patch.
Every static table has a file under /sys/firmware/acpi/tables/.
The file name is constituted of the table signature and instance number.
With this patch, we can get all the static ACPI tables except for RSDP and RSDT.
For example, "#cat /sys/firmware/acpi/tables/dsdt > /tmp/dsdt.bin"
can help you get the content of dsdt table.
But iasl is still needed to disassemble the acpi tables.
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
drivers/acpi/system.c | 165 +++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 144 insertions(+), 21 deletions(-)
Index: linux-2.6.22-rc4/drivers/acpi/system.c
===================================================================
--- linux-2.6.22-rc4.orig/drivers/acpi/system.c 2007-06-13 16:00:45.000000000 +0800
+++ linux-2.6.22-rc4/drivers/acpi/system.c 2007-06-14 19:06:03.000000000 +0800
@@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system");
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DEVICE_NAME "System"
-#define ACPI_SYSTEM_FILE_INFO "info"
-#define ACPI_SYSTEM_FILE_EVENT "event"
-#define ACPI_SYSTEM_FILE_DSDT "dsdt"
-#define ACPI_SYSTEM_FILE_FADT "fadt"
/*
* Make ACPICA version work as module param
*/
-static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
+static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
+{
int result;
result = sprintf(buffer, "%x", ACPI_CA_VERSION);
@@ -58,9 +55,126 @@ static int param_get_acpica_version(char
module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
/* --------------------------------------------------------------------------
+ FS Interface (/sys)
+ -------------------------------------------------------------------------- */
+static LIST_HEAD(acpi_table_attr_list);
+static struct kobject tables_kobj;
+
+struct acpi_table_attr {
+ struct bin_attribute attr;
+ char name[8];
+ int instance;
+ struct list_head node;
+};
+
+static ssize_t acpi_table_show(struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t offset, size_t count)
+{
+ struct acpi_table_attr *table_attr =
+ container_of(bin_attr, struct acpi_table_attr, attr);
+ struct acpi_table_header *table_header = NULL;
+ acpi_status status;
+ ssize_t ret_count = count;
+
+ status =
+ acpi_get_table(table_attr->name, table_attr->instance,
+ &table_header);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ if (offset >= table_header->length) {
+ ret_count = 0;
+ goto end;
+ }
+
+ if (offset + ret_count > table_header->length)
+ ret_count = table_header->length - offset;
+
+ memcpy(buf, ((char *)table_header) + offset, ret_count);
+
+ end:
+ return ret_count;
+}
+
+static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
+ struct acpi_table_header *table_header)
+{
+ struct acpi_table_header *header = NULL;
+ struct acpi_table_attr *attr = NULL;
+
+ memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
+
+ list_for_each_entry(attr, &acpi_table_attr_list, node) {
+ if (!memcmp(table_header->signature, attr->name,
+ ACPI_NAME_SIZE))
+ if (table_attr->instance < attr->instance)
+ table_attr->instance = attr->instance;
+ }
+ table_attr->instance++;
+
+ if (table_attr->instance > 1 || (table_attr->instance == 1 &&
+ !acpi_get_table(table_header->
+ signature, 2,
+ &header)))
+ sprintf(table_attr->name + 4, "%d", table_attr->instance);
+
+ table_attr->attr.size = 0;
+ table_attr->attr.read = acpi_table_show;
+ table_attr->attr.attr.name = table_attr->name;
+ table_attr->attr.attr.mode = 0444;
+ table_attr->attr.attr.owner = THIS_MODULE;
+
+ return;
+}
+
+static int acpi_system_sysfs_init(void)
+{
+ struct acpi_table_attr *table_attr;
+ struct acpi_table_header *table_header = NULL;
+ int table_index = 0;
+ int result;
+
+ tables_kobj.parent = &acpi_subsys.kobj;
+ kobject_set_name(&tables_kobj, "tables");
+ result = kobject_register(&tables_kobj);
+ if (result)
+ return result;
+
+ do {
+ result = acpi_get_table_by_index(table_index, &table_header);
+ if (!result) {
+ table_index++;
+ table_attr = NULL;
+ table_attr =
+ kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+ if (!table_attr)
+ return -ENOMEM;
+
+ acpi_table_attr_init(table_attr, table_header);
+ result =
+ sysfs_create_bin_file(&tables_kobj,
+ &table_attr->attr);
+ if (result) {
+ kfree(table_attr);
+ return result;
+ } else
+ list_add_tail(&table_attr->node,
+ &acpi_table_attr_list);
+ }
+ } while (!result);
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCFS
+#define ACPI_SYSTEM_FILE_INFO "info"
+#define ACPI_SYSTEM_FILE_EVENT "event"
+#define ACPI_SYSTEM_FILE_DSDT "dsdt"
+#define ACPI_SYSTEM_FILE_FADT "fadt"
static int acpi_system_read_info(struct seq_file *seq, void *offset)
{
@@ -80,7 +194,6 @@ static const struct file_operations acpi
.llseek = seq_lseek,
.release = single_release,
};
-#endif
static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
loff_t *);
@@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file,
struct acpi_table_header *dsdt = NULL;
ssize_t res;
-
status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
if (ACPI_FAILURE(status))
return -ENODEV;
- res = simple_read_from_buffer(buffer, count, ppos,
- dsdt, dsdt->length);
+ res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
return res;
}
@@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file,
struct acpi_table_header *fadt = NULL;
ssize_t res;
-
status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
if (ACPI_FAILURE(status))
return -ENODEV;
- res = simple_read_from_buffer(buffer, count, ppos,
- fadt, fadt->length);
+ res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
return res;
}
-static int __init acpi_system_init(void)
+static int acpi_system_procfs_init(void)
{
struct proc_dir_entry *entry;
int error = 0;
char *name;
-
- if (acpi_disabled)
- return 0;
-
-#ifdef CONFIG_ACPI_PROCFS
/* 'info' [R] */
name = ACPI_SYSTEM_FILE_INFO;
entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -153,7 +257,6 @@ static int __init acpi_system_init(void)
else {
entry->proc_fops = &acpi_system_info_ops;
}
-#endif
/* 'dsdt' [R] */
name = ACPI_SYSTEM_FILE_DSDT;
@@ -177,12 +280,32 @@ static int __init acpi_system_init(void)
Error:
remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
-#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
-#endif
error = -EFAULT;
goto Done;
}
+#else
+static int acpi_system_procfs_init(void)
+{
+ return 0;
+}
+#endif
+
+static int __init acpi_system_init(void)
+{
+ int result = 0;
+
+ if (acpi_disabled)
+ return 0;
+
+ result = acpi_system_procfs_init();
+ if (result)
+ return result;
+
+ result = acpi_system_sysfs_init();
+
+ return result;
+}
subsys_initcall(acpi_system_init);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] [-mm]: ACPI: expose ACPI tables in sysfs
2007-06-14 9:43 [PATCH] [-mm]: ACPI: expose ACPI tables in sysfs Zhang Rui
@ 2007-06-14 11:31 ` Henrique de Moraes Holschuh
2007-06-15 1:09 ` Zhang Rui
0 siblings, 1 reply; 3+ messages in thread
From: Henrique de Moraes Holschuh @ 2007-06-14 11:31 UTC (permalink / raw)
To: Zhang Rui; +Cc: linux-acpi, lenb
Will we get the dynamic tables exported in a later patch?
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] [-mm]: ACPI: expose ACPI tables in sysfs
2007-06-14 11:31 ` Henrique de Moraes Holschuh
@ 2007-06-15 1:09 ` Zhang Rui
0 siblings, 0 replies; 3+ messages in thread
From: Zhang Rui @ 2007-06-15 1:09 UTC (permalink / raw)
To: Henrique de Moraes Holschuh; +Cc: linux-acpi@vger, lenb
On Thu, 2007-06-14 at 08:31 -0300, Henrique de Moraes Holschuh wrote:
> Will we get the dynamic tables exported in a later patch?
>
Yes. I send the patch for static tables first in hopes of
it can hit 2.6.23.
The patch for dynamic tables needs some hooks in ACPICA code.
And it may take some time, maybe a couple of weeks.
Thanks,
Rui
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-06-15 1:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-14 9:43 [PATCH] [-mm]: ACPI: expose ACPI tables in sysfs Zhang Rui
2007-06-14 11:31 ` Henrique de Moraes Holschuh
2007-06-15 1:09 ` Zhang Rui
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox