[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Freeipmi-devel] [PATCH v2 3/5] Add support for parsing SPMI tables expo
From: |
dann frazier |
Subject: |
[Freeipmi-devel] [PATCH v2 3/5] Add support for parsing SPMI tables exposed via sysfs |
Date: |
Wed, 1 Aug 2018 11:01:10 -0600 |
Since 2.6.22 (released in 2007), the Linux kernel has exposed individual
ACPI tables under /sys/firmware/acpi/tables. When available, we can parse
these files instead of poking around in /dev/mem, which is more portable.
Keep the /dev/mem parsing code as a fallback for older Linux kernels.
---
ChangeLog | 3 +
libfreeipmi/locate/ipmi-locate-acpi-spmi.c | 116 ++++++++++++++++++++-
2 files changed, 114 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8858b7127..4cce75cf8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,9 @@
split the header off of the ACPI table, as it will be consumed
by the SPMI table template.
+ * libfreeipmi/locate/ipmi-locate-acpi-spmi.c: Add support for
+ parsing SPMI tables exposed via sysfs.
+
2018-07-31 Albert Chu <address@hidden>
* libfreeipmi/locate/ipmi-locate-acpi-spmi.c
diff --git a/libfreeipmi/locate/ipmi-locate-acpi-spmi.c
b/libfreeipmi/locate/ipmi-locate-acpi-spmi.c
index 4eb5adae7..503d4528e 100644
--- a/libfreeipmi/locate/ipmi-locate-acpi-spmi.c
+++ b/libfreeipmi/locate/ipmi-locate-acpi-spmi.c
@@ -598,6 +598,11 @@ static int _ipmi_acpi_get_table_dev_mem (ipmi_locate_ctx_t
ctx,
unsigned int table_instance,
uint8_t **acpi_table,
uint32_t *acpi_table_length);
+static int _ipmi_acpi_get_table_sysfs (ipmi_locate_ctx_t ctx,
+ char *signature,
+ unsigned int table_instance,
+ uint8_t **acpi_table,
+ uint32_t *acpi_table_length);
static int _ipmi_acpi_get_firmware_table (ipmi_locate_ctx_t ctx,
char *signature,
unsigned int table_instance,
@@ -1133,6 +1138,105 @@ _ipmi_acpi_get_table (ipmi_locate_ctx_t ctx,
return (rv);
}
+/*******************************************************************************
+ *
+ * FUNCTION:
+ * _ipmi_acpi_get_table_sysfs
+ *
+ * PARAMETERS:
+ * signature - signature of the table
+ * table_instance - Which instance of the firmware table
+ * acpi_table - ACPI table in malloc'ed memory
+ * acpi_table_length - ACPI table length
+ *
+ * RETURN:
+ * A return value of 0 means success. ACPI table (including header) is
+ * returned through acpi_table parameter.
+ *
+ * DESCRIPTION:
+ * Retrieve any ACPI table (including header) from sysfs.
+ *
+
******************************************************************************/
+static int
+_ipmi_acpi_get_table_sysfs (ipmi_locate_ctx_t ctx,
+ char *signature,
+ unsigned int table_instance,
+ uint8_t **acpi_table,
+ uint32_t *acpi_table_length)
+{
+ int sysfs_acpi_fd = -1;
+ int rv = -1;
+ static char const sysfs_fw_acpi_tables[] = "/sys/firmware/acpi/tables";
+ char *sysfs_path;
+ int instance_length;
+ int sysfs_path_length;
+ uint8_t *acpi_table_buf = NULL;
+
+ assert (ctx);
+ assert (ctx->magic == IPMI_LOCATE_CTX_MAGIC);
+ assert (signature);
+ assert (table_instance >= 0);
+ assert (acpi_table);
+ assert (acpi_table_length);
+
+ *acpi_table = NULL;
+
+ instance_length = (table_instance + 1) / 10 + 1;
+ sysfs_path_length = strlen (sysfs_fw_acpi_tables) + strlen(signature) + \
+ instance_length + 2;
+
+ if (!(sysfs_path = malloc (sysfs_path_length)))
+ {
+ LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_OUT_OF_MEMORY);
+ return (-1);
+ }
+
+ snprintf (sysfs_path, sysfs_path_length, "%s/%s%d",
+ sysfs_fw_acpi_tables, signature, table_instance + 1);
+ if ((sysfs_acpi_fd = open (sysfs_path, O_RDONLY)) < 0)
+ {
+ if (table_instance > 0)
+ goto cleanup;
+ /* If there is only 1 instance of a table on the system, the sysfs
+ file will be the same as the signature, (e.g.
+ /sys/firmware/acpi/tables/SPMI). If there are multiple instances
+ of the same table, they will have the instance # as a suffix (e.g.:
+ /sys/firmware/acpi/tables/SPMI1 & /sys/firmware/acpi/tables/SPMI2).
+ So, for table_instance == 0, we need to try both */
+ snprintf (sysfs_path, sysfs_path_length, "%s/%s",
+ sysfs_fw_acpi_tables, signature);
+ if ((sysfs_acpi_fd = open (sysfs_path, O_RDONLY)) < 0)
+ goto cleanup;
+ }
+ if ((*acpi_table_length = lseek (sysfs_acpi_fd, 0, SEEK_END)) == -1)
+ {
+ LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_SYSTEM_ERROR);
+ goto cleanup;
+ }
+ if ((lseek (sysfs_acpi_fd, 0, SEEK_SET)) == -1)
+ {
+ LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_SYSTEM_ERROR);
+ goto cleanup;
+ }
+ if (!(acpi_table_buf = malloc (*acpi_table_length)))
+ {
+ LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_OUT_OF_MEMORY);
+ goto cleanup;
+ }
+ if ((read (sysfs_acpi_fd, acpi_table_buf, *acpi_table_length)) !=
+ *acpi_table_length)
+ {
+ LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_SYSTEM_ERROR);
+ goto cleanup;
+ }
+
+ *acpi_table = acpi_table_buf;
+ rv = 0;
+ cleanup:
+ close (sysfs_acpi_fd);
+ return rv;
+}
+
/*******************************************************************************
*
* FUNCTION:
@@ -1393,12 +1497,14 @@ _ipmi_acpi_get_firmware_table (ipmi_locate_ctx_t ctx,
*sign_table_data = NULL;
- if ((_ipmi_acpi_get_table_dev_mem (ctx, signature,
- table_instance,
- &acpi_table,
- &acpi_table_length) != 0))
+ if ((_ipmi_acpi_get_table_sysfs (ctx, signature, table_instance,
+ &acpi_table, &acpi_table_length) != 0))
{
- LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_SYSTEM_ERROR);
+ if ((_ipmi_acpi_get_table_dev_mem (ctx, signature,
+ table_instance,
+ &acpi_table,
+ &acpi_table_length) != 0))
+ LOCATE_SET_ERRNUM (ctx, IPMI_LOCATE_ERR_SYSTEM_ERROR);
goto cleanup;
}
--
2.18.0
- [Freeipmi-devel] [PATCH v2 0/5], dann frazier, 2018/08/01
- [Freeipmi-devel] [PATCH v2 2/5] Split RSDT/XSDT parsing into new function, dann frazier, 2018/08/01
- [Freeipmi-devel] [PATCH v2 1/5] Don't try to separate the header from the ACPI table data, dann frazier, 2018/08/01
- [Freeipmi-devel] [PATCH v2 5/5] Correct order of bytes in specification_revision field of ACPI SPMI table, dann frazier, 2018/08/01
- [Freeipmi-devel] [PATCH v2 3/5] Add support for parsing SPMI tables exposed via sysfs,
dann frazier <=
- [Freeipmi-devel] [PATCH v2 4/5] Allow sysfs SPMI parsing on ARM platforms, dann frazier, 2018/08/01
- Re: [Freeipmi-devel] [PATCH v2 0/5], Albert Chu, 2018/08/01