summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/bcm53xx/files/drivers/firmware/broadcom/bcm47xx_nvram.c60
-rw-r--r--target/linux/bcm53xx/files/include/linux/bcm47xx_nvram.h15
2 files changed, 60 insertions, 15 deletions
diff --git a/target/linux/bcm53xx/files/drivers/firmware/broadcom/bcm47xx_nvram.c b/target/linux/bcm53xx/files/drivers/firmware/broadcom/bcm47xx_nvram.c
index c7dcf1a297..3f3574637e 100644
--- a/target/linux/bcm53xx/files/drivers/firmware/broadcom/bcm47xx_nvram.c
+++ b/target/linux/bcm53xx/files/drivers/firmware/broadcom/bcm47xx_nvram.c
@@ -94,17 +94,22 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
return -ENXIO;
found:
- if (header->len > size)
- pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
- if (header->len > NVRAM_SPACE)
- pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
- header->len, NVRAM_SPACE - 1);
-
src = (u32 *)header;
dst = (u32 *)nvram_buf;
for (i = 0; i < sizeof(struct nvram_header); i += 4)
*dst++ = __raw_readl(src++);
- for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4)
+ header = (struct nvram_header *)nvram_buf;
+ if (header->len > size) {
+ pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
+ header->len = size;
+ }
+ if (header->len >= NVRAM_SPACE) {
+ pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
+ header->len, NVRAM_SPACE - 1);
+ header->len = NVRAM_SPACE - 1;
+ }
+ /* proceed reading data after header */
+ for (; i < header->len; i += 4)
*dst++ = readl(src++);
nvram_buf[NVRAM_SPACE - 1] = '\0';
@@ -139,6 +144,7 @@ static int nvram_init(void)
#ifdef CONFIG_MTD
struct mtd_info *mtd;
struct nvram_header header;
+ struct nvram_header *pheader;
size_t bytes_read;
int err;
@@ -147,20 +153,21 @@ static int nvram_init(void)
return -ENODEV;
err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header);
- if (!err && header.magic == NVRAM_MAGIC) {
- u8 *dst = (uint8_t *)nvram_buf;
- size_t len = header.len;
-
- if (len >= NVRAM_SPACE) {
- len = NVRAM_SPACE - 1;
+ if (!err && header.magic == NVRAM_MAGIC &&
+ header.len > sizeof(header)) {
+ if (header.len >= NVRAM_SPACE) {
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
- header.len, len);
+ header.len, NVRAM_SPACE);
+ header.len = NVRAM_SPACE - 1;
}
- err = mtd_read(mtd, 0, len, &bytes_read, dst);
+ err = mtd_read(mtd, 0, header.len, &bytes_read,
+ (u8 *)nvram_buf);
if (err)
return err;
+ pheader = (struct nvram_header *)nvram_buf;
+ pheader->len = header.len;
return 0;
}
#endif
@@ -220,4 +227,27 @@ int bcm47xx_nvram_gpio_pin(const char *name)
}
EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
+char *bcm47xx_nvram_get_contents(size_t *nvram_size)
+{
+ int err;
+ char *nvram;
+ struct nvram_header *header;
+
+ if (!nvram_buf[0]) {
+ err = nvram_init();
+ if (err)
+ return NULL;
+ }
+
+ header = (struct nvram_header *)nvram_buf;
+ *nvram_size = header->len - sizeof(struct nvram_header);
+ nvram = vmalloc(*nvram_size);
+ if (!nvram)
+ return NULL;
+ memcpy(nvram, &nvram_buf[sizeof(struct nvram_header)], *nvram_size);
+
+ return nvram;
+}
+EXPORT_SYMBOL(bcm47xx_nvram_get_contents);
+
MODULE_LICENSE("GPLv2");
diff --git a/target/linux/bcm53xx/files/include/linux/bcm47xx_nvram.h b/target/linux/bcm53xx/files/include/linux/bcm47xx_nvram.h
index 0e52a92e84..2793652fbf 100644
--- a/target/linux/bcm53xx/files/include/linux/bcm47xx_nvram.h
+++ b/target/linux/bcm53xx/files/include/linux/bcm47xx_nvram.h
@@ -10,11 +10,17 @@
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/vmalloc.h>
#ifdef CONFIG_BCM47XX_NVRAM
int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
int bcm47xx_nvram_gpio_pin(const char *name);
+char *bcm47xx_nvram_get_contents(size_t *val_len);
+static inline void bcm47xx_nvram_release_contents(char *nvram)
+{
+ vfree(nvram);
+};
#else
static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
{
@@ -29,6 +35,15 @@ static inline int bcm47xx_nvram_gpio_pin(const char *name)
{
return -ENOTSUPP;
};
+
+static inline char *bcm47xx_nvram_get_contents(size_t *val_len)
+{
+ return NULL;
+};
+
+static inline void bcm47xx_nvram_release_contents(char *nvram)
+{
+};
#endif
#endif /* __BCM47XX_NVRAM_H */