mtdpart.c 19 KB

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