[Skiboot] [PATCH REBASE 2/2] libflash: start using the blocklevel interface.

Cyril Bur cyril.bur at au1.ibm.com
Tue Jun 2 10:51:02 AEST 2015


Converted all the libflash calls to use the blocklevel interface, modified all
callers to libflash to use the blocklevel interface.

This patch should introduce next to no functional change.

Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
---
 core/flash.c               | 35 ++++++++++---------
 external/pflash/pflash.c   | 31 ++++++++---------
 external/pflash/rules.mk   |  2 +-
 include/skiboot.h          |  4 ++-
 libflash/libffs.c          | 51 ++++++++++++++--------------
 libflash/libffs.h          |  7 ++--
 libflash/libflash.c        | 83 ++++++++++++++++++++++++++++------------------
 libflash/libflash.h        | 25 +++++---------
 libflash/test/test-flash.c | 20 +++++------
 platforms/astbmc/pnor.c    | 12 ++++---
 platforms/rhesus/rhesus.c  | 11 +++---
 11 files changed, 153 insertions(+), 128 deletions(-)

diff --git a/core/flash.c b/core/flash.c
index 601a9ab..7cd9153 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -22,12 +22,13 @@
 #include <device.h>
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
+#include <libflash/blocklevel.h>
 #include <ecc.h>
 
 struct flash {
 	bool			registered;
 	bool			busy;
-	struct flash_chip	*chip;
+	struct blocklevel_device *bl;
 	uint32_t		size;
 	uint32_t		block_size;
 };
@@ -108,7 +109,7 @@ static int flash_nvram_start_read(void *dst, uint32_t src, uint32_t len)
 		goto out;
 	}
 
-	rc = flash_read(nvram_flash->chip, nvram_offset + src, dst, len);
+	rc = blocklevel_read(nvram_flash->bl, nvram_offset + src, dst, len);
 
 out:
 	unlock(&flash_lock);
@@ -137,7 +138,7 @@ static int flash_nvram_write(uint32_t dst, void *src, uint32_t len)
 		rc = OPAL_PARAMETER;
 		goto out;
 	}
-	rc = flash_smart_write(nvram_flash->chip, nvram_offset + dst, src, len);
+	rc = blocklevel_write(nvram_flash->bl, nvram_offset + dst, src, len);
 
 out:
 	unlock(&flash_lock);
@@ -222,7 +223,7 @@ static void setup_system_flash(struct flash *flash, struct dt_node *node,
 	flash_nvram_probe(flash, ffs);
 }
 
-int flash_register(struct flash_chip *chip, bool is_system_flash)
+int flash_register(struct blocklevel_device *bl, bool is_system_flash)
 {
 	uint32_t size, block_size;
 	struct ffs_handle *ffs;
@@ -232,7 +233,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash)
 	unsigned int i;
 	int rc;
 
-	rc = flash_get_info(chip, &name, &size, &block_size);
+	rc = blocklevel_get_info(bl, &name, &size, &block_size);
 	if (rc)
 		return rc;
 
@@ -248,7 +249,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash)
 		flash = &flashes[i];
 		flash->registered = true;
 		flash->busy = false;
-		flash->chip = chip;
+		flash->bl = bl;
 		flash->size = size;
 		flash->block_size = block_size;
 		break;
@@ -260,7 +261,7 @@ int flash_register(struct flash_chip *chip, bool is_system_flash)
 		return OPAL_RESOURCE;
 	}
 
