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