@ -73,7 +73,7 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
+obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
--- /dev/null
--- /dev/null
+++ b/drivers/mtd/maps/bcm963xx-flash.c
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -0,0 +1,267 @@
@@ -0,0 +1,314 @@
+/*
+/*
+ * Copyright (C) 2006-2008 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2006-2008 Florian Fainelli <florian@openwrt.org>
+ * Mike Albon <malbon@openwrt.org>
+ * Mike Albon <malbon@openwrt.org>
@ -101,6 +101,8 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+#include <linux/slab.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+#include <linux/platform_device.h>
+#include <linux/magic.h>
+#include <linux/jffs2.h>
+
+
+#include <bcm_tag.h>
+#include <bcm_tag.h>
+#include <asm/io.h>
+#include <asm/io.h>
@ -110,6 +112,12 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+
+
+#define PFX KBUILD_MODNAME ": "
+#define PFX KBUILD_MODNAME ": "
+
+
+struct squashfs_super_block {
+ __le32 s_magic;
+ __le32 pad0[9];
+ __le64 bytes_used;
+};
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
+static struct mtd_partition *parsed_parts;
+static struct mtd_partition *parsed_parts;
+
+
@ -120,7 +128,6 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+ .bankwidth = BUSWIDTH,
+ .bankwidth = BUSWIDTH,
+};
+};
+
+
+
+static int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition **pparts)
+static int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition **pparts)
+{
+{
+ int nrparts = 3, curpart = 0; /* CFE,NVRAM and global LINUX are always present. */
+ int nrparts = 3, curpart = 0; /* CFE,NVRAM and global LINUX are always present. */
@ -131,9 +138,10 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+ unsigned int rootfsaddr, kerneladdr, spareaddr;
+ unsigned int rootfsaddr, kerneladdr, spareaddr;
+ unsigned int rootfslen, kernellen, sparelen, totallen;
+ unsigned int rootfslen, kernellen, sparelen, totallen;
+ int namelen = 0;
+ int namelen = 0;
+ int i;
+ int i, offset ;
+ char *boardid;
+ char *boardid;
+ char *tagversion;
+ char *tagversion;
+ struct squashfs_super_block sb;
+
+
+ /* Allocate memory for buffer */
+ /* Allocate memory for buffer */
+ buf = vmalloc(sizeof(struct bcm_tag));
+ buf = vmalloc(sizeof(struct bcm_tag));
@ -157,9 +165,48 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+
+
+ kerneladdr = kerneladdr - EXTENDED_SIZE;
+ kerneladdr = kerneladdr - EXTENDED_SIZE;
+ rootfsaddr = kerneladdr + kernellen;
+ rootfsaddr = kerneladdr + kernellen;
+
+ // offset = master->erasesize + sizeof(struct bcm_tag) + kernellen;
+ offset = rootfsaddr;
+ ret = master->read(master, offset, sizeof(sb), &retlen, (void *) &sb);
+ if (ret || (retlen != sizeof(sb))) {
+ printk(KERN_ALERT PFX "parse_cfe_partitions: error occured while reading "
+ "from \"%s\"\n", master->name);
+ return -EINVAL;
+ }
+
+ // if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) {
+ printk(KERN_DEBUG PFX "Squash magic %08lx: Found: %08lx\n", (long unsigned int)SQUASHFS_MAGIC, (long unsigned int)le32_to_cpu(sb.s_magic));
+ if ((uint32_t)SQUASHFS_MAGIC != (uint32_t)le32_to_cpu(sb.s_magic) ) {
+ /* Not a squashfs image */
+ printk(KERN_DEBUG PFX "No squashfs image in \"%s\"\n", master->name);
+ printk(KERN_DEBUG PFX "Jffs magic %04x: Found: %04x\n", (uint16_t)(JFFS2_MAGIC_BITMASK), *(uint16_t *)(&sb));
+ if (*(uint16_t *)(&sb) == JFFS2_MAGIC_BITMASK) {
+ printk(KERN_DEBUG PFX "jffs image in \"%s\"\n", master->name);
+ /* Is JFFS2 so have rootfslen so that true length gets calculated */
+ rootfslen = master->size - master->erasesize - offset;
+ } else {
+ /* We only recognize squashfs and jffs2. If it's not either of these,
+ don't create a rootfs partition. */
+ printk(KERN_INFO PFX "No known root filesystem in \"%s\"\n", master->name);
+ rootfslen = 0;
+ }
+ } else {
+ /* Is a squash image so find where the squash ends */
+ if (le64_to_cpu((sb.bytes_used)) <= 0) {
+ printk(KERN_ALERT PFX "split_squashfs: squashfs is empty in \"%s\"\n",
+ master->name);
+ return 0;
+ }
+
+ rootfslen = (u32) le64_to_cpu(sb.bytes_used);
+ }
+
+ rootfslen = ( ( rootfslen % master->erasesize ) > 0 ? (((rootfslen / master->erasesize) + 1 ) * master->erasesize) : rootfslen);
+ totallen = rootfslen + kernellen + sizeof(struct bcm_tag);
+
+ spareaddr = roundup(totallen, master->erasesize) + master->erasesize;
+ spareaddr = roundup(totallen, master->erasesize) + master->erasesize;
+ sparelen = master->size - spareaddr - master->erasesize;
+ sparelen = master->size - spareaddr - master->erasesize;
+ rootfslen = spareaddr - rootfsaddr;
+
+
+ /* Determine number of partitions */
+ /* Determine number of partitions */
+ namelen = 8;
+ namelen = 8;