-	rc = ffs_open_flash(chip, 0, flash->size, &ffs);
+	rc = ffs_init(0, flash->size, bl, &ffs);
 	if (rc) {
 		prlog(PR_WARNING, "FLASH: No ffs info; "
 				"using raw device only\n");
@@ -318,13 +319,17 @@ static int64_t opal_flash_op(enum flash_op op, uint64_t id, uint64_t offset,
 
 	switch (op) {
 	case FLASH_OP_READ:
-		rc = flash_read(flash->chip, offset, (void *)buf, size);
+		rc = blocklevel_read(flash->bl, offset, (void *)buf, size);
 		break;
 	case FLASH_OP_WRITE:
-		rc = flash_write(flash->chip, offset, (void *)buf, size, false);
+		/*
+		 * Note: blocklevel_write() uses flash_smart_write(), this call used to
+		 * be flash_write()
+		 */
+		rc = blocklevel_write(flash->bl, offset, (void *)buf, size);
 		break;
 	case FLASH_OP_ERASE:
-		rc = flash_erase(flash->chip, offset, size);
+		rc = blocklevel_erase(flash->bl, offset, size);
 		break;
 	default:
 		assert(0);
@@ -397,7 +402,7 @@ struct flash_hostboot_header {
 };
 
 /* start and total size include ECC */
-static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid,
+static int flash_find_subpartition(struct blocklevel_device *bl, uint32_t subid,
 				   uint32_t *start, uint32_t *total_size,
 				   bool *ecc)
 {
@@ -416,7 +421,7 @@ static int flash_find_subpartition(struct flash_chip *chip, uint32_t subid,
 		partsize = BUFFER_SIZE_MINUS_ECC(*total_size);
 
 	/* Get the TOC */
-	rc = flash_read_corrected(chip, *start, header,
+	rc = flash_read_corrected(bl, *start, header,
 			FLASH_SUBPART_HEADER_SIZE, ecc);
 	if (rc) {
 		prerror("FLASH: flash subpartition TOC read failed %i\n", rc);
@@ -536,7 +541,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid,
 		goto out_unlock;
 	}
 
-	rc = ffs_open_flash(flash->chip, 0, flash->size, &ffs);
+	rc = ffs_init(0, flash->size, flash->bl, &ffs);
 	if (rc) {
 		prerror("FLASH: Can't open ffs handle\n");
 		goto out_unlock;
@@ -563,7 +568,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid,
 
 	/* Find the sub partition if required */
 	if (subid != RESOURCE_SUBID_NONE) {
-		rc = flash_find_subpartition(flash->chip, subid, &part_start,
+		rc = flash_find_subpartition(flash->bl, subid, &part_start,
 					     &part_size, &ecc);
 		if (rc)
 			goto out_free_ffs;
@@ -586,7 +591,7 @@ static int flash_load_resource(enum resource_id id, uint32_t subid,
 		goto out_free_ffs;
 	}
 
-	rc = flash_read_corrected(flash->chip, part_start, buf, size, ecc);
+	rc = flash_read_corrected(flash->bl, part_start, buf, size, ecc);
 	if (rc) {
 		prerror("FLASH: failed to read %s partition\n", name);
 		goto out_free_ffs;
diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c
index 0722bc6..9244570 100644
--- a/external/pflash/pflash.c
+++ b/external/pflash/pflash.c
@@ -16,6 +16,7 @@
 
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
+#include <libflash/blocklevel.h>
 #include "progress.h"
 #include "io.h"
 #include "ast.h"
@@ -39,8 +40,8 @@ static bool using_sfc;
 #define FILE_BUF_SIZE	0x10000
 static uint8_t file_buf[FILE_BUF_SIZE] __aligned(0x1000);
 
+static struct blocklevel_device *bl;
 static struct spi_flash_ctrl	*fl_ctrl;
-static struct flash_chip	*fl_chip;
 static struct ffs_handle	*ffsh;
 static uint32_t			fl_total_size, fl_erase_granule;
 static const char		*fl_name;
@@ -79,7 +80,7 @@ static void print_ffs_info(uint32_t toc_offset)
 	int rc;
 	uint32_t i;
 
-	rc = ffs_open_flash(fl_chip, toc_offset, 0, &ffs_handle);
+	rc = ffs_init(toc_offset, fl_total_size, bl, &ffs_handle);
 	if (rc) {
 		fprintf(stderr, "Error %d opening ffs !\n", rc);
 		return;
@@ -139,7 +140,7 @@ static int open_partition(const char *name)
 
 	/* Open libffs if needed */
 	if (!ffsh) {
-		rc = ffs_open_flash(fl_chip, ffs_toc, 0, &ffsh);
+		rc = ffs_init(ffs_toc, fl_total_size, bl, &ffsh);
 		if (rc) {
 			fprintf(stderr, "Error %d opening ffs !\n", rc);
 			if (ffs_toc)
@@ -210,7 +211,7 @@ static void erase_chip(void)
 		return;
 	}
 
-	rc = flash_erase_chip(fl_chip);
+	rc = flash_erase_chip(bl);
 	if (rc) {
 		fprintf(stderr, "Error %d erasing chip\n", rc);
 		exit(1);
@@ -237,7 +238,7 @@ static void erase_range(uint32_t start, uint32_t size, bool will_program)
 	while(size) {
 		/* If aligned to 64k and at least 64k, use 64k erase */
 		if ((start & 0xffff) == 0 && size >= 0x10000) {
-			rc = flash_erase(fl_chip, start, 0x10000);
+			rc = blocklevel_erase(bl, start, 0x10000);
 			if (rc) {
 				fprintf(stderr, "Error %d erasing 0x%08x\n",
 					rc, start);
@@ -247,7 +248,7 @@ static void erase_range(uint32_t start, uint32_t size, bool will_program)
 			size -= 0x10000;
 			done += 0x10000;
 		} else {
-			rc = flash_erase(fl_chip, start, 0x1000);
+			rc = blocklevel_erase(bl, start, 0x1000);
 			if (rc) {
 				fprintf(stderr, "Error %d erasing 0x%08x\n",
 					rc, start);
@@ -304,7 +305,7 @@ static void program_file(const char *file, uint32_t start, uint32_t size)
 			len = size;
 		size -= len;
 		actual_size += len;
-		rc = flash_write(fl_chip, start, file_buf, len, true);
+		rc = blocklevel_write(bl, start, file_buf, len);
 		if (rc) {
 			if (rc == FLASH_ERR_VERIFY_FAILURE)
 				fprintf(stderr, "Verification failed for"
@@ -344,7 +345,7 @@ static void do_read_file(const char *file, uint32_t start, uint32_t size)
 	progress_init(size >> 8);
 	while(size) {
 		len = size > FILE_BUF_SIZE ? FILE_BUF_SIZE : size;
-		rc = flash_read(fl_chip, start, file_buf, len);
+		rc = blocklevel_read(bl, start, file_buf, len);
 		if (rc) {
 			fprintf(stderr, "Flash read error %d for"
 				" chunk at 0x%08x\n", rc, start);
@@ -370,7 +371,7 @@ static void enable_4B_addresses(void)
 
 	printf("Switching to 4-bytes address mode\n");
 
-	rc = flash_force_4b_mode(fl_chip, true);
+	rc = flash_force_4b_mode(bl, true);
 	if (rc) {
 		fprintf(stderr, "Error %d enabling 4b mode\n", rc);
 		exit(1);
@@ -383,7 +384,7 @@ static void disable_4B_addresses(void)
 
 	printf("Switching to 3-bytes address mode\n");
 
-	rc = flash_force_4b_mode(fl_chip, false);
+	rc = flash_force_4b_mode(bl, false);
 	if (rc) {
 		fprintf(stderr, "Error %d disabling 4b mode\n", rc);
 		exit(1);
@@ -394,7 +395,7 @@ static void flash_access_cleanup_bmc(void)
 {
 	if (ffsh)
 		ffs_close(ffsh);
-	flash_exit(fl_chip);
+	flash_exit(bl);
 	ast_sf_close(fl_ctrl);
 	close_devs();
 }
@@ -414,7 +415,7 @@ static void flash_access_setup_bmc(bool use_lpc, bool need_write)
 	}
 
 	/* Open flash chip */
-	rc = flash_init(fl_ctrl, &fl_chip);
+	rc = flash_init(fl_ctrl, &bl);
 	if (rc) {
 		fprintf(stderr, "Failed to open flash chip\n");
 		exit(1);
@@ -432,7 +433,7 @@ static void flash_access_cleanup_pnor(void)
 
 	if (ffsh)
 		ffs_close(ffsh);
-	flash_exit(fl_chip);
+	flash_exit(bl);
 #ifdef __powerpc__
 	if (using_sfc)
 		sfc_close(fl_ctrl);
@@ -473,7 +474,7 @@ static void flash_access_setup_pnor(bool use_lpc, bool use_sfc, bool need_write)
 #endif
 
 	/* Open flash chip */
-	rc = flash_init(fl_ctrl, &fl_chip);
+	rc = flash_init(fl_ctrl, &bl);
 	if (rc) {
 		fprintf(stderr, "Failed to open flash chip\n");
 		exit(1);
@@ -776,7 +777,7 @@ int main(int argc, char *argv[])
 		flash_access_setup_pnor(use_lpc, has_sfc, erase || program);
 	}
 
-	rc = flash_get_info(fl_chip, &fl_name,
+	rc = blocklevel_get_info(bl, &fl_name,
 			    &fl_total_size, &fl_erase_granule);
 	if (rc) {
 		fprintf(stderr, "Error %d getting flash info\n", rc);
diff --git a/external/pflash/rules.mk b/external/pflash/rules.mk
index 0c396a2..f59e2ee 100644
--- a/external/pflash/rules.mk
+++ b/external/pflash/rules.mk
@@ -15,7 +15,7 @@ endif
 CFLAGS  = -O2 -Wall -I.
 LDFLAGS	= -lrt
 OBJS    = pflash.o progress.o ast-sf-ctrl.o version.o
-OBJS	+= libflash/libflash.o libflash/libffs.o libflash/ecc.o
+OBJS	+= libflash/libflash.o libflash/libffs.o libflash/ecc.o libflash/blocklevel.o
 OBJS	+= $(ARCH_OBJS)
 EXE     = pflash
 
diff --git a/include/skiboot.h b/include/skiboot.h
index 5aa0c85..790f3db 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -36,6 +36,8 @@
 #include <ccan/endian/endian.h>
 #include <ccan/str/str.h>
 
+#include <libflash/blocklevel.h>
+
 #include <mem-map.h>
 #include <op-panel.h>
 #include <platform.h>
@@ -217,7 +219,7 @@ extern void occ_fsp_init(void);
 
 /* flash support */
 struct flash_chip;
-extern int flash_register(struct flash_chip *chip, bool is_system_flash);
+extern int flash_register(struct blocklevel_device *bl, bool is_system_flash);
 extern int flash_start_preload_resource(enum resource_id id, uint32_t subid,
 					void *buf, size_t *len);
 extern int flash_resource_loaded(enum resource_id id, uint32_t idx);
diff --git a/libflash/libffs.c b/libflash/libffs.c
index 55e6895..c03c56a 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -41,6 +41,7 @@ struct ffs_handle {
 	uint32_t		max_size;
 	void			*cache;
 	uint32_t		cached_size;
+	struct blocklevel_device *bl;
 };
 
 static uint32_t ffs_checksum(void* data, size_t size)
@@ -71,31 +72,31 @@ static int ffs_check_convert_header(struct ffs_hdr *dst, struct ffs_hdr *src)
 	return 0;
 }
 
-int ffs_open_flash(struct flash_chip *chip, uint32_t toc_offset,
-		   uint32_t max_size, struct ffs_handle **ffs)
+int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,
+		struct ffs_handle **ffs)
 {
 	struct ffs_hdr hdr;
 	struct ffs_handle *f;
-	uint32_t fl_size, erase_size;
+	uint32_t total_size;
 	int rc;
 
-	if (!ffs)
+	if (!ffs || !bl)
 		return FLASH_ERR_PARM_ERROR;
 	*ffs = NULL;
 
-	/* Grab some info about our flash chip */
-	rc = flash_get_info(chip, NULL, &fl_size, &erase_size);
+	rc = blocklevel_get_info(bl, NULL, &total_size, NULL);
 	if (rc) {
 		FL_ERR("FFS: Error %d retrieving flash info\n", rc);
 		return rc;
 	}
-	if ((toc_offset + max_size) < toc_offset)
+	if ((offset + max_size) < offset)
 		return FLASH_ERR_PARM_ERROR;
-	if ((toc_offset + max_size) > fl_size)
+
+	if ((max_size > total_size))
 		return FLASH_ERR_PARM_ERROR;
 
 	/* Read flash header */
-	rc = flash_read(chip, toc_offset, &hdr, sizeof(hdr));
+	rc = blocklevel_read(bl, offset, &hdr, sizeof(hdr));
 	if (rc) {
 		FL_ERR("FFS: Error %d reading flash header\n", rc);
 		return rc;
@@ -106,17 +107,16 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t toc_offset,
 	if (!f)
 		return FLASH_ERR_MALLOC_FAILED;
 	memset(f, 0, sizeof(*f));
-	f->type = ffs_type_flash;
-	f->toc_offset = toc_offset;
-	f->max_size = max_size ? max_size : (fl_size - toc_offset);
-	f->chip = chip;
+
+	f->toc_offset = offset;
+	f->max_size = max_size;
+	f->bl = bl;
 
 	/* 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;
+		goto out;
 	}
 
 	/*
@@ -126,26 +126,26 @@ int ffs_open_flash(struct flash_chip *chip, uint32_t toc_offset,
 	f->cached_size = f->hdr.block_size * f->hdr.size;
 	FL_DBG("FFS: Partition map size: 0x%x\n", f->cached_size);
 
-	/* Align to erase size */
-	f->cached_size |= (erase_size - 1);
-	f->cached_size &= ~(erase_size - 1);
-	FL_DBG("FFS:         Aligned to: 0x%x\n", f->cached_size);
-
 	/* Allocate cache */
 	f->cache = malloc(f->cached_size);
 	if (!f->cache) {
-		free(f);
-		return FLASH_ERR_MALLOC_FAILED;
+		rc = FLASH_ERR_MALLOC_FAILED;
+		goto out;
 	}
 
 	/* Read the cached map */
-	rc = flash_read(chip, toc_offset, f->cache, f->cached_size);
+	rc = blocklevel_read(bl, offset, f->cache, f->cached_size);
 	if (rc) {
 		FL_ERR("FFS: Error %d reading flash partition map\n", rc);
-		free(f);
+		goto out;
 	}
+
+out:
 	if (rc == 0)
 		*ffs = f;
+	else
+		free(f);
+
 	return rc;
 }
 
@@ -361,6 +361,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
 	ent->checksum = ffs_checksum(ent, FFS_ENTRY_SIZE_CSUM);
 	if (!ffs->chip)
 		return 0;
-	return flash_smart_write(ffs->chip, offset, ent, FFS_ENTRY_SIZE);
+
+	return blocklevel_write(ffs->bl, offset, ent, FFS_ENTRY_SIZE);
 }
 
diff --git a/libflash/libffs.h b/libflash/libffs.h
index faaa4bc..a0040e9 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -18,6 +18,7 @@
 
 #include <libflash/libflash.h>
 #include <libflash/ffs.h>
+#include <libflash/blocklevel.h>
 
 /* FFS handle, opaque */
 struct ffs_handle;
@@ -34,8 +35,10 @@ struct ffs_handle;
 #define FFS_ERR_PART_NOT_FOUND	103
 #define FFS_ERR_BAD_ECC		104
 
-int ffs_open_flash(struct flash_chip *chip, uint32_t toc_offset,
-		   uint32_t max_size, struct ffs_handle **ffs);
+/* Init */
+
+int ffs_init(uint32_t offset, uint32_t max_size,
+		struct blocklevel_device *bl, struct ffs_handle **ffs);
 
 /* ffs_open_image is Linux only as it uses lseek, which skiboot does not
  * implement */
diff --git a/libflash/libflash.c b/libflash/libflash.c
index e43be4f..2af0c79 100644
--- a/libflash/libflash.c
+++ b/libflash/libflash.c
@@ -20,6 +20,7 @@
 #include "libflash.h"
 #include "libflash-priv.h"
 #include "ecc.h"
+#include "blocklevel.h"
 
 #ifndef MIN
 #define MIN(a, b)	((a) < (b) ? (a) : (b))
@@ -45,6 +46,7 @@ struct flash_chip {
 	bool			mode_4b;	/* Flash currently in 4b mode */
 	struct flash_req	*cur_req;	/* Current request */
 	void			*smart_buf;	/* Buffer for smart writes */
+	struct blocklevel_device bl;
 };
 
 #ifndef __SKIBOOT__
@@ -112,8 +114,9 @@ int fl_wren(struct spi_flash_ctrl *ct)
 	return FLASH_ERR_WREN_TIMEOUT;
 }
 
-int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len)
+static int flash_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	struct spi_flash_ctrl *ct = c->ctrl;
 
 	/* XXX Add sanity/bound checking */
@@ -138,7 +141,7 @@ int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len)
  * This provides a wrapper around flash_read on ECCed data
  * len is length of data without ECC attached
  */
-int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf,
+int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf,
 		uint32_t len, bool ecc)
 {
 	struct ecc64 *bufecc;
@@ -147,7 +150,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf,
 	uint8_t ret;
 
 	if (!ecc)
-		return flash_read(c, pos, buf, len);
+		return flash_read(bl, pos, buf, len);
 
 	/* Copy the buffer in chunks */
 	bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH));
@@ -159,7 +162,7 @@ int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf,
 		copylen = MIN(len, COPY_BUFFER_LENGTH);
 
 		/* Read ECCed data from flash */
-		rc = flash_read(c, pos, bufecc, ECC_BUFFER_SIZE(copylen));
+		rc = flash_read(bl, pos, bufecc, ECC_BUFFER_SIZE(copylen));
 		if (rc)
 			goto err;
 
@@ -215,8 +218,9 @@ static void fl_get_best_erase(struct flash_chip *c, uint32_t dst, uint32_t size,
 	*cmd = CMD_BE;
 }
 
-int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size)
+static int flash_erase(struct blocklevel_device *bl, uint32_t dst, uint32_t size)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	struct spi_flash_ctrl *ct = c->ctrl;
 	uint32_t chunk;
 	uint8_t cmd;
@@ -262,8 +266,9 @@ int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size)
 	return 0;
 }
 
-int flash_erase_chip(struct flash_chip *c)
+int flash_erase_chip(struct blocklevel_device *bl)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	struct spi_flash_ctrl *ct = c->ctrl;
 	int rc;
 
@@ -311,9 +316,10 @@ static int fl_wpage(struct flash_chip *c, uint32_t dst, const void *src,
 	return fl_sync_wait_idle(ct);
 }
 
-int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
+static int flash_write(struct blocklevel_device *bl, uint32_t dst, const void *src,
 		uint32_t size, bool verify)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	struct spi_flash_ctrl *ct = c->ctrl;
 	uint32_t todo = size;
 	uint32_t d = dst;
@@ -374,7 +380,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
 		chunk = sizeof(vbuf);
 		if (chunk > size)
 			chunk = size;
-		rc = flash_read(c, dst, vbuf, chunk);
+		rc = flash_read(bl, dst, vbuf, chunk);
 		if (rc) return rc;
 		if (memcmp(vbuf, src, chunk)) {
 			FL_ERR("LIBFLASH: Miscompare at 0x%08x\n", dst);
@@ -387,7 +393,7 @@ int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
 	return 0;
 }
 
-int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void *buf,
+int flash_write_corrected(struct blocklevel_device *bl, uint32_t pos, const void *buf,
 		uint32_t len, bool verify, bool ecc)
 {
 	struct ecc64 *bufecc;
@@ -396,7 +402,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void *buf,
 	uint8_t ret;
 
 	if (!ecc)
-		return flash_write(c, pos, buf, len, verify);
+		return flash_write(bl, pos, buf, len, verify);
 
 	/* Copy the buffer in chunks */
 	bufecc = malloc(ECC_BUFFER_SIZE(COPY_BUFFER_LENGTH));
@@ -415,7 +421,7 @@ int flash_write_corrected(struct flash_chip *c, uint32_t pos, const void *buf,
 		}
 
 		/* Write ECCed data to the flash */
-		rc = flash_write(c, pos, bufecc, copylen, verify);
+		rc = flash_write(bl, pos, bufecc, copylen, verify);
 		if (rc)
 			goto err;
 
@@ -463,12 +469,12 @@ static enum sm_comp_res flash_smart_comp(struct flash_chip *c,
 	return is_same ? sm_no_change : sm_need_write;
 }
 
-int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
-		      uint32_t size)
+static int flash_smart_write(struct blocklevel_device *bl, uint32_t dst, const void *src, uint32_t size)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	uint32_t er_size = c->min_erase_mask + 1;
 	uint32_t end = dst + size;
-	int rc;	
+	int rc;
 
 	/* Some sanity checking */
 	if (end <= dst || !size || end > c->tsize) {
@@ -489,7 +495,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
 		off = dst & c->min_erase_mask;
 		FL_DBG("LIBFLASH:   reading page 0x%08x..0x%08x...",
 		       page, page + er_size);
-		rc = flash_read(c, page, c->smart_buf, er_size);
+		rc = flash_read(bl, page, c->smart_buf, er_size);
 		if (rc) {
 			FL_DBG(" error %d!\n", rc);
 			return rc;
@@ -510,7 +516,7 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
 		case sm_need_write:
 			/* Just needs writing over */
 			FL_DBG(" need write !\n");
-			rc = flash_write(c, dst, src, chunk, true);
+			rc = flash_write(bl, dst, src, chunk, true);
 			if (rc) {
 				FL_DBG("LIBFLASH: Write error %d !\n", rc);
 				return rc;
@@ -518,14 +524,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
 			break;
 		case sm_need_erase:
 			FL_DBG(" need erase !\n");
-			rc = flash_erase(c, page, er_size);
+			rc = flash_erase(bl, page, er_size);
 			if (rc) {
 				FL_DBG("LIBFLASH: erase error %d !\n", rc);
 				return rc;
 			}
 			/* Then update the portion of the buffer and write the block */
 			memcpy(c->smart_buf + off, src, chunk);
-			rc = flash_write(c, page, c->smart_buf, er_size, true);
+			rc = flash_write(bl, page, c->smart_buf, er_size, true);
 			if (rc) {
 				FL_DBG("LIBFLASH: write error %d !\n", rc);
 				return rc;
@@ -539,14 +545,14 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
 	return 0;
 }
 
-int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const void *src,
+int flash_smart_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src,
 		      uint32_t size, bool ecc)
 {
 	struct ecc64 *buf;
 	int rc;
 
 	if (!ecc)
-		return flash_smart_write(c, dst, src, size);
+		return flash_smart_write(bl, dst, src, size);
 
 	buf = malloc(ECC_BUFFER_SIZE(size));
 	if (!buf)
@@ -558,7 +564,7 @@ int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const void *
 		goto out;
 	}
 
-	rc = flash_smart_write(c, dst, buf, ECC_BUFFER_SIZE(size));
+	rc = flash_smart_write(bl, dst, buf, ECC_BUFFER_SIZE(size));
 
 out:
 	free(buf);
@@ -684,8 +690,9 @@ static int flash_set_4b(struct flash_chip *c, bool enable)
 	return ct->cmd_wr(ct, enable ? CMD_EN4B : CMD_EX4B, false, 0, NULL, 0);
 }
 
-int flash_force_4b_mode(struct flash_chip *c, bool enable_4b)
+int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	struct spi_flash_ctrl *ct = c->ctrl;
 	int rc;
 
@@ -776,24 +783,29 @@ static int flash_configure(struct flash_chip *c)
 	return 0;
 }
 
-int flash_get_info(struct flash_chip *chip, const char **name,
+static int flash_get_info(struct blocklevel_device *bl, const char **name,
 		   uint32_t *total_size, uint32_t *erase_granule)
 {
+	struct flash_chip *c = container_of(bl, struct flash_chip, bl);
 	if (name)
-		*name = chip->info.name;
+		*name = c->info.name;
 	if (total_size)
-		*total_size = chip->tsize;
+		*total_size = c->tsize;
 	if (erase_granule)
-		*erase_granule = chip->min_erase_mask + 1;
+		*erase_granule = c->min_erase_mask + 1;
 	return 0;
 }
 
-int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash)
+int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl)
 {
 	struct flash_chip *c;
 	int rc;
 
-	*flash = NULL;
+	if (!bl)
+		return FLASH_ERR_PARM_ERROR;
+
+	*bl = NULL;
+
 	c = malloc(sizeof(struct flash_chip));
 	if (!c)
 		return FLASH_ERR_MALLOC_FAILED;
@@ -814,18 +826,25 @@ int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash)
 	rc = flash_configure(c);
 	if (rc)
 		FL_ERR("LIBFLASH: Flash configuration failed\n");
- bail:
+bail:
 	if (rc) {
 		free(c);
 		return rc;
 	}
-	*flash = c;
+
+	c->bl.read = &flash_read;
+	c->bl.write = &flash_smart_write;
+	c->bl.erase = &flash_erase;
+	c->bl.get_info = &flash_get_info;
+
+	*bl = &(c->bl);
 	return 0;
 }
 
-void flash_exit(struct flash_chip *chip)
+void flash_exit(struct blocklevel_device *bl)
 {
 	/* XXX Make sure we are idle etc... */
-	free(chip);
+	if (bl)
+		free(container_of(bl, struct flash_chip, bl));
 }
 
diff --git a/libflash/libflash.h b/libflash/libflash.h
index 7ed65d0..30f984d 100644
--- a/libflash/libflash.h
+++ b/libflash/libflash.h
@@ -18,6 +18,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <libflash/blocklevel.h>
 
 #ifdef __SKIBOOT__
 #include <skiboot.h>
@@ -59,18 +60,13 @@ extern bool libflash_debug;
 struct flash_chip;
 struct spi_flash_ctrl;
 
-int flash_init(struct spi_flash_ctrl *ctrl, struct flash_chip **flash);
-void flash_exit(struct flash_chip *chip);
-
-int flash_get_info(struct flash_chip *chip, const char **name,
-		   uint32_t *total_size, uint32_t *erase_granule);
+int flash_init(struct spi_flash_ctrl *ctrl, struct blocklevel_device **bl);
+void flash_exit(struct blocklevel_device *bl);
 
 /* libflash sets the 4b mode automatically based on the flash
  * size and controller capabilities but it can be overriden
  */
-int flash_force_4b_mode(struct flash_chip *chip, bool enable_4b);
-
-int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len);
+int flash_force_4b_mode(struct blocklevel_device *bl, bool enable_4b);
 
 /*
  * This provides a wapper around flash_read() on ECCed data. All params are
@@ -80,11 +76,8 @@ int flash_read(struct flash_chip *c, uint32_t pos, void *buf, uint32_t len);
  * len is length of data without ecc attached therefore this will read beyond
  * pos + len.
  */
-int flash_read_corrected(struct flash_chip *c, uint32_t pos, void *buf,
+int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf,
 		uint32_t len, bool ecc);
-int flash_erase(struct flash_chip *c, uint32_t dst, uint32_t size);
-int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
-		uint32_t size, bool verify);
 
 /*
  * This provides a wrapper around flash_write() on ECCed data. All params are
@@ -94,10 +87,8 @@ int flash_write(struct flash_chip *c, uint32_t dst, const void *src,
  * size is length of data without ECC attached therefore this will write beyond
  * dst + size.
  */
-int flash_write_corrected(struct flash_chip *c, uint32_t dst, const void *src,
+int flash_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src,
 		uint32_t size, bool verify, bool ecc);
-int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
-		      uint32_t size);
 
 /*
  * This provides a wrapper around flash_smart_write() on ECCed data. All
@@ -107,12 +98,12 @@ int flash_smart_write(struct flash_chip *c, uint32_t dst, const void *src,
  * size is length of data without ECC attached therefore this will write beyond
  * dst + size.
  */
-int flash_smart_write_corrected(struct flash_chip *c, uint32_t dst, const void *src,
+int flash_smart_write_corrected(struct blocklevel_device *bl, uint32_t dst, const void *src,
 		      uint32_t size, bool ecc);
 
 /* chip erase may not be supported by all chips/controllers, get ready
  * for FLASH_ERR_CHIP_ER_NOT_SUPPORTED
  */
-int flash_erase_chip(struct flash_chip *c);
+int flash_erase_chip(struct blocklevel_device *bl);
 
 #endif /* __LIBFLASH_H */
diff --git a/libflash/test/test-flash.c b/libflash/test/test-flash.c
index 4479b5a..cf2b3a5 100644
--- a/libflash/test/test-flash.c
+++ b/libflash/test/test-flash.c
@@ -366,7 +366,7 @@ struct spi_flash_ctrl sim_ctrl = {
 
 int main(void)
 {
-	struct flash_chip *fl;
+	struct blocklevel_device *bl;
 	uint32_t total_size, erase_granule;
 	const char *name;
 	uint16_t *test;
@@ -378,12 +378,12 @@ int main(void)
 	memset(sim_image, 0xff, sim_image_sz);
 	test = malloc(0x10000 * 2);
 
-	rc = flash_init(&sim_ctrl, &fl);
+	rc = flash_init(&sim_ctrl, &bl);
 	if (rc) {
 		ERR("flash_init failed with err %d\n", rc);
 		exit(1);
 	}
-	rc = flash_get_info(fl, &name, &total_size, &erase_granule);
+	rc = flash_get_info(bl, &name, &total_size, &erase_granule);
 	if (rc) {
 		ERR("flash_get_info failed with err %d\n", rc);
 		exit(1);
@@ -395,13 +395,13 @@ int main(void)
 
 	/* Write 64k of stuff at 0 and at 128k */
 	printf("Writing test patterns...\n");
-	flash_smart_write(fl, 0, test, 0x10000);
-	flash_smart_write(fl, 0x20000, test, 0x10000);
+	flash_smart_write(bl, 0, test, 0x10000);
+	flash_smart_write(bl, 0x20000, test, 0x10000);
 
 	/* Write "Hello world" straddling the 64k boundary */
 #define HW "Hello World"
 	printf("Writing test string...\n");
-	flash_smart_write(fl, 0xfffc, HW, sizeof(HW));
+	flash_smart_write(bl, 0xfffc, HW, sizeof(HW));
 
 	/* Check result */
 	if (memcmp(sim_image + 0xfffc, HW, sizeof(HW))) {
@@ -416,7 +416,7 @@ int main(void)
 	printf("Test pattern pass\n");
 
 	printf("Test ECC interfaces\n");
-	flash_smart_write_corrected(fl, 0, test, 0x10000, 1);
+	flash_smart_write_corrected(bl, 0, test, 0x10000, 1);
 	ecc_test = (struct ecc64 *)sim_image;
 	test64 = (uint64_t *)test;
 	for (i = 0; i < 0x10000 / sizeof(*ecc_test); i++) {
@@ -433,7 +433,7 @@ int main(void)
 	printf("Test ECC interface pass\n");
 
 	printf("Test ECC erase\n");
-	if (flash_erase(fl, 0, 0x10000) != 0) {
+	if (flash_erase(bl, 0, 0x10000) != 0) {
 		ERR("flash_erase didn't return 0\n");
 		exit(1);
 	}
@@ -444,7 +444,7 @@ int main(void)
 			ERR("Data not properly cleared at %d\n", i);
 			exit(1);
 		}
-		rc = flash_write(fl, i * sizeof(*ecc_test) + 8, &zero, 1, 0);
+		rc = flash_write(bl, i * sizeof(*ecc_test) + 8, &zero, 1, 0);
 		if (rc || ecc_test[i].ecc != 0) {
 			ERR("Cleared data not correctly ECCed: 0x%02x (0x%016lx) expecting 0 at %d\n", ecc_test[i].ecc, ecc_test[i].data, i);
 			exit(1);
@@ -452,7 +452,7 @@ int main(void)
 	}
 	printf("Test ECC erase pass\n");
 
-	flash_exit(fl);
+	flash_exit(bl);
 
 	return 0;
 }
diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c
index d294c1f..634cb86 100644
--- a/platforms/astbmc/pnor.c
+++ b/platforms/astbmc/pnor.c
@@ -20,6 +20,7 @@
 #include <opal.h>
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
+#include <libflash/blocklevel.h>
 #include <ast.h>
 
 #include "astbmc.h"
@@ -27,7 +28,7 @@
 int pnor_init(void)
 {
 	struct spi_flash_ctrl *pnor_ctrl;
-	struct flash_chip *pnor_chip = NULL;
+	struct blocklevel_device *bl;
 	int rc;
 
 	/* Open controller and flash. If the LPC->AHB doesn't point to
@@ -44,19 +45,20 @@ int pnor_init(void)
 		prerror("PLAT: Failed to open PNOR flash controller\n");
 		goto fail;
 	}
-	rc = flash_init(pnor_ctrl, &pnor_chip);
+
+	rc = flash_init(pnor_ctrl, &bl);
 	if (rc) {
 		prerror("PLAT: Failed to open init PNOR driver\n");
 		goto fail;
 	}
 
-	rc = flash_register(pnor_chip, true);
+	rc = flash_register(bl, true);
 	if (!rc)
 		return 0;
 
  fail:
-	if (pnor_chip)
-		flash_exit(pnor_chip);
+	if (bl)
+		flash_exit(bl);
 	if (pnor_ctrl)
 		ast_sf_close(pnor_ctrl);
 
diff --git a/platforms/rhesus/rhesus.c b/platforms/rhesus/rhesus.c
index 27e1c91..855d0e4 100644
--- a/platforms/rhesus/rhesus.c
+++ b/platforms/rhesus/rhesus.c
@@ -22,6 +22,7 @@
 #include <opal.h>
 #include <libflash/libflash.h>
 #include <libflash/libffs.h>
+#include <libflash/blocklevel.h>
 #include <sfc-ctrl.h>
 #include <ec/config.h>
 #include <ec/gpio.h>
@@ -118,7 +119,7 @@ static int64_t rhesus_power_down(uint64_t request __unused)
 static int rhesus_pnor_init(void)
 {
 	struct spi_flash_ctrl *pnor_ctrl;
-	struct flash_chip *pnor_chip = NULL;
+	struct blocklevel_device *bl;
 	int rc;
 
 	/* Open controller, flash and ffs */
@@ -127,19 +128,19 @@ static int rhesus_pnor_init(void)
 		prerror("PLAT: Failed to open PNOR flash controller\n");
 		goto fail;
 	}
-	rc = flash_init(pnor_ctrl, &pnor_chip);
+	rc = flash_init(pnor_ctrl, &bl);
 	if (rc) {
 		prerror("PLAT: Failed to open init PNOR driver\n");
 		goto fail;
 	}
 
-	rc = flash_register(pnor_chip, true);
+	rc = flash_register(bl, true);
 	if (!rc)
 		return 0;
 
  fail:
-	if (pnor_chip)
-		flash_exit(pnor_chip);
+	if (bl)
+		flash_exit(bl);
 	if (pnor_ctrl)
 		sfc_close(pnor_ctrl);
 
-- 
1.9.1



More information about the Skiboot mailing list