From 5730eb7752a985301185abf4e091022eea2c7119 Mon Sep 17 00:00:00 2001
From: nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Fri, 23 Jun 2006 16:30:30 +0000
Subject: broadcom 2.4: update the trx for jffs2 directly in the flash map
 driver

git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4055 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 target/linux/brcm-2.4/patches/004-flash.patch | 206 +++++++++++++++++++++-----
 1 file changed, 167 insertions(+), 39 deletions(-)

(limited to 'target/linux')

diff --git a/target/linux/brcm-2.4/patches/004-flash.patch b/target/linux/brcm-2.4/patches/004-flash.patch
index 3511091ed..4fbf3da7e 100644
--- a/target/linux/brcm-2.4/patches/004-flash.patch
+++ b/target/linux/brcm-2.4/patches/004-flash.patch
@@ -1,6 +1,6 @@
-diff -Nur linux-2.4.32/drivers/mtd/devices/Config.in linux-2.4.32-flash/drivers/mtd/devices/Config.in
---- linux-2.4.32/drivers/mtd/devices/Config.in	2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.32-flash/drivers/mtd/devices/Config.in	2006-03-27 17:10:51.000000000 +0200
+diff -urN linux.old/drivers/mtd/devices/Config.in linux.dev/drivers/mtd/devices/Config.in
+--- linux.old/drivers/mtd/devices/Config.in	2006-06-22 17:35:39.000000000 +0200
++++ linux.dev/drivers/mtd/devices/Config.in	2006-06-21 21:41:24.000000000 +0200
 @@ -5,6 +5,7 @@
  mainmenu_option next_comment
  
@@ -9,9 +9,9 @@ diff -Nur linux-2.4.32/drivers/mtd/devices/Config.in linux-2.4.32-flash/drivers/
  dep_tristate '  Ramix PMC551 PCI Mezzanine RAM card support' CONFIG_MTD_PMC551 $CONFIG_MTD $CONFIG_PCI
  if [ "$CONFIG_MTD_PMC551" = "y" -o  "$CONFIG_MTD_PMC551" = "m" ]; then
     bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
-diff -Nur linux-2.4.32/drivers/mtd/devices/Makefile linux-2.4.32-flash/drivers/mtd/devices/Makefile
---- linux-2.4.32/drivers/mtd/devices/Makefile	2002-11-29 00:53:13.000000000 +0100
-+++ linux-2.4.32-flash/drivers/mtd/devices/Makefile	2006-03-27 17:10:51.000000000 +0200
+diff -urN linux.old/drivers/mtd/devices/Makefile linux.dev/drivers/mtd/devices/Makefile
+--- linux.old/drivers/mtd/devices/Makefile	2006-06-22 17:35:39.000000000 +0200
++++ linux.dev/drivers/mtd/devices/Makefile	2006-06-21 21:41:24.000000000 +0200
 @@ -3,6 +3,8 @@
  #
  # $Id: Makefile,v 1.4 2001/06/26 21:10:05 spse Exp $
@@ -29,9 +29,9 @@ diff -Nur linux-2.4.32/drivers/mtd/devices/Makefile linux-2.4.32-flash/drivers/m
  obj-$(CONFIG_MTD_DOC1000)	+= doc1000.o
  obj-$(CONFIG_MTD_DOC2000)	+= doc2000.o
  obj-$(CONFIG_MTD_DOC2001)	+= doc2001.o
-diff -Nur linux-2.4.32/drivers/mtd/devices/sflash.c linux-2.4.32-flash/drivers/mtd/devices/sflash.c
---- linux-2.4.32/drivers/mtd/devices/sflash.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-flash/drivers/mtd/devices/sflash.c	2006-03-27 17:10:51.000000000 +0200
+diff -urN linux.old/drivers/mtd/devices/sflash.c linux.dev/drivers/mtd/devices/sflash.c
+--- linux.old/drivers/mtd/devices/sflash.c	1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/mtd/devices/sflash.c	2006-06-21 21:41:24.000000000 +0200
 @@ -0,0 +1,298 @@
 +/*
 + * Broadcom SiliconBackplane chipcommon serial flash interface
@@ -331,10 +331,10 @@ diff -Nur linux-2.4.32/drivers/mtd/devices/sflash.c linux-2.4.32-flash/drivers/m
 +
 +module_init(sflash_mtd_init);
 +module_exit(sflash_mtd_exit);
-diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/drivers/mtd/maps/bcm947xx-flash.c
---- linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-flash/drivers/mtd/maps/bcm947xx-flash.c	2006-03-27 17:07:27.000000000 +0200
-@@ -0,0 +1,416 @@
+diff -urN linux.old/drivers/mtd/maps/bcm947xx-flash.c linux.dev/drivers/mtd/maps/bcm947xx-flash.c
+--- linux.old/drivers/mtd/maps/bcm947xx-flash.c	1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/mtd/maps/bcm947xx-flash.c	2006-06-23 18:08:46.000000000 +0200
+@@ -0,0 +1,544 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
 + *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
@@ -377,13 +377,17 @@ diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/driv
 +#include <linux/module.h>
 +#include <linux/types.h>
 +#include <linux/kernel.h>
-+#include <asm/io.h>
++#include <linux/wait.h>
 +#include <linux/mtd/mtd.h>
 +#include <linux/mtd/map.h>
 +#ifdef CONFIG_MTD_PARTITIONS
 +#include <linux/mtd/partitions.h>
 +#endif
 +#include <linux/config.h>
++#include <linux/squashfs_fs.h>
++#include <linux/jffs2.h>
++#include <linux/crc32.h>
++#include <asm/io.h>
 +
 +#include <typedefs.h>
 +#include <osl.h>
@@ -521,7 +525,7 @@ diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/driv
 +
 +		/* found a TRX header */
 +		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
