Răsfoiți Sursa

bcm53xx: update NVRAM driver to support getting contents

Signed-off-by: Rafał Miłecki <[email protected]>

SVN-Revision: 45907
Rafał Miłecki 10 ani în urmă
părinte
comite
48da51ed03

+ 45 - 15
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;
 	return -ENXIO;
 
 
 found:
 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;
 	src = (u32 *)header;
 	dst = (u32 *)nvram_buf;
 	dst = (u32 *)nvram_buf;
 	for (i = 0; i < sizeof(struct nvram_header); i += 4)
 	for (i = 0; i < sizeof(struct nvram_header); i += 4)
 		*dst++ = __raw_readl(src++);
 		*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++);
 		*dst++ = readl(src++);
 	nvram_buf[NVRAM_SPACE - 1] = '\0';
 	nvram_buf[NVRAM_SPACE - 1] = '\0';
 
 
@@ -139,6 +144,7 @@ static int nvram_init(void)
 #ifdef CONFIG_MTD
 #ifdef CONFIG_MTD
 	struct mtd_info *mtd;
 	struct mtd_info *mtd;
 	struct nvram_header header;
 	struct nvram_header header;
+	struct nvram_header *pheader;
 	size_t bytes_read;
 	size_t bytes_read;
 	int err;
 	int err;
 
 
@@ -147,20 +153,21 @@ static int nvram_init(void)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header);
 	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",
 			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)
 		if (err)
 			return err;
 			return err;
 
 
+		pheader = (struct nvram_header *)nvram_buf;
+		pheader->len = header.len;
 		return 0;
 		return 0;
 	}
 	}
 #endif
 #endif
@@ -220,4 +227,27 @@ int bcm47xx_nvram_gpio_pin(const char *name)
 }
 }
 EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
 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");
 MODULE_LICENSE("GPLv2");

+ 15 - 0
target/linux/bcm53xx/files/include/linux/bcm47xx_nvram.h

@@ -10,11 +10,17 @@
 
 
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
+#include <linux/vmalloc.h>
 
 
 #ifdef CONFIG_BCM47XX_NVRAM
 #ifdef CONFIG_BCM47XX_NVRAM
 int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
 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_getenv(const char *name, char *val, size_t val_len);
 int bcm47xx_nvram_gpio_pin(const char *name);
 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
 #else
 static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
 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;
 	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
 
 
 #endif /* __BCM47XX_NVRAM_H */
 #endif /* __BCM47XX_NVRAM_H */