Commit 987b913c authored by Boris Brezillon's avatar Boris Brezillon

mtd: nand: sm_common: switch to mtd_ooblayout_ops

Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent e7049f29
...@@ -12,14 +12,47 @@ ...@@ -12,14 +12,47 @@
#include <linux/sizes.h> #include <linux/sizes.h>
#include "sm_common.h" #include "sm_common.h"
static struct nand_ecclayout nand_oob_sm = { static int oob_sm_ooblayout_ecc(struct mtd_info *mtd, int section,
.eccbytes = 6, struct mtd_oob_region *oobregion)
.eccpos = {8, 9, 10, 13, 14, 15}, {
.oobfree = { if (section > 1)
{.offset = 0 , .length = 4}, /* reserved */ return -ERANGE;
{.offset = 6 , .length = 2}, /* LBA1 */
{.offset = 11, .length = 2} /* LBA2 */ oobregion->length = 3;
oobregion->offset = ((section + 1) * 8) - 3;
return 0;
}
static int oob_sm_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
switch (section) {
case 0:
/* reserved */
oobregion->offset = 0;
oobregion->length = 4;
break;
case 1:
/* LBA1 */
oobregion->offset = 6;
oobregion->length = 2;
break;
case 2:
/* LBA2 */
oobregion->offset = 11;
oobregion->length = 2;
break;
default:
return -ERANGE;
} }
return 0;
}
static const struct mtd_ooblayout_ops oob_sm_ops = {
.ecc = oob_sm_ooblayout_ecc,
.free = oob_sm_ooblayout_free,
}; };
/* NOTE: This layout is is not compatabable with SmartMedia, */ /* NOTE: This layout is is not compatabable with SmartMedia, */
...@@ -28,15 +61,43 @@ static struct nand_ecclayout nand_oob_sm = { ...@@ -28,15 +61,43 @@ static struct nand_ecclayout nand_oob_sm = {
/* If you use smftl, it will bypass this and work correctly */ /* If you use smftl, it will bypass this and work correctly */
/* If you not, then you break SmartMedia compliance anyway */ /* If you not, then you break SmartMedia compliance anyway */
static struct nand_ecclayout nand_oob_sm_small = { static int oob_sm_small_ooblayout_ecc(struct mtd_info *mtd, int section,
.eccbytes = 3, struct mtd_oob_region *oobregion)
.eccpos = {0, 1, 2}, {
.oobfree = { if (section)
{.offset = 3 , .length = 2}, /* reserved */ return -ERANGE;
{.offset = 6 , .length = 2}, /* LBA1 */
oobregion->length = 3;
oobregion->offset = 0;
return 0;
}
static int oob_sm_small_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
switch (section) {
case 0:
/* reserved */
oobregion->offset = 3;
oobregion->length = 2;
break;
case 1:
/* LBA1 */
oobregion->offset = 6;
oobregion->length = 2;
break;
default:
return -ERANGE;
} }
};
return 0;
}
static const struct mtd_ooblayout_ops oob_sm_small_ops = {
.ecc = oob_sm_small_ooblayout_ecc,
.free = oob_sm_small_ooblayout_free,
};
static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs) static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs)
{ {
...@@ -121,9 +182,9 @@ int sm_register_device(struct mtd_info *mtd, int smartmedia) ...@@ -121,9 +182,9 @@ int sm_register_device(struct mtd_info *mtd, int smartmedia)
/* ECC layout */ /* ECC layout */
if (mtd->writesize == SM_SECTOR_SIZE) if (mtd->writesize == SM_SECTOR_SIZE)
chip->ecc.layout = &nand_oob_sm; mtd_set_ooblayout(mtd, &oob_sm_ops);
else if (mtd->writesize == SM_SMALL_PAGE) else if (mtd->writesize == SM_SMALL_PAGE)
chip->ecc.layout = &nand_oob_sm_small; mtd_set_ooblayout(mtd, &oob_sm_small_ops);
else else
return -ENODEV; return -ENODEV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment