diff mbox series

[v3,3/3] libsbefifo: Set long read timeout for chip-ops

Message ID 20220303014616.757411-4-joel@jms.id.au
State New
Headers show
Series sbefifo long running chip-op ioctl support | expand

Checks

Context Check Description
snowpatch_ozlabs/github-CI success Successfully ran 1 jobs.
snowpatch_ozlabs/github-build_and_test success Successfully ran 1 jobs.

Commit Message

Joel Stanley March 3, 2022, 1:46 a.m. UTC
From: Amitay Isaacs <amitay@ozlabs.org>

SBE interface specification lists several sbe chip-ops that require long
read timeout as those chip-ops can take up to 30 seconds to complete.

Reset the long timeout back to the default after performing the chip-op.

The list of chip-ops from the spec (v2.0):

 0xA1	0x01	Execute istep
 0xA2 	0x05	Execute multi-SCOM
 0xA3	0x01	Get Ring
	0x02	Set Ring
 0xA4	0x01	Get Memory
	0x02	Put Memory
	0x03	Get SRAM
	0x04	Put SRAM
 0xA5	0x01	Get Architected Register
 	0x02	Put Architected Register
 0xA6	0x01	Control Fast Array
 	0x02	Control Trace Array
 0xA8	0x03	Quiesce SBE
 0xA9	0x01	Enter MPIPL
 	0x02	Continue MPIPL
	0x04	TI Info

Signed-off-by: Amitay Isaacs <amitay@ozlabs.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
v3:
  Fix up error handling: don't leak msg, and ensure we reset the timeout
  another call fails

  Document long running ops in sbefifo_private.h

 libsbefifo/sbefifo_private.h | 37 ++++++++++++++++++++----------------
 libsbefifo/cmd_array.c       | 14 ++++++++++++++
 libsbefifo/cmd_control.c     |  7 +++++++
 libsbefifo/cmd_generic.c     |  7 +++++++
 libsbefifo/cmd_memory.c      | 29 +++++++++++++++++++++++++++-
 libsbefifo/cmd_mpipl.c       | 21 ++++++++++++++++++++
 libsbefifo/cmd_register.c    | 12 ++++++++++++
 libsbefifo/cmd_ring.c        | 21 ++++++++++++++++++++
 8 files changed, 131 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/libsbefifo/sbefifo_private.h b/libsbefifo/sbefifo_private.h
index 373f7f3c90ed..e6de9e21e114 100644
--- a/libsbefifo/sbefifo_private.h
+++ b/libsbefifo/sbefifo_private.h
@@ -20,8 +20,13 @@ 
 #include <stdint.h>
 #include "libsbefifo.h"
 
+/*
+ * Long running commands will set a long (30 second) timeout when the kernel
+ * supports it.
+ */
+
 #define SBEFIFO_CMD_CLASS_CONTROL        0xA100
-#define   SBEFIFO_CMD_EXECUTE_ISTEP        0x01
+#define   SBEFIFO_CMD_EXECUTE_ISTEP        0x01 /* long running */
 #define   SBEFIFO_CMD_SUSPEND_IO           0x02
 
 #define SBEFIFO_CMD_CLASS_SCOM           0xA200
@@ -29,28 +34,28 @@ 
 #define   SBEFIFO_CMD_PUT_SCOM             0x02
 #define   SBEFIFO_CMD_MODIFY_SCOM          0x03
 #define   SBEFIFO_CMD_PUT_SCOM_MASK        0x04
-#define   SBEFIFO_CMD_MULTI_SCOM           0x05
+#define   SBEFIFO_CMD_MULTI_SCOM           0x05 /* long running */
 
 #define SBEFIFO_CMD_CLASS_RING           0xA300
-#define   SBEFIFO_CMD_GET_RING             0x01
-#define   SBEFIFO_CMD_PUT_RING             0x02
+#define   SBEFIFO_CMD_GET_RING             0x01 /* long running */
+#define   SBEFIFO_CMD_PUT_RING             0x02 /* long running */
 #define   SBEFIFO_CMD_PUT_RING_IMAGE       0x03
 
 #define SBEFIFO_CMD_CLASS_MEMORY         0xA400
