[Skiboot] [PATCH 08/13] libflash: Implement ffs_open_image

Jeremy Kerr jk at ozlabs.org
Fri Feb 27 20:11:06 AEDT 2015


From: Joel Stanley <joel at jms.id.au>

ffs_open_image is like ffs_open_flash, but it can operate on a file
descriptor to a pnor image instead of a flash device.

It is currently disabled in skiboot as it does not provide the read
and lseek used by libffs.

Signed-off-by: Joel Stanley <joel at jms.id.au>
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>

---
 libflash/libffs.c   |   85 +++++++++++++++++++++++++++++++++++++++++---
 libflash/libffs.h   |    9 +++-
 libflash/libflash.h |    1 
 3 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/libflash/libffs.c b/libflash/libffs.c
index 109ac40..2d05cc9 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -19,6 +19,11 @@
 #include <stdio.h>
 #include <string.h>
 
+#ifndef __SKIBOOT__
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
 #include <ccan/endian/endian.h>
 
 #include "libffs.h"
@@ -144,12 +149,84 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t offset,
 	return rc;
 }
 
-#if 0 /* XXX TODO: For FW updates so we can copy nvram around */
-int ffs_open_image(void *image, uint32_t size, uint32_t offset,
-		   struct ffs_handle **ffs)
+/* ffs_open_image is Linux only as it uses lseek, which skiboot does not
+ * implement */
+#ifndef __SKIBOOT__
+int ffs_open_image(int fd, uint32_t size, uint32_t offset,
+		   struct ffs_handle **ffsh)
 {
+	struct ffs_hdr hdr;
+	struct ffs_handle *f;
+	int rc;
+
+	if (!ffsh)
+		return FLASH_ERR_PARM_ERROR;
+	*ffsh = NULL;
+
+	if (fd < 0)
+		return FLASH_ERR_PARM_ERROR;
+
+	if ((offset + size) < offset)
+		return FLASH_ERR_PARM_ERROR;
+
+	/* Read flash header */
+	rc = lseek(fd, offset, SEEK_SET);
+	if (rc < 0)
+		return FLASH_ERR_PARM_ERROR;
+
+	rc = read(fd, &hdr, sizeof(hdr));
+	if (rc != sizeof(hdr))
+		return FLASH_ERR_BAD_READ;
+
+	/* Allocate ffs_handle structure and start populating */
+	f = malloc(sizeof(*f));
+	if (!f)
+		return FLASH_ERR_MALLOC_FAILED;
+	memset(f, 0, sizeof(*f));
+	f->type = ffs_type_image;
+	f->flash_offset = offset;
+	f->max_size = size;
+	f->chip = NULL;
+
+	/* Convert and check flash header */
+	rc = ffs_check_convert_header(&f->hdr, &hdr);
+	if (rc) {
+		FL_ERR("FFS: Error %d checking flash header\n", rc);
+		free(f);
+		return rc;
+	}
+
+	/*
+	 * Decide how much of the image to grab to get the whole
+	 * partition map.
+	 */
+	f->cached_size = f->hdr.block_size * f->hdr.size;
+	FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size);
+
+	/* Allocate cache */
+	f->cache = malloc(f->cached_size);
+	if (!f->cache) {
+		free(f);
+		return FLASH_ERR_MALLOC_FAILED;
+	}
+
+	/* Read the cached map */
+	rc = lseek(fd, offset, SEEK_SET);
+	if (rc < 0)
+		return FLASH_ERR_PARM_ERROR;
+
+	rc = read(fd, f->cache, f->cached_size);
+	if (rc != f->cached_size) {
+		FL_ERR("FFS: Error %d reading flash partition map\n", rc);
+		free(f);
+		return FLASH_ERR_BAD_READ;
+	}
+
+	*ffsh = f;
+
+	return 0;
 }
-#endif
+#endif /*!__SKIBOOT__*/
 
 void ffs_close(struct ffs_handle *ffs)
 {
diff --git a/libflash/libffs.h b/libflash/libffs.h
index b597118..dd58d28 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -37,9 +37,12 @@ struct ffs_handle;
 int ffs_open_flash(struct flash_chip *chip, uint32_t offset,
 		   uint32_t max_size, struct ffs_handle **ffs);
 
-/* TODO
-int ffs_open_image(void *image, uint32_t size, struct ffs_handle **ffs);
-*/
+/* ffs_open_image is Linux only as it uses lseek, which skiboot does not
+ * implement */
+#ifndef __SKIBOOT__
+int ffs_open_image(int fd, uint32_t size, uint32_t offset,
+		   struct ffs_handle **ffs);
+#endif
 
 void ffs_close(struct ffs_handle *ffs);
 
diff --git a/libflash/libflash.h b/libflash/libflash.h
index 01806d5..c7d7040 100644
--- a/libflash/libflash.h
+++ b/libflash/libflash.h
@@ -53,6 +53,7 @@ extern bool libflash_debug;
 #define FLASH_ERR_CTRL_CMD_UNSUPPORTED	12
 #define FLASH_ERR_CTRL_TIMEOUT		13
 #define FLASH_ERR_ECC_INVALID		14
+#define FLASH_ERR_BAD_READ		15
 
 /* Flash chip, opaque */
 struct flash_chip;


More information about the Skiboot mailing list