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/uio.h>
25#include <linux/notifier.h>
26#include <linux/device.h>
27#include <linux/of.h>
28
29#include <mtd/mtd-abi.h>
30
31#include <asm/div64.h>
32
33#define MTD_ERASE_PENDING 0x01
34#define MTD_ERASING 0x02
35#define MTD_ERASE_SUSPEND 0x04
36#define MTD_ERASE_DONE 0x08
37#define MTD_ERASE_FAILED 0x10
38
39#define MTD_FAIL_ADDR_UNKNOWN -1LL
40
41
42
43
44
45
46struct erase_info {
47 struct mtd_info *mtd;
48 uint64_t addr;
49 uint64_t len;
50 uint64_t fail_addr;
51 u_long time;
52 u_long retries;
53 unsigned dev;
54 unsigned cell;
55 void (*callback) (struct erase_info *self);
56 u_long priv;
57 u_char state;
58 struct erase_info *next;
59};
60
61struct mtd_erase_region_info {
62 uint64_t offset;
63 uint32_t erasesize;
64 uint32_t numblocks;
65 unsigned long *lockmap;
66};
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87struct mtd_oob_ops {
88 unsigned int mode;
89 size_t len;
90 size_t retlen;
91 size_t ooblen;
92 size_t oobretlen;
93 uint32_t ooboffs;
94 uint8_t *datbuf;
95 uint8_t *oobbuf;
96};
97
98#define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
99#define MTD_MAX_ECCPOS_ENTRIES_LARGE 640
100
101
102
103
104
105
106
107
108
109
110struct mtd_oob_region {
111 u32 offset;
112 u32 length;
113};
114
115
116
117
118
119
120
121
122
123
124struct mtd_ooblayout_ops {
125 int (*ecc)(struct mtd_info *mtd, int section,
126 struct mtd_oob_region *oobecc);
127 int (*free)(struct mtd_info *mtd, int section,
128 struct mtd_oob_region *oobfree);
129};
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161struct mtd_pairing_info {
162 int pair;
163 int group;
164};
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199struct mtd_pairing_scheme {
200 int ngroups;
201 int (*get_info)(struct mtd_info *mtd, int wunit,
202 struct mtd_pairing_info *info);
203 int (*get_wunit)(struct mtd_info *mtd,
204 const struct mtd_pairing_info *info);
205};
206
207struct module;
208
209struct mtd_info {
210 u_char type;
211 uint32_t flags;
212 uint64_t size;
213
214
215
216
217
218 uint32_t erasesize;
219
220
221
222
223
224
225
226 uint32_t writesize;
227
228
229
230
231
232
233
234
235
236
237 uint32_t writebufsize;
238
239 uint32_t oobsize;
240 uint32_t oobavail;
241
242
243
244
245
246 unsigned int erasesize_shift;
247 unsigned int writesize_shift;
248
249 unsigned int erasesize_mask;
250 unsigned int writesize_mask;
251
252
253
254
255
256
257
258
259 unsigned int bitflip_threshold;
260
261
262 const char *name;
263 int index;
264
265
266 const struct mtd_ooblayout_ops *ooblayout;
267
268
269 const struct mtd_pairing_scheme *pairing;
270
271
272 unsigned int ecc_step_size;
273
274
275 unsigned int ecc_strength;
276
277
278
279
280 int numeraseregions;
281 struct mtd_erase_region_info *eraseregions;
282
283
284
285
286
287 int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
288 int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
289 size_t *retlen, void **virt, resource_size_t *phys);
290 int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
291 unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
292 unsigned long len,
293 unsigned long offset,
294 unsigned long flags);
295 int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
296 size_t *retlen, u_char *buf);
297 int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
298 size_t *retlen, const u_char *buf);
299 int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
300 size_t *retlen, const u_char *buf);
301 int (*_read_oob) (struct mtd_info *mtd, loff_t from,
302 struct mtd_oob_ops *ops);
303 int (*_write_oob) (struct mtd_info *mtd, loff_t to,
304 struct mtd_oob_ops *ops);
305 int (*_get_fact_prot_info) (struct mtd_info *mtd, size_t len,
306 size_t *retlen, struct otp_info *buf);
307 int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
308 size_t len, size_t *retlen, u_char *buf);
309 int (*_get_user_prot_info) (struct mtd_info *mtd, size_t len,
310 size_t *retlen, struct otp_info *buf);
311 int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
312 size_t len, size_t *retlen, u_char *buf);
313 int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
314 size_t len, size_t *retlen, u_char *buf);
315 int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
316 size_t len);
317 int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
318 unsigned long count, loff_t to, size_t *retlen);
319 void (*_sync) (struct mtd_info *mtd);
320 int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
321 int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
322 int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
323 int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
324 int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
325 int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
326 int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
327 int (*_suspend) (struct mtd_info *mtd);
328 void (*_resume) (struct mtd_info *mtd);
329 void (*_reboot) (struct mtd_info *mtd);
330
331
332
333
334 int (*_get_device) (struct mtd_info *mtd);
335 void (*_put_device) (struct mtd_info *mtd);
336
337 struct notifier_block reboot_notifier;
338
339
340 struct mtd_ecc_stats ecc_stats;
341
342 int subpage_sft;
343
344 void *priv;
345
346 struct module *owner;
347 struct device dev;
348 int usecount;
349};
350
351int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
352 struct mtd_oob_region *oobecc);
353int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
354 int *section,
355 struct mtd_oob_region *oobregion);
356int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
357 const u8 *oobbuf, int start, int nbytes);
358int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
359 u8 *oobbuf, int start, int nbytes);
360int mtd_ooblayout_free(struct mtd_info *mtd, int section,
361 struct mtd_oob_region *oobfree);
362int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
363 const u8 *oobbuf, int start, int nbytes);
364int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
365 u8 *oobbuf, int start, int nbytes);
366int mtd_ooblayout_count_freebytes(struct mtd_info *mtd);
367int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd);
368
369static inline void mtd_set_ooblayout(struct mtd_info *mtd,
370 const struct mtd_ooblayout_ops *ooblayout)
371{
372 mtd->ooblayout = ooblayout;
373}
374
375static inline void mtd_set_pairing_scheme(struct mtd_info *mtd,
376 const struct mtd_pairing_scheme *pairing)
377{
378 mtd->pairing = pairing;
379}
380
381static inline void mtd_set_of_node(struct mtd_info *mtd,
382 struct device_node *np)
383{
384 mtd->dev.of_node = np;
385 if (!mtd->name)
386 of_property_read_string(np, "label", &mtd->name);
387}
388
389static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd)
390{
391 return dev_of_node(&mtd->dev);
392}
393
394static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
395{
396 return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
397}
398
399static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
400 loff_t ofs, size_t len)
401{
402 if (!mtd->_max_bad_blocks)
403 return -ENOTSUPP;
404
405 if (mtd->size < (len + ofs) || ofs < 0)
406 return -EINVAL;
407
408 return mtd->_max_bad_blocks(mtd, ofs, len);
409}
410
411int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
412 struct mtd_pairing_info *info);
413int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
414 const struct mtd_pairing_info *info);
415int mtd_pairing_groups(struct mtd_info *mtd);
416int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
417int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
418 void **virt, resource_size_t *phys);
419int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
420unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
421 unsigned long offset, unsigned long flags);
422int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
423 u_char *buf);
424int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
425 const u_char *buf);
426int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
427 const u_char *buf);
428
429int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
430int mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
431
432int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
433 struct otp_info *buf);
434int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
435 size_t *retlen, u_char *buf);
436int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
437 struct otp_info *buf);
438int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
439 size_t *retlen, u_char *buf);
440int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
441 size_t *retlen, u_char *buf);
442int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
443
444int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
445 unsigned long count, loff_t to, size_t *retlen);
446
447static inline void mtd_sync(struct mtd_info *mtd)
448{
449 if (mtd->_sync)
450 mtd->_sync(mtd);
451}
452
453int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
454int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
455int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
456int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
457int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
458int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
459
460static inline int mtd_suspend(struct mtd_info *mtd)
461{
462 return mtd->_suspend ? mtd->_suspend(mtd) : 0;
463}
464
465static inline void mtd_resume(struct mtd_info *mtd)
466{
467 if (mtd->_resume)
468 mtd->_resume(mtd);
469}
470
471static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
472{
473 if (mtd->erasesize_shift)
474 return sz >> mtd->erasesize_shift;
475 do_div(sz, mtd->erasesize);
476 return sz;
477}
478
479static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
480{
481 if (mtd->erasesize_shift)
482 return sz & mtd->erasesize_mask;
483 return do_div(sz, mtd->erasesize);
484}
485
486static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
487{
488 if (mtd->writesize_shift)
489 return sz >> mtd->writesize_shift;
490 do_div(sz, mtd->writesize);
491 return sz;
492}
493
494static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
495{
496 if (mtd->writesize_shift)
497 return sz & mtd->writesize_mask;
498 return do_div(sz, mtd->writesize);
499}
500
501static inline int mtd_wunit_per_eb(struct mtd_info *mtd)
502{
503 return mtd->erasesize / mtd->writesize;
504}
505
506static inline int mtd_offset_to_wunit(struct mtd_info *mtd, loff_t offs)
507{
508 return mtd_div_by_ws(mtd_mod_by_eb(offs, mtd), mtd);
509}
510
511static inline loff_t mtd_wunit_to_offset(struct mtd_info *mtd, loff_t base,
512 int wunit)
513{
514 return base + (wunit * mtd->writesize);
515}
516
517
518static inline int mtd_has_oob(const struct mtd_info *mtd)
519{
520 return mtd->_read_oob && mtd->_write_oob;
521}
522
523static inline int mtd_type_is_nand(const struct mtd_info *mtd)
524{
525 return mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH;
526}
527
528static inline int mtd_can_have_bb(const struct mtd_info *mtd)
529{
530 return !!mtd->_block_isbad;
531}
532
533
534
535struct mtd_partition;
536struct mtd_part_parser_data;
537
538extern int mtd_device_parse_register(struct mtd_info *mtd,
539 const char * const *part_probe_types,
540 struct mtd_part_parser_data *parser_data,
541 const struct mtd_partition *defparts,
542 int defnr_parts);
543#define mtd_device_register(master, parts, nr_parts) \
544 mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
545extern int mtd_device_unregister(struct mtd_info *master);
546extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
547extern int __get_mtd_device(struct mtd_info *mtd);
548extern void __put_mtd_device(struct mtd_info *mtd);
549extern struct mtd_info *get_mtd_device_nm(const char *name);
550extern void put_mtd_device(struct mtd_info *mtd);
551
552
553struct mtd_notifier {
554 void (*add)(struct mtd_info *mtd);
555 void (*remove)(struct mtd_info *mtd);
556 struct list_head list;
557};
558
559
560extern void register_mtd_user (struct mtd_notifier *new);
561extern int unregister_mtd_user (struct mtd_notifier *old);
562void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
563
564void mtd_erase_callback(struct erase_info *instr);
565
566static inline int mtd_is_bitflip(int err) {
567 return err == -EUCLEAN;
568}
569
570static inline int mtd_is_eccerr(int err) {
571 return err == -EBADMSG;
572}
573
574static inline int mtd_is_bitflip_or_eccerr(int err) {
575 return mtd_is_bitflip(err) || mtd_is_eccerr(err);
576}
577
578unsigned mtd_mmap_capabilities(struct mtd_info *mtd);
579
580#endif
581