protocol: Provide abstraction over event notification
How this works will be transport-dependent. Move the event notification
helpers into the protocol abstraction and call-back through the
registered flush handler as necessary.
Change-Id: I29e3a9a9785b92de46a2b2750257fb7f8480a184
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/control.c b/control.c
index c9956e9..01a2e5f 100644
--- a/control.c
+++ b/control.c
@@ -47,7 +47,7 @@
* mapping back to flash, or memory in case we're using a virtual pnor.
* Better set the bmc event to notify the host of this.
*/
- windows_reset_all(context, SET_BMC_EVENT);
+ windows_reset_all(context, EVENT_TRIGGER);
rc = lpc_reset(context);
if (rc < 0) {
return rc;
@@ -71,7 +71,7 @@
flash_set_bytemap(context, 0, context->flash_size, FLASH_DIRTY);
/* Force daemon to reload all windows -> Set BMC event to notify host */
- windows_reset_all(context, SET_BMC_EVENT);
+ windows_reset_all(context, EVENT_TRIGGER);
return 0;
}
@@ -86,7 +86,7 @@
}
/* Nothing to check - Just set the bit to notify the host */
- rc = set_bmc_events(context, BMC_EVENT_FLASH_CTRL_LOST, SET_BMC_EVENT);
+ rc = protocol_events_set(context, BMC_EVENT_FLASH_CTRL_LOST, EVENT_TRIGGER);
if (rc < 0) {
return rc;
}
@@ -111,7 +111,7 @@
}
/* Clear the bit and send the BMC Event to the host */
- rc = clr_bmc_events(context, BMC_EVENT_FLASH_CTRL_LOST, SET_BMC_EVENT);
+ rc = protocol_events_clear(context, BMC_EVENT_FLASH_CTRL_LOST, EVENT_TRIGGER);
if (rc < 0) {
return rc;
}
diff --git a/mbox.h b/mbox.h
index 3676825..c2db30c 100644
--- a/mbox.h
+++ b/mbox.h
@@ -10,6 +10,7 @@
#include <stdbool.h>
#include "protocol.h"
+#include "transport.h"
#include "vpnor/mboxd_pnor_partition_table.h"
enum api_version {
@@ -134,12 +135,10 @@
struct mbox_context;
-typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
- struct mbox_msg *);
-
struct mbox_context {
enum api_version version;
const struct protocol_ops *protocol;
+ const struct transport_ops *transport;
/* System State */
enum mbox_state state;
@@ -149,9 +148,6 @@
uint8_t bmc_events;
uint8_t prev_seq;
-/* Command Dispatch */
- const mboxd_mbox_handler *handlers;
-
/* Window State */
/* The window list struct containing all current "windows" */
struct window_list windows;
diff --git a/mboxd.c b/mboxd.c
index 2382724..a5c7ef6 100644
--- a/mboxd.c
+++ b/mboxd.c
@@ -139,7 +139,7 @@
break;
case SIGHUP:
/* Host didn't request reset -> Notify it */
- windows_reset_all(context, SET_BMC_EVENT);
+ windows_reset_all(context, EVENT_TRIGGER);
rc = lpc_reset(context);
if (rc < 0) {
MSG_ERR("WARNING: Failed to point the "
@@ -177,7 +177,7 @@
/* Best to reset windows and the lpc mapping for safety */
/* Host didn't request reset -> Notify it */
- windows_reset_all(context, SET_BMC_EVENT);
+ windows_reset_all(context, EVENT_TRIGGER);
rc = lpc_reset(context);
/* Not much we can do if this fails */
if (rc < 0) {
@@ -394,7 +394,7 @@
MSG_ERR("LPC configuration failed, RESET required: %d\n", rc);
}
- rc = set_bmc_events(context, BMC_EVENT_DAEMON_READY, SET_BMC_EVENT);
+ rc = protocol_events_set(context, BMC_EVENT_DAEMON_READY, EVENT_TRIGGER);
if (rc) {
goto finish;
}
@@ -406,7 +406,7 @@
finish:
MSG_INFO("Daemon Exiting...\n");
- clr_bmc_events(context, BMC_EVENT_DAEMON_READY, SET_BMC_EVENT);
+ protocol_events_clear(context, BMC_EVENT_DAEMON_READY, EVENT_TRIGGER);
#ifdef VIRTUAL_PNOR_ENABLED
destroy_vpnor(context);
diff --git a/protocol.c b/protocol.c
index 4160e6e..c18083f 100644
--- a/protocol.c
+++ b/protocol.c
@@ -5,16 +5,61 @@
#include <errno.h>
#include <stdint.h>
+#include "common.h"
#include "flash.h"
#include "mbox.h"
#include "lpc.h"
-#include "transport_mbox.h" /* TODO: Remove dependency on transport_mbox.h */
#include "windows.h"
+/*
+ * protocol_events_set() - Set BMC events
+ * @context: The mbox context pointer
+ * @bmc_event: The bits to set
+ * @write_back: Whether to write back to the register -> will interrupt host
+ *
+ * Return: 0 on success otherwise negative error code
+ */
+int protocol_events_set(struct mbox_context *context, uint8_t bmc_event,
+ bool write_back)
+{
+ uint8_t mask = 0x00;
+
+ switch (context->version) {
+ case API_VERSION_1:
+ mask = BMC_EVENT_V1_MASK;
+ break;
+ default:
+ mask = BMC_EVENT_V2_MASK;
+ break;
+ }
+
+ context->bmc_events |= (bmc_event & mask);
+ MSG_DBG("BMC Events set to: 0x%.2x\n", context->bmc_events);
+
+ return write_back ? context->transport->flush_events(context) : 0;
+}
+
+/*
+ * protocol_events_clear() - Clear BMC events
+ * @context: The mbox context pointer
+ * @bmc_event: The bits to clear
+ * @write_back: Whether to write back to the register -> will interrupt host
+ *
+ * Return: 0 on success otherwise negative error code
+ */
+int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event,
+ bool write_back)
+{
+ context->bmc_events &= ~bmc_event;
+ MSG_DBG("BMC Events clear to: 0x%.2x\n", context->bmc_events);
+
+ return write_back ? context->transport->flush_events(context) : 0;
+}
+
int protocol_v1_reset(struct mbox_context *context)
{
/* Host requested it -> No BMC Event */
- windows_reset_all(context, NO_BMC_EVENT);
+ windows_reset_all(context, EVENT_SUPPRESS);
return lpc_reset(context);
}
@@ -31,7 +76,7 @@
/* Do the {up,down}grade if necessary*/
if (rc != old_version) {
- windows_reset_all(context, SET_BMC_EVENT);
+ windows_reset_all(context, EVENT_TRIGGER);
return context->protocol->get_info(context, io);
}
@@ -104,7 +149,7 @@
return rc;
}
}
- windows_close_current(context, NO_BMC_EVENT, FLAGS_NONE);
+ windows_close_current(context, EVENT_SUPPRESS, FLAGS_NONE);
}
/* Offset the host has requested */
@@ -284,15 +329,15 @@
}
/* Host asked for it -> Don't set the BMC Event */
- windows_close_current(context, NO_BMC_EVENT, io->req.flags);
+ windows_close_current(context, EVENT_SUPPRESS, io->req.flags);
return 0;
}
int protocol_v1_ack(struct mbox_context *context, struct protocol_ack *io)
{
- return clr_bmc_events(context, (io->req.flags & BMC_EVENT_ACK_MASK),
- SET_BMC_EVENT);
+ return protocol_events_clear(context, (io->req.flags & BMC_EVENT_ACK_MASK),
+ EVENT_TRIGGER);
}
/*
@@ -327,7 +372,7 @@
/* Do the {up,down}grade if necessary*/
if (rc != old_version) {
- windows_reset_all(context, SET_BMC_EVENT);
+ windows_reset_all(context, EVENT_TRIGGER);
return context->protocol->get_info(context, io);
}
@@ -449,7 +494,7 @@
}
/* Host asked for it -> Don't set the BMC Event */
- windows_close_current(context, NO_BMC_EVENT, io->req.flags);
+ windows_close_current(context, EVENT_SUPPRESS, io->req.flags);
return 0;
}
diff --git a/protocol.h b/protocol.h
index 5cdc2eb..f2b8e6f 100644
--- a/protocol.h
+++ b/protocol.h
@@ -120,6 +120,14 @@
int protocol_negotiate_version(struct mbox_context *context, uint8_t requested);
+#define EVENT_SUPPRESS false
+#define EVENT_TRIGGER true
+
+int protocol_events_set(struct mbox_context *context, uint8_t bmc_event,
+ bool write_back);
+int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event,
+ bool write_back);
+
/* Protocol v1 */
int protocol_v1_reset(struct mbox_context *context);
int protocol_v1_get_info(struct mbox_context *context,
diff --git a/test/bmc_event_ack_v2.c b/test/bmc_event_ack_v2.c
index 3bf1f37..c9056de 100644
--- a/test/bmc_event_ack_v2.c
+++ b/test/bmc_event_ack_v2.c
@@ -49,7 +49,7 @@
rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info));
assert(rc == 1);
- set_bmc_events(ctx, FLAGS, SET_BMC_EVENT);
+ protocol_events_set(ctx, FLAGS, EVENT_TRIGGER);
rc = mbox_command_dispatch(ctx, command, sizeof(command));
assert(rc == 1);
diff --git a/transport.h b/transport.h
new file mode 100644
index 0000000..d6ec39e
--- /dev/null
+++ b/transport.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/* Copyright (C) 2018 IBM Corp. */
+
+#ifndef TRANSPORT_H
+#define TRANSPORT_H
+
+#include "mbox.h"
+
+struct transport_ops {
+ int (*flush_events)(struct mbox_context *context);
+};
+
+#endif /* TRANSPORT_H */
diff --git a/transport_mbox.c b/transport_mbox.c
index fcc4430..fb4c28a 100644
--- a/transport_mbox.c
+++ b/transport_mbox.c
@@ -84,12 +84,13 @@
}
/*
- * write_bmc_event_reg() - Write to the BMC controlled status register (reg 15)
+ * transport_mbox_flush_events() - Write to the BMC controlled status register
+ * (reg 15)
* @context: The mbox context pointer
*
* Return: 0 on success otherwise negative error code
*/
-static int write_bmc_event_reg(struct mbox_context *context)
+static int transport_mbox_flush_events(struct mbox_context *context)
{
int rc;
@@ -98,7 +99,7 @@
if (rc != MBOX_BMC_EVENT) {
MSG_ERR("Couldn't lseek mbox to byte %d: %s\n", MBOX_BMC_EVENT,
strerror(errno));
- return -MBOX_R_SYSTEM_ERROR;
+ return -errno;
}
/* Write to mbox status register */
@@ -106,7 +107,7 @@
if (rc != 1) {
MSG_ERR("Couldn't write to BMC status reg: %s\n",
strerror(errno));
- return -MBOX_R_SYSTEM_ERROR;
+ return -errno;
}
/* Reset to start */
@@ -114,57 +115,12 @@
if (rc) {
MSG_ERR("Couldn't reset MBOX offset to zero: %s\n",
strerror(errno));
- return -MBOX_R_SYSTEM_ERROR;
+ return -errno;
}
return 0;
}
-/*
- * set_bmc_events() - Set BMC events
- * @context: The mbox context pointer
- * @bmc_event: The bits to set
- * @write_back: Whether to write back to the register -> will interrupt host
- *
- * Return: 0 on success otherwise negative error code
- */
-int set_bmc_events(struct mbox_context *context, uint8_t bmc_event,
- bool write_back)
-{
- uint8_t mask = 0x00;
-
- switch (context->version) {
- case API_VERSION_1:
- mask = BMC_EVENT_V1_MASK;
- break;
- default:
- mask = BMC_EVENT_V2_MASK;
- break;
- }
-
- context->bmc_events |= (bmc_event & mask);
- MSG_DBG("BMC Events set to: 0x%.2x\n", context->bmc_events);
-
- return write_back ? write_bmc_event_reg(context) : 0;
-}
-
-/*
- * clr_bmc_events() - Clear BMC events
- * @context: The mbox context pointer
- * @bmc_event: The bits to clear
- * @write_back: Whether to write back to the register -> will interrupt host
- *
- * Return: 0 on success otherwise negative error code
- */
-int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event,
- bool write_back)
-{
- context->bmc_events &= ~bmc_event;
- MSG_DBG("BMC Events clear to: 0x%.2x\n", context->bmc_events);
-
- return write_back ? write_bmc_event_reg(context) : 0;
-}
-
/* Command Handlers */
/*
@@ -532,7 +488,10 @@
return 0;
}
-static const mboxd_mbox_handler mbox_handlers[] = {
+typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
+ struct mbox_msg *);
+
+static const mboxd_mbox_handler transport_mbox_handlers[] = {
mbox_handle_reset,
mbox_handle_mbox_info,
mbox_handle_flash_info,
@@ -565,9 +524,11 @@
MSG_INFO("Received MBOX command: %u\n", req->msg.command);
rc = check_req_valid(context, req);
if (!rc) {
+ mboxd_mbox_handler handler;
+
/* Commands start at 1 so we have to subtract 1 from the cmd */
- mboxd_mbox_handler h = context->handlers[req->msg.command - 1];
- rc = h(context, req, &resp);
+ handler = transport_mbox_handlers[req->msg.command - 1];
+ rc = handler(context, req, &resp);
if (rc < 0) {
MSG_ERR("Error handling mbox cmd: %d\n",
req->msg.command);
@@ -645,11 +606,15 @@
return handle_mbox_req(context, &req);
}
+static const struct transport_ops transport_mbox_ops = {
+ .flush_events = transport_mbox_flush_events,
+};
+
int __init_mbox_dev(struct mbox_context *context, const char *path)
{
int fd;
- context->handlers = mbox_handlers;
+ context->transport = &transport_mbox_ops;
/* Open MBOX Device */
fd = open(path, O_RDWR | O_NONBLOCK);
diff --git a/transport_mbox.h b/transport_mbox.h
index 8f65f7d..4c2952c 100644
--- a/transport_mbox.h
+++ b/transport_mbox.h
@@ -7,13 +7,6 @@
#include "common.h"
#include "mbox.h"
-#define NO_BMC_EVENT false
-#define SET_BMC_EVENT true
-
-int set_bmc_events(struct mbox_context *context, uint8_t bmc_event,
- bool write_back);
-int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event,
- bool write_back);
int dispatch_mbox(struct mbox_context *context);
int init_mbox_dev(struct mbox_context *context);
void free_mbox_dev(struct mbox_context *context);
diff --git a/windows.c b/windows.c
index a126365..b56f73f 100644
--- a/windows.c
+++ b/windows.c
@@ -394,7 +394,7 @@
MSG_DBG("Close current window, flags: 0x%.2x\n", flags);
if (set_bmc_event) {
- set_bmc_events(context, BMC_EVENT_WINDOW_RESET, SET_BMC_EVENT);
+ protocol_events_set(context, BMC_EVENT_WINDOW_RESET, EVENT_TRIGGER);
}
if (flags & FLAGS_SHORT_LIFETIME) {