-#define   SBEFIFO_CMD_GET_MEMORY           0x01
-#define   SBEFIFO_CMD_PUT_MEMORY           0x02
-#define   SBEFIFO_CMD_GET_SRAM             0x03
-#define   SBEFIFO_CMD_PUT_SRAM             0x04
+#define   SBEFIFO_CMD_GET_MEMORY           0x01 /* long running */
+#define   SBEFIFO_CMD_PUT_MEMORY           0x02 /* long running */
+#define   SBEFIFO_CMD_GET_SRAM             0x03 /* long running */
+#define   SBEFIFO_CMD_PUT_SRAM             0x04 /* long running */
 
 #define SBEFIFO_CMD_CLASS_REGISTER       0xA500
-#define   SBEFIFO_CMD_GET_REGISTER         0x01
-#define   SBEFIFO_CMD_PUT_REGISTER         0x02
+#define   SBEFIFO_CMD_GET_REGISTER         0x01 /* long running */
+#define   SBEFIFO_CMD_PUT_REGISTER         0x02 /* long running */
 #define   SBEFIFO_CMD_GET_HW_REGISTER      0x03
 #define   SBEFIFO_CMD_PUT_HW_REGISTER      0x04
 
 #define SBEFIFO_CMD_CLASS_ARRAY          0xA600
-#define   SBEFIFO_CMD_FAST_ARRAY           0x01
-#define   SBEFIFO_CMD_TRACE_ARRAY          0x02
+#define   SBEFIFO_CMD_FAST_ARRAY           0x01 /* long running */
+#define   SBEFIFO_CMD_TRACE_ARRAY          0x02 /* long running */
 
 #define SBEFIFO_CMD_CLASS_INSTRUCTION    0xA700
 #define   SBEFIFO_CMD_CONTROL_INSN         0x01
@@ -58,15 +63,15 @@ 
 #define SBEFIFO_CMD_CLASS_GENERIC        0xA800
 #define   SBEFIFO_CMD_GET_FFDC             0x01
 #define   SBEFIFO_CMD_GET_CAPABILITY       0x02
-#define   SBEFIFO_CMD_QUIESCE              0x03
+#define   SBEFIFO_CMD_QUIESCE              0x03 /* long running */
 /* missing ids */
 #define   SBEFIFO_CMD_LPC_TIMEOUT          0x08
 
 #define SBEFIFO_CMD_CLASS_MPIPL          0xA900
-#define   SBEFIFO_CMD_ENTER_MPIPL          0x01
-#define   SBEFIFO_CMD_CONTINUE_MPIPL       0x02
+#define   SBEFIFO_CMD_ENTER_MPIPL          0x01 /* long running */
+#define   SBEFIFO_CMD_CONTINUE_MPIPL       0x02 /* long running */
 #define   SBEFIFO_CMD_STOP_CLOCKS          0x03
-#define   SBEFIFO_CMD_GET_TI_INFO          0x04
+#define   SBEFIFO_CMD_GET_TI_INFO          0x04 /* long running */
 
 #define SBEFIFO_CMD_CLASS_DUMP           0xAA00
 #define   SBEFIFO_CMD_GET_DUMP             0x01
