1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#ifndef __MTD_MTD_H__
21#define __MTD_MTD_H__
22
23#include <linux/types.h>
24#include <linux/module.h>
25#include <linux/uio.h>
26#include <linux/notifier.h>
27#include <linux/device.h>
28
29#include <mtd/mtd-abi.h>
30
31#include <asm/div64.h>
32
33#define MTD_CHAR_MAJOR 90
34#define MTD_BLOCK_MAJOR 31
35
36#define MTD_ERASE_PENDING 0x01
37#define MTD_ERASING 0x02
38#define MTD_ERASE_SUSPEND 0x04
39#define MTD_ERASE_DONE 0x08
40#define MTD_ERASE_FAILED 0x10
41
42#define MTD_FAIL_ADDR_UNKNOWN -1LL
43
44
45
46
47struct erase_info {
48 struct mtd_info *mtd;
49 uint64_t addr;
50 uint64_t len;
51 uint64_t fail_addr;
52 u_long time;
53 u_long retries;
54 unsigned dev;
55 unsigned cell;
56 void (*callback) (struct erase_info *self);
57 u_long priv;
58 u_char state;
59 struct erase_info *next;
60};
61
62struct mtd_erase_region_info {
63 uint64_t offset;
64 uint32_t erasesize;
65 uint32_t numblocks;
66 unsigned long *lockmap;
67};
68
69
70
71
72
73
74
75
76
77typedef enum {
78 MTD_OOB_PLACE,
79 MTD_OOB_AUTO,
80 MTD_OOB_RAW,
81} mtd_oob_mode_t;
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102struct mtd_oob_ops {
103 mtd_oob_mode_t mode;
104 size_t len;
105 size_t retlen;
106 size_t ooblen;
107 size_t oobretlen;
108 uint32_t ooboffs;
109 uint8_t *datbuf;
110 uint8_t *oobbuf;
111};
112
113#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
114#define MTD_MAX_ECCPOS_ENTRIES_LARGE 448
115
116
117
118
119
120
121struct nand_ecclayout {
122 __u32 eccbytes;
123 __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
124 __u32 oobavail;
125 struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
126};
127
128struct mtd_info {
129 u_char type;
130 uint32_t flags;
131 uint64_t size;
132
133
134
135
136
137 uint32_t erasesize;
138
139
140
141
142
143
144
145 uint32_t writesize;
146
147
148
149
150
151
152
153
154
155
156 uint32_t writebufsize;
157
158 uint32_t oobsize;
159 uint32_t oobavail;
160
161
162
163
164
165 unsigned int erasesize_shift;
166 unsigned int writesize_shift;
167
168 unsigned int erasesize_mask;
169 unsigned int writesize_mask;
170
171
172 const char *name;
173 int index;
174
175
176 struct nand_ecclayout *ecclayout;
177
178
179
180
181 int numeraseregions;
182 struct mtd_erase_region_info *eraseregions;
183
184
185
186
187
188
189
190
191 int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
192
193
194
195 int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
196 size_t *retlen, void **virt, resource_size_t *phys);
197
198
199 void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
200
201
202
203
204
205 unsigned long (*get_unmapped_area) (struct mtd_info *mtd,
206 unsigned long len,
207 unsigned long offset,
208 unsigned long flags);
209
210
211
212
213 struct backing_dev_info *backing_dev_info;
214
215
216 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
217 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
218
219
220
221
222
223
224
225
226 int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
227
228 int (*read_oob) (struct mtd_info *mtd, loff_t from,
229 struct mtd_oob_ops *ops);
230 int (*write_oob) (struct mtd_info *mtd, loff_t to,
231 struct mtd_oob_ops *ops);
232
233
234
235
236
237
238 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
239 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
240 int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
241 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
242 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
243 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
244
245
246
247
248
249 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
250
251
252 void (*sync) (struct mtd_info *mtd);
253
254
255 int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
256 int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
257 int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
258
259
260 int (*suspend) (struct mtd_info *mtd);
261 void (*resume) (struct mtd_info *mtd);
262
263
264 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
265 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
266
267 struct notifier_block reboot_notifier;
268
269
270 struct mtd_ecc_stats ecc_stats;
271
272 int subpage_sft;
273
274 void *priv;
275
276 struct module *owner;
277 struct device dev;
278 int usecount;
279
280
281
282
283
284 int (*get_device) (struct mtd_info *mtd);
285 void (*put_device) (struct mtd_info *mtd);
286};
287
288static inline struct mtd_info *dev_to_mtd(struct device *dev)
289{
290 return dev ? dev_get_drvdata(dev) : NULL;
291}
292
293static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
294{
295 if (mtd->erasesize_shift)
296 return sz >> mtd->erasesize_shift;
297 do_div(sz, mtd->erasesize);
298 return sz;
299}
300
301static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
302{
303 if (mtd->erasesize_shift)
304 return sz & mtd->erasesize_mask;
305 return do_div(sz, mtd->erasesize);
306}
307
308static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
309{
310 if (mtd->writesize_shift)
311 return sz >> mtd->writesize_shift;
312 do_div(sz, mtd->writesize);
313 return sz;
314}
315
316static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
317{
318 if (mtd->writesize_shift)
319 return sz & mtd->writesize_mask;
320 return do_div(sz, mtd->writesize);
321}
322
323
324
325extern int add_mtd_device(struct mtd_info *mtd);
326extern int del_mtd_device (struct mtd_info *mtd);
327
328extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
329extern int __get_mtd_device(struct mtd_info *mtd);
330extern void __put_mtd_device(struct mtd_info *mtd);
331extern struct mtd_info *get_mtd_device_nm(const char *name);
332extern void put_mtd_device(struct mtd_info *mtd);
333
334
335struct mtd_notifier {
336 void (*add)(struct mtd_info *mtd);
337 void (*remove)(struct mtd_info *mtd);
338 struct list_head list;
339};
340
341
342extern void register_mtd_user (struct mtd_notifier *new);
343extern int unregister_mtd_user (struct mtd_notifier *old);
344
345int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
346 unsigned long count, loff_t to, size_t *retlen);
347
348int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
349 unsigned long count, loff_t from, size_t *retlen);
350
351#ifdef CONFIG_MTD_PARTITIONS
352void mtd_erase_callback(struct erase_info *instr);
353#else
354static inline void mtd_erase_callback(struct erase_info *instr)
355{
356 if (instr->callback)
357 instr->callback(instr);
358}
359#endif
360
361
362
363
364#define MTD_DEBUG_LEVEL0 (0)
365#define MTD_DEBUG_LEVEL1 (1)
366#define MTD_DEBUG_LEVEL2 (2)
367#define MTD_DEBUG_LEVEL3 (3)
368
369#ifdef CONFIG_MTD_DEBUG
370#define DEBUG(n, args...) \
371 do { \
372 if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
373 printk(KERN_INFO args); \
374 } while(0)
375#else
376#define DEBUG(n, args...) \
377 do { \
378 if (0) \
379 printk(KERN_INFO args); \
380 } while(0)
381
382#endif
383
384#endif
385