transport: Switch transports as required on GET_MBOX_INFO

Also flush the event state out via the new transport. This must be done
after the command has completed for the mbox transport.

Change-Id: I251fb949ae67a477288d0d57a1a6afe5b2af5f8f
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/transport_mbox.c b/transport_mbox.c
index d325b19..24d4734 100644
--- a/transport_mbox.c
+++ b/transport_mbox.c
@@ -121,6 +121,10 @@
 	return 0;
 }
 
+static const struct transport_ops transport_mbox_ops = {
+	.flush_events = transport_mbox_flush_events,
+};
+
 /* Command Handlers */
 
 /*
@@ -170,6 +174,12 @@
 		return rc;
 	}
 
+	/*
+	 * Switch transport to mbox, however we need to delay flushing the
+	 * event state until after the command is processed.
+	 */
+	context->transport = &transport_mbox_ops;
+
 	resp->args[0] = io.resp.api_version;
 	if (io.resp.api_version == API_VERSION_1) {
 		put_u16(&resp->args[1], io.resp.v1.read_window_size);
@@ -477,6 +487,14 @@
 		}
 	}
 
+	if (context->transport != &transport_mbox_ops) {
+		if (cmd != MBOX_C_RESET_STATE && cmd != MBOX_C_GET_MBOX_INFO) {
+			MSG_ERR("Cannot switch transport with command %d\n",
+				cmd);
+			return -EPROTO;
+		}
+	}
+
 	if (!(context->state & MAPS_MEM)) {
 		if (cmd != MBOX_C_RESET_STATE && cmd != MBOX_C_GET_MBOX_INFO
 					      && cmd != MBOX_C_ACK) {
@@ -513,6 +531,7 @@
  */
 static int handle_mbox_req(struct mbox_context *context, union mbox_regs *req)
 {
+	const struct transport_ops *old_transport = context->transport;
 	struct mbox_msg resp = {
 		.command = req->msg.command,
 		.seq = req->msg.seq,
@@ -522,6 +541,7 @@
 	int rc = 0, len, i;
 
 	MSG_INFO("Received MBOX command: %u\n", req->msg.command);
+
 	rc = check_req_valid(context, req);
 	if (!rc) {
 		mboxd_mbox_handler handler;
@@ -552,6 +572,11 @@
 		rc = -errno;
 	}
 
+	if (context->transport != old_transport &&
+			context->transport == &transport_mbox_ops) {
+		transport_mbox_flush_events(context);
+	}
+
 	return rc;
 }
 
@@ -606,10 +631,6 @@
 	return handle_mbox_req(context, &req);
 }
 
-static const struct transport_ops transport_mbox_ops = {
-	.flush_events = transport_mbox_flush_events,
-};
-
 int __transport_mbox_init(struct mbox_context *context, const char *path)
 {
 	int fd;