mboxd: Add a backend abstraction layer to mboxd.

Introduce a backend abstraction, enabling multiple implementations to be
compiled in at once. This change formally abstracts the two existing
backends, mtd and vpnor.

With the backend abstraction in place, subsequent backends are easier to
implement.

This change is based of Evan's work and he retains authorship credit. I
(AJ) have reworked the patch to pass the vpnor tests, refactored some
parts to enable broader use of const structures and others to clarify
the initialisation sequences.

Due to the existing lack of abstraction the patch has unfortunately
wide-ranging impacts. I've whittled it down as much as I consider
reasonable.

Change-Id: I29984a36dae4ea86ec00b853d2a756f0b9afb3ec
Signed-off-by: Evan Lojewski <github@meklort.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/mboxd.c b/mboxd.c
index c2f2623..d0c4490 100644
--- a/mboxd.c
+++ b/mboxd.c
@@ -31,7 +31,7 @@
 #include "common.h"
 #include "dbus.h"
 #include "control_dbus.h"
-#include "flash.h"
+#include "backend.h"
 #include "lpc.h"
 #include "transport_mbox.h"
 #include "transport_dbus.h"
@@ -246,7 +246,7 @@
 		case 0:
 			break;
 		case 'f':
-			context->flash_size = strtol(optarg, &endptr, 10);
+			context->backend.flash_size = strtol(optarg, &endptr, 10);
 			if (optarg == endptr) {
 				fprintf(stderr, "Unparseable flash size\n");
 				return false;
@@ -255,9 +255,9 @@
 			case '\0':
 				break;
 			case 'M':
-				context->flash_size <<= 10;
+				context->backend.flash_size <<= 10;
 			case 'K':
-				context->flash_size <<= 10;
+				context->backend.flash_size <<= 10;
 				break;
 			default:
 				fprintf(stderr, "Unknown units '%c'\n",
@@ -307,12 +307,15 @@
 		}
 	}
 
-	if (!context->flash_size) {
+	if (!context->path) {
+		context->path = get_dev_mtd();
+	}
+	if (!context->backend.flash_size) {
 		fprintf(stderr, "Must specify a non-zero flash size\n");
 		return false;
 	}
 
-	MSG_INFO("Flash size: 0x%.8x\n", context->flash_size);
+	MSG_INFO("Flash size: 0x%.8x\n", context->backend.flash_size);
 
 	if (verbosity) {
 		MSG_INFO("%s logging\n", verbosity == MBOX_LOG_DEBUG ? "Debug" :
@@ -322,6 +325,24 @@
 	return true;
 }
 
+static int mboxd_backend_init(struct mbox_context *context)
+{
+	int rc;
+
+#ifdef VIRTUAL_PNOR_ENABLED
+	struct vpnor_partition_paths paths;
+	vpnor_default_paths(&paths);
+
+	rc = backend_probe_vpnor(&context->backend, &paths);
+	if(rc)
+#endif
+	{
+		rc = backend_probe_mtd(&context->backend, context->path);
+	}
+
+	return rc;
+}
+
 int main(int argc, char **argv)
 {
 	const struct transport_ops *mbox_ops, *dbus_ops;
@@ -353,6 +374,11 @@
 		goto finish;
 	}
 
+	rc = mboxd_backend_init(context);
+	if (rc) {
+		goto finish;
+	}
+
 	rc = protocol_init(context);
 	if (rc) {
 		goto finish;
@@ -374,20 +400,11 @@
 		goto finish;
 	}
 
-	rc = flash_dev_init(context);
-	if (rc) {
-		goto finish;
-	}
-
 	rc = dbus_init(context, &dbus_ops);
 	if (rc) {
 		goto finish;
 	}
 
-#ifdef VIRTUAL_PNOR_ENABLED
-	init_vpnor(context);
-#endif
-
 	/* Set the LPC bus mapping */
 	__protocol_reset(context);
 
@@ -421,10 +438,10 @@
 	protocol_events_put(context, dbus_ops);
 
 #ifdef VIRTUAL_PNOR_ENABLED
-	destroy_vpnor(context);
+	vpnor_destroy(&context->backend);
 #endif
 	dbus_free(context);
-	flash_dev_free(context);
+	backend_free(&context->backend);
 	lpc_dev_free(context);
 	transport_mbox_free(context);
 	windows_free(context);