diff options
author | Joel Stanley <joel@jms.id.au> | 2015-02-27 17:11:06 +0800 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-04 13:06:11 +1100 |
commit | bbbf4806d3610efd25edaadc17c73b07ca1f4dcd (patch) | |
tree | 54650bda7bb70952fdbd6ff92091e230fad6c4a7 /libflash | |
parent | 0776752eb2576cbd642b739a0dcfffcd3deae984 (diff) | |
download | skiboot-bbbf4806d3610efd25edaadc17c73b07ca1f4dcd.zip skiboot-bbbf4806d3610efd25edaadc17c73b07ca1f4dcd.tar.gz skiboot-bbbf4806d3610efd25edaadc17c73b07ca1f4dcd.tar.bz2 |
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 <joel@jms.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libflash')
-rw-r--r-- | libflash/libffs.c | 85 | ||||
-rw-r--r-- | libflash/libffs.h | 9 | ||||
-rw-r--r-- | 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; |