From bbbf4806d3610efd25edaadc17c73b07ca1f4dcd Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Fri, 27 Feb 2015 17:11:06 +0800 Subject: libflash: Implement ffs_open_image 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 Signed-off-by: Jeremy Kerr Signed-off-by: Stewart Smith --- libflash/libffs.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++--- libflash/libffs.h | 9 ++++-- libflash/libflash.h | 1 + 3 files changed, 88 insertions(+), 7 deletions(-) (limited to 'libflash') 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 #include +#ifndef __SKIBOOT__ +#include +#include +#endif + #include #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; -- cgit v1.1