aboutsummaryrefslogtreecommitdiff
path: root/core/flash.c
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2016-07-05 21:31:26 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-07-20 18:18:55 +1000
commitf8493fda6431965885c6f9cd9c8d2e5099a8ea17 (patch)
treec953a18233c0c47527ae43c18543de6bf8751c71 /core/flash.c
parentd0030c1a39eb1ef47f01d5557a1d45a642cc1518 (diff)
downloadskiboot-f8493fda6431965885c6f9cd9c8d2e5099a8ea17.zip
skiboot-f8493fda6431965885c6f9cd9c8d2e5099a8ea17.tar.gz
skiboot-f8493fda6431965885c6f9cd9c8d2e5099a8ea17.tar.bz2
flash: Allocate flashes dynamically
Convert flashes from a static array which wastes memory and limits us. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/flash.c')
-rw-r--r--core/flash.c69
1 files changed, 35 insertions, 34 deletions
diff --git a/core/flash.c b/core/flash.c
index 5036707..d3bda65 100644
--- a/core/flash.c
+++ b/core/flash.c
@@ -26,15 +26,15 @@
#include <libflash/ecc.h>
struct flash {
- bool registered;
+ struct list_node list;
bool busy;
struct blocklevel_device *bl;
uint32_t size;
uint32_t block_size;
+ int id;
};
-#define MAX_FLASH 8
-static struct flash flashes[MAX_FLASH];
+static LIST_HEAD(flashes);
static struct flash *system_flash;
/* Using a single lock as we only have one flash at present. */
@@ -243,14 +243,24 @@ static void setup_system_flash(struct flash *flash, struct dt_node *node,
flash_nvram_probe(flash, ffs);
}
+static int num_flashes(void)
+{
+ struct flash *flash;
+ int i = 0;
+
+ list_for_each(&flashes, flash, list)
+ i++;
+
+ return i;
+}
+
int flash_register(struct blocklevel_device *bl, bool is_system_flash)
{
uint32_t size, block_size;
struct ffs_handle *ffs;
struct dt_node *node;
- struct flash *flash = NULL;
+ struct flash *flash;
const char *name;
- unsigned int i;
int rc;
rc = blocklevel_get_info(bl, &name, &size, &block_size);
@@ -262,31 +272,22 @@ int flash_register(struct blocklevel_device *bl, bool is_system_flash)
name ?: "(unnamed)", size, block_size);
lock(&flash_lock);
- for (i = 0; i < ARRAY_SIZE(flashes); i++) {
- if (flashes[i].registered)
- continue;
-
- flash = &flashes[i];
- flash->registered = true;
- flash->busy = false;
- flash->bl = bl;
- flash->size = size;
- flash->block_size = block_size;
- break;
- }
+ flash = malloc(sizeof(struct flash));
if (!flash) {
+ prlog(PR_ERR, "FLASH: Error allocating flash structure\n");
unlock(&flash_lock);
- /**
- * @fwts-label NoFlashSlots
- * @fwts-advice System has more flash chips than skiboot
- * was configured to know about. Your system will not be
- * able to access some of the flash it has.
- */
- prlog(PR_ERR, "FLASH: No flash slots available\n");
return OPAL_RESOURCE;
}
+ flash->busy = false;
+ flash->bl = bl;
+ flash->size = size;
+ flash->block_size = block_size;
+ flash->id = num_flashes();
+
+ list_add(&flashes, &flash->list);
+
rc = ffs_init(0, flash->size, bl, &ffs, 0);
if (rc) {
/**
@@ -300,7 +301,7 @@ int flash_register(struct blocklevel_device *bl, bool is_system_flash)
ffs = NULL;
}
- node = flash_add_dt_node(flash, i);
+ node = flash_add_dt_node(flash, flash->id);
if (is_system_flash)
setup_system_flash(flash, node, name, ffs);
@@ -322,24 +323,24 @@ enum flash_op {
static int64_t opal_flash_op(enum flash_op op, uint64_t id, uint64_t offset,
uint64_t buf, uint64_t size, uint64_t token)
{
- struct flash *flash;
+ struct flash *flash = NULL;
int rc;
- if (id >= ARRAY_SIZE(flashes))
- return OPAL_PARAMETER;
-
if (!try_lock(&flash_lock))
return OPAL_BUSY;
- flash = &flashes[id];
+ list_for_each(&flashes, flash, list)
+ if (flash->id == id)
+ break;
- if (flash->busy) {
- rc = OPAL_BUSY;
+ if (flash->id != id) {
+ /* Couldn't find the flash */
+ rc = OPAL_PARAMETER;
goto err;
}
- if (!flash->registered) {
- rc = OPAL_PARAMETER;
+ if (flash->busy) {
+ rc = OPAL_BUSY;
goto err;
}