1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Simple MTD partitioning layer
4 *
5 * Copyright © 2000 Nicolas Pitre <nico@fluxnic.net>
6 * Copyright © 2002 Thomas Gleixner <gleixner@linutronix.de>
7 * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
8 */
9
10#include <linux/module.h>
11#include <linux/types.h>
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/list.h>
15#include <linux/kmod.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/partitions.h>
18#include <linux/err.h>
19#include <linux/of.h>
20#include <linux/of_platform.h>
21
22#include "mtdcore.h"
23
24/*
25 * MTD methods which simply translate the effective address and pass through
26 * to the _real_ device.
27 */
28
29static inline void free_partition(struct mtd_info *mtd)
30{
31 kfree(objp: mtd->name);
32 kfree(objp: mtd);
33}
34
35void release_mtd_partition(struct mtd_info *mtd)
36{
37 WARN_ON(!list_empty(&mtd->part.node));
38 free_partition(mtd);
39}
40
41static struct mtd_info *allocate_partition(struct mtd_info *parent,
42 const struct mtd_partition *part,
43 int partno, uint64_t cur_offset)
44{
45 struct mtd_info *master = mtd_get_master(mtd: parent);
46 int wr_alignment = (parent->flags & MTD_NO_ERASE) ?
47 master->writesize : master->erasesize;
48 u64 parent_size = mtd_is_partition(mtd: parent) ?
49 parent->part.size : parent->size;
50 struct mtd_info *child;
51 u32 remainder;
52 char *name;
53 u64 tmp;
54
55 /* allocate the partition structure */
56 child = kzalloc(sizeof(*child), GFP_KERNEL);
57 name = kstrdup(s: part->name, GFP_KERNEL);
58 if (!name || !child) {
59 printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",
60 parent->name);
61 kfree(objp: name);
62 kfree(objp: child);
63 return ERR_PTR(error: -ENOMEM);
64 }
65
66 /* set up the MTD object for this partition */
67 child->type = parent->type;
68 child->part.flags = parent->flags & ~part->mask_flags;
69 child->part.flags |= part->add_flags;
70 child->flags = child->part.flags;
71 child->part.size = part->size;
72 child->writesize = parent->writesize;
73 child->writebufsize = parent->writebufsize;
74 child->oobsize = parent->oobsize;
75 child->oobavail = parent->oobavail;
76 child->subpage_sft = parent->subpage_sft;
77
78 child->name = name;
79 child->owner = parent->owner;
80
81 /* NOTE: Historically, we didn't arrange MTDs as a tree out of
82 * concern for showing the same data in multiple partitions.
83 * However, it is very useful to have the master node present,
84 * so the MTD_PARTITIONED_MASTER option allows that. The master
85 * will have device nodes etc only if this is set, so make the
86 * parent conditional on that option. Note, this is a way to
87 * distinguish between the parent and its partitions in sysfs.
88 */
89 child->dev.parent = &parent->dev;
90 child->dev.of_node = part->of_node;
91 child->parent = parent;
92 child->part.offset = part->offset;
93 INIT_LIST_HEAD(list: &child->partitions);
94
95 if (child->part.offset == MTDPART_OFS_APPEND)
96 child->part.offset = cur_offset;
97 if (child->part.offset == MTDPART_OFS_NXTBLK) {
98 tmp = cur_offset;
99 child->part.offset = cur_offset;
100 remainder = do_div(tmp, wr_alignment);
101 if (remainder) {
102 child->part.offset += wr_alignment - remainder;
103 printk(KERN_NOTICE "Moving partition %d: "
104 "0x%012llx -> 0x%012llx\n", partno,
105 (unsigned long long)cur_offset,
106 child->part.offset);
107 }
108 }
109 if (child->part.offset == MTDPART_OFS_RETAIN) {
110 child->part.offset = cur_offset;
111 if (parent_size - child->part.offset >= child->part.size) {
112 child->part.size = parent_size - child->part.offset -
113 child->part.size;
114 } else {
115 printk(KERN_ERR "mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n",
116 part->name, parent_size - child->part.offset,
117 child->part.size);
118 /* register to preserve ordering */
119 goto out_register;
120 }
121 }
122 if (child->part.size == MTDPART_SIZ_FULL)
123 child->part.size = parent_size - child->part.offset;
124
125 printk(KERN_NOTICE "0x%012llx-0x%012llx : \"%s\"\n",
126 child->part.offset, child->part.offset + child->part.size,
127 child->name);
128
129 /* let's do some sanity checks */
130 if (child->part.offset >= parent_size) {
131 /* let's register it anyway to preserve ordering */
132 child->part.offset = 0;
133 child->part.size = 0;
134
135 /* Initialize ->erasesize to make add_mtd_device() happy. */
136 child->erasesize = parent->erasesize;
137 printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n",
138 part->name);
139 goto out_register;
140 }
141 if (child->part.offset + child->part.size > parent->size) {
142 child->part.size = parent_size - child->part.offset;
143 printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n",
144 part->name, parent->name, child->part.size);
145 }
146
147 if (parent->numeraseregions > 1) {
148 /* Deal with variable erase size stuff */
149 int i, max = parent->numeraseregions;
150 u64 end = child->part.offset + child->part.size;
151 struct mtd_erase_region_info *regions = parent->eraseregions;
152
153 /* Find the first erase regions which is part of this
154 * partition. */
155 for (i = 0; i < max && regions[i].offset <= child->part.offset;
156 i++)
157 ;
158 /* The loop searched for the region _behind_ the first one */
159 if (i > 0)
160 i--;
161
162 /* Pick biggest erasesize */
163 for (; i < max && regions[i].offset < end; i++) {
164 if (child->erasesize < regions[i].erasesize)
165 child->erasesize = regions[i].erasesize;
166 }
167 BUG_ON(child->erasesize == 0);
168 } else {
169 /* Single erase size */
170 child->erasesize = master->erasesize;
171 }
172
173 /*
174 * Child erasesize might differ from the parent one if the parent
175 * exposes several regions with different erasesize. Adjust
176 * wr_alignment accordingly.
177 */
178 if (!(child->flags & MTD_NO_ERASE))
179 wr_alignment = child->erasesize;
180
181 tmp = mtd_get_master_ofs(mtd: child, ofs: 0);
182 remainder = do_div(tmp, wr_alignment);
183 if ((child->flags & MTD_WRITEABLE) && remainder) {
184 /* Doesn't start on a boundary of major erase size */
185 /* FIXME: Let it be writable if it is on a boundary of
186 * _minor_ erase size though */
187 child->flags &= ~MTD_WRITEABLE;
188 printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n",
189 part->name);
190 }
191
192 tmp = mtd_get_master_ofs(mtd: child, ofs: 0) + child->part.size;
193 remainder = do_div(tmp, wr_alignment);
194 if ((child->flags & MTD_WRITEABLE) && remainder) {
195 child->flags &= ~MTD_WRITEABLE;
196 printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n",
197 part->name);
198 }
199
200 child->size = child->part.size;
201 child->ecc_step_size = parent->ecc_step_size;
202 child->ecc_strength = parent->ecc_strength;
203 child->bitflip_threshold = parent->bitflip_threshold;
204
205 if (master->_block_isbad) {
206 uint64_t offs = 0;
207
208 while (offs < child->part.size) {
209 if (mtd_block_isreserved(mtd: child, ofs: offs))
210 child->ecc_stats.bbtblocks++;
211 else if (mtd_block_isbad(mtd: child, ofs: offs))
212 child->ecc_stats.badblocks++;
213 offs += child->erasesize;
214 }
215 }
216
217out_register:
218 return child;
219}
220
221static ssize_t offset_show(struct device *dev,
222 struct device_attribute *attr, char *buf)
223{
224 struct mtd_info *mtd = dev_get_drvdata(dev);
225
226 return sysfs_emit(buf, fmt: "%lld\n", mtd->part.offset);
227}
228static DEVICE_ATTR_RO(offset); /* mtd partition offset */
229
230static const struct attribute *mtd_partition_attrs[] = {
231 &dev_attr_offset.attr,
232 NULL
233};
234
235static int mtd_add_partition_attrs(struct mtd_info *new)
236{
237 int ret = sysfs_create_files(kobj: &new->dev.kobj, attr: mtd_partition_attrs);
238 if (ret)
239 printk(KERN_WARNING
240 "mtd: failed to create partition attrs, err=%d\n", ret);
241 return ret;
242}
243
244int mtd_add_partition(struct mtd_info *parent, const char *name,
245 long long offset, long long length, struct mtd_info **out)
246{
247 struct mtd_info *master = mtd_get_master(mtd: parent);
248 u64 parent_size = mtd_is_partition(mtd: parent) ?
249 parent->part.size : parent->size;
250 struct mtd_partition part;
251 struct mtd_info *child;
252 int ret = 0;
253
254 /* the direct offset is expected */
255 if (offset == MTDPART_OFS_APPEND ||
256 offset == MTDPART_OFS_NXTBLK)
257 return -EINVAL;
258
259 if (length == MTDPART_SIZ_FULL)
260 length = parent_size - offset;
261
262 if (length <= 0)
263 return -EINVAL;
264
265 memset(&part, 0, sizeof(part));
266 part.name = name;
267 part.size = length;
268 part.offset = offset;
269
270 child = allocate_partition(parent, part: &part, partno: -1, cur_offset: offset);
271 if (IS_ERR(ptr: child))
272 return PTR_ERR(ptr: child);
273
274 mutex_lock(&master->master.partitions_lock);
275 list_add_tail(new: &child->part.node, head: &parent->partitions);
276 mutex_unlock(lock: &master->master.partitions_lock);
277
278 ret = add_mtd_device(mtd: child, partitioned: true);
279 if (ret)
280 goto err_remove_part;
281
282 mtd_add_partition_attrs(new: child);
283
284 if (out)
285 *out = child;
286
287 return 0;
288
289err_remove_part:
290 mutex_lock(&master->master.partitions_lock);
291 list_del(entry: &child->part.node);
292 mutex_unlock(lock: &master->master.partitions_lock);
293
294 free_partition(mtd: child);
295
296 return ret;
297}
298EXPORT_SYMBOL_GPL(mtd_add_partition);
299
300/**
301 * __mtd_del_partition - delete MTD partition
302 *
303 * @mtd: MTD structure to be deleted
304 *
305 * This function must be called with the partitions mutex locked.
306 */
307static int __mtd_del_partition(struct mtd_info *mtd)
308{
309 struct mtd_info *child, *next;
310 int err;
311
312 list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {
313 err = __mtd_del_partition(mtd: child);
314 if (err)
315 return err;
316 }
317
318 sysfs_remove_files(kobj: &mtd->dev.kobj, attr: mtd_partition_attrs);
319
320 list_del_init(entry: &mtd->part.node);
321 err = del_mtd_device(mtd);
322 if (err)
323 return err;
324
325 return 0;
326}
327
328/*
329 * This function unregisters and destroy all slave MTD objects which are
330 * attached to the given MTD object, recursively.
331 */
332static int __del_mtd_partitions(struct mtd_info *mtd)
333{
334 struct mtd_info *child, *next;
335 int ret, err = 0;
336
337 list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {
338 if (mtd_has_partitions(mtd: child))
339 __del_mtd_partitions(mtd: child);
340
341 pr_info("Deleting %s MTD partition\n", child->name);
342 list_del_init(entry: &child->part.node);
343 ret = del_mtd_device(mtd: child);
344 if (ret < 0) {
345 pr_err("Error when deleting partition \"%s\" (%d)\n",
346 child->name, ret);
347 err = ret;
348 continue;
349 }
350 }
351
352 return err;
353}
354
355int del_mtd_partitions(struct mtd_info *mtd)
356{
357 struct mtd_info *master = mtd_get_master(mtd);
358 int ret;
359
360 pr_info("Deleting MTD partitions on \"%s\":\n", mtd->name);
361
362 mutex_lock(&master->master.partitions_lock);
363 ret = __del_mtd_partitions(mtd);
364 mutex_unlock(lock: &master->master.partitions_lock);
365
366 return ret;
367}
368
369int mtd_del_partition(struct mtd_info *mtd, int partno)
370{
371 struct mtd_info *child, *master = mtd_get_master(mtd);
372 int ret = -EINVAL;
373
374 mutex_lock(&master->master.partitions_lock);
375 list_for_each_entry(child, &mtd->partitions, part.node) {
376 if (child->index == partno) {
377 ret = __mtd_del_partition(mtd: child);
378 break;
379 }
380 }
381 mutex_unlock(lock: &master->master.partitions_lock);
382
383 return ret;
384}
385EXPORT_SYMBOL_GPL(mtd_del_partition);
386
387/*
388 * This function, given a parent MTD object and a partition table, creates
389 * and registers the child MTD objects which are bound to the parent according
390 * to the partition definitions.
391 *
392 * For historical reasons, this function's caller only registers the parent
393 * if the MTD_PARTITIONED_MASTER config option is set.
394 */
395
396int add_mtd_partitions(struct mtd_info *parent,
397 const struct mtd_partition *parts,
398 int nbparts)
399{
400 struct mtd_info *child, *master = mtd_get_master(mtd: parent);
401 uint64_t cur_offset = 0;
402 int i, ret;
403
404 printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n",
405 nbparts, parent->name);
406
407 for (i = 0; i < nbparts; i++) {
408 child = allocate_partition(parent, part: parts + i, partno: i, cur_offset);
409 if (IS_ERR(ptr: child)) {
410 ret = PTR_ERR(ptr: child);
411 goto err_del_partitions;
412 }
413
414 mutex_lock(&master->master.partitions_lock);
415 list_add_tail(new: &child->part.node, head: &parent->partitions);
416 mutex_unlock(lock: &master->master.partitions_lock);
417
418 ret = add_mtd_device(mtd: child, partitioned: true);
419 if (ret) {
420 mutex_lock(&master->master.partitions_lock);
421 list_del(entry: &child->part.node);
422 mutex_unlock(lock: &master->master.partitions_lock);
423
424 free_partition(mtd: child);
425 goto err_del_partitions;
426 }
427
428 mtd_add_partition_attrs(new: child);
429
430 /* Look for subpartitions */
431 ret = parse_mtd_partitions(master: child, types: parts[i].types, NULL);
432 if (ret < 0) {
433 pr_err("Failed to parse subpartitions: %d\n", ret);
434 goto err_del_partitions;
435 }
436
437 cur_offset = child->part.offset + child->part.size;
438 }
439
440 return 0;
441
442err_del_partitions:
443 del_mtd_partitions(mtd: master);
444
445 return ret;
446}
447
448static DEFINE_SPINLOCK(part_parser_lock);
449static LIST_HEAD(part_parsers);
450
451static struct mtd_part_parser *mtd_part_parser_get(const char *name)
452{
453 struct mtd_part_parser *p, *ret = NULL;
454
455 spin_lock(lock: &part_parser_lock);
456
457 list_for_each_entry(p, &part_parsers, list)
458 if (!strcmp(p->name, name) && try_module_get(module: p->owner)) {
459 ret = p;
460 break;
461 }
462
463 spin_unlock(lock: &part_parser_lock);
464
465 return ret;
466}
467
468static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
469{
470 module_put(module: p->owner);
471}
472
473/*
474 * Many partition parsers just expected the core to kfree() all their data in
475 * one chunk. Do that by default.
476 */
477static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts,
478 int nr_parts)
479{
480 kfree(objp: pparts);
481}
482
483int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner)
484{
485 p->owner = owner;
486
487 if (!p->cleanup)
488 p->cleanup = &mtd_part_parser_cleanup_default;
489
490 spin_lock(lock: &part_parser_lock);
491 list_add(new: &p->list, head: &part_parsers);
492 spin_unlock(lock: &part_parser_lock);
493
494 return 0;
495}
496EXPORT_SYMBOL_GPL(__register_mtd_parser);
497
498void deregister_mtd_parser(struct mtd_part_parser *p)
499{
500 spin_lock(lock: &part_parser_lock);
501 list_del(entry: &p->list);
502 spin_unlock(lock: &part_parser_lock);
503}
504EXPORT_SYMBOL_GPL(deregister_mtd_parser);
505
506/*
507 * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
508 * are changing this array!
509 */
510static const char * const default_mtd_part_types[] = {
511 "cmdlinepart",
512 "ofpart",
513 NULL
514};
515
516/* Check DT only when looking for subpartitions. */
517static const char * const default_subpartition_types[] = {
518 "ofpart",
519 NULL
520};
521
522static int mtd_part_do_parse(struct mtd_part_parser *parser,
523 struct mtd_info *master,
524 struct mtd_partitions *pparts,
525 struct mtd_part_parser_data *data)
526{
527 int ret;
528
529 ret = (*parser->parse_fn)(master, &pparts->parts, data);
530 pr_debug("%s: parser %s: %i\n", master->name, parser->name, ret);
531 if (ret <= 0)
532 return ret;
533
534 pr_notice("%d %s partitions found on MTD device %s\n", ret,
535 parser->name, master->name);
536
537 pparts->nr_parts = ret;
538 pparts->parser = parser;
539
540 return ret;
541}
542
543/**
544 * mtd_part_get_compatible_parser - find MTD parser by a compatible string
545 *
546 * @compat: compatible string describing partitions in a device tree
547 *
548 * MTD parsers can specify supported partitions by providing a table of
549 * compatibility strings. This function finds a parser that advertises support
550 * for a passed value of "compatible".
551 */
552static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
553{
554 struct mtd_part_parser *p, *ret = NULL;
555
556 spin_lock(lock: &part_parser_lock);
557
558 list_for_each_entry(p, &part_parsers, list) {
559 const struct of_device_id *matches;
560
561 matches = p->of_match_table;
562 if (!matches)
563 continue;
564
565 for (; matches->compatible[0]; matches++) {
566 if (!strcmp(matches->compatible, compat) &&
567 try_module_get(module: p->owner)) {
568 ret = p;
569 break;
570 }
571 }
572
573 if (ret)
574 break;
575 }
576
577 spin_unlock(lock: &part_parser_lock);
578
579 return ret;
580}
581
582static int mtd_part_of_parse(struct mtd_info *master,
583 struct mtd_partitions *pparts)
584{
585 struct mtd_part_parser *parser;
586 struct device_node *np;
587 struct device_node *child;
588 struct property *prop;
589 struct device *dev;
590 const char *compat;
591 const char *fixed = "fixed-partitions";
592 int ret, err = 0;
593
594 dev = &master->dev;
595
596 np = mtd_get_of_node(mtd: master);
597 if (mtd_is_partition(mtd: master))
598 of_node_get(node: np);
599 else
600 np = of_get_child_by_name(node: np, name: "partitions");
601
602 /*
603 * Don't create devices that are added to a bus but will never get
604 * probed. That'll cause fw_devlink to block probing of consumers of
605 * this partition until the partition device is probed.
606 */
607 for_each_child_of_node(np, child)
608 if (of_device_is_compatible(device: child, "nvmem-cells"))
609 of_node_set_flag(n: child, OF_POPULATED);
610
611 of_property_for_each_string(np, "compatible", prop, compat) {
612 parser = mtd_part_get_compatible_parser(compat);
613 if (!parser)
614 continue;
615 ret = mtd_part_do_parse(parser, master, pparts, NULL);
616 if (ret > 0) {
617 of_platform_populate(root: np, NULL, NULL, parent: dev);
618 of_node_put(node: np);
619 return ret;
620 }
621 mtd_part_parser_put(p: parser);
622 if (ret < 0 && !err)
623 err = ret;
624 }
625 of_platform_populate(root: np, NULL, NULL, parent: dev);
626 of_node_put(node: np);
627
628 /*
629 * For backward compatibility we have to try the "fixed-partitions"
630 * parser. It supports old DT format with partitions specified as a
631 * direct subnodes of a flash device DT node without any compatibility
632 * specified we could match.
633 */
634 parser = mtd_part_parser_get(name: fixed);
635 if (!parser && !request_module("%s", fixed))
636 parser = mtd_part_parser_get(name: fixed);
637 if (parser) {
638 ret = mtd_part_do_parse(parser, master, pparts, NULL);
639 if (ret > 0)
640 return ret;
641 mtd_part_parser_put(p: parser);
642 if (ret < 0 && !err)
643 err = ret;
644 }
645
646 return err;
647}
648
649/**
650 * parse_mtd_partitions - parse and register MTD partitions
651 *
652 * @master: the master partition (describes whole MTD device)
653 * @types: names of partition parsers to try or %NULL
654 * @data: MTD partition parser-specific data
655 *
656 * This function tries to find & register partitions on MTD device @master. It
657 * uses MTD partition parsers, specified in @types. However, if @types is %NULL,
658 * then the default list of parsers is used. The default list contains only the
659 * "cmdlinepart" and "ofpart" parsers ATM.
660 * Note: If there are more then one parser in @types, the kernel only takes the
661 * partitions parsed out by the first parser.
662 *
663 * This function may return:
664 * o a negative error code in case of failure
665 * o number of found partitions otherwise
666 */
667int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
668 struct mtd_part_parser_data *data)
669{
670 struct mtd_partitions pparts = { };
671 struct mtd_part_parser *parser;
672 int ret, err = 0;
673
674 if (!types)
675 types = mtd_is_partition(mtd: master) ? default_subpartition_types :
676 default_mtd_part_types;
677
678 for ( ; *types; types++) {
679 /*
680 * ofpart is a special type that means OF partitioning info
681 * should be used. It requires a bit different logic so it is
682 * handled in a separated function.
683 */
684 if (!strcmp(*types, "ofpart")) {
685 ret = mtd_part_of_parse(master, pparts: &pparts);
686 } else {
687 pr_debug("%s: parsing partitions %s\n", master->name,
688 *types);
689 parser = mtd_part_parser_get(name: *types);
690 if (!parser && !request_module("%s", *types))
691 parser = mtd_part_parser_get(name: *types);
692 if (!parser)
693 continue;
694 pr_debug("%s: got parser %s\n", master->name, parser->name);
695 ret = mtd_part_do_parse(parser, master, pparts: &pparts, data);
696 if (ret <= 0)
697 mtd_part_parser_put(p: parser);
698 }
699 /* Found partitions! */
700 if (ret > 0) {
701 err = add_mtd_partitions(parent: master, parts: pparts.parts,
702 nbparts: pparts.nr_parts);
703 mtd_part_parser_cleanup(parts: &pparts);
704 return err ? err : pparts.nr_parts;
705 }
706 /*
707 * Stash the first error we see; only report it if no parser
708 * succeeds
709 */
710 if (ret < 0 && !err)
711 err = ret;
712 }
713
714 return err;
715}
716
717void mtd_part_parser_cleanup(struct mtd_partitions *parts)
718{
719 const struct mtd_part_parser *parser;
720
721 if (!parts)
722 return;
723
724 parser = parts->parser;
725 if (parser) {
726 if (parser->cleanup)
727 parser->cleanup(parts->parts, parts->nr_parts);
728
729 mtd_part_parser_put(p: parser);
730 }
731}
732
733/* Returns the size of the entire flash chip */
734uint64_t mtd_get_device_size(const struct mtd_info *mtd)
735{
736 struct mtd_info *master = mtd_get_master(mtd: (struct mtd_info *)mtd);
737
738 return master->size;
739}
740EXPORT_SYMBOL_GPL(mtd_get_device_size);
741

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of linux/drivers/mtd/mtdpart.c