-+			goto done;
++			goto found;
 +		}
 +	}
 +
@@ -530,47 +534,115 @@ diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/driv
 +	       mtd->name);
 +	return -1;
 +
-+ done:
++ found:
 +	printk(KERN_NOTICE "bootloader size: %d\n", off);
 +	return off;
 +
 +}
 +
++/*
++ * Copied from mtdblock.c
++ *
++ * Cache stuff...
++ * 
++ * Since typical flash erasable sectors are much larger than what Linux's
++ * buffer cache can handle, we must implement read-modify-write on flash
++ * sectors for each block write requests.  To avoid over-erasing flash sectors
++ * and to speed things up, we locally cache a whole flash sector while it is
++ * being written to until a different sector is required.
++ */
++
++static void erase_callback(struct erase_info *done)
++{
++	wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
++	wake_up(wait_q);
++}
++
++static int erase_write (struct mtd_info *mtd, unsigned long pos, 
++			int len, const char *buf)
++{
++	struct erase_info erase;
++	DECLARE_WAITQUEUE(wait, current);
++	wait_queue_head_t wait_q;
++	size_t retlen;
++	int ret;
++
++	/*
++	 * First, let's erase the flash block.
++	 */
++
++	init_waitqueue_head(&wait_q);
++	erase.mtd = mtd;
++	erase.callback = erase_callback;
++	erase.addr = pos;
++	erase.len = len;
++	erase.priv = (u_long)&wait_q;
++
++	set_current_state(TASK_INTERRUPTIBLE);
++	add_wait_queue(&wait_q, &wait);
++
++	ret = MTD_ERASE(mtd, &erase);
++	if (ret) {
++		set_current_state(TASK_RUNNING);
++		remove_wait_queue(&wait_q, &wait);
++		printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
++				     "on \"%s\" failed\n",
++			pos, len, mtd->name);
++		return ret;
++	}
++
++	schedule();  /* Wait for erase to finish. */
++	remove_wait_queue(&wait_q, &wait);
++
++	/*
++	 * Next, writhe data to flash.
++	 */
++
++	ret = MTD_WRITE (mtd, pos, len, &retlen, buf);
++	if (ret)
++		return ret;
++	if (retlen != len)
++		return -EIO;
++	return 0;
++}
++
++
++
++
 +static int __init
 +find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
 +{
-+	struct trx_header *trx;
-+	unsigned char buf[512];
-+	int off;
++	struct trx_header trx, *trx2;
++	unsigned char buf[512], *block;
++	int off, blocksize;
++	u32 i, crc = ~0;
 +	size_t len;
-+	int blocksize;
-+
-+	trx = (struct trx_header *) buf;
++	struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
 +
 +	blocksize = mtd->erasesize;
 +	if (blocksize < 0x10000)
 +		blocksize = 0x10000;
 +
 +	for (off = (128*1024); off < size; off += blocksize) {
-+		memset(buf, 0xe5, sizeof(buf));
++		memset(&trx, 0xe5, sizeof(trx));
 +
 +		/*
 +		 * Read into buffer 
 +		 */
-+		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
-+		    len != sizeof(buf))
++		if (MTD_READ(mtd, off, sizeof(trx), &len, (char *) &trx) ||
++		    len != sizeof(trx))
 +			continue;
 +
 +		/* found a TRX header */
-+		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
-+			part->offset = le32_to_cpu(trx->offsets[2]) ? : 
-+				le32_to_cpu(trx->offsets[1]);
-+			part->size = le32_to_cpu(trx->len); 
++		if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
++			part->offset = le32_to_cpu(trx.offsets[2]) ? : 
++				le32_to_cpu(trx.offsets[1]);
++			part->size = le32_to_cpu(trx.len); 
 +
 +			part->size -= part->offset;
 +			part->offset += off;
 +
-+			goto done;
++			goto found;
 +		}
 +	}
 +
