@@ -879,9 +879,9 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int pag
879879{
880880 int i , status ;
881881 uint8_t ecc_code [32 ];
882- int eccmode = oobsel -> useecc ? this -> eccmode : NAND_ECC_NONE ;
882+ int eccmode = oobsel -> useecc ? this -> ecc . mode : NAND_ECC_NONE ;
883883 int * oob_config = oobsel -> eccpos ;
884- int datidx = 0 , eccidx = 0 , eccsteps = this -> eccsteps ;
884+ int datidx = 0 , eccidx = 0 , eccsteps = this -> ecc . steps ;
885885 int eccbytes = 0 ;
886886
887887 /* FIXME: Enable cached programming */
@@ -901,28 +901,28 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int pag
901901 /* Software ecc 3/256, write all */
902902 case NAND_ECC_SOFT :
903903 for (; eccsteps ; eccsteps -- ) {
904- this -> calculate_ecc (mtd , & this -> data_poi [datidx ], ecc_code );
904+ this -> ecc . calculate (mtd , & this -> data_poi [datidx ], ecc_code );
905905 for (i = 0 ; i < 3 ; i ++ , eccidx ++ )
906906 oob_buf [oob_config [eccidx ]] = ecc_code [i ];
907- datidx += this -> eccsize ;
907+ datidx += this -> ecc . size ;
908908 }
909909 this -> write_buf (mtd , this -> data_poi , mtd -> oobblock );
910910 break ;
911911 default :
912- eccbytes = this -> eccbytes ;
912+ eccbytes = this -> ecc . bytes ;
913913 for (; eccsteps ; eccsteps -- ) {
914914 /* enable hardware ecc logic for write */
915- this -> enable_hwecc (mtd , NAND_ECC_WRITE );
916- this -> write_buf (mtd , & this -> data_poi [datidx ], this -> eccsize );
917- this -> calculate_ecc (mtd , & this -> data_poi [datidx ], ecc_code );
915+ this -> ecc . hwctl (mtd , NAND_ECC_WRITE );
916+ this -> write_buf (mtd , & this -> data_poi [datidx ], this -> ecc . size );
917+ this -> ecc . calculate (mtd , & this -> data_poi [datidx ], ecc_code );
918918 for (i = 0 ; i < eccbytes ; i ++ , eccidx ++ )
919919 oob_buf [oob_config [eccidx ]] = ecc_code [i ];
920920 /* If the hardware ecc provides syndromes then
921921 * the ecc code must be written immidiately after
922922 * the data bytes (words) */
923923 if (this -> options & NAND_HWECC_SYNDROME )
924924 this -> write_buf (mtd , ecc_code , eccbytes );
925- datidx += this -> eccsize ;
925+ datidx += this -> ecc . size ;
926926 }
927927 break ;
928928 }
@@ -1155,7 +1155,7 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
11551155 if (oobsel -> useecc == MTD_NANDECC_AUTOPLACE )
11561156 oobsel = this -> autooob ;
11571157
1158- eccmode = oobsel -> useecc ? this -> eccmode : NAND_ECC_NONE ;
1158+ eccmode = oobsel -> useecc ? this -> ecc . mode : NAND_ECC_NONE ;
11591159 oob_config = oobsel -> eccpos ;
11601160
11611161 /* Select the NAND device */
@@ -1170,8 +1170,8 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
11701170 col = from & (mtd -> oobblock - 1 );
11711171
11721172 end = mtd -> oobblock ;
1173- ecc = this -> eccsize ;
1174- eccbytes = this -> eccbytes ;
1173+ ecc = this -> ecc . size ;
1174+ eccbytes = this -> ecc . bytes ;
11751175
11761176 if ((eccmode == NAND_ECC_NONE ) || (this -> options & NAND_HWECC_SYNDROME ))
11771177 compareecc = 0 ;
@@ -1216,7 +1216,7 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
12161216 oobsel -> useecc == MTD_NANDECC_AUTOPL_USR )
12171217 oob_data = & this -> data_buf [end ];
12181218
1219- eccsteps = this -> eccsteps ;
1219+ eccsteps = this -> ecc . steps ;
12201220
12211221 switch (eccmode ) {
12221222 case NAND_ECC_NONE :{
@@ -1234,32 +1234,32 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
12341234 case NAND_ECC_SOFT : /* Software ECC 3/256: Read in a page + oob data */
12351235 this -> read_buf (mtd , data_poi , end );
12361236 for (i = 0 , datidx = 0 ; eccsteps ; eccsteps -- , i += 3 , datidx += ecc )
1237- this -> calculate_ecc (mtd , & data_poi [datidx ], & ecc_calc [i ]);
1237+ this -> ecc . calculate (mtd , & data_poi [datidx ], & ecc_calc [i ]);
12381238 break ;
12391239
12401240 default :
12411241 for (i = 0 , datidx = 0 ; eccsteps ; eccsteps -- , i += eccbytes , datidx += ecc ) {
1242- this -> enable_hwecc (mtd , NAND_ECC_READ );
1242+ this -> ecc . hwctl (mtd , NAND_ECC_READ );
12431243 this -> read_buf (mtd , & data_poi [datidx ], ecc );
12441244
12451245 /* HW ecc with syndrome calculation must read the
12461246 * syndrome from flash immidiately after the data */
12471247 if (!compareecc ) {
12481248 /* Some hw ecc generators need to know when the
12491249 * syndrome is read from flash */
1250- this -> enable_hwecc (mtd , NAND_ECC_READSYN );
1250+ this -> ecc . hwctl (mtd , NAND_ECC_READSYN );
12511251 this -> read_buf (mtd , & oob_data [i ], eccbytes );
12521252 /* We calc error correction directly, it checks the hw
12531253 * generator for an error, reads back the syndrome and
12541254 * does the error correction on the fly */
1255- ecc_status = this -> correct_data (mtd , & data_poi [datidx ], & oob_data [i ], & ecc_code [i ]);
1255+ ecc_status = this -> ecc . correct (mtd , & data_poi [datidx ], & oob_data [i ], & ecc_code [i ]);
12561256 if ((ecc_status == -1 ) || (ecc_status > (flags && 0xff ))) {
12571257 DEBUG (MTD_DEBUG_LEVEL0 , "nand_read_ecc: "
12581258 "Failed ECC read, page 0x%08x on chip %d\n" , page , chipnr );
12591259 ecc_failed ++ ;
12601260 }
12611261 } else {
1262- this -> calculate_ecc (mtd , & data_poi [datidx ], & ecc_calc [i ]);
1262+ this -> ecc . calculate (mtd , & data_poi [datidx ], & ecc_calc [i ]);
12631263 }
12641264 }
12651265 break ;
@@ -1277,8 +1277,8 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
12771277 ecc_code [j ] = oob_data [oob_config [j ]];
12781278
12791279 /* correct data, if necessary */
1280- for (i = 0 , j = 0 , datidx = 0 ; i < this -> eccsteps ; i ++ , datidx += ecc ) {
1281- ecc_status = this -> correct_data (mtd , & data_poi [datidx ], & ecc_code [j ], & ecc_calc [j ]);
1280+ for (i = 0 , j = 0 , datidx = 0 ; i < this -> ecc . steps ; i ++ , datidx += ecc ) {
1281+ ecc_status = this -> ecc . correct (mtd , & data_poi [datidx ], & ecc_code [j ], & ecc_calc [j ]);
12821282
12831283 /* Get next chunk of ecc bytes */
12841284 j += eccbytes ;
@@ -1315,7 +1315,7 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
13151315 break ;
13161316 case MTD_NANDECC_PLACE :
13171317 /* YAFFS1 legacy mode */
1318- oob_data += this -> eccsteps * sizeof (int );
1318+ oob_data += this -> ecc . steps * sizeof (int );
13191319 default :
13201320 oob_data += mtd -> oobsize ;
13211321 }
@@ -2648,99 +2648,49 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
26482648 * check ECC mode, default to software if 3byte/512byte hardware ECC is
26492649 * selected and we have 256 byte pagesize fallback to software ECC
26502650 */
2651- this -> eccsize = 256 ;
2652- this -> eccbytes = 3 ;
2653-
2654- switch (this -> eccmode ) {
2655- case NAND_ECC_HW12_2048 :
2656- if (mtd -> oobblock < 2048 ) {
2657- printk (KERN_WARNING "2048 byte HW ECC not possible on "
2658- "%d byte page size, fallback to SW ECC\n" ,
2659- mtd -> oobblock );
2660- this -> eccmode = NAND_ECC_SOFT ;
2661- this -> calculate_ecc = nand_calculate_ecc ;
2662- this -> correct_data = nand_correct_data ;
2663- } else
2664- this -> eccsize = 2048 ;
2665- break ;
2666-
2667- case NAND_ECC_HW3_512 :
2668- case NAND_ECC_HW6_512 :
2669- case NAND_ECC_HW8_512 :
2670- if (mtd -> oobblock == 256 ) {
2671- printk (KERN_WARNING "512 byte HW ECC not possible on "
2672- "256 Byte pagesize, fallback to SW ECC \n" );
2673- this -> eccmode = NAND_ECC_SOFT ;
2674- this -> calculate_ecc = nand_calculate_ecc ;
2675- this -> correct_data = nand_correct_data ;
2676- } else
2677- this -> eccsize = 512 ; /* set eccsize to 512 */
2678- break ;
2651+ switch (this -> ecc .mode ) {
2652+ case NAND_ECC_HW :
2653+ case NAND_ECC_HW_SYNDROME :
2654+ if (!this -> ecc .calculate || !this -> ecc .correct ||
2655+ !this -> ecc .hwctl ) {
2656+ printk (KERN_WARNING "No ECC functions supplied, "
2657+ "Hardware ECC not possible\n" );
2658+ BUG ();
2659+ }
2660+ if (mtd -> oobblock >= this -> ecc .size )
2661+ break ;
2662+ printk (KERN_WARNING "%d byte HW ECC not possible on "
2663+ "%d byte page size, fallback to SW ECC\n" ,
2664+ this -> ecc .size , mtd -> oobblock );
2665+ this -> ecc .mode = NAND_ECC_SOFT ;
26792666
2680- case NAND_ECC_HW3_256 :
2667+ case NAND_ECC_SOFT :
2668+ this -> ecc .calculate = nand_calculate_ecc ;
2669+ this -> ecc .correct = nand_correct_data ;
2670+ this -> ecc .size = 256 ;
2671+ this -> ecc .bytes = 3 ;
26812672 break ;
26822673
26832674 case NAND_ECC_NONE :
26842675 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. "
26852676 "This is not recommended !!\n" );
2686- this -> eccmode = NAND_ECC_NONE ;
2677+ this -> ecc .size = mtd -> oobblock ;
2678+ this -> ecc .bytes = 0 ;
26872679 break ;
2688-
2689- case NAND_ECC_SOFT :
2690- this -> calculate_ecc = nand_calculate_ecc ;
2691- this -> correct_data = nand_correct_data ;
2692- break ;
2693-
26942680 default :
26952681 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n" ,
2696- this -> eccmode );
2697- BUG ();
2698- }
2699-
2700- /*
2701- * Check hardware ecc function availability and adjust number of ecc
2702- * bytes per calculation step
2703- */
2704- switch (this -> eccmode ) {
2705- case NAND_ECC_HW12_2048 :
2706- this -> eccbytes += 4 ;
2707- case NAND_ECC_HW8_512 :
2708- this -> eccbytes += 2 ;
2709- case NAND_ECC_HW6_512 :
2710- this -> eccbytes += 3 ;
2711- case NAND_ECC_HW3_512 :
2712- case NAND_ECC_HW3_256 :
2713- if (this -> calculate_ecc && this -> correct_data &&
2714- this -> enable_hwecc )
2715- break ;
2716- printk (KERN_WARNING "No ECC functions supplied, "
2717- "Hardware ECC not possible\n" );
2682+ this -> ecc .mode );
27182683 BUG ();
27192684 }
27202685
2721- mtd -> eccsize = this -> eccsize ;
2722-
27232686 /*
27242687 * Set the number of read / write steps for one page depending on ECC
27252688 * mode
27262689 */
2727- switch (this -> eccmode ) {
2728- case NAND_ECC_HW12_2048 :
2729- this -> eccsteps = mtd -> oobblock / 2048 ;
2730- break ;
2731- case NAND_ECC_HW3_512 :
2732- case NAND_ECC_HW6_512 :
2733- case NAND_ECC_HW8_512 :
2734- this -> eccsteps = mtd -> oobblock / 512 ;
2735- break ;
2736- case NAND_ECC_HW3_256 :
2737- case NAND_ECC_SOFT :
2738- this -> eccsteps = mtd -> oobblock / 256 ;
2739- break ;
2740-
2741- case NAND_ECC_NONE :
2742- this -> eccsteps = 1 ;
2743- break ;
2690+ this -> ecc .steps = mtd -> oobblock / this -> ecc .size ;
2691+ if (this -> ecc .steps * this -> ecc .size != mtd -> oobblock ) {
2692+ printk (KERN_WARNING "Invalid ecc parameters\n" );
2693+ BUG ();
27442694 }
27452695
27462696 /* Initialize state, waitqueue and spinlock */
0 commit comments