@@ -879,9 +879,9 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int pag
879
879
{
880
880
int i , status ;
881
881
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 ;
883
883
int * oob_config = oobsel -> eccpos ;
884
- int datidx = 0 , eccidx = 0 , eccsteps = this -> eccsteps ;
884
+ int datidx = 0 , eccidx = 0 , eccsteps = this -> ecc . steps ;
885
885
int eccbytes = 0 ;
886
886
887
887
/* FIXME: Enable cached programming */
@@ -901,28 +901,28 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *this, int pag
901
901
/* Software ecc 3/256, write all */
902
902
case NAND_ECC_SOFT :
903
903
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 );
905
905
for (i = 0 ; i < 3 ; i ++ , eccidx ++ )
906
906
oob_buf [oob_config [eccidx ]] = ecc_code [i ];
907
- datidx += this -> eccsize ;
907
+ datidx += this -> ecc . size ;
908
908
}
909
909
this -> write_buf (mtd , this -> data_poi , mtd -> oobblock );
910
910
break ;
911
911
default :
912
- eccbytes = this -> eccbytes ;
912
+ eccbytes = this -> ecc . bytes ;
913
913
for (; eccsteps ; eccsteps -- ) {
914
914
/* 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 );
918
918
for (i = 0 ; i < eccbytes ; i ++ , eccidx ++ )
919
919
oob_buf [oob_config [eccidx ]] = ecc_code [i ];
920
920
/* If the hardware ecc provides syndromes then
921
921
* the ecc code must be written immidiately after
922
922
* the data bytes (words) */
923
923
if (this -> options & NAND_HWECC_SYNDROME )
924
924
this -> write_buf (mtd , ecc_code , eccbytes );
925
- datidx += this -> eccsize ;
925
+ datidx += this -> ecc . size ;
926
926
}
927
927
break ;
928
928
}
@@ -1155,7 +1155,7 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1155
1155
if (oobsel -> useecc == MTD_NANDECC_AUTOPLACE )
1156
1156
oobsel = this -> autooob ;
1157
1157
1158
- eccmode = oobsel -> useecc ? this -> eccmode : NAND_ECC_NONE ;
1158
+ eccmode = oobsel -> useecc ? this -> ecc . mode : NAND_ECC_NONE ;
1159
1159
oob_config = oobsel -> eccpos ;
1160
1160
1161
1161
/* Select the NAND device */
@@ -1170,8 +1170,8 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1170
1170
col = from & (mtd -> oobblock - 1 );
1171
1171
1172
1172
end = mtd -> oobblock ;
1173
- ecc = this -> eccsize ;
1174
- eccbytes = this -> eccbytes ;
1173
+ ecc = this -> ecc . size ;
1174
+ eccbytes = this -> ecc . bytes ;
1175
1175
1176
1176
if ((eccmode == NAND_ECC_NONE ) || (this -> options & NAND_HWECC_SYNDROME ))
1177
1177
compareecc = 0 ;
@@ -1216,7 +1216,7 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1216
1216
oobsel -> useecc == MTD_NANDECC_AUTOPL_USR )
1217
1217
oob_data = & this -> data_buf [end ];
1218
1218
1219
- eccsteps = this -> eccsteps ;
1219
+ eccsteps = this -> ecc . steps ;
1220
1220
1221
1221
switch (eccmode ) {
1222
1222
case NAND_ECC_NONE :{
@@ -1234,32 +1234,32 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1234
1234
case NAND_ECC_SOFT : /* Software ECC 3/256: Read in a page + oob data */
1235
1235
this -> read_buf (mtd , data_poi , end );
1236
1236
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 ]);
1238
1238
break ;
1239
1239
1240
1240
default :
1241
1241
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 );
1243
1243
this -> read_buf (mtd , & data_poi [datidx ], ecc );
1244
1244
1245
1245
/* HW ecc with syndrome calculation must read the
1246
1246
* syndrome from flash immidiately after the data */
1247
1247
if (!compareecc ) {
1248
1248
/* Some hw ecc generators need to know when the
1249
1249
* syndrome is read from flash */
1250
- this -> enable_hwecc (mtd , NAND_ECC_READSYN );
1250
+ this -> ecc . hwctl (mtd , NAND_ECC_READSYN );
1251
1251
this -> read_buf (mtd , & oob_data [i ], eccbytes );
1252
1252
/* We calc error correction directly, it checks the hw
1253
1253
* generator for an error, reads back the syndrome and
1254
1254
* 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 ]);
1256
1256
if ((ecc_status == -1 ) || (ecc_status > (flags && 0xff ))) {
1257
1257
DEBUG (MTD_DEBUG_LEVEL0 , "nand_read_ecc: "
1258
1258
"Failed ECC read, page 0x%08x on chip %d\n" , page , chipnr );
1259
1259
ecc_failed ++ ;
1260
1260
}
1261
1261
} else {
1262
- this -> calculate_ecc (mtd , & data_poi [datidx ], & ecc_calc [i ]);
1262
+ this -> ecc . calculate (mtd , & data_poi [datidx ], & ecc_calc [i ]);
1263
1263
}
1264
1264
}
1265
1265
break ;
@@ -1277,8 +1277,8 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1277
1277
ecc_code [j ] = oob_data [oob_config [j ]];
1278
1278
1279
1279
/* 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 ]);
1282
1282
1283
1283
/* Get next chunk of ecc bytes */
1284
1284
j += eccbytes ;
@@ -1315,7 +1315,7 @@ int nand_do_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
1315
1315
break ;
1316
1316
case MTD_NANDECC_PLACE :
1317
1317
/* YAFFS1 legacy mode */
1318
- oob_data += this -> eccsteps * sizeof (int );
1318
+ oob_data += this -> ecc . steps * sizeof (int );
1319
1319
default :
1320
1320
oob_data += mtd -> oobsize ;
1321
1321
}
@@ -2648,99 +2648,49 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2648
2648
* check ECC mode, default to software if 3byte/512byte hardware ECC is
2649
2649
* selected and we have 256 byte pagesize fallback to software ECC
2650
2650
*/
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 ;
2679
2666
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 ;
2681
2672
break ;
2682
2673
2683
2674
case NAND_ECC_NONE :
2684
2675
printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. "
2685
2676
"This is not recommended !!\n" );
2686
- this -> eccmode = NAND_ECC_NONE ;
2677
+ this -> ecc .size = mtd -> oobblock ;
2678
+ this -> ecc .bytes = 0 ;
2687
2679
break ;
2688
-
2689
- case NAND_ECC_SOFT :
2690
- this -> calculate_ecc = nand_calculate_ecc ;
2691
- this -> correct_data = nand_correct_data ;
2692
- break ;
2693
-
2694
2680
default :
2695
2681
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 );
2718
2683
BUG ();
2719
2684
}
2720
2685
2721
- mtd -> eccsize = this -> eccsize ;
2722
-
2723
2686
/*
2724
2687
* Set the number of read / write steps for one page depending on ECC
2725
2688
* mode
2726
2689
*/
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 ();
2744
2694
}
2745
2695
2746
2696
/* Initialize state, waitqueue and spinlock */
0 commit comments