Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
423 | giacomo | 1 | |
2 | /* $Id: mtd.h,v 1.1 2004-01-28 15:30:50 giacomo Exp $ */ |
||
3 | |||
4 | #ifndef __MTD_MTD_H__ |
||
5 | #define __MTD_MTD_H__ |
||
6 | |||
7 | #ifdef __KERNEL__ |
||
8 | |||
9 | #include <linux/config.h> |
||
10 | #include <linux/version.h> |
||
11 | #include <linux/types.h> |
||
12 | #include <linux/module.h> |
||
13 | #include <linux/uio.h> |
||
14 | |||
15 | #endif /* __KERNEL__ */ |
||
16 | |||
17 | struct erase_info_user { |
||
18 | u_int32_t start; |
||
19 | u_int32_t length; |
||
20 | }; |
||
21 | |||
22 | struct mtd_oob_buf { |
||
23 | u_int32_t start; |
||
24 | u_int32_t length; |
||
25 | unsigned char *ptr; |
||
26 | }; |
||
27 | |||
28 | #define MTD_CHAR_MAJOR 90 |
||
29 | #define MTD_BLOCK_MAJOR 31 |
||
30 | #define MAX_MTD_DEVICES 16 |
||
31 | |||
32 | |||
33 | |||
34 | #define MTD_ABSENT 0 |
||
35 | #define MTD_RAM 1 |
||
36 | #define MTD_ROM 2 |
||
37 | #define MTD_NORFLASH 3 |
||
38 | #define MTD_NANDFLASH 4 |
||
39 | #define MTD_PEROM 5 |
||
40 | #define MTD_OTHER 14 |
||
41 | #define MTD_UNKNOWN 15 |
||
42 | |||
43 | |||
44 | |||
45 | #define MTD_CLEAR_BITS 1 // Bits can be cleared (flash) |
||
46 | #define MTD_SET_BITS 2 // Bits can be set |
||
47 | #define MTD_ERASEABLE 4 // Has an erase function |
||
48 | #define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible |
||
49 | #define MTD_VOLATILE 16 // Set for RAMs |
||
50 | #define MTD_XIP 32 // eXecute-In-Place possible |
||
51 | #define MTD_OOB 64 // Out-of-band data (NAND flash) |
||
52 | #define MTD_ECC 128 // Device capable of automatic ECC |
||
53 | |||
54 | // Some common devices / combinations of capabilities |
||
55 | #define MTD_CAP_ROM 0 |
||
56 | #define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) |
||
57 | #define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) |
||
58 | #define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) |
||
59 | #define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) |
||
60 | |||
61 | |||
62 | // Types of automatic ECC/Checksum available |
||
63 | #define MTD_ECC_NONE 0 // No automatic ECC available |
||
64 | #define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip |
||
65 | #define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices |
||
66 | |||
67 | struct mtd_info_user { |
||
68 | u_char type; |
||
69 | u_int32_t flags; |
||
70 | u_int32_t size; // Total size of the MTD |
||
71 | u_int32_t erasesize; |
||
72 | u_int32_t oobblock; // Size of OOB blocks (e.g. 512) |
||
73 | u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) |
||
74 | u_int32_t ecctype; |
||
75 | u_int32_t eccsize; |
||
76 | }; |
||
77 | |||
78 | struct region_info_user { |
||
79 | u_int32_t offset; /* At which this region starts, |
||
80 | * from the beginning of the MTD */ |
||
81 | u_int32_t erasesize; /* For this region */ |
||
82 | u_int32_t numblocks; /* Number of blocks in this region */ |
||
83 | u_int32_t regionindex; |
||
84 | }; |
||
85 | |||
86 | #define MEMGETINFO _IOR('M', 1, struct mtd_info_user) |
||
87 | #define MEMERASE _IOW('M', 2, struct erase_info_user) |
||
88 | #define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) |
||
89 | #define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) |
||
90 | #define MEMLOCK _IOW('M', 5, struct erase_info_user) |
||
91 | #define MEMUNLOCK _IOW('M', 6, struct erase_info_user) |
||
92 | #define MEMGETREGIONCOUNT _IOR('M', 7, int) |
||
93 | #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) |
||
94 | #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) |
||
95 | |||
96 | struct nand_oobinfo { |
||
97 | int useecc; |
||
98 | int eccpos[6]; |
||
99 | }; |
||
100 | |||
101 | |||
102 | #ifndef __KERNEL__ |
||
103 | |||
104 | typedef struct mtd_info_user mtd_info_t; |
||
105 | typedef struct erase_info_user erase_info_t; |
||
106 | typedef struct region_info_user region_info_t; |
||
107 | typedef struct nand_oobinfo nand_oobinfo_t; |
||
108 | |||
109 | /* User-space ioctl definitions */ |
||
110 | |||
111 | #else /* __KERNEL__ */ |
||
112 | |||
113 | |||
114 | #define MTD_ERASE_PENDING 0x01 |
||
115 | #define MTD_ERASING 0x02 |
||
116 | #define MTD_ERASE_SUSPEND 0x04 |
||
117 | #define MTD_ERASE_DONE 0x08 |
||
118 | #define MTD_ERASE_FAILED 0x10 |
||
119 | |||
120 | struct erase_info { |
||
121 | struct mtd_info *mtd; |
||
122 | u_int32_t addr; |
||
123 | u_int32_t len; |
||
124 | u_long time; |
||
125 | u_long retries; |
||
126 | u_int dev; |
||
127 | u_int cell; |
||
128 | void (*callback) (struct erase_info *self); |
||
129 | u_long priv; |
||
130 | u_char state; |
||
131 | struct erase_info *next; |
||
132 | }; |
||
133 | |||
134 | struct mtd_erase_region_info { |
||
135 | u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ |
||
136 | u_int32_t erasesize; /* For this region */ |
||
137 | u_int32_t numblocks; /* Number of blocks of erasesize in this region */ |
||
138 | }; |
||
139 | |||
140 | struct mtd_info { |
||
141 | u_char type; |
||
142 | u_int32_t flags; |
||
143 | u_int32_t size; // Total size of the MTD |
||
144 | |||
145 | /* "Major" erase size for the device. Naïve users may take this |
||
146 | * to be the only erase size available, or may use the more detailed |
||
147 | * information below if they desire |
||
148 | */ |
||
149 | u_int32_t erasesize; |
||
150 | |||
151 | u_int32_t oobblock; // Size of OOB blocks (e.g. 512) |
||
152 | u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) |
||
153 | u_int32_t ecctype; |
||
154 | u_int32_t eccsize; |
||
155 | |||
156 | |||
157 | // Kernel-only stuff starts here. |
||
158 | char *name; |
||
159 | int index; |
||
160 | |||
161 | // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) |
||
162 | struct nand_oobinfo oobinfo; |
||
163 | |||
164 | /* Data for variable erase regions. If numeraseregions is zero, |
||
165 | * it means that the whole device has erasesize as given above. |
||
166 | */ |
||
167 | int numeraseregions; |
||
168 | struct mtd_erase_region_info *eraseregions; |
||
169 | |||
170 | /* This really shouldn't be here. It can go away in 2.5 */ |
||
171 | u_int32_t bank_size; |
||
172 | |||
173 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); |
||
174 | |||
175 | /* This stuff for eXecute-In-Place */ |
||
176 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); |
||
177 | |||
178 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ |
||
179 | void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); |
||
180 | |||
181 | |||
182 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||
183 | int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); |
||
184 | |||
185 | int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||
186 | int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||
187 | |||
188 | int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||
189 | int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); |
||
190 | |||
191 | /* |
||
192 | * Methods to access the protection register area, present in some |
||
193 | * flash devices. The user data is one time programmable but the |
||
194 | * factory data is read only. |
||
195 | */ |
||
196 | int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||
197 | |||
198 | int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||
199 | |||
200 | /* This function is not yet implemented */ |
||
201 | int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||
202 | |||
203 | /* iovec-based read/write methods. We need these especially for NAND flash, |
||
204 | with its limited number of write cycles per erase. |
||
205 | NB: The 'count' parameter is the number of _vectors_, each of |
||
206 | which contains an (ofs, len) tuple. |
||
207 | */ |
||
208 | int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen); |
||
209 | int (*readv_ecc) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, |
||
210 | size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||
211 | int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen); |
||
212 | int (*writev_ecc) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, |
||
213 | size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||
214 | |||
215 | /* Sync */ |
||
216 | void (*sync) (struct mtd_info *mtd); |
||
217 | |||
218 | /* Chip-supported device locking */ |
||
219 | int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); |
||
220 | int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); |
||
221 | |||
222 | /* Power Management functions */ |
||
223 | int (*suspend) (struct mtd_info *mtd); |
||
224 | void (*resume) (struct mtd_info *mtd); |
||
225 | |||
226 | void *priv; |
||
227 | |||
228 | struct module *owner; |
||
229 | int usecount; |
||
230 | }; |
||
231 | |||
232 | |||
233 | /* Kernel-side ioctl definitions */ |
||
234 | |||
235 | extern int add_mtd_device(struct mtd_info *mtd); |
||
236 | extern int del_mtd_device (struct mtd_info *mtd); |
||
237 | |||
238 | extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); |
||
239 | |||
240 | extern void put_mtd_device(struct mtd_info *mtd); |
||
241 | |||
242 | |||
243 | struct mtd_notifier { |
||
244 | void (*add)(struct mtd_info *mtd); |
||
245 | void (*remove)(struct mtd_info *mtd); |
||
246 | struct list_head list; |
||
247 | }; |
||
248 | |||
249 | |||
250 | extern void register_mtd_user (struct mtd_notifier *new); |
||
251 | extern int unregister_mtd_user (struct mtd_notifier *old); |
||
252 | |||
253 | int default_mtd_writev(struct mtd_info *mtd, const struct iovec *vecs, |
||
254 | unsigned long count, loff_t to, size_t *retlen); |
||
255 | |||
256 | int default_mtd_readv(struct mtd_info *mtd, struct iovec *vecs, |
||
257 | unsigned long count, loff_t from, size_t *retlen); |
||
258 | |||
259 | #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) |
||
260 | #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) |
||
261 | #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) |
||
262 | #define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) |
||
263 | #define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) |
||
264 | #define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) |
||
265 | #define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) |
||
266 | #define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) |
||
267 | #define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) |
||
268 | #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) |
||
269 | #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) |
||
270 | #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) |
||
271 | |||
272 | /* |
||
273 | * Debugging macro and defines |
||
274 | */ |
||
275 | #define MTD_DEBUG_LEVEL0 (0) /* Quiet */ |
||
276 | #define MTD_DEBUG_LEVEL1 (1) /* Audible */ |
||
277 | #define MTD_DEBUG_LEVEL2 (2) /* Loud */ |
||
278 | #define MTD_DEBUG_LEVEL3 (3) /* Noisy */ |
||
279 | |||
280 | #ifdef CONFIG_MTD_DEBUG |
||
281 | #define DEBUG(n, args...) \ |
||
282 | do { \ |
||
283 | if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ |
||
284 | printk(KERN_INFO args); \ |
||
285 | } while(0) |
||
286 | #else /* CONFIG_MTD_DEBUG */ |
||
287 | #define DEBUG(n, args...) do { } while(0) |
||
288 | |||
289 | #endif /* CONFIG_MTD_DEBUG */ |
||
290 | |||
291 | #endif /* __KERNEL__ */ |
||
292 | |||
293 | #endif /* __MTD_MTD_H__ */ |