@@ -1035,49 +1035,15 @@ EXPORT_SYMBOL_GPL(mtd_write_oob);
1035
1035
int mtd_ooblayout_ecc (struct mtd_info * mtd , int section ,
1036
1036
struct mtd_oob_region * oobecc )
1037
1037
{
1038
- int eccbyte = 0 , cursection = 0 , length = 0 , eccpos = 0 ;
1039
-
1040
1038
memset (oobecc , 0 , sizeof (* oobecc ));
1041
1039
1042
1040
if (!mtd || section < 0 )
1043
1041
return - EINVAL ;
1044
1042
1045
- if (!mtd -> ecclayout )
1043
+ if (!mtd -> ooblayout || ! mtd -> ooblayout -> ecc )
1046
1044
return - ENOTSUPP ;
1047
1045
1048
- /*
1049
- * This logic allows us to reuse the ->ecclayout information and
1050
- * expose them as ECC regions (as done for the OOB free regions).
1051
- *
1052
- * TODO: this should be dropped as soon as we get rid of the
1053
- * ->ecclayout field.
1054
- */
1055
- for (eccbyte = 0 ; eccbyte < mtd -> ecclayout -> eccbytes ; eccbyte ++ ) {
1056
- eccpos = mtd -> ecclayout -> eccpos [eccbyte ];
1057
-
1058
- if (eccbyte < mtd -> ecclayout -> eccbytes - 1 ) {
1059
- int neccpos = mtd -> ecclayout -> eccpos [eccbyte + 1 ];
1060
-
1061
- if (eccpos + 1 == neccpos ) {
1062
- length ++ ;
1063
- continue ;
1064
- }
1065
- }
1066
-
1067
- if (section == cursection )
1068
- break ;
1069
-
1070
- length = 0 ;
1071
- cursection ++ ;
1072
- }
1073
-
1074
- if (cursection != section || eccbyte >= mtd -> ecclayout -> eccbytes )
1075
- return - ERANGE ;
1076
-
1077
- oobecc -> length = length + 1 ;
1078
- oobecc -> offset = eccpos - length ;
1079
-
1080
- return 0 ;
1046
+ return mtd -> ooblayout -> ecc (mtd , section , oobecc );
1081
1047
}
1082
1048
EXPORT_SYMBOL_GPL (mtd_ooblayout_ecc );
1083
1049
@@ -1106,16 +1072,10 @@ int mtd_ooblayout_free(struct mtd_info *mtd, int section,
1106
1072
if (!mtd || section < 0 )
1107
1073
return - EINVAL ;
1108
1074
1109
- if (!mtd -> ecclayout )
1075
+ if (!mtd -> ooblayout || ! mtd -> ooblayout -> free )
1110
1076
return - ENOTSUPP ;
1111
1077
1112
- if (section >= MTD_MAX_OOBFREE_ENTRIES_LARGE )
1113
- return - ERANGE ;
1114
-
1115
- oobfree -> offset = mtd -> ecclayout -> oobfree [section ].offset ;
1116
- oobfree -> length = mtd -> ecclayout -> oobfree [section ].length ;
1117
-
1118
- return 0 ;
1078
+ return mtd -> ooblayout -> free (mtd , section , oobfree );
1119
1079
}
1120
1080
EXPORT_SYMBOL_GPL (mtd_ooblayout_free );
1121
1081
@@ -1416,6 +1376,123 @@ int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd)
1416
1376
}
1417
1377
EXPORT_SYMBOL_GPL (mtd_ooblayout_count_eccbytes );
1418
1378
1379
+ /**
1380
+ * mtd_ecclayout_ecc - Default ooblayout_ecc iterator implementation
1381
+ * @mtd: MTD device structure
1382
+ * @section: ECC section. Depending on the layout you may have all the ECC
1383
+ * bytes stored in a single contiguous section, or one section
1384
+ * per ECC chunk (and sometime several sections for a single ECC
1385
+ * ECC chunk)
1386
+ * @oobecc: OOB region struct filled with the appropriate ECC position
1387
+ * information
1388
+ *
1389
+ * This function is just a wrapper around the mtd->ecclayout field and is
1390
+ * here to ease the transition to the mtd_ooblayout_ops approach.
1391
+ * All it does is convert the layout->eccpos information into proper oob
1392
+ * region definitions.
1393
+ *
1394
+ * Returns zero on success, a negative error code otherwise.
1395
+ */
1396
+ static int mtd_ecclayout_ecc (struct mtd_info * mtd , int section ,
1397
+ struct mtd_oob_region * oobecc )
1398
+ {
1399
+ int eccbyte = 0 , cursection = 0 , length = 0 , eccpos = 0 ;
1400
+
1401
+ if (!mtd -> ecclayout )
1402
+ return - ENOTSUPP ;
1403
+
1404
+ /*
1405
+ * This logic allows us to reuse the ->ecclayout information and
1406
+ * expose them as ECC regions (as done for the OOB free regions).
1407
+ *
1408
+ * TODO: this should be dropped as soon as we get rid of the
1409
+ * ->ecclayout field.
1410
+ */
1411
+ for (eccbyte = 0 ; eccbyte < mtd -> ecclayout -> eccbytes ; eccbyte ++ ) {
1412
+ eccpos = mtd -> ecclayout -> eccpos [eccbyte ];
1413
+
1414
+ if (eccbyte < mtd -> ecclayout -> eccbytes - 1 ) {
1415
+ int neccpos = mtd -> ecclayout -> eccpos [eccbyte + 1 ];
1416
+
1417
+ if (eccpos + 1 == neccpos ) {
1418
+ length ++ ;
1419
+ continue ;
1420
+ }
1421
+ }
1422
+
1423
+ if (section == cursection )
1424
+ break ;
1425
+
1426
+ length = 0 ;
1427
+ cursection ++ ;
1428
+ }
1429
+
1430
+ if (cursection != section || eccbyte >= mtd -> ecclayout -> eccbytes )
1431
+ return - ERANGE ;
1432
+
1433
+ oobecc -> length = length + 1 ;
1434
+ oobecc -> offset = eccpos - length ;
1435
+
1436
+ return 0 ;
1437
+ }
1438
+
1439
+ /**
1440
+ * mtd_ecclayout_ecc - Default ooblayout_free iterator implementation
1441
+ * @mtd: MTD device structure
1442
+ * @section: Free section. Depending on the layout you may have all the free
1443
+ * bytes stored in a single contiguous section, or one section
1444
+ * per ECC chunk (and sometime several sections for a single ECC
1445
+ * ECC chunk)
1446
+ * @oobfree: OOB region struct filled with the appropriate free position
1447
+ * information
1448
+ *
1449
+ * This function is just a wrapper around the mtd->ecclayout field and is
1450
+ * here to ease the transition to the mtd_ooblayout_ops approach.
1451
+ * All it does is convert the layout->oobfree information into proper oob
1452
+ * region definitions.
1453
+ *
1454
+ * Returns zero on success, a negative error code otherwise.
1455
+ */
1456
+ static int mtd_ecclayout_free (struct mtd_info * mtd , int section ,
1457
+ struct mtd_oob_region * oobfree )
1458
+ {
1459
+ struct nand_ecclayout * layout = mtd -> ecclayout ;
1460
+
1461
+ if (!layout )
1462
+ return - ENOTSUPP ;
1463
+
1464
+ if (section >= MTD_MAX_OOBFREE_ENTRIES_LARGE ||
1465
+ !layout -> oobfree [section ].length )
1466
+ return - ERANGE ;
1467
+
1468
+ oobfree -> offset = layout -> oobfree [section ].offset ;
1469
+ oobfree -> length = layout -> oobfree [section ].length ;
1470
+
1471
+ return 0 ;
1472
+ }
1473
+
1474
+ static const struct mtd_ooblayout_ops mtd_ecclayout_wrapper_ops = {
1475
+ .ecc = mtd_ecclayout_ecc ,
1476
+ .free = mtd_ecclayout_free ,
1477
+ };
1478
+
1479
+ /**
1480
+ * mtd_set_ecclayout - Attach an ecclayout to an MTD device
1481
+ * @mtd: MTD device structure
1482
+ * @ecclayout: The ecclayout to attach to the device
1483
+ *
1484
+ * Returns zero on success, a negative error code otherwise.
1485
+ */
1486
+ void mtd_set_ecclayout (struct mtd_info * mtd , struct nand_ecclayout * ecclayout )
1487
+ {
1488
+ if (!mtd || !ecclayout )
1489
+ return ;
1490
+
1491
+ mtd -> ecclayout = ecclayout ;
1492
+ mtd_set_ooblayout (mtd , & mtd_ecclayout_wrapper_ops );
1493
+ }
1494
+ EXPORT_SYMBOL_GPL (mtd_set_ecclayout );
1495
+
1419
1496
/*
1420
1497
* Method to access the protection register area, present in some flash
1421
1498
* devices. The user data is one time programmable but the factory data is read
0 commit comments