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';
#ifdef CONFIG_MTD
struct mtd_info *mtd;
struct nvram_header header;
+ struct nvram_header *pheader;
size_t bytes_read;
int err;
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
}
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");
#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)
{
{
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 */