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