protocol: Add get_info

Change-Id: Ie3338714813bb65f5d37fcd046dd5bebc0ba21f0
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/transport_mbox.c b/transport_mbox.c
index c14ab27..ec6d601 100644
--- a/transport_mbox.c
+++ b/transport_mbox.c
@@ -30,6 +30,52 @@
 #include "windows.h"
 #include "lpc.h"
 
+struct errno_map {
+	int rc;
+	int mbox_errno;
+};
+
+static const struct errno_map errno_map_v1[] = {
+	{ 0, MBOX_R_SUCCESS },
+	{ EACCES, MBOX_R_PARAM_ERROR },
+	{ EBUSY, MBOX_R_SYSTEM_ERROR },
+	{ EINVAL, MBOX_R_PARAM_ERROR },
+	{ EPERM, MBOX_R_PARAM_ERROR },
+	{ ETIMEDOUT, MBOX_R_TIMEOUT },
+	{ -1, MBOX_R_SYSTEM_ERROR },
+};
+
+static const struct errno_map errno_map_v2[] = {
+	{ 0, MBOX_R_SUCCESS },
+	{ EACCES, MBOX_R_PARAM_ERROR },
+	{ EBUSY, MBOX_R_BUSY },
+	{ EINVAL, MBOX_R_PARAM_ERROR },
+	{ EPERM, MBOX_R_WINDOW_ERROR },
+	{ ETIMEDOUT, MBOX_R_TIMEOUT },
+	{ -1, MBOX_R_SYSTEM_ERROR },
+};
+
+static const struct errno_map *errno_maps[] = {
+	[0] = NULL,
+	[1] = errno_map_v1,
+	[2] = errno_map_v2,
+};
+
+static inline int mbox_xlate_errno(struct mbox_context *context,
+					     int rc)
+{
+	const struct errno_map *entry;
+
+	rc = -rc;
+	for(entry = errno_maps[context->version]; entry->rc != -1; entry++) {
+		if (rc == entry->rc) {
+			return -entry->mbox_errno;
+		}
+	}
+
+	return -entry->mbox_errno;
+}
+
 /*
  * write_bmc_event_reg() - Write to the BMC controlled status register (reg 15)
  * @context:	The mbox context pointer
@@ -128,25 +174,6 @@
 }
 
 /*
- * get_suggested_timeout() - get the suggested timeout value in seconds
- * @context:	The mbox context pointer
- *
- * Return:	Suggested timeout in seconds
- */
-static uint16_t get_suggested_timeout(struct mbox_context *context)
-{
-	struct window_context *window = windows_find_largest(context);
-	uint32_t max_size_mb = window ? (window->size >> 20) : 0;
-	uint16_t ret;
-
-	ret = align_up(max_size_mb * FLASH_ACCESS_MS_PER_MB, 1000) / 1000;
-
-	MSG_DBG("Suggested Timeout: %us, max window size: %uMB, for %dms/MB\n",
-		ret, max_size_mb, FLASH_ACCESS_MS_PER_MB);
-	return ret;
-}
-
-/*
  * Command: GET_MBOX_INFO
  * Get the API version, default window size and block size
  * We also set the LPC mapping to point to the reserved memory region here so
@@ -172,65 +199,23 @@
 				 union mbox_regs *req, struct mbox_msg *resp)
 {
 	uint8_t mbox_api_version = req->msg.args[0];
-	uint8_t old_api_version = context->version;
+	struct protocol_get_info io = {
+		.req = { .api_version = mbox_api_version }
+	};
 	int rc;
 
-	/* Check we support the version requested */
-	if (mbox_api_version < API_MIN_VERSION)
-		return -MBOX_R_PARAM_ERROR;
-
-	if (mbox_api_version > API_MAX_VERSION)
-		mbox_api_version = API_MAX_VERSION;
-
-	context->version = mbox_api_version;
-	MSG_INFO("Using Protocol Version: %d\n", context->version);
-
-	/*
-	 * The reset state is currently to have the LPC bus point directly to
-	 * flash, since we got a mbox_info command we know the host can talk
-	 * mbox so point the LPC bus mapping to the reserved memory region now
-	 * so the host can access what we put in it.
-	 */
-	rc = lpc_map_memory(context);
+	rc = context->protocol->get_info(context, &io);
 	if (rc < 0) {
-		return rc;
+		return mbox_xlate_errno(context, rc);
 	}
 
-	switch (context->version) {
-	case API_VERSION_1:
-		context->block_size_shift = BLOCK_SIZE_SHIFT_V1;
-		break;
-	default:
-		context->block_size_shift = log_2(context->mtd_info.erasesize);
-		break;
-	}
-	MSG_INFO("Block Size: 0x%.8x (shift: %u)\n",
-		 1 << context->block_size_shift, context->block_size_shift);
-
-	/* Now we know the blocksize we can allocate the window dirty_bytemap */
-	if (mbox_api_version != old_api_version) {
-		windows_alloc_dirty_bytemap(context);
-	}
-	/* Reset if we were V1 since this required exact window mapping */
-	if (old_api_version == API_VERSION_1) {
-		/*
-		 * This will only set the BMC event if there was a current
-		 * window -> In which case we are better off notifying the
-		 * host.
-		 */
-		windows_reset_all(context, SET_BMC_EVENT);
-	}
-
-	resp->args[0] = mbox_api_version;
-	if (context->version == API_VERSION_1) {
-		put_u16(&resp->args[1], context->windows.default_size >>
-					context->block_size_shift);
-		put_u16(&resp->args[3], context->windows.default_size >>
-					context->block_size_shift);
-	}
-	if (context->version >= API_VERSION_2) {
-		resp->args[5] = context->block_size_shift;
-		put_u16(&resp->args[6], get_suggested_timeout(context));
+	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);
+		put_u16(&resp->args[3], io.resp.v1.write_window_size);
+	} else if (io.resp.api_version >= API_VERSION_2) {
+		resp->args[5] = io.resp.v2.block_size_shift;
+		put_u16(&resp->args[6], io.resp.v2.timeout);
 	}
 
 	return 0;