freeipmi-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Freeipmi-devel] [PATCH 3/5] Add support for parsing SPMI table exposed


From: dann frazier
Subject: [Freeipmi-devel] [PATCH 3/5] Add support for parsing SPMI table exposed via sysfs
Date: Tue, 31 Jul 2018 11:42:25 -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.
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]