app: aboot: Ability to flash only one volume for UBIFS partitions

UBIFS partitions may have multiple UBI volumes written to them. For example:
system partition image may hold: system, rootfs, userdata and cache volumes.
With current implementation the only way to update just one of the volumes is to
flash the entire system image partition.
Note that currently only system image is considered to hold multiple volumes.
The provided volume image should be a UBIFS image.

This patch adds the ability to update the data for just one volume.
The command used is:
fastboot flash <volume name> <volume image - UBIFS>
For example:
fastboot flash usrfs usrfs.ubifs
Due to the difficulty in adding a new fastboot command the existing "fastboot flash"
command implementation was reused:
When trying to flash a partition, if the provided partition name does not correspond
with any partition, treat the call as a ubiupdatevol. Meaning, search for a
corresponding volume.
The above is working due to the fact that volumes and partitions are named
differently.

Change-Id: I9f2ea580c3a07955925c062df1302bf3194f27b9
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 1ebf2a6..ccf95c8 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2285,6 +2285,30 @@
 	return;
 }
 
+void cmd_updatevol(const char *vol_name, void *data, unsigned sz)
+{
+	struct ptentry *sys_ptn;
+	struct ptable *ptable;
+
+	ptable = flash_get_ptable();
+	if (ptable == NULL) {
+		fastboot_fail("partition table doesn't exist");
+		return;
+	}
+
+	sys_ptn = ptable_find(ptable, "system");
+	if (sys_ptn == NULL) {
+		fastboot_fail("system partition not found");
+		return;
+	}
+
+	sz = ROUND_TO_PAGE(sz, page_mask);
+	if (update_ubi_vol(sys_ptn, vol_name, data, sz))
+		fastboot_fail("update_ubi_vol failed");
+	else
+		fastboot_okay("");
+}
+
 void cmd_flash_nand(const char *arg, void *data, unsigned sz)
 {
 	struct ptentry *ptn;
@@ -2299,7 +2323,9 @@
 
 	ptn = ptable_find(ptable, arg);
 	if (ptn == NULL) {
-		fastboot_fail("unknown partition name");
+		dprintf(INFO, "unknown partition name (%s). Trying updatevol\n",
+				arg);
+		cmd_updatevol(arg, data, sz);
 		return;
 	}
 
diff --git a/include/dev/flash-ubi.h b/include/dev/flash-ubi.h
index 50577cc..679e5ac 100644
--- a/include/dev/flash-ubi.h
+++ b/include/dev/flash-ubi.h
@@ -155,4 +155,9 @@
 };
 
 int flash_ubi_img(struct ptentry *ptn, void *data, unsigned size);
+inline int update_ubi_vol(struct ptentry *ptn, const char* vol_name,
+				void *data, unsigned size)
+{
+	return -1;
+}
 #endif
diff --git a/target/init.c b/target/init.c
index 9c850e5..ae1e311 100644
--- a/target/init.c
+++ b/target/init.c
@@ -59,6 +59,11 @@
     return 0;
 }
 
+__WEAK int update_ubi_vol(void)
+{
+    return 0;
+}
+
 __WEAK int target_is_emmc_boot(void)
 {
 #if _EMMC_BOOT