diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-11-22 02:38:23 +0900 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2017-11-29 00:28:58 +0900 |
commit | 13f3b04f61aa6a0ec61bf01bb404f21c10b48bd0 (patch) | |
tree | 11f3cbb52d2c96b8418cb87bf3a44ca53d0119a6 /include/linux/mtd | |
parent | 1fb87de83dd6e76307e110100f265deb2d8d8163 (diff) |
mtd: add mtd_ooblayout_xxx() helper functions
In order to make the ecclayout definition completely dynamic we need to
rework the way the OOB layout are defined and iterated.
Create a few mtd_ooblayout_xxx() helpers to ease OOB bytes manipulation
and hide ecclayout internals to their users.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
[Linux commit: 75eb2cec251fda33c9bb716ecc372819abb9278a]
[masahiro:
cherry-pick more code from adbbc3bc827eb1f43a932d783f09ba55c8ec8379]
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'include/linux/mtd')
-rw-r--r-- | include/linux/mtd/mtd.h | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 4bde251322..ba4cbba949 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -103,6 +103,36 @@ struct mtd_oob_ops { #else #define MTD_MAX_ECCPOS_ENTRIES_LARGE 680 #endif +/** + * struct mtd_oob_region - oob region definition + * @offset: region offset + * @length: region length + * + * This structure describes a region of the OOB area, and is used + * to retrieve ECC or free bytes sections. + * Each section is defined by an offset within the OOB area and a + * length. + */ +struct mtd_oob_region { + u32 offset; + u32 length; +}; + +/* + * struct mtd_ooblayout_ops - NAND OOB layout operations + * @ecc: function returning an ECC region in the OOB area. + * Should return -ERANGE if %section exceeds the total number of + * ECC sections. + * @free: function returning a free region in the OOB area. + * Should return -ERANGE if %section exceeds the total number of + * free sections. + */ +struct mtd_ooblayout_ops { + int (*ecc)(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobecc); + int (*free)(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobfree); +}; /* * Internal ECC layout control structure. For historical reasons, there is a @@ -179,6 +209,9 @@ struct mtd_info { #endif int index; + /* OOB layout description */ + const struct mtd_ooblayout_ops *ooblayout; + /* ECC layout structure pointer - read only! */ struct nand_ecclayout *ecclayout; @@ -278,6 +311,30 @@ struct mtd_info { int usecount; }; +int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobecc); +int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte, + int *section, + struct mtd_oob_region *oobregion); +int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf, + const u8 *oobbuf, int start, int nbytes); +int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf, + u8 *oobbuf, int start, int nbytes); +int mtd_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobfree); +int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf, + const u8 *oobbuf, int start, int nbytes); +int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf, + u8 *oobbuf, int start, int nbytes); +int mtd_ooblayout_count_freebytes(struct mtd_info *mtd); +int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd); + +static inline void mtd_set_ooblayout(struct mtd_info *mtd, + const struct mtd_ooblayout_ops *ooblayout) +{ + mtd->ooblayout = ooblayout; +} + static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) { return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize; |