diff --git a/libsbefifo/cmd_array.c b/libsbefifo/cmd_array.c
index 1ff8c03d7278..9c60b3fe9513 100644
--- a/libsbefifo/cmd_array.c
+++ b/libsbefifo/cmd_array.c
@@ -69,8 +69,15 @@  int sbefifo_control_fast_array(struct sbefifo_context *sctx, uint16_t target_typ
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -136,9 +143,16 @@  int sbefifo_control_trace_array(struct sbefifo_context *sctx, uint16_t target_ty
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	/* The size of returned data is just a guess */
 	out_len = 16 * sizeof(uint32_t);
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
diff --git a/libsbefifo/cmd_control.c b/libsbefifo/cmd_control.c
index e64f555c665d..2ff7ebcac468 100644
--- a/libsbefifo/cmd_control.c
+++ b/libsbefifo/cmd_control.c
@@ -64,8 +64,15 @@  int sbefifo_istep_execute(struct sbefifo_context *sctx, uint8_t major, uint8_t m
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
diff --git a/libsbefifo/cmd_generic.c b/libsbefifo/cmd_generic.c
index 16c61f4a7863..7035af41b2c8 100644
--- a/libsbefifo/cmd_generic.c
+++ b/libsbefifo/cmd_generic.c
@@ -199,8 +199,15 @@  int sbefifo_quiesce(struct sbefifo_context *sctx)
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
diff --git a/libsbefifo/cmd_memory.c b/libsbefifo/cmd_memory.c
index 4195a1269963..546037dd84b1 100644
--- a/libsbefifo/cmd_memory.c
+++ b/libsbefifo/cmd_memory.c
@@ -125,6 +125,12 @@  int sbefifo_mem_get(struct sbefifo_context *sctx, uint64_t addr, uint32_t size,
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	/* length is 6th word in the request */
 	len = be32toh(*(uint32_t *)(msg + 20));
 	extra_bytes = 0;
@@ -137,11 +143,11 @@  int sbefifo_mem_get(struct sbefifo_context *sctx, uint64_t addr, uint32_t size,
 
 	out_len = len + extra_bytes + 4;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
 
-
 	rc = sbefifo_mem_get_pull(out, out_len, addr, size, flags, data);
 	if (out)
 		free(out);
@@ -206,8 +212,15 @@  int sbefifo_mem_put(struct sbefifo_context *sctx, uint64_t addr, uint8_t *data,
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 1 * 4;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -295,11 +308,18 @@  int sbefifo_sram_get(struct sbefifo_context *sctx, uint16_t chiplet_id, uint64_t
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	/* length is 6th word in the request */
 	len = be32toh(*(uint32_t *)(msg + 20));
 
 	out_len = len + 4;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -375,8 +395,15 @@  int sbefifo_sram_put(struct sbefifo_context *sctx, uint16_t chiplet_id, uint64_t
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 4;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
diff --git a/libsbefifo/cmd_mpipl.c b/libsbefifo/cmd_mpipl.c
index 1d3249483375..81816fa13012 100644
--- a/libsbefifo/cmd_mpipl.c
+++ b/libsbefifo/cmd_mpipl.c
@@ -61,8 +61,15 @@  int sbefifo_mpipl_enter(struct sbefifo_context *sctx)
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -112,8 +119,15 @@  int sbefifo_mpipl_continue(struct sbefifo_context *sctx)
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -224,8 +238,15 @@  int sbefifo_mpipl_get_ti_info(struct sbefifo_context *sctx, uint8_t **data, uint
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
diff --git a/libsbefifo/cmd_register.c b/libsbefifo/cmd_register.c
index 1e74b6ec4eb9..076b774cb905 100644
--- a/libsbefifo/cmd_register.c
+++ b/libsbefifo/cmd_register.c
@@ -88,12 +88,18 @@  int sbefifo_register_get(struct sbefifo_context *sctx, uint8_t core_id, uint8_t
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc)
+		return rc;
+
 	out_len = reg_count * 8;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
 	free(msg);
 	if (rc)
 		return rc;
 
+	sbefifo_reset_timeout(sctx);
+
 	rc = sbefifo_register_get_pull(out, out_len, reg_count, value);
 	if (out)
 		free(out);
@@ -154,12 +160,18 @@  int sbefifo_register_put(struct sbefifo_context *sctx, uint8_t core_id, uint8_t
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc)
+		return rc;
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
 	free(msg);
 	if (rc)
 		return rc;
 
+	sbefifo_reset_timeout(sctx);
+
 	rc = sbefifo_register_put_pull(out, out_len);
 	if (out)
 		free(out);
diff --git a/libsbefifo/cmd_ring.c b/libsbefifo/cmd_ring.c
index 44e8effc4c99..ef6d5b569052 100644
--- a/libsbefifo/cmd_ring.c
+++ b/libsbefifo/cmd_ring.c
@@ -71,9 +71,16 @@  int sbefifo_ring_get(struct sbefifo_context *sctx, uint32_t ring_addr, uint32_t
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	/* multiples of 64 bits */
 	out_len = (ring_len_bits + 63) / 8;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -125,8 +132,15 @@  int sbefifo_ring_put(struct sbefifo_context *sctx, uint16_t ring_mode, uint8_t *
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(msg);
 	if (rc)
 		return rc;
@@ -185,8 +199,15 @@  int sbefifo_ring_put_from_image(struct sbefifo_context *sctx, uint16_t target, u
 	if (rc)
 		return rc;
 
+	rc = sbefifo_set_long_timeout(sctx);
+	if (rc) {
+		free(msg);
+		return rc;
+	}
+
 	out_len = 0;
 	rc = sbefifo_operation(sctx, msg, msg_len, &out, &out_len);
+	sbefifo_reset_timeout(sctx);
 	free(out);
 	if (rc)
 		return rc;