aboutsummaryrefslogtreecommitdiff
path: root/include/linux/mtd
diff options
context:
space:
mode:
authorBoris Brezillon2017-11-22 02:38:23 +0900
committerMasahiro Yamada2017-11-29 00:28:58 +0900
commit13f3b04f61aa6a0ec61bf01bb404f21c10b48bd0 (patch)
tree11f3cbb52d2c96b8418cb87bf3a44ca53d0119a6 /include/linux/mtd
parent1fb87de83dd6e76307e110100f265deb2d8d8163 (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.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 4bde2513223..ba4cbba949a 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;