mtdpart.c 19 KB

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