[RFC,12/13] libflash/libffs: Allow caller to specifiy header partition

Message ID 20170829062506.8317-13-cyril.bur@au1.ibm.com
State New
Headers show
Series
  • Rework flash TOC generation
Related show

Commit Message

Cyril Bur Aug. 29, 2017, 6:25 a.m.
An FFS TOC is comprised of two parts. A small header which has a magic
and very minimmal information about the TOC which will be common to all
partitions, things like number of patritions, block sizes and the like.
Following this small header are a series of entries. Importantly there
is always an entry which encompases the TOC its self, this is usually
called the 'part' partition.

Currently libffs always assumes that the 'part' partition is at zero.
While there is always a TOC and zero there doesn't actually have to be.
PNORs may have multiple TOCs within them, therefore libffs needs to be
flexible enough to allow callers to specify TOCs not at zero.

The 'part' partition is otherwise a regular partition which may have
flags associated with it. libffs should allow the user to set the flags
for the 'part' partition.

This patch achieves both by allowing the caller to specify the 'part'
partition. The caller can not and libffs will provide a sensible
default.

Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com>
---
 external/ffspart/ffspart.c |  2 +-
 libflash/ffs.h             |  1 -
 libflash/libffs.c          | 28 ++++++++++++++++++++--------
 libflash/libffs.h          |  2 +-
 4 files changed, 22 insertions(+), 11 deletions(-)

Patch

diff --git a/external/ffspart/ffspart.c b/external/ffspart/ffspart.c
index cd944651..9b66f4fe 100644
--- a/external/ffspart/ffspart.c
+++ b/external/ffspart/ffspart.c
@@ -131,7 +131,7 @@  int main(int argc, char *argv[])
 		goto out;
 	}
 
-	rc = ffs_hdr_new(block_size, block_count, &new_hdr);
+	rc = ffs_hdr_new(block_size, block_count, NULL, &new_hdr);
 	if (rc) {
 		if (rc == FFS_ERR_BAD_SIZE) {
 			/* Well this check is a tad redudant now */
diff --git a/libflash/ffs.h b/libflash/ffs.h
index 6a5ad49f..460f5ca2 100644
--- a/libflash/ffs.h
+++ b/libflash/ffs.h
@@ -210,7 +210,6 @@  struct __ffs_hdr {
  */
 struct ffs_hdr {
 	uint32_t version;
-	uint32_t base;
 	uint32_t size;
 	uint32_t block_size;
 	uint32_t block_count;
diff --git a/libflash/libffs.c b/libflash/libffs.c
index a9a2b961..5accf1ff 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -672,8 +672,8 @@  int ffs_hdr_finalise(struct blocklevel_device *bl, struct ffs_hdr *hdr)
 	}
 
 	/* Don't really care if this fails */
-	blocklevel_erase(bl, hdr->base, hdr->size);
-	rc = blocklevel_write(bl, hdr->base, real_hdr,
+	blocklevel_erase(bl, hdr->part->base, hdr->size);
+	rc = blocklevel_write(bl, hdr->part->base, real_hdr,
 		ffs_hdr_raw_size(num_entries));
 	if (rc)
 		goto out;
@@ -756,7 +756,8 @@  int ffs_entry_set_act_size(struct ffs_entry *ent, uint32_t actual_size)
 	return 0;
 }
 
-int ffs_hdr_new(uint32_t block_size, uint32_t block_count, struct ffs_hdr **r)
+int ffs_hdr_new(uint32_t block_size, uint32_t block_count,
+		struct ffs_entry **e, struct ffs_hdr **r)
 {
 	struct ffs_hdr *ret;
 	struct ffs_entry *part_table;
@@ -772,12 +773,23 @@  int ffs_hdr_new(uint32_t block_size, uint32_t block_count, struct ffs_hdr **r)
 	ret->entries = calloc(HDR_ENTRIES_NUM, sizeof(struct ffs_entry *));
 	ret->entries_size = HDR_ENTRIES_NUM;
 
-	/* Don't know how big it will be, ffs_hdr_finalise() will fix */
-	rc = ffs_entry_new("part", 0, 0, &part_table);
-	if (rc) {
-		free(ret);
-		return rc;
+	if (!e || !(*e)) {
+		/* Don't know how big it will be, ffs_hdr_finalise() will fix */
+		rc = ffs_entry_new("part", 0, 0, &part_table);
+		if (rc) {
+			free(ret);
+			return rc;
+		}
+		if (e)
+			*e = part_table;
+	} else {
+		part_table = *e;
 	}
+
+	/* If the user still holds a ref to e, then inc the refcount */
+	if (e)
+		part_table->ref++;
+
 	ret->part = part_table;
 
 	part_table->pid = FFS_PID_TOPLEVEL;
diff --git a/libflash/libffs.h b/libflash/libffs.h
index eabca23a..d820838c 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -139,7 +139,7 @@  int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
 			uint32_t act_size);
 
 int ffs_hdr_new(uint32_t block_size, uint32_t block_count,
-		struct ffs_hdr **r);
+		struct ffs_entry **e, struct ffs_hdr **r);
 
 int ffs_hdr_add_side(struct ffs_hdr *hdr);