diff mbox

[v2,3/4] ipmi: Add support for synchronous message sending

Message ID 1423026466-31386-4-git-send-email-alistair@popple.id.au
State Accepted
Headers show

Commit Message

Alistair Popple Feb. 4, 2015, 5:07 a.m. UTC
This patch adds support for sending ipmi messages synchronously. This
is necessary to allow messages to be sent during skiboot
initialisation as interrupt servicing/polling is controlled by the
host operating system which is not yet running.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
 core/ipmi.c    | 23 +++++++++++++++++++++++
 include/ipmi.h |  4 ++++
 2 files changed, 27 insertions(+)

Comments

Joel Stanley Feb. 5, 2015, 5:22 a.m. UTC | #1
On Wed, Feb 4, 2015 at 3:37 PM, Alistair Popple <alistair@popple.id.au> wrote:
> This patch adds support for sending ipmi messages synchronously. This
> is necessary to allow messages to be sent during skiboot
> initialisation as interrupt servicing/polling is controlled by the
> host operating system which is not yet running.
>
> Signed-off-by: Alistair Popple <alistair@popple.id.au>

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  core/ipmi.c    | 23 +++++++++++++++++++++++
>  include/ipmi.h |  4 ++++
>  2 files changed, 27 insertions(+)
diff mbox

Patch

diff --git a/core/ipmi.c b/core/ipmi.c
index da06c5f..99c2fd9 100644
--- a/core/ipmi.c
+++ b/core/ipmi.c
@@ -19,8 +19,13 @@ 
 #include <ipmi.h>
 #include <opal.h>
 #include <device.h>
+#include <lock.h>
+#include <cpu.h>
+#include <timebase.h>
 
 struct ipmi_backend *ipmi_backend = NULL;
+static struct lock sync_lock = LOCK_UNLOCKED;
+static struct ipmi_msg *sync_msg = NULL;
 
 void ipmi_free_msg(struct ipmi_msg *msg)
 {
@@ -109,6 +114,24 @@  void ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc, struct ipmi_msg *msg)
 
 	/* At this point the message has should have been freed by the
 	   completion functions. */
+
+	/* If this is a synchronous message flag that we are done */
+	if (msg == sync_msg)
+		sync_msg = NULL;
+}
+
+void ipmi_queue_msg_sync(struct ipmi_msg *msg)
+{
+	lock(&sync_lock);
+
+	assert(!sync_msg);
+	sync_msg = msg;
+	ipmi_queue_msg(msg);
+
+	while (sync_msg)
+		time_wait_ms(100);
+
+	unlock(&sync_lock);
 }
 
 static void ipmi_read_event_complete(struct ipmi_msg *msg)
diff --git a/include/ipmi.h b/include/ipmi.h
index 9c3f295..5cee692 100644
--- a/include/ipmi.h
+++ b/include/ipmi.h
@@ -193,6 +193,10 @@  int ipmi_queue_msg(struct ipmi_msg *msg);
 /* Add an ipmi message to the start of the queue */
 int ipmi_queue_msg_head(struct ipmi_msg *msg);
 
+/* Synchronously send an ipmi message. This won't return until the
+ * messages callback has been called. */
+void ipmi_queue_msg_sync(struct ipmi_msg *msg);
+
 /* Process a completed message */
 void ipmi_cmd_done(uint8_t cmd, uint8_t netfn, uint8_t cc, struct ipmi_msg *msg);