Sync from SUSE:SLFO:Main librtas revision 219e53c2fa80d95f7f213c84093ff785
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
From 569da8e5f0d5009694dc2def350cb9cd2c1d81a6 Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Date: Sat, 12 Aug 2023 12:41:36 -0500
|
||||
Subject: [PATCH 1/6] librtas: expose low-level RTAS call APIs internally
|
||||
|
||||
Make these functions available outside of syscall_calls.c, marking
|
||||
them hidden so that they aren't exposed in the library ABI.
|
||||
|
||||
The implementations of librtas APIs will move into separate C files as
|
||||
they gain support for new interfaces offered by the kernel.
|
||||
|
||||
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
---
|
||||
librtas_src/internal.h | 5 +++++
|
||||
librtas_src/syscall_calls.c | 11 ++++++-----
|
||||
2 files changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/librtas_src/internal.h b/librtas_src/internal.h
|
||||
index 3b6ba88..97411d3 100644
|
||||
--- a/librtas_src/internal.h
|
||||
+++ b/librtas_src/internal.h
|
||||
@@ -52,6 +52,11 @@ int read_entire_file(int fd, char **buf, size_t *len);
|
||||
int rtas_token(const char *call_name);
|
||||
int sanity_check(void);
|
||||
|
||||
+#define CALL_AGAIN 1
|
||||
+unsigned int handle_delay(int status, uint64_t * elapsed);
|
||||
+int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...);
|
||||
+int rtas_call(const char *name, int ninputs, int nrets, ...);
|
||||
+
|
||||
#define BITS32_LO(_num) (uint32_t) (_num & 0xffffffffll)
|
||||
#define BITS32_HI(_num) (uint32_t) (_num >> 32)
|
||||
#define BITS64(_high, _low) (uint64_t) (((uint64_t) _high << 32) | _low)
|
||||
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
||||
index 1e09217..eabc5ea 100644
|
||||
--- a/librtas_src/syscall_calls.c
|
||||
+++ b/librtas_src/syscall_calls.c
|
||||
@@ -32,8 +32,6 @@
|
||||
#include "internal.h"
|
||||
#include "librtas.h"
|
||||
|
||||
-#define CALL_AGAIN 1
|
||||
-
|
||||
int dbg_lvl = 0;
|
||||
static uint64_t rtas_timeout_ms;
|
||||
|
||||
@@ -65,7 +63,8 @@ int sanity_check(void)
|
||||
* CALL_AGAIN if the status is delay related
|
||||
* RTAS_TIMEOUT if the requested timeout has been exceeded
|
||||
*/
|
||||
-static unsigned int handle_delay(int status, uint64_t * elapsed)
|
||||
+__attribute__((visibility("hidden")))
|
||||
+unsigned int handle_delay(int status, uint64_t * elapsed)
|
||||
{
|
||||
int order = status - EXTENDED_DELAY_MIN;
|
||||
unsigned long ms = 0;
|
||||
@@ -213,7 +212,8 @@ static int _rtas_call(int delay_handling, int token, int ninputs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...)
|
||||
+__attribute__((visibility("hidden")))
|
||||
+int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rc, token;
|
||||
@@ -229,7 +229,8 @@ static int rtas_call_no_delay(const char *name, int ninputs, int nrets, ...)
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int rtas_call(const char *name, int ninputs, int nrets, ...)
|
||||
+__attribute__((visibility("hidden")))
|
||||
+int rtas_call(const char *name, int ninputs, int nrets, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rc, token;
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,198 +0,0 @@
|
||||
From ee06898b1e7807a6e201b281ffc8ee3fa96136f4 Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Date: Sat, 12 Aug 2023 12:44:38 -0500
|
||||
Subject: [PATCH 2/6] librtas: move VPD code into separate module
|
||||
|
||||
This code will gain the ability to retrieve VPD using a different
|
||||
interface exposed by newer kernels. This will be a lot of additional
|
||||
code, so move it out of syscall_calls.c.
|
||||
|
||||
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
librtas_src/syscall_calls.c | 67 ------------------------------
|
||||
librtas_src/vpd.c | 81 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 82 insertions(+), 67 deletions(-)
|
||||
create mode 100644 librtas_src/vpd.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index c4bf09d..37df243 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -28,6 +28,7 @@ LIBRTAS_LIBRARY_VERSION = $(LIBRTAS_CURRENT):$(LIBRTAS_REVISION):$(LIBRTAS_AGE)
|
||||
lib_LTLIBRARIES += librtas.la
|
||||
librtas_la_LDFLAGS = -version-info $(LIBRTAS_LIBRARY_VERSION)
|
||||
librtas_la_SOURCES = \
|
||||
+ librtas_src/vpd.c \
|
||||
librtas_src/ofdt.c \
|
||||
librtas_src/syscall_calls.c \
|
||||
librtas_src/syscall_rmo.c
|
||||
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
||||
index eabc5ea..05f3c7c 100644
|
||||
--- a/librtas_src/syscall_calls.c
|
||||
+++ b/librtas_src/syscall_calls.c
|
||||
@@ -753,73 +753,6 @@ int rtas_get_time(uint32_t *year, uint32_t *month, uint32_t *day,
|
||||
return rc ? rc : status;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * rtas_get_vpd
|
||||
- * @brief Interface to the ibm,get-vpd rtas call
|
||||
- *
|
||||
- * @param loc_code location code
|
||||
- * @param workarea additional args to rtas call
|
||||
- * @param size
|
||||
- * @param sequence
|
||||
- * @param seq_next
|
||||
- * @param bytes_ret
|
||||
- * @return 0 on success, !0 otherwise
|
||||
- */
|
||||
-int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||
- unsigned int sequence, unsigned int *seq_next,
|
||||
- unsigned int *bytes_ret)
|
||||
-{
|
||||
- uint32_t kernbuf_pa;
|
||||
- uint32_t loc_pa = 0;
|
||||
- uint32_t rmo_pa = 0;
|
||||
- uint64_t elapsed = 0;
|
||||
- void *kernbuf;
|
||||
- void *rmobuf;
|
||||
- void *locbuf;
|
||||
- int rc, status;
|
||||
-
|
||||
- rc = sanity_check();
|
||||
- if (rc)
|
||||
- return rc;
|
||||
-
|
||||
- rc = rtas_get_rmo_buffer(size + WORK_AREA_SIZE, &rmobuf, &rmo_pa);
|
||||
- if (rc)
|
||||
- return rc;
|
||||
-
|
||||
- kernbuf = rmobuf + WORK_AREA_SIZE;
|
||||
- kernbuf_pa = rmo_pa + WORK_AREA_SIZE;
|
||||
- locbuf = rmobuf;
|
||||
- loc_pa = rmo_pa;
|
||||
-
|
||||
- /* If user didn't set loc_code, copy a NULL string */
|
||||
- strncpy(locbuf, loc_code ? loc_code : "", WORK_AREA_SIZE);
|
||||
-
|
||||
- *seq_next = htobe32(sequence);
|
||||
- do {
|
||||
- sequence = *seq_next;
|
||||
- rc = rtas_call_no_delay("ibm,get-vpd", 4, 3, htobe32(loc_pa),
|
||||
- htobe32(kernbuf_pa), htobe32(size),
|
||||
- sequence, &status, seq_next,
|
||||
- bytes_ret);
|
||||
- if (rc < 0)
|
||||
- break;
|
||||
-
|
||||
- rc = handle_delay(status, &elapsed);
|
||||
- } while (rc == CALL_AGAIN);
|
||||
-
|
||||
- if (rc == 0)
|
||||
- memcpy(workarea, kernbuf, size);
|
||||
-
|
||||
- (void) rtas_free_rmo_buffer(rmobuf, rmo_pa, size + WORK_AREA_SIZE);
|
||||
-
|
||||
- *seq_next = be32toh(*seq_next);
|
||||
- *bytes_ret = be32toh(*bytes_ret);
|
||||
-
|
||||
- dbg("(%s, 0x%p, %zu, %u) = %d, %u, %u\n", loc_code ? loc_code : "NULL",
|
||||
- workarea, size, sequence, status, *seq_next, *bytes_ret);
|
||||
- return rc ? rc : status;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* rtas_lpar_perftools
|
||||
* @brief Interface to the ibm,lpar-perftools rtas call
|
||||
diff --git a/librtas_src/vpd.c b/librtas_src/vpd.c
|
||||
new file mode 100644
|
||||
index 0000000..b2689fb
|
||||
--- /dev/null
|
||||
+++ b/librtas_src/vpd.c
|
||||
@@ -0,0 +1,81 @@
|
||||
+// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+
|
||||
+// Support for accessing IBM Power systems Vital Product Data (VPD)
|
||||
+// via the rtas() syscall.
|
||||
+
|
||||
+#include <endian.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/unistd.h>
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/syscall.h>
|
||||
+
|
||||
+#include "internal.h"
|
||||
+#include "librtas.h"
|
||||
+
|
||||
+/**
|
||||
+ * rtas_get_vpd
|
||||
+ * @brief Interface to the ibm,get-vpd rtas call
|
||||
+ *
|
||||
+ * @param loc_code location code
|
||||
+ * @param workarea additional args to rtas call
|
||||
+ * @param size
|
||||
+ * @param sequence
|
||||
+ * @param seq_next
|
||||
+ * @param bytes_ret
|
||||
+ * @return 0 on success, !0 otherwise
|
||||
+ */
|
||||
+int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||
+ unsigned int sequence, unsigned int *seq_next,
|
||||
+ unsigned int *bytes_ret)
|
||||
+{
|
||||
+ uint32_t kernbuf_pa;
|
||||
+ uint32_t loc_pa = 0;
|
||||
+ uint32_t rmo_pa = 0;
|
||||
+ uint64_t elapsed = 0;
|
||||
+ void *kernbuf;
|
||||
+ void *rmobuf;
|
||||
+ void *locbuf;
|
||||
+ int rc, status;
|
||||
+
|
||||
+ rc = sanity_check();
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = rtas_get_rmo_buffer(size + WORK_AREA_SIZE, &rmobuf, &rmo_pa);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ kernbuf = rmobuf + WORK_AREA_SIZE;
|
||||
+ kernbuf_pa = rmo_pa + WORK_AREA_SIZE;
|
||||
+ locbuf = rmobuf;
|
||||
+ loc_pa = rmo_pa;
|
||||
+
|
||||
+ /* If user didn't set loc_code, copy a NULL string */
|
||||
+ strncpy(locbuf, loc_code ? loc_code : "", WORK_AREA_SIZE);
|
||||
+
|
||||
+ *seq_next = htobe32(sequence);
|
||||
+ do {
|
||||
+ sequence = *seq_next;
|
||||
+ rc = rtas_call_no_delay("ibm,get-vpd", 4, 3, htobe32(loc_pa),
|
||||
+ htobe32(kernbuf_pa), htobe32(size),
|
||||
+ sequence, &status, seq_next,
|
||||
+ bytes_ret);
|
||||
+ if (rc < 0)
|
||||
+ break;
|
||||
+
|
||||
+ rc = handle_delay(status, &elapsed);
|
||||
+ } while (rc == CALL_AGAIN);
|
||||
+
|
||||
+ if (rc == 0)
|
||||
+ memcpy(workarea, kernbuf, size);
|
||||
+
|
||||
+ (void) rtas_free_rmo_buffer(rmobuf, rmo_pa, size + WORK_AREA_SIZE);
|
||||
+
|
||||
+ *seq_next = be32toh(*seq_next);
|
||||
+ *bytes_ret = be32toh(*bytes_ret);
|
||||
+
|
||||
+ dbg("(%s, 0x%p, %zu, %u) = %d, %u, %u\n", loc_code ? loc_code : "NULL",
|
||||
+ workarea, size, sequence, status, *seq_next, *bytes_ret);
|
||||
+ return rc ? rc : status;
|
||||
+}
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,231 +0,0 @@
|
||||
From c47176a5f1ce7bb16ba02b8c8520e02b285d7e9f Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Date: Mon, 25 Sep 2023 11:32:33 -0500
|
||||
Subject: [PATCH 3/6] librtas: move system parameter code to separate module
|
||||
|
||||
This code will gain the ability to access system parameters using a
|
||||
different interface exposed by newer kernels. This will involve adding
|
||||
a nontrivial amount of code, so move it out of syscall_calls.c.
|
||||
|
||||
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
---
|
||||
Makefile.am | 3 +-
|
||||
librtas_src/syscall_calls.c | 84 -----------------------------------
|
||||
librtas_src/sysparm.c | 88 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 90 insertions(+), 85 deletions(-)
|
||||
create mode 100644 librtas_src/sysparm.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 37df243..1385ac7 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -31,7 +31,8 @@ librtas_la_SOURCES = \
|
||||
librtas_src/vpd.c \
|
||||
librtas_src/ofdt.c \
|
||||
librtas_src/syscall_calls.c \
|
||||
- librtas_src/syscall_rmo.c
|
||||
+ librtas_src/syscall_rmo.c \
|
||||
+ librtas_src/sysparm.c
|
||||
|
||||
library_include_HEADERS += librtas_src/librtas.h
|
||||
noinst_HEADERS += librtas_src/internal.h
|
||||
diff --git a/librtas_src/syscall_calls.c b/librtas_src/syscall_calls.c
|
||||
index 05f3c7c..b28af2d 100644
|
||||
--- a/librtas_src/syscall_calls.c
|
||||
+++ b/librtas_src/syscall_calls.c
|
||||
@@ -674,44 +674,6 @@ int rtas_get_sensor(int sensor, int index, int *state)
|
||||
return rc ? rc : status;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * rtas_get_sysparm
|
||||
- * @brief Interface to the ibm,get-system-parameter rtas call
|
||||
- *
|
||||
- * On successful completion the data parameter will contain the system
|
||||
- * parameter results
|
||||
- *
|
||||
- * @param parameter system parameter to retrieve
|
||||
- * @param length data buffer length
|
||||
- * @param data reference to buffer to return parameter in
|
||||
- * @return 0 on success, !0 otherwise
|
||||
- */
|
||||
-int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||
-{
|
||||
- uint32_t kernbuf_pa;
|
||||
- void *kernbuf;
|
||||
- int rc, status;
|
||||
-
|
||||
- rc = sanity_check();
|
||||
- if (rc)
|
||||
- return rc;
|
||||
-
|
||||
- rc = rtas_get_rmo_buffer(length, &kernbuf, &kernbuf_pa);
|
||||
- if (rc)
|
||||
- return rc;
|
||||
-
|
||||
- rc = rtas_call("ibm,get-system-parameter", 3, 1, htobe32(parameter),
|
||||
- htobe32(kernbuf_pa), htobe32(length), &status);
|
||||
-
|
||||
- if (rc == 0)
|
||||
- memcpy(data, kernbuf, length);
|
||||
-
|
||||
- (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, length);
|
||||
-
|
||||
- dbg("(%u, %u, %p) = %d\n", parameter, length, data, rc ? rc : status);
|
||||
- return rc ? rc : status;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* rtas_get_time
|
||||
* @brief Interface to get-time-of-day rtas call
|
||||
@@ -1109,52 +1071,6 @@ int rtas_set_poweron_time(uint32_t year, uint32_t month, uint32_t day,
|
||||
return rc ? rc : status;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * rtas_set_sysparm
|
||||
- * @brief Interface to the ibm,set-system-parameter rtas call
|
||||
- *
|
||||
- * @param parameter
|
||||
- * @param data
|
||||
- * @return 0 on success, !0 otherwise
|
||||
- */
|
||||
-int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||
-{
|
||||
- uint32_t kernbuf_pa;
|
||||
- void *kernbuf;
|
||||
- int rc, status;
|
||||
- uint16_t size;
|
||||
-
|
||||
- rc = sanity_check();
|
||||
- if (rc)
|
||||
- return rc;
|
||||
- /*
|
||||
- * We have to copy the contents of @data to a RMO buffer. The
|
||||
- * caller has encoded the data length in the first two bytes
|
||||
- * of @data in MSB order, and we can't assume any
|
||||
- * alignment. So interpret @data as:
|
||||
- *
|
||||
- * struct {
|
||||
- * unsigned char len_msb;
|
||||
- * unsigned char len_lsb;
|
||||
- * char [(len_msb << 8) + len_lsb];
|
||||
- * }
|
||||
- */
|
||||
- size = 2 + (((unsigned char)data[0] << 8) | (unsigned char)data[1]);
|
||||
- rc = rtas_get_rmo_buffer(size, &kernbuf, &kernbuf_pa);
|
||||
- if (rc)
|
||||
- return rc;
|
||||
-
|
||||
- memcpy(kernbuf, data, size);
|
||||
-
|
||||
- rc = rtas_call("ibm,set-system-parameter", 2, 1, htobe32(parameter),
|
||||
- htobe32(kernbuf_pa), &status);
|
||||
-
|
||||
- (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, size);
|
||||
-
|
||||
- dbg("(%u, %p) = %d\n", parameter, data, rc ? rc : status);
|
||||
- return rc ? rc : status;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* rtas_set_time
|
||||
* @brief Interface to the set-time-of-day rtas call
|
||||
diff --git a/librtas_src/sysparm.c b/librtas_src/sysparm.c
|
||||
new file mode 100644
|
||||
index 0000000..40af55e
|
||||
--- /dev/null
|
||||
+++ b/librtas_src/sysparm.c
|
||||
@@ -0,0 +1,88 @@
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+#include "internal.h"
|
||||
+#include "librtas.h"
|
||||
+
|
||||
+/**
|
||||
+ * rtas_get_sysparm
|
||||
+ * @brief Interface to the ibm,get-system-parameter rtas call
|
||||
+ *
|
||||
+ * On successful completion the data parameter will contain the system
|
||||
+ * parameter results
|
||||
+ *
|
||||
+ * @param parameter system parameter to retrieve
|
||||
+ * @param length data buffer length
|
||||
+ * @param data reference to buffer to return parameter in
|
||||
+ * @return 0 on success, !0 otherwise
|
||||
+ */
|
||||
+int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||
+{
|
||||
+ uint32_t kernbuf_pa;
|
||||
+ void *kernbuf;
|
||||
+ int rc, status;
|
||||
+
|
||||
+ rc = sanity_check();
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = rtas_get_rmo_buffer(length, &kernbuf, &kernbuf_pa);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = rtas_call("ibm,get-system-parameter", 3, 1, htobe32(parameter),
|
||||
+ htobe32(kernbuf_pa), htobe32(length), &status);
|
||||
+
|
||||
+ if (rc == 0)
|
||||
+ memcpy(data, kernbuf, length);
|
||||
+
|
||||
+ (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, length);
|
||||
+
|
||||
+ dbg("(%u, %u, %p) = %d\n", parameter, length, data, rc ? rc : status);
|
||||
+ return rc ? rc : status;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * rtas_set_sysparm
|
||||
+ * @brief Interface to the ibm,set-system-parameter rtas call
|
||||
+ *
|
||||
+ * @param parameter
|
||||
+ * @param data
|
||||
+ * @return 0 on success, !0 otherwise
|
||||
+ */
|
||||
+int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||
+{
|
||||
+ uint32_t kernbuf_pa;
|
||||
+ void *kernbuf;
|
||||
+ int rc, status;
|
||||
+ uint16_t size;
|
||||
+
|
||||
+ rc = sanity_check();
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ /*
|
||||
+ * We have to copy the contents of @data to a RMO buffer. The
|
||||
+ * caller has encoded the data length in the first two bytes
|
||||
+ * of @data in MSB order, and we can't assume any
|
||||
+ * alignment. So interpret @data as:
|
||||
+ *
|
||||
+ * struct {
|
||||
+ * unsigned char len_msb;
|
||||
+ * unsigned char len_lsb;
|
||||
+ * char [(len_msb << 8) + len_lsb];
|
||||
+ * }
|
||||
+ */
|
||||
+ size = 2 + (((unsigned char)data[0] << 8) | (unsigned char)data[1]);
|
||||
+ rc = rtas_get_rmo_buffer(size, &kernbuf, &kernbuf_pa);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+
|
||||
+ memcpy(kernbuf, data, size);
|
||||
+
|
||||
+ rc = rtas_call("ibm,set-system-parameter", 2, 1, htobe32(parameter),
|
||||
+ htobe32(kernbuf_pa), &status);
|
||||
+
|
||||
+ (void)rtas_free_rmo_buffer(kernbuf, kernbuf_pa, size);
|
||||
+
|
||||
+ dbg("(%u, %p) = %d\n", parameter, data, rc ? rc : status);
|
||||
+ return rc ? rc : status;
|
||||
+}
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,49 +0,0 @@
|
||||
From c914a1a701391c565203b10603ad0fbc52438bf7 Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Date: Mon, 25 Sep 2023 11:41:22 -0500
|
||||
Subject: [PATCH 4/6] librtas: vendor papr-miscdev.h
|
||||
|
||||
This is a common header used by other kernel uapi headers that we will
|
||||
copy into the source tree.
|
||||
|
||||
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
---
|
||||
Makefile.am | 4 +++-
|
||||
librtas_src/papr-miscdev.h | 9 +++++++++
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
create mode 100644 librtas_src/papr-miscdev.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 1385ac7..d0cabfb 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -35,7 +35,9 @@ librtas_la_SOURCES = \
|
||||
librtas_src/sysparm.c
|
||||
|
||||
library_include_HEADERS += librtas_src/librtas.h
|
||||
-noinst_HEADERS += librtas_src/internal.h
|
||||
+noinst_HEADERS += \
|
||||
+ librtas_src/internal.h \
|
||||
+ librtas_src/papr-miscdev.h
|
||||
|
||||
# See "Updating library version information" in the libtool manual for
|
||||
# how to maintain these values. They are *not* tied to the release
|
||||
diff --git a/librtas_src/papr-miscdev.h b/librtas_src/papr-miscdev.h
|
||||
new file mode 100644
|
||||
index 0000000..c0b1072
|
||||
--- /dev/null
|
||||
+++ b/librtas_src/papr-miscdev.h
|
||||
@@ -0,0 +1,9 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
+#ifndef _UAPI_PAPR_MISCDEV_H_
|
||||
+#define _UAPI_PAPR_MISCDEV_H_
|
||||
+
|
||||
+enum {
|
||||
+ PAPR_MISCDEV_IOC_ID = 0xb2,
|
||||
+};
|
||||
+
|
||||
+#endif /* _UAPI_PAPR_MISCDEV_H_ */
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,287 +0,0 @@
|
||||
From 57d5e1c07b40e56f6209e7b806208818464f8e8d Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Date: Sat, 12 Aug 2023 13:27:39 -0500
|
||||
Subject: [PATCH 5/6] librtas/vpd: prefer /dev/papr-vpd when available
|
||||
|
||||
Change rtas_get_vpd() to prefer the /dev/papr-vpd character device
|
||||
expected in Linux v6.8.
|
||||
|
||||
On the first invocation of rtas_get_vpd(), probe for the new ABI and
|
||||
initialize an internal function pointer according to the result. Use
|
||||
pthread_once() to ensure that this probe step is performed atomically
|
||||
and only once. It would not make sense to re-probe (and potentially
|
||||
update the implementation) on every call, since the implementations
|
||||
differ in the way state for the call sequence is maintained.
|
||||
|
||||
Assuming the new ABI is available: upon first call to rtas_get_vpd(),
|
||||
open /dev/papr-vpd and obtain a file descriptor using the
|
||||
PAPR_VPD_CREATE_HANDLE ioctl() command. This file descriptor is a
|
||||
reference to the VPD returned from a complete ibm,get-vpd call
|
||||
sequence. Subsequent calls sequentially read the VPD from the fd,
|
||||
which is closed once EOF is reached.
|
||||
|
||||
To existing users of rtas_get_vpd(), the new implementation is
|
||||
indistinguishable from the old one, with one exception:
|
||||
|
||||
* When using the rtas() syscall on current systems, RTAS advances the
|
||||
sequence number by a fixed interval on each call in a sequence. This
|
||||
is visible in the values returned in the 'seq_next' out parameter.
|
||||
|
||||
* When using /dev/papr-vpd, the value returned in 'seq_next' does not
|
||||
change between calls; librtas treats it as a "handle" for a sequence
|
||||
in progress.
|
||||
|
||||
In PAPR there is no meaning attached to the value returned in the
|
||||
'seq_next' out parameter, and there is no requirement that it must
|
||||
change or increment on each call. No user should be relying on the
|
||||
behavior of this aspect of the interface to judge the status of a
|
||||
sequence.
|
||||
|
||||
I have verified that an unmodified vpdupdate command from a distro
|
||||
lsvpd package works correctly when linked to a librtas.so with this
|
||||
change. This is the primary (and perhaps only) user of rtas_get_vpd().
|
||||
|
||||
For now, carry a copy of the kernel uapi header.
|
||||
|
||||
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
---
|
||||
Makefile.am | 5 +-
|
||||
librtas_src/papr-vpd.h | 22 ++++++
|
||||
librtas_src/vpd.c | 155 ++++++++++++++++++++++++++++++++++++-----
|
||||
3 files changed, 162 insertions(+), 20 deletions(-)
|
||||
create mode 100644 librtas_src/papr-vpd.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index d0cabfb..89a6eaa 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -26,7 +26,7 @@ LIBRTAS_AGE = 0
|
||||
LIBRTAS_LIBRARY_VERSION = $(LIBRTAS_CURRENT):$(LIBRTAS_REVISION):$(LIBRTAS_AGE)
|
||||
|
||||
lib_LTLIBRARIES += librtas.la
|
||||
-librtas_la_LDFLAGS = -version-info $(LIBRTAS_LIBRARY_VERSION)
|
||||
+librtas_la_LDFLAGS = -version-info $(LIBRTAS_LIBRARY_VERSION) -lpthread
|
||||
librtas_la_SOURCES = \
|
||||
librtas_src/vpd.c \
|
||||
librtas_src/ofdt.c \
|
||||
@@ -37,7 +37,8 @@ librtas_la_SOURCES = \
|
||||
library_include_HEADERS += librtas_src/librtas.h
|
||||
noinst_HEADERS += \
|
||||
librtas_src/internal.h \
|
||||
- librtas_src/papr-miscdev.h
|
||||
+ librtas_src/papr-miscdev.h \
|
||||
+ librtas_src/papr-vpd.h
|
||||
|
||||
# See "Updating library version information" in the libtool manual for
|
||||
# how to maintain these values. They are *not* tied to the release
|
||||
diff --git a/librtas_src/papr-vpd.h b/librtas_src/papr-vpd.h
|
||||
new file mode 100644
|
||||
index 0000000..b57cf30
|
||||
--- /dev/null
|
||||
+++ b/librtas_src/papr-vpd.h
|
||||
@@ -0,0 +1,22 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
+#ifndef _UAPI_PAPR_VPD_H_
|
||||
+#define _UAPI_PAPR_VPD_H_
|
||||
+
|
||||
+#include <asm/ioctl.h>
|
||||
+#include "papr-miscdev.h"
|
||||
+
|
||||
+struct papr_location_code {
|
||||
+ /*
|
||||
+ * PAPR+ 12.3.2.4 Converged Location Code Rules - Length
|
||||
+ * Restrictions. 79 characters plus nul.
|
||||
+ */
|
||||
+ char str[80];
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * ioctl for /dev/papr-vpd. Returns a VPD handle fd corresponding to
|
||||
+ * the location code.
|
||||
+ */
|
||||
+#define PAPR_VPD_IOC_CREATE_HANDLE _IOW(PAPR_MISCDEV_IOC_ID, 0, struct papr_location_code)
|
||||
+
|
||||
+#endif /* _UAPI_PAPR_VPD_H_ */
|
||||
diff --git a/librtas_src/vpd.c b/librtas_src/vpd.c
|
||||
index b2689fb..544560f 100644
|
||||
--- a/librtas_src/vpd.c
|
||||
+++ b/librtas_src/vpd.c
|
||||
@@ -1,33 +1,33 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
// Support for accessing IBM Power systems Vital Product Data (VPD)
|
||||
-// via the rtas() syscall.
|
||||
+// via /dev/papr-vpd or the legacy rtas() syscall.
|
||||
|
||||
-#include <endian.h>
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <limits.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/unistd.h>
|
||||
-#include <stdint.h>
|
||||
+#include <pthread.h>
|
||||
+#include <search.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "librtas.h"
|
||||
+#include "papr-vpd.h"
|
||||
|
||||
-/**
|
||||
- * rtas_get_vpd
|
||||
- * @brief Interface to the ibm,get-vpd rtas call
|
||||
- *
|
||||
- * @param loc_code location code
|
||||
- * @param workarea additional args to rtas call
|
||||
- * @param size
|
||||
- * @param sequence
|
||||
- * @param seq_next
|
||||
- * @param bytes_ret
|
||||
- * @return 0 on success, !0 otherwise
|
||||
- */
|
||||
-int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||
- unsigned int sequence, unsigned int *seq_next,
|
||||
- unsigned int *bytes_ret)
|
||||
+static int
|
||||
+get_vpd_syscall_fallback(const char *loc_code, char *workarea, size_t size,
|
||||
+ unsigned int sequence, unsigned int *seq_next,
|
||||
+ unsigned int *bytes_ret)
|
||||
{
|
||||
uint32_t kernbuf_pa;
|
||||
uint32_t loc_pa = 0;
|
||||
@@ -79,3 +79,122 @@ int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||
workarea, size, sequence, status, *seq_next, *bytes_ret);
|
||||
return rc ? rc : status;
|
||||
}
|
||||
+
|
||||
+static bool get_vpd_can_use_chardev(void)
|
||||
+{
|
||||
+ struct stat statbuf;
|
||||
+
|
||||
+ if (stat("/dev/papr-vpd", &statbuf))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!S_ISCHR(statbuf.st_mode))
|
||||
+ return false;
|
||||
+
|
||||
+ if (close(open("/dev/papr-vpd", O_RDONLY)))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+#define DEVPATH "/dev/papr-vpd"
|
||||
+
|
||||
+static int vpd_fd_new(const char *loc_code)
|
||||
+{
|
||||
+ const int devfd = open(DEVPATH, O_WRONLY);
|
||||
+ struct papr_location_code lc = {};
|
||||
+ int fd = -1;
|
||||
+
|
||||
+ if (devfd < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (!loc_code)
|
||||
+ loc_code = "";
|
||||
+
|
||||
+ if (sizeof(lc.str) < strlen(loc_code))
|
||||
+ goto close_devfd;
|
||||
+
|
||||
+ strncpy(lc.str, loc_code, sizeof(lc.str));
|
||||
+ fd = ioctl(devfd, PAPR_VPD_IOC_CREATE_HANDLE, &lc);
|
||||
+close_devfd:
|
||||
+ close(devfd);
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+get_vpd_chardev(const char *loc_code, char *workarea, size_t size,
|
||||
+ unsigned int sequence, unsigned int *seq_next,
|
||||
+ unsigned int *bytes_ret)
|
||||
+{
|
||||
+ int fd = (sequence == 1) ? vpd_fd_new(loc_code) : (int)sequence;
|
||||
+
|
||||
+ /*
|
||||
+ * Ensure we return a fd > 0 in seq_next.
|
||||
+ */
|
||||
+ if (fd == 1) {
|
||||
+ int newfd = dup(fd);
|
||||
+ close(fd);
|
||||
+ fd = newfd;
|
||||
+ }
|
||||
+
|
||||
+ if (fd < 0)
|
||||
+ return -3; /* Synthesize ibm,get-vpd "parameter error" */
|
||||
+
|
||||
+ int rtas_status = 0;
|
||||
+ ssize_t res = read(fd, workarea, size);
|
||||
+ if (res < 0) {
|
||||
+ rtas_status = -1; /* Synthesize ibm,get-vpd "hardware error" */
|
||||
+ close(fd);
|
||||
+ } else if (res == 0 || res < (ssize_t)size) {
|
||||
+ rtas_status = 0; /* Done with sequence, no more data */
|
||||
+ close(fd);
|
||||
+ if (seq_next)
|
||||
+ *seq_next = 1;
|
||||
+ if (bytes_ret)
|
||||
+ *bytes_ret = res;
|
||||
+ } else {
|
||||
+ rtas_status = 1; /* More data available, call again */
|
||||
+ if (seq_next)
|
||||
+ *seq_next = fd;
|
||||
+ if (bytes_ret)
|
||||
+ *bytes_ret = res;
|
||||
+ }
|
||||
+
|
||||
+ return rtas_status;
|
||||
+}
|
||||
+
|
||||
+static int (*get_vpd_fn)(const char *loc_code,
|
||||
+ char *workarea,
|
||||
+ size_t size,
|
||||
+ unsigned int sequence,
|
||||
+ unsigned int *seq_next,
|
||||
+ unsigned int *bytes_ret);
|
||||
+
|
||||
+static void get_vpd_fn_setup(void)
|
||||
+{
|
||||
+ get_vpd_fn = get_vpd_can_use_chardev() ?
|
||||
+ get_vpd_chardev : get_vpd_syscall_fallback;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * rtas_get_vpd
|
||||
+ * @brief Interface to the ibm,get-vpd rtas call
|
||||
+ *
|
||||
+ * @param loc_code location code
|
||||
+ * @param workarea additional args to rtas call
|
||||
+ * @param size
|
||||
+ * @param sequence
|
||||
+ * @param seq_next
|
||||
+ * @param bytes_ret
|
||||
+ * @return 0 on success, !0 otherwise
|
||||
+ */
|
||||
+int rtas_get_vpd(char *loc_code, char *workarea, size_t size,
|
||||
+ unsigned int sequence, unsigned int *seq_next,
|
||||
+ unsigned int *bytes_ret)
|
||||
+{
|
||||
+ static pthread_once_t get_vpd_fn_once = PTHREAD_ONCE_INIT;
|
||||
+
|
||||
+ pthread_once(&get_vpd_fn_once, get_vpd_fn_setup);
|
||||
+
|
||||
+ return get_vpd_fn(loc_code, workarea, size, sequence,
|
||||
+ seq_next, bytes_ret);
|
||||
+}
|
||||
--
|
||||
2.43.0
|
||||
|
@@ -1,285 +0,0 @@
|
||||
From d8d4ee6f5052704ac82bb8aa8d8fe8816dac41cd Mon Sep 17 00:00:00 2001
|
||||
From: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Date: Mon, 25 Sep 2023 11:42:26 -0500
|
||||
Subject: [PATCH 6/6] librtas/sysparm: prefer /dev/papr-sysparm when available
|
||||
|
||||
Change rtas_get_sysparm() and rtas_set_sysparm() to prefer the
|
||||
/dev/papr-sysparm character device expected in Linux v6.8.
|
||||
|
||||
On the first invocation of either function, probe for the new ABI and
|
||||
initialize internal function pointers according to the result. Use
|
||||
pthread_once() to ensure that this initialization step is performed
|
||||
atomically and only once.
|
||||
|
||||
When /dev/papr-sysparm is available, use its PAPR_SYSPARM_IOC_GET and
|
||||
PAPR_SYSPARM_IOC_SET ioctl commands to retrieve and update system
|
||||
parameters. Most of the complexity of calling RTAS is handled
|
||||
internally to the kernel and the ioctl follows Linux conventions,
|
||||
returning 0 on success or -1 w/errno on failure. On failure,
|
||||
back-convert the errno to an RTAS status value that callers will
|
||||
recognize.
|
||||
|
||||
For now, carry a copy of the kernel uapi header.
|
||||
|
||||
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
||||
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
librtas_src/papr-sysparm.h | 58 +++++++++++++++
|
||||
librtas_src/sysparm.c | 144 ++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 201 insertions(+), 2 deletions(-)
|
||||
create mode 100644 librtas_src/papr-sysparm.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 89a6eaa..67257e3 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -38,6 +38,7 @@ library_include_HEADERS += librtas_src/librtas.h
|
||||
noinst_HEADERS += \
|
||||
librtas_src/internal.h \
|
||||
librtas_src/papr-miscdev.h \
|
||||
+ librtas_src/papr-sysparm.h \
|
||||
librtas_src/papr-vpd.h
|
||||
|
||||
# See "Updating library version information" in the libtool manual for
|
||||
diff --git a/librtas_src/papr-sysparm.h b/librtas_src/papr-sysparm.h
|
||||
new file mode 100644
|
||||
index 0000000..e0c0ebb
|
||||
--- /dev/null
|
||||
+++ b/librtas_src/papr-sysparm.h
|
||||
@@ -0,0 +1,58 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
+#ifndef _UAPI_PAPR_SYSPARM_H_
|
||||
+#define _UAPI_PAPR_SYSPARM_H_
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+#include <asm/ioctl.h>
|
||||
+#include "papr-miscdev.h"
|
||||
+
|
||||
+enum {
|
||||
+ PAPR_SYSPARM_MAX_INPUT = 1024,
|
||||
+ PAPR_SYSPARM_MAX_OUTPUT = 4000,
|
||||
+};
|
||||
+
|
||||
+struct papr_sysparm_io_block {
|
||||
+ __u32 parameter;
|
||||
+ __u16 length;
|
||||
+ char data[PAPR_SYSPARM_MAX_OUTPUT];
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * PAPR_SYSPARM_IOC_GET - Retrieve the value of a PAPR system parameter.
|
||||
+ *
|
||||
+ * Uses _IOWR because of one corner case: Retrieving the value of the
|
||||
+ * "OS Service Entitlement Status" parameter (60) requires the caller
|
||||
+ * to supply input data (a date string) in the buffer passed to
|
||||
+ * firmware. So the @length and @data of the incoming
|
||||
+ * papr_sysparm_io_block are always used to initialize the work area
|
||||
+ * supplied to ibm,get-system-parameter. No other parameters are known
|
||||
+ * to parameterize the result this way, and callers are encouraged
|
||||
+ * (but not required) to zero-initialize @length and @data in the
|
||||
+ * common case.
|
||||
+ *
|
||||
+ * On error the contents of the ioblock are indeterminate.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * 0: Success; @length is the length of valid data in @data, not to exceed @PAPR_SYSPARM_MAX_OUTPUT.
|
||||
+ * -EIO: Platform error. (-1)
|
||||
+ * -EINVAL: Incorrect data length or format. (-9999)
|
||||
+ * -EPERM: The calling partition is not allowed to access this parameter. (-9002)
|
||||
+ * -EOPNOTSUPP: Parameter not supported on this platform (-3)
|
||||
+ */
|
||||
+#define PAPR_SYSPARM_IOC_GET _IOWR(PAPR_MISCDEV_IOC_ID, 1, struct papr_sysparm_io_block)
|
||||
+
|
||||
+/**
|
||||
+ * PAPR_SYSPARM_IOC_SET - Update the value of a PAPR system parameter.
|
||||
+ *
|
||||
+ * The contents of the ioblock are unchanged regardless of success.
|
||||
+ *
|
||||
+ * Return:
|
||||
+ * 0: Success; the parameter has been updated.
|
||||
+ * -EIO: Platform error. (-1)
|
||||
+ * -EINVAL: Incorrect data length or format. (-9999)
|
||||
+ * -EPERM: The calling partition is not allowed to access this parameter. (-9002)
|
||||
+ * -EOPNOTSUPP: Parameter not supported on this platform (-3)
|
||||
+ */
|
||||
+#define PAPR_SYSPARM_IOC_SET _IOW(PAPR_MISCDEV_IOC_ID, 2, struct papr_sysparm_io_block)
|
||||
+
|
||||
+#endif /* _UAPI_PAPR_SYSPARM_H_ */
|
||||
diff --git a/librtas_src/sysparm.c b/librtas_src/sysparm.c
|
||||
index 40af55e..b4d2054 100644
|
||||
--- a/librtas_src/sysparm.c
|
||||
+++ b/librtas_src/sysparm.c
|
||||
@@ -1,7 +1,16 @@
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <pthread.h>
|
||||
+#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <sys/stat.h>
|
||||
#include "internal.h"
|
||||
#include "librtas.h"
|
||||
+#include "papr-sysparm.h"
|
||||
+
|
||||
+static const char sysparm_devpath[] = "/dev/papr-sysparm";
|
||||
|
||||
/**
|
||||
* rtas_get_sysparm
|
||||
@@ -15,7 +24,8 @@
|
||||
* @param data reference to buffer to return parameter in
|
||||
* @return 0 on success, !0 otherwise
|
||||
*/
|
||||
-int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||
+static int
|
||||
+get_sysparm_syscall_fallback(unsigned int parameter, unsigned int length, char *data)
|
||||
{
|
||||
uint32_t kernbuf_pa;
|
||||
void *kernbuf;
|
||||
@@ -49,7 +59,8 @@ int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||
* @param data
|
||||
* @return 0 on success, !0 otherwise
|
||||
*/
|
||||
-int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||
+static int
|
||||
+set_sysparm_syscall_fallback(unsigned int parameter, char *data)
|
||||
{
|
||||
uint32_t kernbuf_pa;
|
||||
void *kernbuf;
|
||||
@@ -86,3 +97,132 @@ int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||
dbg("(%u, %p) = %d\n", parameter, data, rc ? rc : status);
|
||||
return rc ? rc : status;
|
||||
}
|
||||
+
|
||||
+static bool sysparm_can_use_chardev(void)
|
||||
+{
|
||||
+ struct stat statbuf;
|
||||
+
|
||||
+ if (stat(sysparm_devpath, &statbuf))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!S_ISCHR(statbuf.st_mode))
|
||||
+ return false;
|
||||
+
|
||||
+ if (close(open(sysparm_devpath, O_RDONLY)))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Only to be used when converting an actual error from a syscall.
|
||||
+ */
|
||||
+static int chardev_backconvert_errno(int saved_errno)
|
||||
+{
|
||||
+ const struct {
|
||||
+ int linux_errno;
|
||||
+ int rtas_status;
|
||||
+ } map[] = {
|
||||
+#define errno_to_status(e, s) { .linux_errno = (e), .rtas_status = (s), }
|
||||
+ errno_to_status(EINVAL, -9999),
|
||||
+ errno_to_status(EPERM, -9002),
|
||||
+ errno_to_status(EOPNOTSUPP, -3),
|
||||
+ errno_to_status(EIO, -1),
|
||||
+ errno_to_status(EFAULT, -1),
|
||||
+#undef errno_to_status
|
||||
+ };
|
||||
+
|
||||
+ for (size_t i = 0; i < sizeof(map) / sizeof(map[0]); ++i)
|
||||
+ if (map[i].linux_errno == saved_errno)
|
||||
+ return map[i].rtas_status;
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int get_sysparm_chardev(unsigned int parameter, unsigned int length, char *data)
|
||||
+{
|
||||
+ const int fd = open(sysparm_devpath, O_RDWR);
|
||||
+ struct papr_sysparm_io_block buf = {
|
||||
+ .parameter = parameter,
|
||||
+ };
|
||||
+
|
||||
+ if (fd < 0) {
|
||||
+ /*
|
||||
+ * Really shouldn't get here without misconfiguration,
|
||||
+ * e.g. removal of /dev/papr-sysparm. Synthesize a
|
||||
+ * hardware/platform error.
|
||||
+ */
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * It might make sense to have special handling for parameter
|
||||
+ * 60 (OS Service Entitlement Status), which takes input data,
|
||||
+ * but librtas has never handled that one correctly. So ignore
|
||||
+ * it for now and don't copy incoming data into the block we
|
||||
+ * pass to PAPR_SYSPARM_IOC_GET.
|
||||
+ */
|
||||
+
|
||||
+ const int res = ioctl(fd, PAPR_SYSPARM_IOC_GET, &buf);
|
||||
+ const int saved_errno = errno;
|
||||
+ (void)close(fd);
|
||||
+
|
||||
+ if (res != 0)
|
||||
+ return chardev_backconvert_errno(saved_errno);
|
||||
+
|
||||
+ const uint16_t result_size_msb = htobe16(buf.length);
|
||||
+ memcpy(data, &result_size_msb, sizeof(result_size_msb));
|
||||
+ length -= sizeof(result_size_msb);
|
||||
+ data += sizeof(result_size_msb);
|
||||
+
|
||||
+ /*
|
||||
+ * Copy no more than min(@length, sizeof(buf.data)).
|
||||
+ */
|
||||
+ const size_t copy_size = sizeof(buf.data) < length ?
|
||||
+ sizeof(buf.data) : length;
|
||||
+ memcpy(data, buf.data, copy_size);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int set_sysparm_chardev(unsigned int parameter, char *data)
|
||||
+{
|
||||
+ const int fd = open(sysparm_devpath, O_RDWR);
|
||||
+ struct papr_sysparm_io_block buf = {
|
||||
+ .parameter = parameter,
|
||||
+ .length = (((unsigned char)data[0] << 8) | (unsigned char)data[1]),
|
||||
+ };
|
||||
+
|
||||
+ memcpy(buf.data, data + 2, buf.length);
|
||||
+
|
||||
+ const int res = ioctl(fd, PAPR_SYSPARM_IOC_SET, &buf);
|
||||
+ const int saved_errno = errno;
|
||||
+ (void)close(fd);
|
||||
+
|
||||
+ return res == 0 ? 0 : chardev_backconvert_errno(saved_errno);
|
||||
+}
|
||||
+
|
||||
+static int (*get_sysparm_fn)(unsigned int parameter, unsigned int length, char *data);
|
||||
+static int (*set_sysparm_fn)(unsigned int parameter, char *data);
|
||||
+
|
||||
+static void sysparm_fn_setup(void)
|
||||
+{
|
||||
+ const bool use_chardev = sysparm_can_use_chardev();
|
||||
+
|
||||
+ get_sysparm_fn = use_chardev ?
|
||||
+ get_sysparm_chardev : get_sysparm_syscall_fallback;
|
||||
+ set_sysparm_fn = use_chardev ?
|
||||
+ set_sysparm_chardev : set_sysparm_syscall_fallback;
|
||||
+}
|
||||
+
|
||||
+static pthread_once_t sysparm_fn_setup_once = PTHREAD_ONCE_INIT;
|
||||
+
|
||||
+int rtas_get_sysparm(unsigned int parameter, unsigned int length, char *data)
|
||||
+{
|
||||
+ pthread_once(&sysparm_fn_setup_once, sysparm_fn_setup);
|
||||
+ return get_sysparm_fn(parameter, length, data);
|
||||
+}
|
||||
+
|
||||
+int rtas_set_sysparm(unsigned int parameter, char *data)
|
||||
+{
|
||||
+ pthread_once(&sysparm_fn_setup_once, sysparm_fn_setup);
|
||||
+ return set_sysparm_fn(parameter, data);
|
||||
+}
|
||||
--
|
||||
2.43.0
|
||||
|
BIN
librtas-2.0.5.tar.gz
(Stored with Git LFS)
BIN
librtas-2.0.5.tar.gz
(Stored with Git LFS)
Binary file not shown.
BIN
librtas-2.0.6.tar.gz
(Stored with Git LFS)
Normal file
BIN
librtas-2.0.6.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
Name: librtas-doc
|
||||
Version: 2.0.5
|
||||
Version: 2.0.6
|
||||
Release: 0
|
||||
Summary: Documents for librtas
|
||||
License: LGPL-2.1-or-later
|
||||
@@ -27,12 +27,6 @@ Source0: https://github.com/ibm-power-utilities/librtas/archive/v%{versio
|
||||
Source2: activate-firmware-regress
|
||||
Source3: vpdupdate-regress
|
||||
Patch0: librtas.fix_doc_path.patch
|
||||
Patch1: 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch
|
||||
Patch2: 0002-librtas-move-VPD-code-into-separate-module.patch
|
||||
Patch3: 0003-librtas-move-system-parameter-code-to-separate-modul.patch
|
||||
Patch4: 0004-librtas-vendor-papr-miscdev.h.patch
|
||||
Patch5: 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
|
||||
Patch6: 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
|
||||
Patch7: 0001-librtas-Move-platform-dump-rtas-call-code-to-separat.patch
|
||||
Patch8: 0002-librtas-platform-dump-prefer-dev-papr-platform-dump-.patch
|
||||
Patch9: 0003-librtas-move-get-set-indices-RTAS-calls-code-to-sepa.patch
|
||||
|
@@ -1,3 +1,17 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed May 7 11:53:55 UTC 2025 - Michal Suchanek <msuchanek@suse.de>
|
||||
|
||||
- Update to version 2.0.6
|
||||
* Optimize delay handling
|
||||
* Add support for new rtas kernel interface for VPD and sysparm
|
||||
- Drop upstreamed patches
|
||||
* 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch
|
||||
* 0002-librtas-move-VPD-code-into-separate-module.patch
|
||||
* 0003-librtas-move-system-parameter-code-to-separate-modul.patch
|
||||
* 0004-librtas-vendor-papr-miscdev.h.patch
|
||||
* 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
|
||||
* 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Mar 20 14:41:36 UTC 2025 - Michal Suchanek <msuchanek@suse.de>
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
%define sover 2
|
||||
Name: librtas
|
||||
Version: 2.0.5
|
||||
Version: 2.0.6
|
||||
Release: 0
|
||||
Summary: Libraries to provide access to RTAS calls and RTAS events
|
||||
License: LGPL-2.1-or-later
|
||||
@@ -29,12 +29,6 @@ Source1: baselibs.conf
|
||||
Source2: activate-firmware-regress
|
||||
Source3: vpdupdate-regress
|
||||
Patch0: librtas.fix_doc_path.patch
|
||||
Patch1: 0001-librtas-expose-low-level-RTAS-call-APIs-internally.patch
|
||||
Patch2: 0002-librtas-move-VPD-code-into-separate-module.patch
|
||||
Patch3: 0003-librtas-move-system-parameter-code-to-separate-modul.patch
|
||||
Patch4: 0004-librtas-vendor-papr-miscdev.h.patch
|
||||
Patch5: 0005-librtas-vpd-prefer-dev-papr-vpd-when-available.patch
|
||||
Patch6: 0006-librtas-sysparm-prefer-dev-papr-sysparm-when-availab.patch
|
||||
Patch7: 0001-librtas-Move-platform-dump-rtas-call-code-to-separat.patch
|
||||
Patch8: 0002-librtas-platform-dump-prefer-dev-papr-platform-dump-.patch
|
||||
Patch9: 0003-librtas-move-get-set-indices-RTAS-calls-code-to-sepa.patch
|
||||
|
Reference in New Issue
Block a user