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