mbox_msg: Move handler table to struct mbox_context

This allows us to provide alternative implementations for the handlers
as necessary. The vpnor feature, which enforces the read-only property
of FFS partitions, requires this for handling CREATE_WRITE_WINDOW.

Change-Id: Ia969a6f085244b194c500e66b62adca5e10bacba
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/mbox.h b/mbox.h
index 67d5622..7ae002b 100644
--- a/mbox.h
+++ b/mbox.h
@@ -118,6 +118,21 @@
 	struct window_context *window;
 };
 
+struct mbox_msg {
+	uint8_t command;
+	uint8_t seq;
+	uint8_t args[MBOX_ARGS_BYTES];
+	uint8_t response;
+};
+
+union mbox_regs {
+	uint8_t raw[MBOX_REG_BYTES];
+	struct mbox_msg msg;
+};
+
+typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
+				  struct mbox_msg *);
+
 struct mbox_context {
 /* System State */
 	enum mbox_state state;
@@ -128,6 +143,9 @@
 	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_msg.c b/mboxd_msg.c
index 46679b8..4ca8e24 100644
--- a/mboxd_msg.c
+++ b/mboxd_msg.c
@@ -33,9 +33,6 @@
 static int mbox_handle_flush_window(struct mbox_context *context, union mbox_regs *req,
 			     struct mbox_msg *resp);
 
-typedef int (*mboxd_mbox_handler)(struct mbox_context *, union mbox_regs *,
-				  struct mbox_msg *);
-
 /*
  * write_bmc_event_reg() - Write to the BMC controlled status register (reg 15)
  * @context:	The mbox context pointer
@@ -754,7 +751,8 @@
 		resp.response = -rc;
 	} else {
 		/* Commands start at 1 so we have to subtract 1 from the cmd */
-		rc = mbox_handlers[req->msg.command - 1](context, req, &resp);
+		mboxd_mbox_handler h = context->handlers[req->msg.command - 1];
+		rc = h(context, req, &resp);
 		if (rc < 0) {
 			MSG_ERR("Error handling mbox cmd: %d\n",
 				req->msg.command);
@@ -835,6 +833,8 @@
 {
 	int fd;
 
+	context->handlers = mbox_handlers;
+
 	/* Open MBOX Device */
 	fd = open(path, O_RDWR | O_NONBLOCK);
 	if (fd < 0) {
diff --git a/mboxd_msg.h b/mboxd_msg.h
index 124927c..aebf3bd 100644
--- a/mboxd_msg.h
+++ b/mboxd_msg.h
@@ -13,18 +13,6 @@
 #define NO_BMC_EVENT			false
 #define SET_BMC_EVENT			true
 
-struct mbox_msg {
-	uint8_t command;
-	uint8_t seq;
-	uint8_t args[MBOX_ARGS_BYTES];
-	uint8_t response;
-};
-
-union mbox_regs {
-	uint8_t raw[MBOX_REG_BYTES];
-	struct mbox_msg msg;
-};
-
 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,
diff --git a/test/mbox.c b/test/mbox.c
index 932c4d7..3daf493 100644
--- a/test/mbox.c
+++ b/test/mbox.c
@@ -232,9 +232,14 @@
 	test.context.windows.default_size = len;
 
 	/*
-	 * We need to control MBOX_FD, so don't call __init_mbox_dev().
-	 * Instead, insert our temporary file's fd directly into the context
+	 * We need to call __init_mbox_dev() to initialise the handler table.
+	 * However, afterwards we need to discard the fd of the clearly useless
+	 * /dev/null and replace it with our own fd for mbox device emulation
+	 * by the test framework.
 	 */
+	__init_mbox_dev(&test.context, "/dev/null");
+	rc = close(test.context.fds[MBOX_FD].fd);
+	assert(rc == 0);
 	test.context.fds[MBOX_FD].fd = test.mbox.fd;
 
 	rc = init_flash_dev(&test.context);