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. --- libfreeipmi/locate/ipmi-locate-acpi-spmi.c | 97 ++++++++++++++++++++-- 1 file changed, 92 insertions(+), 5 deletions(-)
diff --git a/libfreeipmi/locate/ipmi-locate-acpi-spmi.c b/libfreeipmi/locate/ipmi-locate-acpi-spmi.c index abfb987e1..c243d16f4 100644 --- a/libfreeipmi/locate/ipmi-locate-acpi-spmi.c +++ b/libfreeipmi/locate/ipmi-locate-acpi-spmi.c @@ -598,6 +598,10 @@ 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, + 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 +1137,87 @@ _ipmi_acpi_get_table (ipmi_locate_ctx_t ctx, return (rv); } +/******************************************************************************* + * + * FUNCTION: + * _ipmi_acpi_get_table_sysfs + * + * PARAMETERS: + * signature - signature of the 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, + 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 sysfs_path_length; + uint8_t *acpi_table_buf = NULL; + + assert (ctx); + assert (ctx->magic == IPMI_LOCATE_CTX_MAGIC); + assert (signature); + assert (acpi_table); + assert (acpi_table_length); + + *acpi_table = NULL; + + sysfs_path_length = strlen (sysfs_fw_acpi_tables) + strlen(signature) + 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", + 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 +1478,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, + &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 mailing list Freeipmi-devel@gnu.org https://lists.gnu.org/mailman/listinfo/freeipmi-devel