@@ -579,17 +651,73 @@ diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/driv
 +	       mtd->name);
 +	return -1;
 +
-+ done:
++ found:
++	if (part->size == 0)
++		return 0;
++	
++	if (MTD_READ(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
++		return 0;
++
++	if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
++		printk(KERN_INFO "%s: Filesystem type: squashfs, size=0x%x\n", mtd->name, (u32) sb->bytes_used);
++
++		/* Update the squashfs partition size based on the superblock info */
++		part->size = sb->bytes_used;
++		part->size +=  (mtd->erasesize - 1);
++		part->size &= ~(mtd->erasesize - 1);
++	} else if (*((__u16 *) buf) == JFFS2_MAGIC_BITMASK) {
++		printk(KERN_INFO "%s: Filesystem type: jffs2\n", mtd->name);
++
++		/* Move the squashfs outside of the trx */
++		part->size = 0;
++	} else {
++		printk(KERN_INFO "%s: Filesystem type: unknown\n", mtd->name);
++		return 0;
++	}
++
++	if (trx.len != part->offset + part->size - off) {
++		/* Update the trx offsets and length */
++		trx.len = part->offset + part->size - off;
++	
++		/* Update the trx crc32 */
++		for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
++			if (MTD_READ(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
++				return 0;
++			crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
++		}
++		trx.crc32 = crc;
++
++		/* read first eraseblock from the trx */
++		trx2 = block = kmalloc(mtd->erasesize, GFP_KERNEL);
++		if (MTD_READ(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
++			printk("Error accessing the first trx eraseblock\n");
++			return 0;
++		}
++		
++		printk("Updating TRX offsets and length:\n");
++		printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
++		printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n",   trx.offsets[0],   trx.offsets[1],   trx.offsets[2],   trx.len, trx.crc32);
++
++		/* Write updated trx header to the flash */
++		memcpy(block, &trx, sizeof(trx));
++		if (mtd->unlock)
++			mtd->unlock(mtd, off, mtd->erasesize);
++		erase_write(mtd, off, mtd->erasesize, block);
++		if (mtd->sync)
++			mtd->sync(mtd);
++		kfree(block);
++		printk("Done\n");
++	}
++	
 +	return part->size;
 +}
 +
 +struct mtd_partition * __init
 +init_mtd_partitions(struct mtd_info *mtd, size_t size)
 +{
-+
 +	int cfe_size;
 +
-+	cfe_size = find_cfe_size(mtd,size); 
++	cfe_size = find_cfe_size(mtd,size);
 +
 +	/* boot loader */
 +	bcm947xx_parts[0].offset = 0;
@@ -751,9 +879,9 @@ diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-flash/driv
 +
 +module_init(init_bcm947xx_map);
 +module_exit(cleanup_bcm947xx_map);
-diff -Nur linux-2.4.32/drivers/mtd/maps/Config.in linux-2.4.32-flash/drivers/mtd/maps/Config.in
---- linux-2.4.32/drivers/mtd/maps/Config.in	2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.32-flash/drivers/mtd/maps/Config.in	2006-01-31 22:03:50.000000000 +0100
+diff -urN linux.old/drivers/mtd/maps/Config.in linux.dev/drivers/mtd/maps/Config.in
+--- linux.old/drivers/mtd/maps/Config.in	2006-06-22 17:35:39.000000000 +0200
++++ linux.dev/drivers/mtd/maps/Config.in	2006-06-21 21:41:24.000000000 +0200
 @@ -48,6 +48,7 @@
  fi
  
@@ -762,9 +890,9 @@ diff -Nur linux-2.4.32/drivers/mtd/maps/Config.in linux-2.4.32-flash/drivers/mtd
     dep_tristate '  Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
     dep_tristate '  Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
     dep_tristate '  Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
-diff -Nur linux-2.4.32/drivers/mtd/maps/Makefile linux-2.4.32-flash/drivers/mtd/maps/Makefile
---- linux-2.4.32/drivers/mtd/maps/Makefile	2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.32-flash/drivers/mtd/maps/Makefile	2006-01-31 22:03:50.000000000 +0100
+diff -urN linux.old/drivers/mtd/maps/Makefile linux.dev/drivers/mtd/maps/Makefile
+--- linux.old/drivers/mtd/maps/Makefile	2006-06-22 17:35:39.000000000 +0200
++++ linux.dev/drivers/mtd/maps/Makefile	2006-06-21 21:41:24.000000000 +0200
 @@ -3,6 +3,8 @@
  #
  # $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $
-- 
cgit v1.2.3