--- /dev/null
+diff -ur linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947xx/nvram_linux.c
+--- linux.old/arch/mips/bcm947xx/nvram_linux.c 2007-01-17 13:37:40.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2007-01-17 17:23:55.000000000 +0100
+@@ -57,6 +57,21 @@
+ #define KB * 1024
+ #define MB * 1024 * 1024
+
++static int
++nvram_valid(struct nvram_header *header)
++{
++ return
++ header->magic == NVRAM_MAGIC &&
++ header->len >= sizeof(struct nvram_header) &&
++ header->len <= NVRAM_SPACE &&
++#ifdef MIPSEB
++ 1; /* oleg -- no crc check for now */
++#else
++ (header->crc_ver_init & 255) ==
++ hndcrc8((char *) header + 9, header->len - 9, CRC8_INIT_VALUE);
++#endif
++}
++
+ /* Probe for NVRAM header */
+ static void __init
+ early_nvram_init(void)
+@@ -65,6 +80,7 @@
+ chipcregs_t *cc;
+ int i;
+ uint32 base, off, lim;
++ u32 *src, *dst;
+
+ if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
+ base = KSEG1ADDR(SB_FLASH2);
+@@ -89,26 +105,30 @@
+ while (off <= lim) {
+ /* Windowed flash access */
+ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
+- if (header->magic == NVRAM_MAGIC) {
+- u32 *src = (u32 *) header;
+- u32 *dst = (u32 *) nvram_buf;
+- for (i = 0; i < sizeof(struct nvram_header); i += 4)
+- *dst++ = *src++;
+- for (; i < header->len && i < NVRAM_SPACE; i += 4)
+- *dst++ = ltoh32(*src++);
+- return;
+- }
+-
+- /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
+- if (off == 1 KB)
+- break;
+- else if (off == 4 KB)
+- off = 1 KB;
+- else if (off == lim)
+- off = 4 KB;
+- else
+- off <<= 1;
+- }
++ if (nvram_valid(header))
++ goto found;
++ off <<= 1;
++ }
++
++ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
++ header = (struct nvram_header *) KSEG1ADDR(base + 4 KB);
++ if (header->magic == NVRAM_MAGIC)
++ goto found;
++
++ header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
++ if (header->magic == NVRAM_MAGIC)
++ goto found;
++
++ printk("early_nvram_init: NVRAM not found\n");
++ return;
++
++found:
++ src = (u32 *) header;
++ dst = (u32 *) nvram_buf;
++ for (i = 0; i < sizeof(struct nvram_header); i += 4)
++ *dst++ = *src++;
++ for (; i < header->len && i < NVRAM_SPACE; i += 4)
++ *dst++ = ltoh32(*src++);
+ }
+
+ /* Early (before mm or mtd) read-only access to NVRAM */
+@@ -119,6 +139,10 @@
+
+ if (!name)
+ return NULL;
++
++ /* Too early? */
++ if (sbh == NULL)
++ return NULL;
+
+ if (!nvram_buf[0])
+ early_nvram_init();
+@@ -165,7 +189,8 @@
+ if (!nvram_mtd ||
+ MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
+ len != NVRAM_SPACE ||
+- header->magic != NVRAM_MAGIC) {
++ !nvram_valid(header)) {
++ printk("_nvram_read: invalid nvram image\n");
+ /* Maybe we can recover some data from early initialization */
+ memcpy(buf, nvram_buf, NVRAM_SPACE);
+ }
--- /dev/null
+--- linuz/drivers/mtd/chips/cfi_cmdset_0002.c 2004-12-03 05:56:56.000000000 +0300
++++ linux/drivers/mtd/chips/cfi_cmdset_0002.c 2006-09-03 16:54:11.773175416 +0400
+@@ -129,7 +129,8 @@
+ } /* CFI mode */
+
+ for (i=0; i< cfi->numchips; i++) {
+- cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
++ cfi->chips[i].word_write_time = 1<< /* mirrorbit hack */
++ min(cfi->cfiq->WordWriteTimeoutTyp,cfi->cfiq->WordWriteTimeoutMax);
+ cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
+ cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
+ }