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
113struct mtd_info {
114 u_char type;
115 uint32_t flags;
116 uint64_t size;
117
118
119
120
121
122 uint32_t erasesize;
123
124
125
126
127
128
129
130 uint32_t writesize;
131
132 uint32_t oobsize;
133 uint32_t oobavail;
134
135
136
137
138
139 unsigned int erasesize_shift;
140 unsigned int writesize_shift;
141
142 unsigned int erasesize_mask;
143 unsigned int writesize_mask;
144
145
146 const char *name;
147 int index;
148
149
150 struct nand_ecclayout *ecclayout;
151
152
153
154
155 int numeraseregions;
156 struct mtd_erase_region_info *eraseregions;
157
158
159
160
161
162
163
164
165 int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
166
167
168
169 int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
170 size_t *retlen, void **virt, resource_size_t *phys);
171
172
173 void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
174
175
176
177
178
179 unsigned long (*get_unmapped_area) (struct mtd_info *mtd,
180 unsigned long len,
181 unsigned long offset,
182 unsigned long flags);
183
184
185
186
187 struct backing_dev_info *backing_dev_info;
188
189
190 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
191 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
192
193
194
195
196
197
198
199
200 int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
201
202 int (*read_oob) (struct mtd_info *mtd, loff_t from,
203 struct mtd_oob_ops *ops);
204 int (*write_oob) (struct mtd_info *mtd, loff_t to,
205 struct mtd_oob_ops *ops);
206
207
208
209
210
211
212 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
213 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
214 int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
215 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
216 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
217 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
218
219
220
221
222
223 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
224
225
226 void (*sync) (struct mtd_info *mtd);
227
228
229 int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
230 int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
231 int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
232
233
234 int (*suspend) (struct mtd_info *mtd);
235 void (*resume) (struct mtd_info *mtd);
236
237
238 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
239 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
240
241 struct notifier_block reboot_notifier;
242
243
244 struct mtd_ecc_stats ecc_stats;
245
246 int subpage_sft;
247
248 void *priv;
249
250 struct module *owner;
251 struct device dev;
252 int usecount;
253
254
255
256
257
258 int (*get_device) (struct mtd_info *mtd);
259 void (*put_device) (struct mtd_info *mtd);
260};
261
262static inline struct mtd_info *dev_to_mtd(struct device *dev)
263{
264 return dev ? dev_get_drvdata(dev) : NULL;
265}
266
267static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
268{
269 if (mtd->erasesize_shift)
270 return sz >> mtd->erasesize_shift;
271 do_div(sz, mtd->erasesize);
272 return sz;
273}
274
275static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
276{
277 if (mtd->erasesize_shift)
278 return sz & mtd->erasesize_mask;
279 return do_div(sz, mtd->erasesize);
280}
281
282static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
283{
284 if (mtd->writesize_shift)
285 return sz >> mtd->writesize_shift;
286 do_div(sz, mtd->writesize);
287 return sz;
288}
289
290static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
291{
292 if (mtd->writesize_shift)
293 return sz & mtd->writesize_mask;
294 return do_div(sz, mtd->writesize);
295}
296
297
298
299extern int add_mtd_device(struct mtd_info *mtd);
300extern int del_mtd_device (struct mtd_info *mtd);
301
302extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
303extern int __get_mtd_device(struct mtd_info *mtd);
304extern void __put_mtd_device(struct mtd_info *mtd);
305extern struct mtd_info *get_mtd_device_nm(const char *name);
306extern void put_mtd_device(struct mtd_info *mtd);
307
308
309struct mtd_notifier {
310 void (*add)(struct mtd_info *mtd);
311 void (*remove)(struct mtd_info *mtd);
312 struct list_head list;
313};
314
315
316extern void register_mtd_user (struct mtd_notifier *new);
317extern int unregister_mtd_user (struct mtd_notifier *old);
318
319int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
320 unsigned long count, loff_t to, size_t *retlen);
321
322int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
323 unsigned long count, loff_t from, size_t *retlen);
324
325#ifdef CONFIG_MTD_PARTITIONS
326void mtd_erase_callback(struct erase_info *instr);
327#else
328static inline void mtd_erase_callback(struct erase_info *instr)
329{
330 if (instr->callback)
331 instr->callback(instr);
332}
333#endif
334
335
336
337
338#define MTD_DEBUG_LEVEL0 (0)
339#define MTD_DEBUG_LEVEL1 (1)
340#define MTD_DEBUG_LEVEL2 (2)
341#define MTD_DEBUG_LEVEL3 (3)
342
343#ifdef CONFIG_MTD_DEBUG
344#define DEBUG(n, args...) \
345 do { \
346 if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
347 printk(KERN_INFO args); \
348 } while(0)
349#else
350#define DEBUG(n, args...) \
351 do { \
352 if (0) \
353 printk(KERN_INFO args); \
354 } while(0)
355
356#endif
357
358#endif
359