247be626efe52c581321428b589e9da7447a3ecf
[vuplus_openembedded] / recipes / linux / linux-vuuno-2.6.18 / linux_vuuno_nand2.patch
1 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
2 index 0a5babf..d5299d9 100644
3 --- a/arch/mips/Kconfig
4 +++ b/arch/mips/Kconfig
5 @@ -157,7 +157,6 @@ config MIPS_BCM7405DX_NAND
6         select BMIPS4380
7         select MTD_BRCMNAND
8         select MTD_BRCMNAND_VERIFY_WRITE
9 -       select MTD_BLOCK_ROMBLOCK
10  
11  config MIPS_BCM97459BX_NAND
12         bool "Support for BCM97459Bx with NAND flash"
13 diff --git a/arch/mips/brcmstb/common/cfe_call.c b/arch/mips/brcmstb/common/cfe_call.c
14 index 56f2bc9..38c2f77 100644
15 --- a/arch/mips/brcmstb/common/cfe_call.c
16 +++ b/arch/mips/brcmstb/common/cfe_call.c
17 @@ -34,6 +34,7 @@
18  
19  extern unsigned int cfe_seal;
20  
21 +#if 0 // by doliyu, to fixed mtd block
22  cfeEnvVarPairs_t gCfeEnvVarPairs[] = {
23         { "LINUX_FFS_STARTAD",          "LINUX_FFS_SIZE" },
24         { "SPLASH_PART_STARTAD",        "SPLASH_PART_SIZE" },
25 @@ -45,6 +46,13 @@ cfeEnvVarPairs_t gCfeEnvVarPairs[] = {
26  */
27         { NULL, NULL },
28  };
29 +#else
30 +cfeEnvVarPairs_t gCfeEnvVarPairs[] = {
31 +
32 +       { NULL, NULL },
33 +};
34 +
35 +#endif
36  EXPORT_SYMBOL(gCfeEnvVarPairs);
37  
38  /*
39 diff --git a/drivers/mtd/brcmnand/bcm7xxx-nand.c b/drivers/mtd/brcmnand/bcm7xxx-nand.c
40 index 6cea6bf..d1cddfd 100644
41 --- a/drivers/mtd/brcmnand/bcm7xxx-nand.c
42 +++ b/drivers/mtd/brcmnand/bcm7xxx-nand.c
43 @@ -46,12 +46,13 @@ when        who what
44  #include <linux/mtd/brcmnand.h>
45  #include "brcmnand_priv.h"
46  
47 -#define PRINTK(...)
48 -//#define PRINTK printk
49 +//#define PRINTK(...)
50 +#define PRINTK printk
51  
52  #define DRIVER_NAME    "bcm7xxx-nand"
53  #define DRIVER_INFO "Broadcom STB NAND controller"
54  
55 +
56  //#ifdef CONFIG_MTD_PARTITIONS
57  //static const char *part_probes[] = { "cmdlinepart", NULL,  };
58  //#endif
59 @@ -74,7 +75,9 @@ when  who what
60   *     start of flash  1f7f_ffff               flashSize-8MB   rootfs          Linux File System
61   */
62  #define SMALLEST_FLASH_SIZE    (16<<20)
63 -#define DEFAULT_RESERVED_SIZE  (8<<20) 
64 +//#define DEFAULT_RESERVED_SIZE        (8<<20) 
65 +#define DEFAULT_RESERVED_SIZE  (14<<20)  //doliyu
66 +
67  #define DEFAULT_SPLASH_SIZE    (1<<20)
68  #define DEFAULT_BBT0_SIZE_MB   (1)
69  #define DEFAULT_BBT1_SIZE_MB   (4)
70 @@ -176,6 +179,7 @@ static struct mtd_partition bcm7XXX_new_partition[] =
71  
72  static struct mtd_partition bcm7XXX_old_partition[] = 
73  {
74 +#if 0
75         { name: N_ROOTFS,       offset: 0,                                      size: DEFAULT_ROOTFS_SIZE },    
76  #ifdef CONFIG_MTD_ECM_PARTITION
77         { name: N_AVAIL1,       offset: DEFAULT_ROOTFS_SIZE,    size: DEFAULT_AVAIL1_SIZE },
78 @@ -189,8 +193,66 @@ static struct mtd_partition bcm7XXX_old_partition[] =
79  /* Add 1 extra place-holder partition for splash, and a safety guard element */
80         {name: NULL, offset: 0, size: 0},
81         {name: NULL, offset: 0, size: 0}
82 + #else /* by doliyu : for splash init*/
83 +     /* name         offset      size */
84 +         { name: "rootfs",               offset: 0,              size:0x07200000 /* DEFAULT_ROOTFS_SIZE*/ },   /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */ 
85 +         { name: "kernel",       offset: 0x07200000,             size: 4<<20 },        
86 +         { name: "boot",       offset: 0x07600000,             size: 4<<20 },
87 +         { name: "splash",       offset: 0x07A00000,             size: 2<<20 },
88 +         { name: "cfe",          offset: 0x07C00000,             size: 1<<20 },
89 +         { name: "mac",          offset: 0x07D00000,             size: 1<<19 },
90 +         { name: "env",          offset: 0x07D80000,             size: 1<<19 },
91 +         { name: "nvm",          offset: 0x07E00000,             size: 1<<20 }, //csh change to 1 20091207
92 +         /* BBT 1MB not mountable by anyone */
93 + /*        { name: "data",         offset: 0x20000000,             size: 0 },*/
94 + /* Add 1 extra place-holder partition for splash, and a safety guard element */
95 +         /* Add 1 extra place-holder partition for splash, and a safety guard element */
96 +         {name: NULL, offset: 0, size: 0},
97 +         {name: NULL, offset: 0, size: 0},
98 +         {name: NULL, offset: 0, size: 0}
99 + #endif
100 +};
101 +
102 +
103 +static struct mtd_partition bcm7XXX_marusys_partition[] = 
104 +{
105 +        /* name         offset      size */
106 +            { name: "rootfs",               offset: 0,              size:0x07400000 /* DEFAULT_ROOTFS_SIZE*/ },   /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */ 
107 +            { name: "kernel",       offset: 0x07400000,             size: 4<<20 },        
108 +            { name: "boot",       offset: 0x07800000,             size: 4<<20 },
109 +            { name: "cfe",          offset: 0x07C00000,             size: 1<<20 },
110 +            { name: "mac",          offset: 0x07D00000,             size: 1<<19 },
111 +            { name: "env",          offset: 0x07D80000,             size: 1<<19 },
112 +            { name: "nvm",          offset: 0x07E00000,             size: 1<<20 }, //csh change to 1 20091207
113 +            /* BBT 1MB not mountable by anyone */
114 +    /*        { name: "data",         offset: 0x20000000,             size: 0 },*/
115 +    /* Add 1 extra place-holder partition for splash, and a safety guard element */
116 +            /* Add 1 extra place-holder partition for splash, and a safety guard element */
117 +            {name: NULL, offset: 0, size: 0},
118 +            {name: NULL, offset: 0, size: 0}
119  };
120  
121 +static struct mtd_partition bcm7XXX_marusys_splash_partition[] = 
122 +{
123 +        /* name         offset      size */
124 +            { name: "rootfs",               offset: 0,              size:0x07200000 /* DEFAULT_ROOTFS_SIZE*/ },   /* rootfs is total nand size - 6 M Bytes. referr to cfe. bcm97335_devs.c */ 
125 +            { name: "kernel",       offset: 0x07200000,             size: 4<<20 },        
126 +            { name: "boot",       offset: 0x07600000,             size: 4<<20 },
127 +            { name: "splash",       offset: 0x07A00000,             size: 2<<20 },
128 +            { name: "cfe",          offset: 0x07C00000,             size: 1<<20 },
129 +            { name: "mac",          offset: 0x07D00000,             size: 1<<19 },
130 +            { name: "env",          offset: 0x07D80000,             size: 1<<19 },
131 +            { name: "nvm",          offset: 0x07E00000,             size: 1<<20 }, //csh change to 1 20091207
132 +            /* BBT 1MB not mountable by anyone */
133 +    /*        { name: "data",         offset: 0x20000000,             size: 0 },*/
134 +    /* Add 1 extra place-holder partition for splash, and a safety guard element */
135 +            /* Add 1 extra place-holder partition for splash, and a safety guard element */
136 +            {name: NULL, offset: 0, size: 0},
137 +            {name: NULL, offset: 0, size: 0}
138 +
139 +};
140 +
141 +
142  #if defined( CONFIG_MTD_BRCMNAND_DISABLE_XOR )
143  static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_no_xor_partition;
144  
145 @@ -198,7 +260,9 @@ static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_no_xor_partition;
146  static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_new_partition;
147  
148  #else
149 -static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_old_partition;
150 +//static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_old_partition;
151 +static struct mtd_partition* bcm7XXX_nand_parts = bcm7XXX_marusys_splash_partition;
152 +
153  #endif
154  
155  struct brcmnand_info {
156 @@ -261,7 +325,7 @@ brcmnanddrv_setup_mtd_partitions(struct brcmnand_info* nandinfo, int *numParts)
157         /* 
158          * Is XOR disabled? if so use the new partition.
159          */
160 -       if (nandinfo->brcmnand.xor_disable) {
161 +       if (nandinfo->brcmnand.xor_disable[0]) { //by doliyu
162                 bcm7XXX_nand_parts = bcm7XXX_no_xor_partition;
163  
164                 if (device_size(mtd) <= (512ULL <<20)) {
165 @@ -309,7 +373,7 @@ brcmnanddrv_setup_mtd_partitions(struct brcmnand_info* nandinfo, int *numParts)
166         
167         return;
168  #else
169 -                                                                  
170 +                  
171         /* NAND on CS1, same partition as that of CONFIG_MTD_NEW_PARTITION */
172  PRINTK("nandinfo->brcmnand.CS[0] = %d\n", nandinfo->brcmnand.CS[0]);
173  PRINTK("bcm7XXX_nand_parts=%p, bcm7XXX_new_partition=%p, bcm7XXX_old_partition=%p\n",
174 @@ -375,7 +439,7 @@ print_partition(*numParts);
175         nandinfo->parts = bcm7XXX_nand_parts;
176         bcm7XXX_nand_parts[0].size = size - DEFAULT_RESERVED_SIZE - ecm_size;
177         bcm7XXX_nand_parts[0].ecclayout = mtd->ecclayout;
178 -PRINTK("numParts=%d\n", numParts);
179 +PRINTK("numParts=%d\n", *numParts);
180  PRINTK("Part[%d] name=%s, size=%llx, offset=%llx\n", i, bcm7XXX_nand_parts[0].name, 
181  bcm7XXX_nand_parts[0].size, bcm7XXX_nand_parts[0].offset);
182  
183 diff --git a/drivers/mtd/brcmnand/brcmnand_base.c b/drivers/mtd/brcmnand/brcmnand_base.c
184 index 3bc428a..294cdfc 100644
185 --- a/drivers/mtd/brcmnand/brcmnand_base.c
186 +++ b/drivers/mtd/brcmnand/brcmnand_base.c
187 @@ -181,8 +181,8 @@ static brcmnand_chip_Id brcmnand_chips[] = {
188                 .options = NAND_USE_FLASH_BBT,          /* Use BBT on flash */
189                 .idOptions = 0,
190                                 //| NAND_COMPLEX_OOB_WRITE      /* Write data together with OOB for write_oob */
191 -               .timing1 = 0, //00070000,
192 -               .timing2 = 0,
193 +               .timing1 = 0x4232222D,
194 +               .timing2 = 0x00000D94,
195                 .nop=8,
196                 .ctrlVersion = 0, /* THT Verified on data-sheet 7/10/08: Allows 4 on main and 4 on OOB */
197         },
198 @@ -537,7 +537,7 @@ static brcmnand_chip_Id brcmnand_chips[] = {
199                 .chipId = HYNIX_HY27UT088G2A,
200                 .mafId = FLASHTYPE_HYNIX,
201                 .chipIdStr = "HYNIX_HY27UT088G2A",
202 -               .options = NAND_USE_FLASH_BBT,          /* Use BBT on flash */
203 +               .options = NAND_USE_FLASH_BBT|NAND_SCAN_BI_3RD_PAGE, /* BBT on flash + BI on (last-2) page */
204                                 //| NAND_COMPLEX_OOB_WRITE      /* Write data together with OOB for write_oob */
205                 .idOptions = BRCMNAND_ID_EXT_BYTES,
206                 .timing1 = 0, 
207 @@ -550,7 +550,7 @@ static brcmnand_chip_Id brcmnand_chips[] = {
208                 .chipId = HYNIX_HY27UAG8T2M,
209                 .mafId = FLASHTYPE_HYNIX,
210                 .chipIdStr = "HYNIX_HY27UAG8T2M",
211 -               .options = NAND_USE_FLASH_BBT,          /* Use BBT on flash */
212 +               .options = NAND_USE_FLASH_BBT|NAND_SCAN_BI_3RD_PAGE, /* BBT on flash + BI on (last-2) page */
213                                 //| NAND_COMPLEX_OOB_WRITE      /* Write data together with OOB for write_oob */
214                 .idOptions = BRCMNAND_ID_EXT_BYTES,
215                 .timing1 = 0, 
216 @@ -605,13 +605,43 @@ static const unsigned char ffchars[] = {
217  
218  //static unsigned char eccmask[128]; // Will be initialized during probe
219  
220 +//static unsigned char eccmask[128]; // Will be initialized during probe
221 +
222 +#define BCHP_NAND_LAST_REG     BCHP_NAND_BLK_WR_PROTECT
223 +static uint32_t brcmnand_registerHoles[] = {
224 +
225 +       // 3.3 and earlier
226 +       0x281c,
227 +       0x2844, 0x284c, 
228 +       0x285c, 
229 +       0x2888, 0x288c, 
230 +       0x28b8, 0x28bc, 
231 +#if CONFIG_MTD_BRCMNAND_VERSION >  CONFIG_MTD_BRCMNAND_VERS_3_3
232 +#error "Not supported in 2.6.18 kernels"
233 +       0x28c4, 0x28c8, 0x28cc, 
234 +       0x2910, 0x2914, 0x2918, 0x291c, 
235 +       0x2920, 0x2924, 0x2928, 0x292c, 
236 +#endif
237 +};
238 +
239 +// Is there a register at the location
240 +static int inRegisterHoles(uint32_t reg)
241 +{
242 +       int i;
243 +
244 +       for (i=0; i < ARRAY_SIZE(brcmnand_registerHoles); i++) {
245 +               if (reg == brcmnand_registerHoles[i])
246 +                       return 1; // In register hole
247 +       }
248 +       return 0; // Not in hole
249 +}
250  
251  static uint32_t brcmnand_ctrl_read(uint32_t nandCtrlReg) 
252  {
253         volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS 
254                 + nandCtrlReg - BCHP_NAND_REVISION);
255  
256 -       if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
257 +       if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_LAST_REG ||
258                 (nandCtrlReg & 0x3) != 0) {
259                 printk("brcmnand_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
260         }
261 @@ -625,7 +655,7 @@ static void brcmnand_ctrl_write(uint32_t nandCtrlReg, uint32_t val)
262         volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS 
263                 + nandCtrlReg - BCHP_NAND_REVISION);
264  
265 -       if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
266 +       if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_LAST_REG ||
267                 (nandCtrlReg & 0x3) != 0) {
268                 printk( "brcmnand_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
269         }
270 @@ -689,6 +719,30 @@ if (gdebug > 3) printk("%s: offset=%0llx  cs=%d ldw = %08x, udw = %08x\n", __FUN
271         return (ldw); //(ldw ^ 0x1FC00000);
272  }
273  
274 +/*
275 + * Disable ECC, and return the original ACC register (for restore)
276 + */
277 +uint32_t brcmnand_disable_ecc(void)
278 +{
279 +       uint32_t acc0;
280 +       uint32_t acc;
281 +       
282 +       /* Disable ECC */
283 +       acc0 = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
284 +       acc = acc0 & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
285 +       brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
286 +
287 +       return acc0;
288 +}
289 +
290 +
291 +void brcmnand_restore_ecc(uint32_t orig_acc0) 
292 +{
293 +       brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, orig_acc0);
294 +}
295 +       
296 +       // Restore acc
297 +
298  #if 1
299  /* Dont delete, may be useful for debugging */
300  
301 @@ -739,7 +793,7 @@ static void print_config_regs(void)
302                 nand_acc_control, nand_config, flash_id, nand_timing1, nand_timing2);   
303  }
304  
305 -#define NUM_NAND_REGS  (1+((BCHP_NAND_BLK_WR_PROTECT-BCHP_NAND_REVISION)/4))
306 +#define NUM_NAND_REGS  (1+((BCHP_NAND_LAST_REG-BCHP_NAND_REVISION)/4))
307  
308  static void print_nand_ctrl_regs(void)
309  {
310 @@ -1533,7 +1587,7 @@ void dump_nand_regs(struct brcmnand_chip* chip, loff_t offset, uint32_t pa, int
311                 uint32_t reg = BCHP_NAND_REVISION+(i*4);
312                 uint32_t regval;
313  
314 -               if (reg == 0x281c) { // No NAND register at 0x281c
315 +               if (inRegisterHoles(reg)) { // No NAND register at 0x281c
316                         regval = 0;
317                 }
318                 else {
319 @@ -1603,6 +1657,7 @@ static int brcmnand_EDU_write_is_complete(struct mtd_info *mtd, int* outp_needBB
320         if (hif_err != 0) // No timeout
321         {
322                 uint32_t flashStatus; // = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
323 +               int retries = 20;
324  
325  #if 0
326  if (!(hif_err & HIF_INTR2_EDU_DONE))
327 @@ -1612,11 +1667,7 @@ printk("hif_err=%08x\n", hif_err);
328                 /******************* BUG BUG BUG *****************
329                  * THT 01/06/09: What if EDU returns bus error?  We should not mark the block bad then.
330                  */
331 -                //Get status:  should we check HIF_INTR2_ERR?
332 -               if (hif_err & HIF_INTR2_EDU_ERR)
333 -                       edu_err = EDU_get_error_status_register();
334 -               else
335 -                       edu_err = 0;
336 +
337  
338                 //Clear interrupt:
339                 //EDU_volatileWrite(EDU_BASE_ADDRESS  + EDU_DONE, 0x00000000);
340 @@ -1624,28 +1675,36 @@ printk("hif_err=%08x\n", hif_err);
341                 flashStatus = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
342  
343                 /* Just to be dead sure */
344 -               if (!(flashStatus & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK)) {
345 -                       ret = brcmnand_ctrl_write_is_complete(mtd, outp_needBBT); 
346 -                       // No need to check on the EDU side, already done inside ctrl_write_is_complete
347 -                       udelay(1000);
348 +               while (!(flashStatus & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK) && retries-- > 0) {
349 +                       // Cant call the ctrl version, we are in ISR context
350 +                       // ret = brcmnand_ctrl_write_is_complete(mtd, outp_needBBT); 
351 +                       udelay(5000); // Wait for a total of 100 usec
352                         //dump_nand_regs(chip, 0, 0, numDumps++);
353 -                       goto out;
354 +                       flashStatus = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
355                 }
356  
357 -#ifdef EDU_DEBUG_5
358 -/* else */ {
359 +                //Get status:  should we check HIF_INTR2_ERR?
360 +               if (hif_err & HIF_INTR2_EDU_ERR)
361 +                       edu_err = EDU_get_error_status_register();
362 +               else
363 +                       edu_err = 0;
364  
365 -// 2nd dump after CTRL_READY is asserted
366 -//udelay(1000);
367 -//dump_nand_regs(chip, 0, 0, numDumps++);
368 -}
369 -#endif
370 -                       
371 -               if ((edu_err & EDU_ERR_STATUS_NandWrite) || (flashStatus & 0x01)) {
372 -                       /* Write did not complete, flash error, will mark block bad */
373 +               /* sanity check on last cmd status */
374 +               if ((edu_err & EDU_ERR_STATUS_NandWrite) && !(flashStatus & 0x1)) {
375 +                       int cmd = chip->ctrl_read(BCHP_NAND_CMD_START);
376 +                       printk(KERN_ERR"%s: false EDU write error status (edu_err: 0x%08X, flashStatus: 0x%08X) for NAND CMD %x  \n", 
377 +                                 __FUNCTION__, edu_err, flashStatus, cmd);
378 +                       edu_err = EDU_get_error_status_register();
379 +               }
380 +
381 +               /* we primarily rely on NAND controller FLASH_STATUS bit 0, since EDU error may not be cleared yet */           
382 +               if ((edu_err & EDU_ERR_STATUS_NandWrite) && (flashStatus & 0x01)) {
383 +                       /* // Write is complete, but not successful, flash error, will mark block bad */
384                         *outp_needBBT = 1;
385 -                       printk("EDU_write_is_complete(): error 0x%08X\n", edu_err);
386 -                       ret = 0;
387 +                       printk(KERN_ERR"%s: flash write error (edu_err: 0x%08X, flashStatus: 0x%08X)\n", 
388 +                               __FUNCTION__, edu_err, flashStatus);
389 +               ret = 1; // Write is complete, but not successful
390 +
391                         goto out;
392                 }
393                 else if (edu_err) {
394 @@ -1743,6 +1802,42 @@ printk("%s: AUTO: oob=%p, chip->oob_poi=%p, ooboffs=%d, len=%d, bytes=%d, boffs=
395  }
396  
397  
398 +
399 +
400 +#define DEBUG_UNCERR
401 +#ifdef DEBUG_UNCERR
402 +static uint32_t uncErrOob[7];
403 +static u_char uncErrData[512];
404 +#endif
405 +
406 +void brcmnand_post_mortem_dump(struct mtd_info* mtd, loff_t offset)
407 +{
408 +       int i;
409 +       
410 +       printk("%s at offset %llx\n", __FUNCTION__, offset);
411 +       dump_stack();
412 +       
413 +       printk("NAND registers snapshot \n");
414 +       for (i=0; i<NUM_NAND_REGS; i++) {
415 +               uint32_t reg = BCHP_NAND_REVISION+(i*4);
416 +               uint32_t regval;
417 +
418 +               if (inRegisterHoles(reg)) { // No NAND register at 0x281c
419 +                       regval = 0;
420 +               }
421 +               else {
422 +                       regval = brcmnand_ctrl_read(reg);
423 +               }
424 +               if ((i % 4) == 0) {
425 +                       printk("\n%08x:", reg);
426 +               }
427 +               printk("  %08x", regval);
428 +       }
429 +
430 +}
431 +
432 +
433 +
434  /*
435   * Returns 0 on success
436   * Expect a controller read was done before hand, and that the OOB data are read into NAND registers.
437 @@ -1769,7 +1864,7 @@ static int brcmnand_handle_false_read_ecc_unc_errors(
438         //u_char oobbuf[16];
439         int erased, allFF;
440         int i;
441 -       uint32_t acc, acc0;
442 +       uint32_t acc0;
443         //int valid;
444  
445         /*
446 @@ -1779,19 +1874,17 @@ static int brcmnand_handle_false_read_ecc_unc_errors(
447  
448  #if 1 /* Testing 1 2 3 */
449         /* Disable ECC */
450 -       acc = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
451 -       acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
452 -       brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
453 +       acc0 = brcmnand_disable_ecc();
454  
455         chip->ctrl_writeAddr(chip, offset, 0);
456         PLATFORM_IOFLUSH_WAR();
457 -       chip->ctrl_write(BCHP_NAND_CMD_START, OP_SPARE_AREA_READ);
458 +       chip->ctrl_write(BCHP_NAND_CMD_START, OP_PAGE_READ);
459  
460         // Wait until cache is filled up, disabling ECC checking
461         (void) brcmnand_spare_is_valid(mtd, FL_READING, 1);
462         
463         // Restore acc
464 -       brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
465 +       brcmnand_restore_ecc(acc0);
466  #endif
467  
468         for (i = 0; i < 4; i++) {
469 @@ -1815,8 +1908,10 @@ print_oobbuf(p8, 16);
470                         if (!erased) {
471                                 printk("p8[%d]=%02x\n", i, p8[i]); 
472                                 break;
473 +                       }
474                 }
475 -               }
476 +
477 +
478  if (gdebug > 3 ) 
479  {printk("%s: offset=%0llx, i=%d from %d to %d, eccOobSize=%d, eccbytes=%d, erased=%d, allFF=%d\n",
480  __FUNCTION__, offset, i, chip->eccOobSize-chip->eccbytes, chip->eccOobSize,
481 @@ -1847,6 +1942,25 @@ chip->eccOobSize, chip->eccbytes, erased, allFF);}
482                 /* Real error: Disturb read returns uncorrectable errors */
483                 ret = -EBADMSG; 
484  if (gdebug > 3 ) {printk("<-- %s: ret -EBADMSG\n", __FUNCTION__);}
485 +
486 +#ifdef DEBUG_UNCERR
487 +               
488 +               // Copy the data buffer 
489 +               brcmnand_from_flash_memcpy32(chip, uncErrData, offset, mtd->eccsize);
490 +               for (i = 0; i < 4; i++) {
491 +                       uncErrOob[i] = p32[i];
492 +               }
493 +
494 +               printk("%s: Uncorrectable error at offset %llx\n", __FUNCTION__, offset);
495 +               
496 +               printk("Data:\n");
497 +               print_databuf(uncErrData, mtd->eccsize);
498 +               printk("Spare Area\n");
499 +               print_oobbuf((u_char*) uncErrOob, 16);
500 +               
501 +               brcmnand_post_mortem_dump(mtd, offset);
502 +                               
503 +#endif
504         }
505         
506         return ret;
507 @@ -2027,16 +2141,14 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
508         struct brcmnand_chip* chip = mtd->priv;
509         static uint32_t ucdata[128];
510         u_char* uncorr_data = (u_char*) ucdata;
511 -       uint32_t acc, acc0;
512 +       uint32_t  acc0;
513         int valid;
514         unsigned long irqflags;
515         
516         int ret = 0, retries=2;
517         
518         /* Disable ECC */
519 -       acc = brcmnand_ctrl_read(BCHP_NAND_ACC_CONTROL);
520 -       acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
521 -       brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
522 +       acc0 = brcmnand_disable_ecc();
523  
524         while (retries >= 0) {
525                 // Resubmit the read-op
526 @@ -2070,7 +2182,7 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
527         }
528  
529         if (retries < 0) {
530 -               return ret;
531 +               goto restore_ecc;
532         }
533  
534         // Reread the uncorrected buffer.
535 @@ -2098,8 +2210,10 @@ static int brcmnand_Hamming_WAR(struct mtd_info* mtd, loff_t offset, void* buffe
536                         offset, inp_hwECC[0], inp_hwECC[1], inp_hwECC[2],
537                         inoutp_swECC[0], inoutp_swECC[1], inoutp_swECC[2]);
538         }
539 +
540 +restore_ecc:
541         // Restore acc
542 -       brcmnand_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
543 +       brcmnand_restore_ecc(acc0);
544         return ret;
545  }
546  #endif
547 @@ -2432,15 +2546,22 @@ brcmnand_edu_read_comp_intr(struct mtd_info* mtd,
548         int i;
549         static uint32_t oob0[4]; // Sparea Area to handle ECC workaround, aligned on DW boundary
550         uint32_t* p32 = (oobarea ?  (uint32_t*) oobarea :  (uint32_t*) &oob0[0]);
551 +       int retries=20;
552         
553         if (intr_status & HIF_INTR2_EDU_ERR) {
554                 printk("%s: Should not call me with EDU ERR\n", __FUNCTION__);
555                 BUG();
556         }
557         intfc_status = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
558 -       if (!(intfc_status & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK)) {
559 -               printk("%s: Impossible, HIF_INTR2_CTRL_READY already asserted\n", __FUNCTION__);
560 -               BUG();          
561 +       while (!(intfc_status & BCHP_NAND_INTFC_STATUS_CTLR_READY_MASK) && retries > 0) {
562 +               retries--;
563 +               udelay(5); // NAND guaranteed to finish read within 90us, this should be plenty of time
564 +               intfc_status = chip->ctrl_read(BCHP_NAND_INTFC_STATUS);
565 +       }
566 +       if (retries <= 0) {
567 +               printk("%s: Impossible, HIF_INTR2_CTRL_READY already asserted, intr_status=%08x, offset=%llx\n", 
568 +                       __FUNCTION__, intr_status, offset);
569 +               //BUG();                Should assert here, but don't want to crash.  HW guy guaranteed that it is set!!!!
570         }
571  
572         // Remember last good sector read.  Needed for HIF_INTR2 workaround.
573 @@ -3905,6 +4026,7 @@ static int brcmnand_refresh_blk(struct mtd_info *mtd, loff_t from)
574   * EDU ISR Implementation
575   */
576  
577 +extern void EDU_issue_command(uint32_t dram_addr, uint32_t ext_addr,uint8 cmd);
578   
579  /*
580   * Submit the read op, then return immediately, without waiting for completion.
581 @@ -4437,7 +4559,7 @@ static int brcmnand_do_read_ops(struct mtd_info *mtd, loff_t from,
582                         buffer_aligned = EDU_buffer_OK(bufpoi, EDU_READ);
583  
584                         // (3) Batch mode if writing more than 1 pages.
585 -                       numPages = min(MAX_JOB_QUEUE_SIZE, readlen>>chip->page_shift);
586 +                       numPages = min(MAX_JOB_QUEUE_SIZE, (int) (readlen>>chip->page_shift));
587  
588                         // Only do Batch mode if all 3 conditions are satisfied.
589                         if (!aligned || !buffer_aligned || numPages <= 1) {
590 @@ -4935,22 +5057,26 @@ if (gdebug > 3) printk("-->%s: addr=%0llx\n", __FUNCTION__, addr);
591          * (2) OOB area is included in ECC calculation for BCH, so no need to check it
592          *      separately.
593          */
594 -       if (chip->ecclevel != BRCMNAND_ECC_HAMMING) {
595 -               return 0;
596 -       }
597 +
598  
599  #if 1
600         page = ((uint64_t) addr) >> chip->page_shift;
601         // Must read entire page
602         ret = chip->read_page(mtd, vbuf, oobbuf, page);
603         if (ret) {
604 -               printk(KERN_ERR "%s: brcmnand_read_page at %08x failed ret=%d\n", 
605 +               printk(KERN_ERR "%s: read_page at %08x failed ret=%d\n", 
606                         __FUNCTION__, (unsigned int) addr, ret);
607 +               brcmnand_post_mortem_dump(mtd, addr);
608                 return ret;
609         }
610  
611 +
612  #endif
613  
614 +       if (chip->ecclevel != BRCMNAND_ECC_HAMMING) {
615 +               return ret; // We won't verify the OOB if not Hamming
616 +       }
617 +
618         /* 
619          * If there are no Input Buffer, there is nothing to verify.
620          * Reading the page should be enough.
621 @@ -5087,6 +5213,7 @@ printk("-->%s, offset=%0llx\n", __FUNCTION__, offset);}
622                 if (ret < 0) {
623                         printk(KERN_ERR "%s: brcmnand_posted_write_cache failed at offset=%0llx, ret=%d\n", 
624                                 __FUNCTION__, offset + dataWritten, ret);
625 +                       dataWritten = 0;
626                         return ret;
627                 }
628                 dataWritten += chip->eccsize;
629 @@ -5142,7 +5269,7 @@ printk("-->%s, page=%0llx\n", __FUNCTION__, page);}
630  #endif
631  
632  
633 -       if (unlikely(!EDU_buffer_OK(inp_buf, EDU_WRITE))) 
634 +       if (unlikely(!EDU_buffer_OK((void*) inp_buf, EDU_WRITE))) 
635         {
636  if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, trying non-EDU read\n", __FUNCTION__);
637                 /* EDU does not work on non-aligned buffers */
638 @@ -5186,6 +5313,9 @@ if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, tryin
639         while (!list_empty(&gJobQ.jobQ)) {
640                 spin_unlock_irqrestore(&gJobQ.lock, flags);
641                 ret = ISR_wait_for_queue_completion();
642 +               if (ret) {
643 +                       dataWritten = 0;
644 +               }
645                 spin_lock_irqsave(&gJobQ.lock, flags);
646         }
647         spin_unlock_irqrestore(&gJobQ.lock, flags);
648 @@ -5267,6 +5397,9 @@ if (gdebug>3) printk("++++++++++++++++++++++++ %s: buffer not 32B aligned, tryin
649         while (!list_empty(&gJobQ.jobQ)) {
650                 spin_unlock_irqrestore(&gJobQ.lock, flags);
651                 ret = ISR_wait_for_queue_completion();
652 +               if (ret) {
653 +                       dataWritten = 0;
654 +               }
655                 spin_lock_irqsave(&gJobQ.lock, flags);
656         }
657         spin_unlock_irqrestore(&gJobQ.lock, flags);
658 @@ -5428,7 +5561,7 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s, offset=%0llx\n", __FUNCTION__, to);
659                 /*
660                  * Group several pages for submission for small page NAND
661                  */
662 -               numPages = min(MAX_JOB_QUEUE_SIZE, writelen>>chip->page_shift);
663 +               numPages = min(MAX_JOB_QUEUE_SIZE, (int) (writelen>>chip->page_shift));
664  
665                 // If Batch mode                
666                 if (buffer_aligned && numPages > 1 && chip->pageSize == chip->eccsize) {
667 @@ -5455,6 +5588,10 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s, offset=%0llx\n", __FUNCTION__, to);
668                         }
669                         
670                         ret = brcmnand_isr_write_pages(mtd, buf, chip->oob_poi, realpage, numPages);
671 +                       if (ret) {
672 +                               ops->retlen = 0;
673 +                               return ret;
674 +                       }
675  
676                 }
677                 
678 @@ -5520,8 +5657,8 @@ printk("-->%s, offset=%0llx\n", __FUNCTION__, to);}
679  
680         /* Do not allow writes past end of device */
681         if (unlikely((to + len) > device_size(mtd))) {
682 -               DEBUG(MTD_DEBUG_LEVEL0, "%s: ", __FUNCTION__,
683 -                     "Attempt to write beyond end of device\n");
684 +               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write beyond end of device\n",
685 +                       __FUNCTION__);
686  printk("Attempt to write beyond end of device\n");     
687         }       
688         if (!len)
689 @@ -5674,8 +5811,8 @@ printk("-->%s, offset=%0llx, len=%08x\n", __FUNCTION__,  to, (int) ops->len);}
690  
691         if (unlikely((to + ops->len) > device_size(mtd))) 
692         {
693 -               DEBUG(MTD_DEBUG_LEVEL0, "%s: ", __FUNCTION__,
694 -                     "Attempt to write beyond end of device\n");
695 +               DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to write beyond end of device\n",
696 +                       __FUNCTION__);
697  printk("Attempt to write beyond end of device\n");             
698                 return -EINVAL;
699         }
700 @@ -6137,8 +6274,9 @@ if (gdebug > 3 ) {printk(  "%s: Erase past end of device, instr_addr=%016llx, in
701   */
702                 /* Check if we have a bad block, we do not erase bad blocks */
703                 if (brcmnand_block_checkbad(mtd, addr, 0, allowbbt)) {
704 -                       printk (KERN_ERR "%s: attempt to erase a bad block at addr 0x%08x\n", __FUNCTION__, (unsigned int) addr);
705 +                       printk (KERN_ERR "%s: attempt to erase a bad block at addr 0x%llx\n", __FUNCTION__, addr);
706                         instr->state = MTD_ERASE_FAILED;
707 +dump_stack();
708                         goto erase_one_block;
709                 }
710  
711 @@ -6898,11 +7036,11 @@ static int brcmnand_probe(struct mtd_info *mtd, unsigned int chipSelect)
712                         if (chip->cellinfo) {
713                                 unsigned long devIdExt = chip->ctrl_read(BCHP_NAND_FLASH_DEVICE_ID_EXT);
714                                 unsigned char devId5thByte = (devIdExt & 0xff000000) >> 24;
715 -                               unsigned int nbrPlanes;
716 -                               unsigned int planeSizeMB, chipSizeMB, nandConfigChipSize;
717 +                               unsigned int nbrPlanes = 0;
718 +                               unsigned int planeSizeMB = 0, chipSizeMB, nandConfigChipSize;
719                                 unsigned char devId4thdByte =  (chip->device_id  & 0xff);
720 -                               unsigned int pageSize, pageSizeBits;
721 -                               unsigned int blockSize, blockSizeBits;
722 +                               unsigned int pageSize = 0, pageSizeBits = 0;
723 +                               unsigned int blockSize = 0, blockSizeBits = 0;
724                                 //unsigned int oobSize;
725  
726  
727 @@ -7043,7 +7181,7 @@ PRINTK("nandConfigChipSize = %04x\n", nandConfigChipSize);
728                                 else if ((brcmnand_chips[i].idOptions & BRCMNAND_ID_EXT_BYTES_TYPE2) == 
729                                         BRCMNAND_ID_EXT_BYTES_TYPE2) 
730                                 {
731 -                                       unsigned int oobSize, oobSizePerPage;
732 +                                       unsigned int oobSize, oobSizePerPage = 0;
733                                         //uint32_t nandconfig, chipSizeShift;
734  
735                                         /*---------------- 4th ID byte: page size, block size and OOB size ---------------- */
736 @@ -7663,11 +7801,6 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
737                                 return (-EINVAL);
738                         cs = chip->CS[chip->numchips - 1];
739         PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
740 -
741 -                               
742 -
743 -                       
744 -
745                 }
746  
747                 /*
748 @@ -7678,6 +7811,7 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
749                 printk("NAND_CS_NAND_XOR=%08x\n", nand_xor);
750                 //
751  #ifdef CONFIG_MTD_BRCMNAND_DISABLE_XOR
752 +#error ""
753         /* Testing 1,2,3: Force XOR disable on CS0, if not done by CFE */
754                 if (chip->CS[0] == 0) { 
755                         printk("Disabling XOR: Before: SEL=%08x, XOR=%08x\n", nand_select, nand_xor);
756 @@ -7699,6 +7833,11 @@ PRINTK("gNumNand=%d, cs=%d\n", gNumNand, cs);
757  printk("Disabling XOR on CS#%1d\n", chip->CS[i]);
758                                 chip->xor_disable[i] = 1;
759                         }
760 +                        else
761 +                        {
762 +                            printk("Enable XOR on CS#%1d\n", chip->CS[i]);
763 +                            chip->xor_disable[i] = 0;
764 +                        }
765                 }
766         }
767  #else
768 @@ -8021,7 +8160,7 @@ printk("Corrected ECC to Hamming for SLC flashes: ACC_CONTROL = %08lx from %08lx
769                         int corr_threshold;
770  
771                         if ( chip->ecclevel >=  BRCMNAND_ECC_BCH_4) {
772 -                               corr_threshold = 2;
773 +                               corr_threshold = 3; // Changed from 2, since refresh is costly and vulnerable to AC-ON/OFF tests.
774                         } 
775                         else {
776                                 corr_threshold = 1;  // 1 , default for Hamming
777 @@ -8227,6 +8366,13 @@ printk(KERN_INFO "ECC layout=%s\n", "brcmnand_oob_bch8_4k");
778                                 chip->ecclayout = &brcmnand_oob_bch8_4k;
779                                 break;
780                         }
781 +                       else if (NAND_IS_MLC(chip) && mtd->oobsize >= 216 && 
782 +                               chip->ecclevel == BRCMNAND_ECC_BCH_4 && mtd->writesize == 4096) 
783 +                       {
784 +printk(KERN_INFO "ECC layout=%s\n", "brcmnand_oob_bch4_4k");
785 +                               chip->ecclayout = &brcmnand_oob_bch4_4k;
786 +                               break;
787 +                       }
788                         
789                         printk(KERN_WARNING "No oob scheme defined for oobsize %d\n", mtd->oobsize);
790                         BUG();
791 @@ -8389,8 +8535,8 @@ printk(KERN_INFO "%s, eccsize=%d, writesize=%d, eccsteps=%d, ecclevel=%d, eccbyt
792  
793  
794  
795 -#ifdef CONFIG_MTD_BRCMNAND_DISABLE_XOR
796 -gdebug=4;
797 +#if 0
798 +//gdebug=4;
799         printk("-----------------------------------------------------\n");
800         print_nand_ctrl_regs();
801         printk("-----------------------------------------------------\n");
802 @@ -8411,7 +8557,6 @@ gdebug=4;
803         }
804  #endif
805  
806 -//gdebug=0;
807  PRINTK("%s 99\n", __FUNCTION__);
808  
809         return err;
810 diff --git a/drivers/mtd/brcmnand/brcmnand_bbt.c b/drivers/mtd/brcmnand/brcmnand_bbt.c
811 index 91e8510..d8924de 100644
812 --- a/drivers/mtd/brcmnand/brcmnand_bbt.c
813 +++ b/drivers/mtd/brcmnand/brcmnand_bbt.c
814 @@ -67,6 +67,7 @@ when  who what
815   */
816  
817  
818 +#include <linux/kernel.h>
819  #include <linux/slab.h>
820  #include <linux/types.h>
821  #include <linux/mtd/mtd.h>
822 @@ -76,6 +77,7 @@ when  who what
823  #include <linux/bitops.h>
824  #include <linux/delay.h>
825  #include <linux/vmalloc.h>
826 +#include <linux/syscalls.h>
827  
828  #include "brcmnand_priv.h"
829  
830 @@ -84,10 +86,50 @@ when        who what
831  #define PRINTK(...)
832  //#define PRINTK printk
833  
834 +char brcmNandBBTMsg[1024];
835 +// #define BBT_DEBUG
836 +#ifdef BBT_DEBUG // Bypass quiet flag
837 +
838 +static int do_printk = 0; // To be turned on when we hit BBT out of space
839 +asmlinkage int bbt_vprintk(const char *fmt, va_list args)
840 +{
841 +       //unsigned long flags;
842 +       int printed_len;
843 +       //char *p;
844 +       //static char printk_buf[1024];
845 +       //static int log_level_unknown = 1;
846 +
847 +       extern void uart_puts(const char *);
848 +       
849 +       printed_len = vsprintf(brcmNandBBTMsg, fmt, args);
850 +       uart_puts(brcmNandBBTMsg);
851 +    
852 +       return printed_len;
853 +
854 +}
855 +asmlinkage int bbt_printk(const char *fmt, ...)
856 +{
857 +       va_list args;
858 +       int r;
859 +
860 +       if (!do_printk)
861 +               return 0;
862 +       
863 +       va_start(args, fmt);
864 +       r = bbt_vprintk(fmt, args);
865 +       va_end(args);
866 +
867 +       return r;
868 +}
869 +
870 +#define PRINTK bbt_printk
871 +//#define printk bbt_printk
872 +
873 +#endif
874 +
875  extern int gClearBBT;
876  extern int gdebug;
877  
878 -char brcmNandBBTMsg[1024];
879  
880         /* brcmnand=
881          *      rescan:         1. Rescan for bad blocks, and update existing BBT
882 @@ -204,7 +246,7 @@ __FUNCTION__,i, i, td->pattern[i], td->offs+i, p[td->offs + i]);
883   * Read the bad block table starting from page.
884   *
885   */
886 -static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
887 +static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, uint64_t page, int num,
888         int bits, int offs, int reserved_block_code)
889  {
890         int res, i, j, act = 0;
891 @@ -212,7 +254,9 @@ static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int
892         size_t retlen, len, totlen;
893         loff_t from;
894         uint8_t msk = (uint8_t) ((1 << bits) - 1);
895 -
896 +#ifdef BBT_DEBUG
897 +int save_do_printk = do_printk;
898 +#endif
899         totlen = (num * bits) >> 3;
900         from = ((loff_t)page) << this->page_shift;
901  
902 @@ -222,6 +266,8 @@ static int brcmnand_read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int
903         this->ctrl_write(BCHP_NAND_ECC_CORR_ADDR, 0);
904         this->ctrl_write(BCHP_NAND_ECC_UNC_ADDR, 0);
905  
906 +//do_printk=1;
907 +
908  
909         while (totlen) {
910                 len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
911 @@ -229,10 +275,14 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
912                 res = mtd->read(mtd, from, len, &retlen, buf);
913                 if (res < 0) {
914                         if (retlen != len) {
915 -                               printk (KERN_INFO "brcmnand_bbt: Error reading bad block table\n");
916 +                               printk (KERN_ERR "%s: Error reading bad block table, retlen=%d\n", __FUNCTION__);
917                                 return res;
918                         }
919 -                       printk (KERN_WARNING "brcmnand_bbt: ECC error while reading bad block table\n");
920 +                       printk (KERN_ERR "%s: ECC error while reading bad block table\n", __FUNCTION__);
921 +PRINTK ("%s: ECC error while reading bad block table, res=%d\n", __FUNCTION__, res);
922 +
923 +                       /* THT 11/10/09: If read fails, we should ignore the data, so return w/o analyzing it */
924 +                       return res;
925                 }
926  
927                 /* Analyse data */
928 @@ -245,6 +295,8 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
929                                 if (reserved_block_code && (tmp == reserved_block_code)) {
930                                         printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n",
931                                                 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
932 +PRINTK ( "nand_read_bbt: Reserved block at 0x%08x\n",
933 +                                               ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
934                                         this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
935                                         mtd->ecc_stats.bbtblocks++;
936                                         continue;
937 @@ -253,6 +305,8 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
938                                  * message to MTD_DEBUG_LEVEL0 */
939                                 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
940                                         ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
941 +PRINTK ( "nand_read_bbt: Bad block at 0x%08x\n",
942 +                                       ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
943                                 /* Factory marked bad or worn out ? */
944                                 if (tmp == 0)
945                                         this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
946 @@ -261,8 +315,11 @@ PRINTK("%s: calling read_ecc len=%d, bits=%d, num=%d, totallen=%d\n", __FUNCTION
947                                 mtd->ecc_stats.badblocks++;
948                         }
949                 }
950 +#ifdef DEBUG_BBT
951 +do_printk=save_do_printk;
952 +#endif
953                 totlen -= len;
954 -               from += len;
955 +               from += (loff_t)len;
956         }
957         return 0;
958  }
959 @@ -283,6 +340,12 @@ static int brcmnand_read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nan
960         struct brcmnand_chip *this = mtd->priv;
961         int res = 0, i;
962         int bits;
963 +#ifdef DEBUG_BBT
964 +int save_do_printk = do_printk;
965 +do_printk = 1;
966 +#endif
967 +PRINTK("-->brcmnand_read_abs_bbt td=%c%c%c%c, td->pages[0]=%llx\n", 
968 +       td->pattern[0], td->pattern[1],td->pattern[2], td->pattern[3], td->pages[0]);
969  
970  PRINTK("-->brcmnand_read_abs_bbt\n");
971         bits = td->options & NAND_BBT_NRBITS_MSK;
972 @@ -293,6 +356,9 @@ PRINTK("-->brcmnand_read_abs_bbt\n");
973                                 res = brcmnand_read_bbt (mtd, buf, td->pages[i], this->chipSize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
974                         if (res) {
975  PRINTK("<-- brcmnand_read_abs_bbt ret = %d\n", res);
976 +#ifdef DEBUG_BBT
977 +do_printk = save_do_printk;
978 +#endif
979                                 return res;
980                         }
981                         offs += this->chipSize >> (this->bbt_erase_shift + 2);
982 @@ -302,10 +368,16 @@ PRINTK("<-- brcmnand_read_abs_bbt ret = %d\n", res);
983                                 (uint32_t) (this->mtdSize >> this->bbt_erase_shift), bits, 0, td->reserved_block_code);
984                 if (res) {
985  PRINTK("<-- brcmnand_read_abs_bbt 2 ret = %d\n", res);
986 +#ifdef DEBUG_BBT
987 +do_printk = save_do_printk;
988 +#endif
989                         return res;
990                 }
991         }
992  PRINTK("<-- brcmnand_read_abs_bbt ret 0\n");
993 +#ifdef DEBUG_BBT
994 +do_printk = save_do_printk;
995 +#endif
996         return 0;
997  }
998  
999 @@ -316,15 +388,23 @@ static int brcmnand_scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t off
1000                          size_t len)
1001  {
1002         struct mtd_oob_ops ops;
1003 +       int ret;
1004  
1005         ops.mode = MTD_OOB_RAW;
1006         ops.ooboffs = 0;
1007         ops.ooblen = mtd->oobsize;
1008 -       ops.oobbuf = buf;
1009 +       ops.oobbuf = &buf[mtd->writesize];
1010         ops.datbuf = buf;
1011         ops.len = len;
1012  
1013 -       return mtd->read_oob(mtd, offs, &ops);
1014 +       ret = mtd->read_oob(mtd, offs, &ops);
1015 +       
1016 +PRINTK("%s: Reading BBT Sig @%0llx, OOB=\n", __FUNCTION__, offs); 
1017 +#ifdef DEBUG_BBT
1018 +if (do_printk || gdebug) 
1019 +       print_oobbuf(ops.oobbuf, mtd->oobsize);
1020 +#endif
1021 +       return ret;
1022  }
1023  
1024  /*
1025 @@ -377,7 +457,9 @@ PRINTK("read primary version\n");
1026                 brcmnand_scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
1027                               mtd->writesize);
1028                 td->version[0] = buf[mtd->writesize + td->veroffs];
1029 -               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
1030 +               printk(KERN_DEBUG "Bad block table at page %llx, version 0x%02X\n",
1031 +                      td->pages[0], td->version[0]);
1032 +PRINTK( "Bad block table at page %llx, version 0x%02X\n",
1033                        td->pages[0], td->version[0]);
1034         }
1035  
1036 @@ -387,8 +469,10 @@ PRINTK("read mirror version\n");
1037                 brcmnand_scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
1038                               mtd->writesize);
1039                 md->version[0] = buf[mtd->writesize + md->veroffs];
1040 -               printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
1041 +               printk(KERN_DEBUG "Bad block table at page %llx, version 0x%02X\n",
1042                        md->pages[0], md->version[0]);
1043 +PRINTK( "Bad block table at page %llx, version 0x%02X\n",
1044 +                      td->pages[0], td->version[0]);
1045         }
1046  PRINTK("<-- %s\n", __FUNCTION__);
1047         return 1;
1048 @@ -434,7 +518,7 @@ static int brcmnand_scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr
1049                 int pagesPerBlock = mtd->erasesize/mtd->writesize;
1050                 
1051                 dir = -1;
1052 -               offs += (pagesPerBlock -1 ) * mtd->writesize;
1053 +               offs += (loff_t)((pagesPerBlock -1 ) * mtd->writesize);
1054         }
1055         ops.len = mtd->oobsize;
1056         ops.ooblen = mtd->oobsize;
1057 @@ -444,19 +528,26 @@ static int brcmnand_scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr
1058         ops.mode = MTD_OOB_PLACE;
1059  
1060         for (j=0; j < len; j++) {
1061 -               /*
1062 -                * Read the full oob until read_oob is fixed to
1063 -                * handle single byte reads for 16 bit
1064 -                * buswidth
1065 -                */
1066                 ret = mtd->read_oob(mtd, offs, &ops);
1067 +               if (ret == -EBADMSG) {// Uncorrectable errors
1068 +                       uint32_t acc0;
1069 +       
1070 +                       // Disable ECC
1071 +                       acc0 = brcmnand_disable_ecc();
1072 +
1073 +                       // Re-read the OOB
1074 +                       ret = mtd->read_oob(mtd, offs, &ops);
1075 +
1076 +                       // Enable ECC back
1077 +                       brcmnand_restore_ecc(acc0);
1078 +               }
1079                 if (ret)
1080                         return ret;
1081  
1082                 if (check_short_pattern(buf, bd))
1083                         return 1;
1084  
1085 -               offs += (dir * mtd->writesize);
1086 +               offs += (loff_t)(dir * mtd->writesize);
1087         }
1088         return 0;
1089  }
1090 @@ -489,8 +580,14 @@ PRINTK("-->brcmnand_create_bbt, bbt_erase_shift=%d, this->page_shift=%d\n", this
1091         if (bd->options & NAND_BBT_SCANALLPAGES)
1092                 len = 1 << (this->bbt_erase_shift - this->page_shift);
1093         else { // Also for MLC
1094 -               if (bd->options & NAND_BBT_SCAN2NDPAGE)
1095 -                       len = 2;
1096 +               if (bd->options & NAND_BBT_SCAN2NDPAGE) {
1097 +                       if (this->options & NAND_SCAN_BI_3RD_PAGE) {
1098 +                               len = 3; // For Hynix MLC chips
1099 +                       }
1100 +                       else {
1101 +                               len = 2;
1102 +                       }
1103 +               }
1104                 else
1105                         len = 1;
1106         }
1107 @@ -546,7 +643,7 @@ from, bd->options, mtd64_ll_low(startblock), mtd64_ll_low(numblocks));
1108                 }
1109  
1110                 i += 2;
1111 -               from += (1 << this->bbt_erase_shift);
1112 +               from += (loff_t)(1 << this->bbt_erase_shift);
1113         }
1114         return 0;
1115  }
1116 @@ -577,6 +674,7 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1117         int scanlen = mtd->writesize + mtd->oobsize;
1118         int bbtblocks;
1119         int blocktopage = this->bbt_erase_shift - this->page_shift;
1120 +       int ret = 0;
1121  
1122         /* Search direction top -> down ? */
1123         if (td->options & NAND_BBT_LASTBLOCK) {
1124 @@ -604,15 +702,22 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1125         for (i = 0; i < chips; i++) {
1126                 /* Reset version information */
1127                 td->version[i] = 0;
1128 -               td->pages[i] = -1;
1129 +               td->pages[i] = BBT_NULL_PAGE;
1130                 /* Scan the maximum number of blocks */
1131                 for (block = 0; block < td->maxblocks; block++) {
1132  
1133 -                       int actblock = startblock + dir * block;
1134 +                       int64_t actblock = startblock + dir * block;
1135                         loff_t offs = (uint64_t) actblock << this->bbt_erase_shift;
1136  
1137 +
1138                         /* Read first page */
1139 -                       brcmnand_scan_read_raw(mtd, buf, offs, mtd->writesize);
1140 +                       ret = brcmnand_scan_read_raw(mtd, buf, offs, mtd->writesize);
1141 +
1142 +                       /* Here if the read routine returns -77 then the BBT data is invalid, ignore it */
1143 +                       
1144 +                       // Ignore BBT if not there.
1145 +                       if (ret)
1146 +                               continue;
1147                         if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
1148                                 td->pages[i] = actblock << blocktopage;
1149                                 if (td->options & NAND_BBT_VERSION) {
1150 @@ -625,10 +730,12 @@ static int brcmnand_search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_
1151         }
1152         /* Check, if we found a bbt for each requested chip */
1153         for (i = 0; i < chips; i++) {
1154 -               if (td->pages[i] == -1)
1155 -                       printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
1156 +               if (td->pages[i] == BBT_NULL_PAGE)
1157 +                       printk (KERN_WARNING "Bad block table %c%c%c%c not found for chip %d\n", 
1158 +                               td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3], i);
1159 +
1160                 else
1161 -                       printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
1162 +                       printk(KERN_DEBUG "Bad block table found at page %llx, version 0x%02X\n", td->pages[i],
1163                                td->version[i]);
1164         }
1165         return 0;
1166 @@ -674,6 +781,8 @@ static int brcmnand_search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
1167   * for BBT.
1168   *
1169  */
1170 +// 0 == OK, 1 = outofspace for BBT0, 2=outofspace for BBT1
1171 +static int outofspace_bbt = 0;
1172  static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1173                      struct nand_bbt_descr *td, struct nand_bbt_descr *md,
1174                      int chipsel)
1175 @@ -682,7 +791,7 @@ static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1176         struct erase_info einfo;
1177         int i, j, res, chip = 0, skip, dir;
1178         uint32_t bits, offs, sft, sftmsk, bbtoffs;
1179 -       uint64_t startblock, numblocks, page, i64;
1180 +       int64_t startblock, numblocks, page, i64;
1181         int nrchips,  pageoffs, ooboffs;
1182         uint8_t msk[4];
1183         uint8_t rcode = td->reserved_block_code;
1184 @@ -690,6 +799,7 @@ static int brcmnand_write_bbt(struct mtd_info *mtd, uint8_t *buf,
1185         loff_t to;
1186         struct mtd_oob_ops ops;
1187  
1188 +bbt_outofspace_retry:
1189  
1190  DEBUG(MTD_DEBUG_LEVEL3, "-->%s\n", __FUNCTION__);
1191         ops.ooblen = mtd->oobsize;
1192 @@ -714,7 +824,8 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s\n", __FUNCTION__);
1193                 nrchips = 1;
1194         }
1195         
1196 -PRINTK("numblocks=%d, nrchips=%d\n", numblocks, nrchips);
1197 +PRINTK("%s Creating %c%c%c%c numblocks=%d, nrchips=%d, td->pages[0]=%llx\n", 
1198 +__FUNCTION__, td->pattern[0],td->pattern[1], td->pattern[2], td->pattern[3] , numblocks, nrchips, td->pages[0]);
1199  
1200         /* Loop through the chips */
1201         for (; chip < nrchips; chip++) {
1202 @@ -723,7 +834,7 @@ PRINTK("numblocks=%d, nrchips=%d\n", numblocks, nrchips);
1203                  * This applies for absolute placement too, as we have the
1204                  * page nr. in td->pages.
1205                  */
1206 -               if (td->pages[chip] != -1LL) {
1207 +               if (td->pages[chip] != BBT_NULL_PAGE) {
1208                         page = td->pages[chip];
1209  PRINTK("There is already a version of the table, go ahead and write it\n");
1210                         goto write;
1211 @@ -741,11 +852,12 @@ PRINTK("There is already a version of the table, go ahead and write it\n");
1212                 skip = 0;
1213  
1214  write_retry:
1215 -printk("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n", 
1216 +PRINTK("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n", 
1217         __FUNCTION__, startblock, dir, td->maxblocks, skip);
1218  
1219                 for (i = skip; i < td->maxblocks; i++) {
1220 -                       uint64_t block = startblock + dir * i;
1221 +                       uint64_t block = startblock + (int64_t) (dir * i);
1222 +                       // THT One byte contains 4 set of 2-bits, so divide block by 4 to index the BBT byte
1223                         uint32_t blockindex = (uint32_t) (block >> 2);
1224  
1225                         /* Check, if the block is bad */
1226 @@ -753,18 +865,36 @@ printk("%s: write_retry: startblock=%0llx, dir=%d, td->maxblocks=%d, skip=%d\n",
1227  PRINTK("%s: Checking BBT: i=%d, block=%0llx, BBT=%08x\n", 
1228  __FUNCTION__, i, block, this->bbt[blockindex]);
1229                         
1230 -                       switch ((this->bbt[blockindex] >>
1231 -                                (2 * (block & 0x03))) & 0x03) {
1232 +                       // THT: bbt[blockindex] is the byte we are looking for, now get the 2 bits that
1233 +                       // is the BBT for the block (Shift (0,1,2,3) *2 positions depending on the block modulo 4)
1234 +                       switch ((this->bbt[blockindex] >> (2 * (block & 0x03))) 
1235 +                                     & 0x03) {
1236                         case 0x01:
1237                         case 0x03:
1238                                 continue;
1239                         }
1240                         page = block << (this->bbt_erase_shift - this->page_shift);
1241 +
1242 +PRINTK("%s: Checking BBT2: page=%llx, md->pages[chip]=%llx\n", 
1243 +       __FUNCTION__, page, md->pages[chip]);
1244 +       
1245                         /* Check, if the block is used by the mirror table */
1246                         if (!md || md->pages[chip] != page)
1247                                 goto write;
1248                 }
1249 -               printk (KERN_ERR "No space left to write bad block table\n");
1250 +
1251 +#ifdef DEBUG_BBT               
1252 +               if (!do_printk) { // If we get here then turn on debugging and retry
1253 +                       do_printk=1;
1254 +                       chip = 0;
1255 +                       len = 0;
1256 +                       uint8_t rcode = td->reserved_block_code;
1257 +                       goto bbt_outofspace_retry;
1258 +               }
1259 +#endif
1260 +               printk (KERN_ERR "No space left to write bad block table %c%c%c%c\n", 
1261 +                       td->pattern[0], td->pattern[1], td->pattern[2], td->pattern[3]);
1262 +               brcmnand_post_mortem_dump(mtd, page<<this->page_shift);
1263                 return -ENOSPC;
1264  write:
1265  
1266 @@ -840,6 +970,11 @@ PRINTK("%s: Not NAND_BBT_SAVECONTENT\n", __FUNCTION__);
1267                         ooboffs = len;
1268                         /* Pattern is located in oob area of first page */
1269                         memcpy(&buf[ooboffs + td->offs], td->pattern, td->len);
1270 +                       
1271 +                       // Write the version number (1 byte)
1272 +                       if (td->options & NAND_BBT_VERSION) {
1273 +                               buf[ooboffs + td->veroffs]=td->version[0];
1274 +                       }
1275                 }
1276  
1277                 /* walk through the memory table */
1278 @@ -955,21 +1090,30 @@ static int brcmnand_check_create (struct mtd_info *mtd, uint8_t *buf, struct nan
1279                 rd2 = NULL;
1280                 /* Per chip or per device ? */
1281                 chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1;
1282 +
1283 +               /*
1284 +                * THT: Reset version to 0 if 0xff
1285 +                */
1286 +               if ((td->options & NAND_BBT_VERSION) && (td->version[i]==0xff) && td->pages[i] != BBT_NULL_PAGE)
1287 +                       td->version[i] = 0;
1288 +               if ((md->options & NAND_BBT_VERSION) && (md->version[i]==0xff) && md->pages[i] != BBT_NULL_PAGE)
1289 +                       md->version[i] = 0;
1290 +               
1291                 /* Mirrored table available ? */
1292                 if (md) {
1293 -                       if (td->pages[i] == -1 && md->pages[i] == -1) {
1294 +                       if (td->pages[i] == BBT_NULL_PAGE && md->pages[i] == BBT_NULL_PAGE) {
1295                                 writeops = 0x03;
1296                                 goto create;
1297                         }
1298  
1299 -                       if (td->pages[i] == -1) {
1300 +                       if (td->pages[i] == BBT_NULL_PAGE) {
1301                                 rd = md;
1302                                 td->version[i] = md->version[i];
1303                                 writeops = 1;
1304                                 goto writecheck;
1305                         }
1306  
1307 -                       if (md->pages[i] == -1) {
1308 +                       if (md->pages[i] == BBT_NULL_PAGE) {
1309                                 rd = td;
1310                                 md->version[i] = td->version[i];
1311                                 writeops = 2;
1312 @@ -996,7 +1140,7 @@ static int brcmnand_check_create (struct mtd_info *mtd, uint8_t *buf, struct nan
1313                         goto writecheck;
1314  
1315                 } else {
1316 -                       if (td->pages[i] == -1) {
1317 +                       if (td->pages[i] == BBT_NULL_PAGE) {
1318                                 writeops = 0x01;
1319                                 goto create;
1320                         }
1321 @@ -1015,25 +1159,46 @@ create:
1322                 if (md)
1323                         md->version[i] = 1;
1324  writecheck:
1325 +               res = 0;
1326 +               
1327                 /* read back first ? */
1328 -               if (rd)
1329 -                       brcmnand_read_abs_bbt (mtd, buf, rd, chipsel);
1330 +               if (rd) {
1331 +                       res = brcmnand_read_abs_bbt (mtd, buf, rd, chipsel);
1332 +               }
1333                 /* If they weren't versioned, read both. */
1334 -               if (rd2)
1335 -                       brcmnand_read_abs_bbt (mtd, buf, rd2, chipsel);
1336 +               if (rd2) {
1337 +                       if (res != 0) {
1338 +                               int bbtlen = (uint32_t) (this->mtdSize >> (this->bbt_erase_shift + 2));
1339 +                               /* Clear the in-memory BBT first */
1340 +PRINTK("%s: Discarding previously read BBT %c%c%c%c, res=%d\n", 
1341 +__FUNCTION__, rd->pattern[0], rd->pattern[1], rd->pattern[2], rd->pattern[3], res);
1342 +                               memset(this->bbt, 0, bbtlen);
1343 +                       }
1344 +                       res = brcmnand_read_abs_bbt (mtd, buf, rd2, chipsel);
1345 +                       if (res != 0) {
1346 +PRINTK("%s: Read BBT %c%c%c%c returns res=%d, discarding\n", 
1347 +__FUNCTION__, rd2->pattern[0], rd2->pattern[1], rd2->pattern[2], rd2->pattern[3], res);
1348 +                       }
1349 +               }
1350  
1351                 /* Write the bad block table to the device ? */
1352                 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1353                         res = brcmnand_write_bbt (mtd, buf, td, md, chipsel);
1354 -                       if (res < 0)
1355 +                       if (res < 0) {
1356 +                               if (res ==-ENOSPC)
1357 +                                       outofspace_bbt |= 1;
1358                                 return res;
1359 +                       }
1360                 }
1361  
1362                 /* Write the mirror bad block table to the device ? */
1363                 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1364                         res = brcmnand_write_bbt (mtd, buf, md, td, chipsel);
1365 -                       if (res < 0)
1366 +                       if (res < 0) {
1367 +                               if (res ==-ENOSPC)
1368 +                                       outofspace_bbt |= 2;
1369                                 return res;
1370 +                       }
1371                 }
1372         }
1373         return 0;
1374 @@ -1067,7 +1232,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
1375         for (i = 0; i < chips; i++) {
1376                 if ((td->options & NAND_BBT_ABSPAGE) ||
1377                     !(td->options & NAND_BBT_WRITE)) {
1378 -                       if (td->pages[i] == -1)
1379 +                       if (td->pages[i] == BBT_NULL_PAGE)
1380                                 continue;
1381                         block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
1382                         block <<= 1;
1383 @@ -1231,9 +1396,14 @@ DEBUG(MTD_DEBUG_LEVEL3, "-->%s offs=%0llx\n", __FUNCTION__, offs);
1384                 chipsel = -1;
1385         }
1386  
1387 -       td->version[chip]++;
1388 +       (td->version[chip])++;
1389 +       // THT Roll over
1390 +       if (td->version[chip] == 0xff)
1391 +               td->version[chip] =1;
1392         if (md)
1393 -               md->version[chip]++;
1394 +               (md->version[chip])++;
1395 +       if (md->version[chip] == 0xff)
1396 +               md->version[chip] =1;
1397  
1398         /* Write the bad block table to the device ? */
1399         if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1400 @@ -1251,6 +1421,219 @@ out:
1401         return res;
1402  }
1403  
1404 +/**
1405 + * brcmnand_reconstruct_bbt - [private] recreate bad block table(s)
1406 + * @mtd:                       MTD device structure
1407 + * @whichbbt:          1 = TD, 2 = MD
1408 + *
1409 + * The function reconstruct the bad block table(s) from the BI indicators.
1410 +*/
1411 +int brcmnand_reconstruct_bbt (struct mtd_info *mtd, int whichbbt)
1412 +{
1413 +       struct brcmnand_chip *this = mtd->priv;
1414 +       int len, res = 0, writeops = 0;
1415 +       int chip, chipsel;
1416 +       uint8_t *buf = NULL;
1417 +       struct nand_bbt_descr *td = this->bbt_td;
1418 +       struct nand_bbt_descr *md = this->bbt_md;
1419 +       uint32_t bbtSize;
1420 +       uint32_t block;
1421 +       uint64_t bOffset, startBlock, badBlock = 0; 
1422 +       int modified = 0;
1423 +
1424 +PRINTK( "-->%s whichBBT=%x\n", __FUNCTION__, whichbbt);
1425 +
1426 +       if (!this->bbt || !td)
1427 +               return -EINVAL;
1428 +
1429 +
1430 +       len = (uint32_t) (this->mtdSize >> (this->bbt_erase_shift + 2));
1431 +       /* Allocate a temporary buffer for one eraseblock incl. oob */
1432 +       len = (1 << this->bbt_erase_shift);
1433 +       len += (len >> this->page_shift) * mtd->oobsize;
1434 +       buf = vmalloc (len);
1435 +       if (!buf) {
1436 +               printk (KERN_ERR "brcmnand_update_bbt: Out of memory\n");
1437 +               return -ENOMEM;
1438 +       }
1439 +
1440 +       /*
1441 +        * Wipe out the BBT entries for the BBT space, and reconstruct it, 
1442 +        * but do not modify the other entries outside the BBT
1443 +        */
1444 +        if (this->mtdSize <= (512<<20)) {
1445 +               bbtSize = 1<<20;
1446 +        }
1447 +        else {
1448 +               bbtSize = 4<<20;
1449 +        }
1450 +
1451 +        /* Here we unset the entries in the BBT for the BBT region */
1452 +        startBlock = this->mtdSize - bbtSize;
1453 +        for (bOffset = startBlock; bOffset < this->mtdSize; bOffset += mtd->erasesize) {
1454 +               // Calculate index into BBT and wipe it out.
1455 +               uint32_t byteIndex = (uint32_t) bOffset >> 2;
1456 +               uint8_t byte = this->bbt[byteIndex];
1457 +               uint8_t byte0 = byte;
1458 +
1459 +               /* Clear the 2 bits for this block, then assign it back */
1460 +               byte &= ~(0x03 << (2 * (bOffset & 0x03)));
1461 +               
1462 +               /* If the contents changed, mark it */
1463 +               if (byte != byte0) {
1464 +                       modified = 1;
1465 +                       badBlock = bOffset;
1466 +               }
1467 +               
1468 +        }
1469 +       
1470 +        /* Now erase the BBT region, adding to bad block if erase fail */
1471 +
1472 +       if (modified) {
1473 +               int64_t goodBlock = BBT_NULL_PAGE;
1474 +
1475 +               switch (writeops & 0x03) {
1476 +               case 0x1:       goodBlock = md->pages[0] >> this->page_shift; break;
1477 +               case 0x2:       goodBlock = td->pages[0] >> this->page_shift; break;
1478 +               case 0x3:       goodBlock = BBT_NULL_PAGE; break;
1479 +               case 0: /* Impossible */ goodBlock = BBT_NULL_PAGE; break;
1480 +               }
1481 +               
1482 +#if 0
1483 +               static char buf[512+58]; // 31 for alignment, +27 for OOB size
1484 +               uint8_t* all0;
1485 +               uint8_t* oob0;
1486 +
1487 +               all0 = (uint8_t*)  ((((unsigned int) &buf[0]) + 31) & (~31));
1488 +               oob0 = &all0[512];
1489 +
1490 +               memset(all0, 0, 512);
1491 +               memset(oob0, 0, 27);
1492 +#endif 
1493 +               for (bOffset = startBlock; bOffset < this->mtdSize; bOffset += mtd->erasesize) {
1494 +                       int needBBT = 0;
1495 +                       
1496 +
1497 +                       /* Skip over the good BBT */
1498 +                       
1499 +                       if (bOffset == goodBlock)
1500 +                               continue;
1501 +                       
1502 +                       PRINTK("Erasing block at %0llx\n",  bOffset);
1503 +                       this->ctrl_writeAddr(this, bOffset, 0);
1504 +
1505 +                       this->ctrl_write(BCHP_NAND_CMD_START, OP_BLOCK_ERASE);
1506 +                       // Wait until flash is ready
1507 +                       (void)  this->write_is_complete(mtd, &needBBT);
1508 +                       if (needBBT) {
1509 +                               printk(KERN_WARNING "%s: Erase failure, marking bad block @%016llx\n", __FUNCTION__, bOffset);
1510 +                               modified = 1;
1511 +                               badBlock = bOffset;
1512 +                               (void) this->block_markbad(mtd, bOffset);
1513 +                       }
1514 +               }
1515 +               /* TBD: We should follow this with an ECC-disable write with all-0, ECC-enable then a re-erase
1516 +                * But that is too dangerous for AC-on-off tests, especially for the BBT area
1517 +                */
1518 +#if 0
1519 +               
1520 +       /* Disable ECC */
1521 +       acc = bbt_ctrl_read(BCHP_NAND_ACC_CONTROL);
1522 +       acc0 = acc & ~(BCHP_NAND_ACC_CONTROL_RD_ECC_EN_MASK | BCHP_NAND_ACC_CONTROL_RD_ECC_BLK0_EN_MASK);
1523 +       bbt_ctrl_write(BCHP_NAND_ACC_CONTROL, acc0);
1524 +
1525 +       chip->ctrl_writeAddr(chip, offset, 0);
1526 +       PLATFORM_IOFLUSH_WAR();
1527 +       chip->ctrl_write(BCHP_NAND_CMD_START, OP_PAGE_PROGRAM);
1528 +
1529 +       // Wait until cache is filled up, disabling ECC checking
1530 +       (void) brcmnand_spare_is_valid(mtd, FL_READING, 1);
1531 +       
1532 +       // Restore acc
1533 +       bbt_ctrl_write(BCHP_NAND_ACC_CONTROL, acc);
1534 +#endif
1535 +       }
1536 +
1537 +       
1538 +       
1539 +
1540 +       writeops = whichbbt;
1541 +       if (modified) writeops = 3; // Do both
1542 +
1543 +#if 0  // THT: TBD when we have per chip BBT
1544 +       /* Do we have a bbt per chip ? */
1545 +       if (td->options & NAND_BBT_PERCHIP) {
1546 +               chip = (int) (offs >> this->chip_shift);
1547 +               chipsel = chip;
1548 +       } else {
1549 +               chip = 0;
1550 +               chipsel = -1;
1551 +       }
1552 +#endif
1553 +
1554 +       /* Warning this codes only support 1 NAND chip */
1555 +do_both:
1556 +       if (((writeops & 3) == 3) && (td->options & NAND_BBT_WRITE)) {
1557 +               int res2 = 0;
1558 +
1559 +PRINTK("%s: Reconstructing both BBTs\n", __FUNCTION__);
1560 +               res = 0;
1561 +               td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1562 +               res = brcmnand_write_bbt (mtd, buf, td, md, 0);
1563 +       
1564 +               res2 = brcmnand_write_bbt (mtd, buf, md, td, 0);
1565 +
1566 +               if (!res && res2) /* At least one table write succeed. */
1567 +                       res = res2;
1568 +               
1569 +               goto out;
1570 +       }
1571 +
1572 +
1573 +       /* Write the bad block table to the device */
1574 +       
1575 +       if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
1576 +PRINTK("%s: Recreating Bbt0\n", __FUNCTION__);
1577 +               // Reset BBT0
1578 +               td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1579 +               
1580 +               // Look for the location of 1BBT
1581 +               res = brcmnand_search_bbt(mtd, buf, md);
1582 +
1583 +               if (res) { // Mirror not found
1584 +                       PRINTK("%s: Re-creating Bbt0, but 1bBT is also bad, rescan for both\n", __FUNCTION__);
1585 +                       writeops = 3;
1586 +                       goto do_both;
1587 +               }
1588 +
1589 +PRINTK("%s: Reconstructing both BBT0 from BBT1 at %08x\n", __FUNCTION__, md->pages[0]);                
1590 +               res = brcmnand_write_bbt (mtd, buf, td, md, 0);
1591 +               if (res < 0)
1592 +                       goto out;
1593 +       }
1594 +       /* Write the mirror bad block table to the device ? */
1595 +       if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
1596 +PRINTK("%s: Recreating 1bBT\n", __FUNCTION__);
1597 +               // Reset BBT0
1598 +               td->pages[0] = md->pages[0] = BBT_NULL_PAGE;
1599 +
1600 +               // Look for the location of Bbt0:
1601 +               res = brcmnand_search_bbt(mtd, buf, td);
1602 +
1603 +               if (res) { // Mirror not found
1604 +                       PRINTK("%s: Re-creating Bbt0, but 1bBT is also bad, rescan for both\n", __FUNCTION__);
1605 +                       writeops = 3;
1606 +                       goto do_both;
1607 +               }
1608 +PRINTK("%s: Reconstructing both BBT1 from BBT0 at %08x\n", __FUNCTION__, td->pages[0]);                        
1609 +               res = brcmnand_write_bbt (mtd, buf, md, td, 0);
1610 +       }
1611 +
1612 +out:
1613 +       vfree (buf);
1614 +       return res;
1615 +}
1616 +
1617  /* Define some generic bad / good block scan pattern which are used
1618   * while scanning a device for factory marked good / bad blocks. */
1619  static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
1620 @@ -1388,11 +1771,17 @@ static int brcmnand_displayBBT(struct mtd_info* mtd)
1621         //unsigned char oobbuf[64];
1622         //struct nand_oobinfo oobsel;
1623         int res;
1624 +#ifdef DEBUG_BBT
1625 +       int dbg=do_printk;
1626 +#endif
1627         // Size of BBT is 1MB if total flash is less than 512MB, 4MB otherwise
1628         int bbtSize = this->mtdSize > (512<<20) ? 4 << 20 : 1 << 20;
1629  
1630         bOffsetStart = 0;
1631 -       bOffsetEnd = this->mtdSize - bbtSize; // Skip BBT itself
1632 +       bOffsetEnd = (loff_t)(this->mtdSize - bbtSize); // Skip BBT itself
1633 +#ifdef DEBUG_BBT
1634 +    do_printk=1;
1635 +#endif
1636  
1637         printk(KERN_INFO "----- Contents of BBT -----\n");
1638         for (bOffset=bOffsetStart; bOffset < bOffsetEnd; bOffset = bOffset + mtd->erasesize) {
1639 @@ -1402,12 +1791,50 @@ static int brcmnand_displayBBT(struct mtd_info* mtd)
1640                 }
1641         }
1642         printk(KERN_INFO "----- END Contents of BBT -----\n");
1643 +
1644 +#ifdef DEBUG_BBT
1645 +    do_printk=dbg;
1646 +#endif
1647         return 0;
1648  }
1649  
1650  #if 1
1651  // Remove this block in production builds.
1652  
1653 +
1654 +//#define TEST_CLEAR_BBT1
1655 +//#define TEST_INVALIDATE_BBT0
1656 +
1657 +#ifdef TEST_INVALIDATE_BBT0
1658 +static uint32_t bbt_ctrl_read(uint32_t nandCtrlReg) 
1659 +{
1660 +       volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS 
1661 +               + nandCtrlReg - BCHP_NAND_REVISION);
1662 +
1663 +       if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
1664 +               (nandCtrlReg & 0x3) != 0) {
1665 +               printk("bbt_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
1666 +       }
1667 +if (gdebug > 3) printk("%s: CMDREG=%08x val=%08x\n", __FUNCTION__, (unsigned int) nandCtrlReg, (unsigned int)*pReg);
1668 +       return (uint32_t) (*pReg);
1669 +}
1670 +
1671 +
1672 +static void bbt_ctrl_write(uint32_t nandCtrlReg, uint32_t val) 
1673 +{
1674 +       volatile unsigned long* pReg = (volatile unsigned long*) (BRCMNAND_CTRL_REGS 
1675 +               + nandCtrlReg - BCHP_NAND_REVISION);
1676 +
1677 +       if (nandCtrlReg < BCHP_NAND_REVISION || nandCtrlReg > BCHP_NAND_BLK_WR_PROTECT ||
1678 +               (nandCtrlReg & 0x3) != 0) {
1679 +               printk( "bbt_ctrl_read: Invalid register value %08x\n", nandCtrlReg);
1680 +       }
1681 +       *pReg = (volatile unsigned long) (val);
1682 +if (gdebug > 3) printk("%s: CMDREG=%08x val=%08x\n", __FUNCTION__, nandCtrlReg, val);
1683 +}
1684 +#endif
1685 +
1686 +
1687  /*
1688   * Process brcmnand= kernel command arg, BEFORE building/reading BBT table.
1689   * Currently, the only accepted command is CLEARBBT, which in itself is a dangerous activity.
1690 @@ -1424,6 +1851,7 @@ static void brcmnand_preprocessKernelArg(struct mtd_info *mtd)
1691         //int page;
1692  
1693  
1694 +
1695  PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n", __FUNCTION__, gClearBBT, device_size(mtd), mtd->erasesize);
1696  
1697  
1698 @@ -1431,10 +1859,48 @@ PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n", __FUNCTION__, gClearB
1699  
1700         case NANDCMD_CLEARBBT: // Force rescan of BBT (DANGEROUS, may lose Mfg's BIs).
1701  
1702 +#ifdef TEST_CLEAR_BBT1
1703 +               bOffsetStart = 0x7ff00000; 
1704 +               bOffsetEnd = 0x7ff00000;
1705 +printk("%s: gClearBBT=clearbbt, start=%0llx, end=%0llx\n", __FUNCTION__, 
1706 +       bOffsetStart, bOffsetEnd);
1707 +#elif defined(TEST_INVALIDATE_BBT0)
1708 +{
1709 +uint32_t oob0[32];
1710 +uint8_t* oob = (uint8_t*) &oob0[0];
1711 +uint32_t acc0;
1712 +uint64_t bbt0Page = ((uint64_t) 0x7ff80000) >> this->page_shift;
1713 +int res;
1714 +
1715 +       bOffsetStart = 0x7ff80000; // FOrce it to skip erase
1716 +       bOffsetEnd = 0x7ff00000;
1717 +       res = this->read_page_oob(mtd, oob, bbt0Page);
1718 +       
1719 +
1720 +memset(&oob[9], 0, 4); // * Overwrite the ECC to force EBADMSG
1721 +//bOffsetStart = 0x7ff80000; 
1722 +//bOffsetEnd = 0x7ff80000;
1723 +
1724 +       /* Disable ECC */
1725 +       acc0 = brcmnand_disable_ecc();
1726 +
1727 +PRINTK("Invalidate ECC at page %llx\n", bbt0Page);
1728 +
1729 +       res = this->write_page_oob(mtd, oob, bbt0Page);
1730 +
1731 +       if (res) PRINTK("%s: write_page_oob failed, res=%d\n", __FUNCTION__, res);
1732 +
1733 +       // Restore acc0
1734 +       brcmnand_restore_ecc(acc0);
1735 +}
1736 +#else
1737 +
1738                 bOffsetStart = this->mtdSize - bbtSize; 
1739                 bOffsetEnd = this->mtdSize - mtd->erasesize;
1740  printk("%s: gClearBBT=clearbbt, start=%0llx, end=%0llx\n", __FUNCTION__, 
1741         bOffsetStart, bOffsetEnd);
1742 +#endif
1743 +
1744                 break;
1745  
1746         case NANDCMD_SHOWBBT:
1747 @@ -1634,7 +2100,12 @@ PRINTK("%s: gClearBBT=%d, size=%016llx, erasesize=%08x\n",
1748                         
1749                         /* How many pages should we scan */
1750                         if (this->badblock_pattern->options & NAND_BBT_SCAN2NDPAGE) {
1751 -                               numpages = 2;
1752 +                               if (this->options &  NAND_SCAN_BI_3RD_PAGE) {
1753 +                                       numpages = 3;
1754 +                               }
1755 +                               else {
1756 +                                       numpages = 2;
1757 +                               }
1758                         } else {
1759                                 numpages = 1;
1760                         }
1761 @@ -1865,6 +2336,18 @@ PRINTK("%s: gClearBBT = %d\n", __FUNCTION__, gClearBBT);
1762                 (void) brcmnand_postprocessKernelArg(mtd);
1763         }
1764  
1765 +       /* TESTING 1 2 3: Once we fixed the bug, there is no longer need for this */
1766 +       if (outofspace_bbt) {
1767 +#ifdef DEBUG_BBT
1768 +               do_printk=1;
1769 +#endif
1770 +               brcmnand_reconstruct_bbt(mtd, outofspace_bbt);
1771 +               outofspace_bbt = 0;
1772 +#ifdef DEBUG_BBT
1773 +               do_printk=0;
1774 +#endif
1775 +       }
1776 +
1777         return res;
1778  }
1779  
1780 diff --git a/drivers/mtd/brcmnand/brcmnand_priv.h b/drivers/mtd/brcmnand/brcmnand_priv.h
1781 index cc0f009..90ece32 100755
1782 --- a/drivers/mtd/brcmnand/brcmnand_priv.h
1783 +++ b/drivers/mtd/brcmnand/brcmnand_priv.h
1784 @@ -313,11 +313,20 @@ extern void* get_brcmnand_handle(void);
1785  extern void print_oobbuf(const unsigned char* buf, int len);
1786  extern void print_databuf(const unsigned char* buf, int len);
1787  
1788 -#if CONFIG_MTD_BRCMNAND_CORRECTABLE_ERR_HANDLING
1789 +#ifdef CONFIG_MTD_BRCMNAND_CORRECTABLE_ERR_HANDLING
1790  extern int brcmnand_cet_update(struct mtd_info *mtd, loff_t from, int *status);
1791  extern int brcmnand_cet_prepare_reboot(struct mtd_info *mtd);
1792  extern int brcmnand_cet_erasecallback(struct mtd_info *mtd, u_int32_t addr);
1793  extern int brcmnand_create_cet(struct mtd_info *mtd);
1794  #endif
1795  
1796 +/*
1797 + * Disable ECC, and return the original ACC register (for restore)
1798 + */
1799 +uint32_t brcmnand_disable_ecc(void);
1800 +
1801 +void brcmnand_restore_ecc(uint32_t orig_acc0);
1802 +
1803 +void brcmnand_post_mortem_dump(struct mtd_info* mtd, loff_t offset);   
1804 +
1805  #endif
1806 diff --git a/drivers/mtd/maps/bcm9xxxx-flash.c b/drivers/mtd/maps/bcm9xxxx-flash.c
1807 index ef050d2..adf8854 100644
1808 --- a/drivers/mtd/maps/bcm9xxxx-flash.c
1809 +++ b/drivers/mtd/maps/bcm9xxxx-flash.c
1810 @@ -176,7 +176,7 @@ struct map_info bcm9XXXX_map
1811  #define AVAIL1_PART                            (-1)
1812  #endif
1813  // DEFAULT_SIZE_MB will be defined later based on platforms.
1814 -#define DEFAULT_ROOTFS_SIZE (DEFAULT_SIZE_MB - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
1815 +#define DEFAULT_ROOTFS_SIZE (((DEFAULT_SIZE_MB)<<20) - DEFAULT_RESERVED_SIZE - DEFAULT_ECM_SIZE)
1816  
1817  
1818  static struct mtd_partition bcm9XXXX_parts[] = {
1819 @@ -213,7 +213,7 @@ static struct mtd_partition bcm9XXXX_parts[] = {
1820  
1821  /* default for 32MB+ platforms */
1822  
1823 -#define DEFAULT_SIZE_MB 32 /* 32MB flash */  
1824 +#define DEFAULT_SIZE_MB 64 /* 32MB flash */  
1825    #if defined( CONFIG_MTD_ECM_PARTITION)
1826         { name: "rootfs",               offset: 0,                              size: DEFAULT_ROOTFS_SIZE },
1827         { name: "avail1",               offset: DEFAULT_ROOTFS_SIZE,    size: DEFAULT_AVAIL1_SIZE },
1828 @@ -249,12 +249,27 @@ void (*gInitialize_Nor_Partition)(void) = (void (*)(void)) 0;
1829  EXPORT_SYMBOL(gInitialize_Nor_Partition);
1830  #endif
1831  
1832 +
1833 +
1834 +#if 1 // Debugging
1835 +static void print_partition(void)
1836 +{
1837 +       int i;
1838 +
1839 +       for (i=0; i<gNumParts; i++) {
1840 +               PRINTK("i=%d, name=%s, start=%0llx, size=%0llx\n", 
1841 +                       i, bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].offset,
1842 +                       bcm9XXXX_parts[i].size);
1843 +       }
1844 +}
1845 +#endif
1846 +
1847  int __init init_bcm9XXXX_map(void)
1848  {
1849         unsigned int avail1_size = DEFAULT_AVAIL1_SIZE;
1850         int i;
1851         struct cfi_private *cfi;
1852 -       u_int64_t ACTUAL_FLASH_SIZE = (u_int64_t) WINDOW_SIZE;
1853 +       unsigned long  ACTUAL_FLASH_SIZE = (unsigned long) WINDOW_SIZE;
1854         unsigned long FLASH_BASE = WINDOW_ADDR;
1855  
1856  #ifdef CONFIG_MTD_ECM_PARTITION
1857 @@ -284,6 +299,7 @@ int __init init_bcm9XXXX_map(void)
1858         
1859         //bcm9XXXX_map.size = WINDOW_SIZE;
1860         ACTUAL_FLASH_SIZE = 1 << cfi->cfiq->DevSize;
1861 +
1862         if (ACTUAL_FLASH_SIZE >= (4<<20)) {
1863                 FLASH_BASE = 0x20000000 - ACTUAL_FLASH_SIZE;
1864         }
1865 @@ -292,6 +308,8 @@ int __init init_bcm9XXXX_map(void)
1866         }
1867         
1868  
1869 +PRINTK("%s: cfiq->DevSize=%08x, actual_flash_size=%08lx, Base=%08lx\n", 
1870 +       __FUNCTION__,  cfi->cfiq->DevSize, ACTUAL_FLASH_SIZE, FLASH_BASE);
1871         /*
1872          * Now that we know the NOR flash size, map again with correct size and base address.
1873          */
1874 @@ -316,6 +334,9 @@ int __init init_bcm9XXXX_map(void)
1875         }
1876         gNumParts = ARRAY_SIZE(bcm9XXXX_parts) - 2; /* Minus the 2 extra place holders */
1877  
1878 +PRINTK("Before adjustment, gNumParts=%d, defaultSize=%dMB\n", gNumParts, DEFAULT_SIZE_MB);
1879 +print_partition();
1880 +
1881  
1882  #ifdef CONFIG_MTD_BRCMNAND_NOR_ACCESS
1883         /* If NOR flash is only 4MB, remove the NOR partition, leaving only CFE partition */
1884 @@ -329,7 +350,30 @@ int __init init_bcm9XXXX_map(void)
1885         bcm9XXXX_parts[1].size = bcm9XXXX_parts[0].offset; // NOR flash ends where CFE starts.
1886         bcm9XXXX_parts[1].offset = 0;
1887  
1888 -#elif defined( CONFIG_MTD_ECM_PARTITION )
1889 +#else
1890 +  /* NOR as only device */
1891 +  #if defined (DEFAULT_SIZE_MB )
1892 +       {
1893 +               unsigned long defaultSize = DEFAULT_SIZE_MB << 20;
1894 +               int i;
1895 +
1896 +               if (ACTUAL_FLASH_SIZE != defaultSize) {
1897 +                       // Adjust rootfs partition size, all others remain the same.
1898 +                       // rootfs
1899 +                       bcm9XXXX_parts[0].offset = 0;  // CFE starts at 1FC00000H
1900 +                       bcm9XXXX_parts[0].size += (int64_t) (ACTUAL_FLASH_SIZE - defaultSize);
1901 +                       //avail1
1902 +                       for (i=1; i<gNumParts; i++) {
1903 +                               // Adjust partition offset, but only for non NULL partitions.  Size remains the same.
1904 +                               if ((bcm9XXXX_parts[0].offset != 0 &&  bcm9XXXX_parts[0].size != 0)) 
1905 +                               {
1906 +                                       bcm9XXXX_parts[i].offset += (int64_t) (ACTUAL_FLASH_SIZE - defaultSize);
1907 +                               }
1908 +                       }
1909 +               }
1910 +       }
1911 +  #endif
1912 +  #if defined( CONFIG_MTD_ECM_PARTITION )
1913         if (ACTUAL_FLASH_SIZE < (64<<20)) {
1914                 ecm_size = DEFAULT_OCAP_SIZE;
1915                 avail1_size = 0;
1916 @@ -371,7 +415,7 @@ bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1917         }
1918  
1919                 
1920 -#elif defined( DEFAULT_SIZE_MB )
1921 +  #elif defined( DEFAULT_SIZE_MB )
1922         if (ACTUAL_FLASH_SIZE != (DEFAULT_SIZE_MB << 20)) {
1923                 int64_t diffSize = (uint64_t) ACTUAL_FLASH_SIZE - (uint64_t) (DEFAULT_SIZE_MB << 20);
1924  
1925 @@ -388,7 +432,8 @@ PRINTK("Part[0] After name=%s, size=%llx, offset=%llx\n", bcm9XXXX_parts[0].name
1926  PRINTK("Part[%d] After: name=%s, size=%llx, offset=%llx\n", i, bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1927                 }
1928         }
1929 -#endif
1930 +  #endif // ECM_PARTITION ... else
1931 +#endif // NOR+NAND ... else
1932  
1933  
1934         if (gBcmSplash) {               
1935 @@ -436,7 +481,8 @@ bcm9XXXX_parts[i].name, bcm9XXXX_parts[i].size, bcm9XXXX_parts[i].offset);
1936         }
1937  
1938         
1939 -
1940 +PRINTK("After adjustment\n");
1941 +print_partition();
1942         
1943  #if defined(CONFIG_MTD_BRCMNAND)
1944    #if defined(CONFIG_MTD_BRCMNAND_NOR_ACCESS)
1945 diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
1946 index 0753e22..6ccc89d 100755
1947 --- a/include/linux/mtd/nand.h
1948 +++ b/include/linux/mtd/nand.h
1949 @@ -184,6 +184,10 @@ typedef enum {
1950  /* This option is defined if the board driver allocates its own buffers
1951     (e.g. because it needs them DMA-coherent */
1952  #define NAND_OWN_BUFFERS       0x00040000
1953 +
1954 +/* For Hynix MLC flashes, the BI are written to last and (last-2) pages. */
1955 +#define NAND_SCAN_BI_3RD_PAGE  0x00100000
1956 +
1957  /* Options set by nand scan */
1958  /* Nand scan has allocated controller struct */
1959  #define NAND_CONTROLLER_ALLOC  0x80000000
1960 @@ -492,9 +496,11 @@ extern struct nand_manufacturers nand_manuf_ids[];
1961   * that the pattern and the version count are always located in the oob area
1962   * of the first block.
1963   */
1964 +#define BBT_NULL_PAGE (-1LL)
1965  struct nand_bbt_descr {
1966         int     options;
1967 -       int     pages[NAND_MAX_CHIPS];
1968 +
1969 +       int64_t pages[NAND_MAX_CHIPS];
1970         int     offs;
1971         int     veroffs;
1972         uint8_t version[NAND_MAX_CHIPS];
1973 @@ -534,6 +540,8 @@ struct nand_bbt_descr {
1974  #define NAND_BBT_SAVECONTENT   0x00002000
1975  /* Search good / bad pattern on the first and the second page */
1976  #define NAND_BBT_SCAN2NDPAGE   0x00004000
1977 +/* For Hynix MLC flashes BI are marked on last and (last-2) pages */
1978 +#define NAND_BBT_SCAN3RDPAGE   0x00008000
1979  
1980  /* The maximum number of blocks to scan for a bbt */
1981  #define NAND_BBT_SCAN_MAXBLOCKS        4