[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