aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-05-28 21:26:58 -0400
committerThomas Gleixner <tglx@cruncher.tec.linutronix.de>2006-05-29 09:06:51 -0400
commit8593fbc68b0df1168995de76d1af38eb62fd6b62 (patch)
treedd244def53d2be4f1fbff9f74eac404fab8e240f /include
parentf4a43cfcecfcaeeaa40a9dbc1d1378298c22446e (diff)
[MTD] Rework the out of band handling completely
Hopefully the last iteration on this! The handling of out of band data on NAND was accompanied by tons of fruitless discussions and halfarsed patches to make it work for a particular problem. Sufficiently annoyed by I all those "I know it better" mails and the resonable amount of discarded "it solves my problem" patches, I finally decided to go for the big rework. After removing the _ecc variants of mtd read/write functions the solution to satisfy the various requirements was to refactor the read/write _oob functions in mtd. The major change is that read/write_oob now takes a pointer to an operation descriptor structure "struct mtd_oob_ops".instead of having a function with at least seven arguments. read/write_oob which should probably renamed to a more descriptive name, can do the following tasks: - read/write out of band data - read/write data content and out of band data - read/write raw data content and out of band data (ecc disabled) struct mtd_oob_ops has a mode field, which determines the oob handling mode. Aside of the MTD_OOB_RAW mode, which is intended to be especially for diagnostic purposes and some internal functions e.g. bad block table creation, the other two modes are for mtd clients: MTD_OOB_PLACE puts/gets the given oob data exactly to/from the place which is described by the ooboffs and ooblen fields of the mtd_oob_ops strcuture. It's up to the caller to make sure that the byte positions are not used by the ECC placement algorithms. MTD_OOB_AUTO puts/gets the given oob data automaticaly to/from the places in the out of band area which are described by the oobfree tuples in the ecclayout data structre which is associated to the devicee. The decision whether data plus oob or oob only handling is done depends on the setting of the datbuf member of the data structure. When datbuf == NULL then the internal read/write_oob functions are selected, otherwise the read/write data routines are invoked. Tested on a few platforms with all variants. Please be aware of possible regressions for your particular device / application scenario Disclaimer: Any whining will be ignored from those who just contributed "hot air blurb" and never sat down to tackle the underlying problem of the mess in the NAND driver grown over time and the big chunk of work to fix up the existing users. The problem was not the holiness of the existing MTD interfaces. The problems was the lack of time to go for the big overhaul. It's easy to add more mess to the existing one, but it takes alot of effort to go for a real solution. Improvements and bugfixes are welcome! Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mtd/mtd.h50
-rw-r--r--include/linux/mtd/nand.h10
2 files changed, 50 insertions, 10 deletions
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 4970c2e96fbf..e75bb584e80b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -67,6 +67,50 @@ struct mtd_ecc_stats {
67 unsigned long failed; 67 unsigned long failed;
68}; 68};
69 69
70/*
71 * oob operation modes
72 *
73 * MTD_OOB_PLACE: oob data are placed at the given offset
74 * MTD_OOB_AUTO: oob data are automatically placed at the free areas
75 * which are defined by the ecclayout
76 * MTD_OOB_RAW: mode to read raw data+oob in one chunk. The oob data
77 * is inserted into the data. Thats a raw image of the
78 * flash contents.
79 */
80typedef enum {
81 MTD_OOB_PLACE,
82 MTD_OOB_AUTO,
83 MTD_OOB_RAW,
84} mtd_oob_mode_t;
85
86/**
87 * struct mtd_oob_ops - oob operation operands
88 * @mode: operation mode
89 *
90 * @len: number of bytes to write/read. When a data buffer is given
91 * (datbuf != NULL) this is the number of data bytes. When
92 + no data buffer is available this is the number of oob bytes.
93 *
94 * @retlen: number of bytes written/read. When a data buffer is given
95 * (datbuf != NULL) this is the number of data bytes. When
96 + no data buffer is available this is the number of oob bytes.
97 *
98 * @ooblen: number of oob bytes per page
99 * @ooboffs: offset of oob data in the oob area (only relevant when
100 * mode = MTD_OOB_PLACE)
101 * @datbuf: data buffer - if NULL only oob data are read/written
102 * @oobbuf: oob data buffer
103 */
104struct mtd_oob_ops {
105 mtd_oob_mode_t mode;
106 size_t len;
107 size_t retlen;
108 size_t ooblen;
109 uint32_t ooboffs;
110 uint8_t *datbuf;
111 uint8_t *oobbuf;
112};
113
70struct mtd_info { 114struct mtd_info {
71 u_char type; 115 u_char type;
72 u_int32_t flags; 116 u_int32_t flags;
@@ -125,8 +169,10 @@ struct mtd_info {
125 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 169 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
126 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 170 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
127 171
128 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 172 int (*read_oob) (struct mtd_info *mtd, loff_t from,
129 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 173 struct mtd_oob_ops *ops);
174 int (*write_oob) (struct mtd_info *mtd, loff_t to,
175 struct mtd_oob_ops *ops);
130 176
131 /* 177 /*
132 * Methods to access the protection register area, present in some 178 * Methods to access the protection register area, present in some
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index dc2bf1bcf42b..bf2ce68901f5 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -31,14 +31,6 @@ extern int nand_scan (struct mtd_info *mtd, int max_chips);
31/* Free resources held by the NAND device */ 31/* Free resources held by the NAND device */
32extern void nand_release (struct mtd_info *mtd); 32extern void nand_release (struct mtd_info *mtd);
33 33
34/* Read raw data from the device without ECC */
35extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from,
36 size_t len, size_t ooblen);
37
38
39extern int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len,
40 size_t *retlen, const uint8_t *buf, uint8_t *oob);
41
42/* The maximum number of NAND chips in an array */ 34/* The maximum number of NAND chips in an array */
43#define NAND_MAX_CHIPS 8 35#define NAND_MAX_CHIPS 8
44 36
@@ -375,6 +367,8 @@ struct nand_chip {
375 struct nand_buffers buffers; 367 struct nand_buffers buffers;
376 struct nand_hw_control hwcontrol; 368 struct nand_hw_control hwcontrol;
377 369
370 struct mtd_oob_ops ops;
371
378 uint8_t *bbt; 372 uint8_t *bbt;
379 struct nand_bbt_descr *bbt_td; 373 struct nand_bbt_descr *bbt_td;
380 struct nand_bbt_descr *bbt_md; 374 struct nand_bbt_descr *bbt_md;