uboot/drivers/mtd/mtdpart.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   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
  11#ifndef __UBOOT__
  12#include <log.h>
  13#include <dm/devres.h>
  14#include <linux/module.h>
  15#include <linux/types.h>
  16#include <linux/kernel.h>
  17#include <linux/slab.h>
  18#include <linux/list.h>
  19#include <linux/kmod.h>
  20#endif
  21
  22#include <common.h>
  23#include <malloc.h>
  24#include <linux/bug.h>
  25#include <linux/errno.h>
  26#include <linux/compat.h>
  27#include <ubi_uboot.h>
  28
  29#include <linux/mtd/mtd.h>
  30#include <linux/mtd/partitions.h>
  31#include <linux/err.h>
  32#include <linux/sizes.h>
  33
  34#include "mtdcore.h"
  35
  36#ifndef __UBOOT__
  37static DEFINE_MUTEX(mtd_partitions_mutex);
  38#else
  39DEFINE_MUTEX(mtd_partitions_mutex);
  40#endif
  41
  42#ifdef __UBOOT__
  43/* from mm/util.c */
  44
  45/**
  46 * kstrdup - allocate space for and copy an existing string
  47 * @s: the string to duplicate
  48 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
  49 */
  50char *kstrdup(const char *s, gfp_t gfp)
  51{
  52        size_t len;
  53        char *buf;
  54
  55        if (!s)
  56                return NULL;
  57
  58        len = strlen(s) + 1;
  59        buf = kmalloc(len, gfp);
  60        if (buf)
  61                memcpy(buf, s, len);
  62        return buf;
  63}
  64#endif
  65
  66#define MTD_SIZE_REMAINING              (~0LLU)
  67#define MTD_OFFSET_NOT_SPECIFIED        (~0LLU)
  68
  69bool mtd_partitions_used(struct mtd_info *master)
  70{
  71        struct mtd_info *slave;
  72
  73        list_for_each_entry(slave, &master->partitions, node) {
  74                if (slave->usecount)
  75                        return true;
  76        }
  77
  78        return false;
  79}
  80
  81/**
  82 * mtd_parse_partition - Parse @mtdparts partition definition, fill @partition
  83 *                       with it and update the @mtdparts string pointer.
  84 *
  85 * The partition name is allocated and must be freed by the caller.
  86 *
  87 * This function is widely inspired from part_parse (mtdparts.c).
  88 *
  89 * @mtdparts: String describing the partition with mtdparts command syntax
  90 * @partition: MTD partition structure to fill
  91 *
  92 * Return: 0 on success, an error otherwise.
  93 */
  94static int mtd_parse_partition(const char **_mtdparts,
  95                               struct mtd_partition *partition)
  96{
  97        const char *mtdparts = *_mtdparts;
  98        const char *name = NULL;
  99        int name_len;
 100        char *buf;
 101
 102        /* Ensure the partition structure is empty */
 103        memset(partition, 0, sizeof(struct mtd_partition));
 104
 105        /* Fetch the partition size */
 106        if (*mtdparts == '-') {
 107                /* Assign all remaining space to this partition */
 108                partition->size = MTD_SIZE_REMAINING;
 109                mtdparts++;
 110        } else {
 111                partition->size = ustrtoull(mtdparts, (char **)&mtdparts, 0);
 112                if (partition->size < SZ_4K) {
 113                        printf("Minimum partition size 4kiB, %lldB requested\n",
 114                               partition->size);
 115                        return -EINVAL;
 116                }
 117        }
 118
 119        /* Check for the offset */
 120        partition->offset = MTD_OFFSET_NOT_SPECIFIED;
 121        if (*mtdparts == '@') {
 122                mtdparts++;
 123                partition->offset = ustrtoull(mtdparts, (char **)&mtdparts, 0);
 124        }
 125
 126        /* Now look for the name */
 127        if (*mtdparts == '(') {
 128                name = ++mtdparts;
 129                mtdparts = strchr(name, ')');
 130                if (!mtdparts) {
 131                        printf("No closing ')' found in partition name\n");
 132                        return -EINVAL;
 133                }
 134                name_len = mtdparts - name + 1;
 135                if ((name_len - 1) == 0) {
 136                        printf("Empty partition name\n");
 137                        return -EINVAL;
 138                }
 139                mtdparts++;
 140        } else {
 141                /* Name will be of the form size@offset */
 142                name_len = 22;
 143        }
 144
 145        /* Check if the partition is read-only */
 146        if (strncmp(mtdparts, "ro", 2) == 0) {
 147                partition->mask_flags |= MTD_WRITEABLE;
 148                mtdparts += 2;
 149        }
 150
 151        /* Check for a potential next partition definition */
 152        if (*mtdparts == ',') {
 153                if (partition->size == MTD_SIZE_REMAINING) {
 154                        printf("No partitions allowed after a fill-up\n");
 155                        return -EINVAL;
 156                }
 157                ++mtdparts;
 158        } else if ((*mtdparts == ';') || (*mtdparts == '\0')) {
 159                /* NOP */
 160        } else {
 161                printf("Unexpected character '%c' in mtdparts\n", *mtdparts);
 162                return -EINVAL;
 163        }
 164
 165        /*
 166         * Allocate a buffer for the name and either copy the provided name or
 167         * auto-generate it with the form 'size@offset'.
 168         */
 169        buf = malloc(name_len);
 170        if (!buf)
 171                return -ENOMEM;
 172
 173        if (name)
 174                strncpy(buf, name, name_len - 1);
 175        else
 176                snprintf(buf, name_len, "0x%08llx@0x%08llx",
 177                         partition->size, partition->offset);
 178
 179        buf[name_len - 1] = '\0';
 180        partition->name = buf;
 181
 182        *_mtdparts = mtdparts;
 183
 184        return 0;
 185}
 186
 187/**
 188 * mtd_parse_partitions - Create a partition array from an mtdparts definition
 189 *
 190 * Stateless function that takes a @parent MTD device, a string @_mtdparts
 191 * describing the partitions (with the "mtdparts" command syntax) and creates
 192 * the corresponding MTD partition structure array @_parts. Both the name and
 193 * the structure partition itself must be freed freed, the caller may use
 194 * @mtd_free_parsed_partitions() for this purpose.
 195 *
 196 * @parent: MTD device which contains the partitions
 197 * @_mtdparts: Pointer to a string describing the partitions with "mtdparts"
 198 *             command syntax.
 199 * @_parts: Allocated array containing the partitions, must be freed by the
 200 *          caller.
 201 * @_nparts: Size of @_parts array.
 202 *
 203 * Return: 0 on success, an error otherwise.
 204 */
 205int mtd_parse_partitions(struct mtd_info *parent, const char **_mtdparts,
 206                         struct mtd_partition **_parts, int *_nparts)
 207{
 208        struct mtd_partition partition = {}, *parts;
 209        const char *mtdparts = *_mtdparts;
 210        uint64_t cur_off = 0, cur_sz = 0;
 211        int nparts = 0;
 212        int ret, idx;
 213        u64 sz;
 214
 215        /* First, iterate over the partitions until we know their number */
 216        while (mtdparts[0] != '\0' && mtdparts[0] != ';') {
 217                ret = mtd_parse_partition(&mtdparts, &partition);
 218                if (ret)
 219                        return ret;
 220
 221                free((char *)partition.name);
 222                nparts++;
 223        }
 224
 225        /* Allocate an array of partitions to give back to the caller */
 226        parts = malloc(sizeof(*parts) * nparts);
 227        if (!parts) {
 228                printf("Not enough space to save partitions meta-data\n");
 229                return -ENOMEM;
 230        }
 231
 232        /* Iterate again over each partition to save the data in our array */
 233        for (idx = 0; idx < nparts; idx++) {
 234                ret = mtd_parse_partition(_mtdparts, &parts[idx]);
 235                if (ret)
 236                        return ret;
 237
 238                if (parts[idx].size == MTD_SIZE_REMAINING)
 239                        parts[idx].size = parent->size - cur_sz;
 240                cur_sz += parts[idx].size;
 241
 242                sz = parts[idx].size;
 243                if (sz < parent->writesize || do_div(sz, parent->writesize)) {
 244                        printf("Partition size must be a multiple of %d\n",
 245                               parent->writesize);
 246                        return -EINVAL;
 247                }
 248
 249                if (parts[idx].offset == MTD_OFFSET_NOT_SPECIFIED)
 250                        parts[idx].offset = cur_off;
 251                cur_off += parts[idx].size;
 252
 253                parts[idx].ecclayout = parent->ecclayout;
 254        }
 255
 256        /* Offset by one mtdparts to point to the next device if any */
 257        if (*_mtdparts[0] == ';')
 258                (*_mtdparts)++;
 259
 260        *_parts = parts;
 261        *_nparts = nparts;
 262
 263        return 0;
 264}
 265
 266/**
 267 * mtd_free_parsed_partitions - Free dynamically allocated partitions
 268 *
 269 * Each successful call to @mtd_parse_partitions must be followed by a call to
 270 * @mtd_free_parsed_partitions to free any allocated array during the parsing
 271 * process.
 272 *
 273 * @parts: Array containing the partitions that will be freed.
 274 * @nparts: Size of @parts array.
 275 */
 276void mtd_free_parsed_partitions(struct mtd_partition *parts,
 277                                unsigned int nparts)
 278{
 279        int i;
 280
 281        for (i = 0; i < nparts; i++)
 282                free((char *)parts[i].name);
 283
 284        free(parts);
 285}
 286
 287/*
 288 * MTD methods which simply translate the effective address and pass through
 289 * to the _real_ device.
 290 */
 291
 292static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
 293                size_t *retlen, u_char *buf)
 294{
 295        struct mtd_ecc_stats stats;
 296        int res;
 297
 298        stats = mtd->parent->ecc_stats;
 299        res = mtd->parent->_read(mtd->parent, from + mtd->offset, len,
 300                                 retlen, buf);
 301        if (unlikely(mtd_is_eccerr(res)))
 302                mtd->ecc_stats.failed +=
 303                        mtd->parent->ecc_stats.failed - stats.failed;
 304        else
 305                mtd->ecc_stats.corrected +=
 306                        mtd->parent->ecc_stats.corrected - stats.corrected;
 307        return res;
 308}
 309
 310#ifndef __UBOOT__
 311static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
 312                size_t *retlen, void **virt, resource_size_t *phys)
 313{
 314        return mtd->parent->_point(mtd->parent, from + mtd->offset, len,
 315                                   retlen, virt, phys);
 316}
 317
 318static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 319{
 320        return mtd->parent->_unpoint(mtd->parent, from + mtd->offset, len);
 321}
 322#endif
 323
 324static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
 325                                            unsigned long len,
 326                                            unsigned long offset,
 327                                            unsigned long flags)
 328{
 329        offset += mtd->offset;
 330        return mtd->parent->_get_unmapped_area(mtd->parent, len, offset, flags);
 331}
 332
 333static int part_read_oob(struct mtd_info *mtd, loff_t from,
 334                struct mtd_oob_ops *ops)
 335{
 336        int res;
 337
 338        if (from >= mtd->size)
 339                return -EINVAL;
 340        if (ops->datbuf && from + ops->len > mtd->size)
 341                return -EINVAL;
 342
 343        /*
 344         * If OOB is also requested, make sure that we do not read past the end
 345         * of this partition.
 346         */
 347        if (ops->oobbuf) {
 348                size_t len, pages;
 349
 350                if (ops->mode == MTD_OPS_AUTO_OOB)
 351                        len = mtd->oobavail;
 352                else
 353                        len = mtd->oobsize;
 354                pages = mtd_div_by_ws(mtd->size, mtd);
 355                pages -= mtd_div_by_ws(from, mtd);
 356                if (ops->ooboffs + ops->ooblen > pages * len)
 357                        return -EINVAL;
 358        }
 359
 360        res = mtd->parent->_read_oob(mtd->parent, from + mtd->offset, ops);
 361        if (unlikely(res)) {
 362                if (mtd_is_bitflip(res))
 363                        mtd->ecc_stats.corrected++;
 364                if (mtd_is_eccerr(res))
 365                        mtd->ecc_stats.failed++;
 366        }
 367        return res;
 368}
 369
 370static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
 371                size_t len, size_t *retlen, u_char *buf)
 372{
 373        return mtd->parent->_read_user_prot_reg(mtd->parent, from, len,
 374                                                retlen, buf);
 375}
 376
 377static int part_get_user_prot_info(struct mtd_info *mtd, size_t len,
 378                                   size_t *retlen, struct otp_info *buf)
 379{
 380        return mtd->parent->_get_user_prot_info(mtd->parent, len, retlen,
 381                                                buf);
 382}
 383
 384static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
 385                size_t len, size_t *retlen, u_char *buf)
 386{
 387        return mtd->parent->_read_fact_prot_reg(mtd->parent, from, len,
 388                                                retlen, buf);
 389}
 390
 391static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len,
 392                                   size_t *retlen, struct otp_info *buf)
 393{
 394        return mtd->parent->_get_fact_prot_info(mtd->parent, len, retlen,
 395                                                buf);
 396}
 397
 398static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
 399                size_t *retlen, const u_char *buf)
 400{
 401        return mtd->parent->_write(mtd->parent, to + mtd->offset, len,
 402                                   retlen, buf);
 403}
 404
 405static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 406                size_t *retlen, const u_char *buf)
 407{
 408        return mtd->parent->_panic_write(mtd->parent, to + mtd->offset, len,
 409                                         retlen, buf);
 410}
 411
 412static int part_write_oob(struct mtd_info *mtd, loff_t to,
 413                struct mtd_oob_ops *ops)
 414{
 415        if (to >= mtd->size)
 416                return -EINVAL;
 417        if (ops->datbuf && to + ops->len > mtd->size)
 418                return -EINVAL;
 419        return mtd->parent->_write_oob(mtd->parent, to + mtd->offset, ops);
 420}
 421
 422static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
 423                size_t len, size_t *retlen, u_char *buf)
 424{
 425        return mtd->parent->_write_user_prot_reg(mtd->parent, from, len,
 426                                                 retlen, buf);
 427}
 428
 429static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
 430                size_t len)
 431{
 432        return mtd->parent->_lock_user_prot_reg(mtd->parent, from, len);
 433}
 434
 435#ifndef __UBOOT__
 436static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
 437                unsigned long count, loff_t to, size_t *retlen)
 438{
 439        return mtd->parent->_writev(mtd->parent, vecs, count,
 440                                    to + mtd->offset, retlen);
 441}
 442#endif
 443
 444static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
 445{
 446        int ret;
 447
 448        instr->addr += mtd->offset;
 449
 450        ret = mtd->parent->_erase(mtd->parent, instr);
 451        if (ret && instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
 452                instr->fail_addr -= mtd->offset;
 453
 454        instr->addr -= mtd->offset;
 455
 456        return ret;
 457}
 458
 459static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 460{
 461        return mtd->parent->_lock(mtd->parent, ofs + mtd->offset, len);
 462}
 463
 464static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 465{
 466        return mtd->parent->_unlock(mtd->parent, ofs + mtd->offset, len);
 467}
 468
 469static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 470{
 471        return mtd->parent->_is_locked(mtd->parent, ofs + mtd->offset, len);
 472}
 473
 474static void part_sync(struct mtd_info *mtd)
 475{
 476        mtd->parent->_sync(mtd->parent);
 477}
 478
 479#ifndef __UBOOT__
 480static int part_suspend(struct mtd_info *mtd)
 481{
 482        return mtd->parent->_suspend(mtd->parent);
 483}
 484
 485static void part_resume(struct mtd_info *mtd)
 486{
 487        mtd->parent->_resume(mtd->parent);
 488}
 489#endif
 490
 491static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs)
 492{
 493        ofs += mtd->offset;
 494        return mtd->parent->_block_isreserved(mtd->parent, ofs);
 495}
 496
 497static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
 498{
 499        ofs += mtd->offset;
 500        return mtd->parent->_block_isbad(mtd->parent, ofs);
 501}
 502
 503static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
 504{
 505        int res;
 506
 507        ofs += mtd->offset;
 508        res = mtd->parent->_block_markbad(mtd->parent, ofs);
 509        if (!res)
 510                mtd->ecc_stats.badblocks++;
 511        return res;
 512}
 513
 514static inline void free_partition(struct mtd_info *p)
 515{
 516        kfree(p->name);
 517        kfree(p);
 518}
 519
 520/*
 521 * This function unregisters and destroy all slave MTD objects which are
 522 * attached to the given master MTD object, recursively.
 523 */
 524static int do_del_mtd_partitions(struct mtd_info *master)
 525{
 526        struct mtd_info *slave, *next;
 527        int ret, err = 0;
 528
 529        list_for_each_entry_safe(slave, next, &master->partitions, node) {
 530                if (mtd_has_partitions(slave))
 531                        del_mtd_partitions(slave);
 532
 533                debug("Deleting %s MTD partition\n", slave->name);
 534                ret = del_mtd_device(slave);
 535                if (ret < 0) {
 536                        printf("Error when deleting partition \"%s\" (%d)\n",
 537                               slave->name, ret);
 538                        err = ret;
 539                        continue;
 540                }
 541
 542                list_del(&slave->node);
 543                free_partition(slave);
 544        }
 545
 546        return err;
 547}
 548
 549int del_mtd_partitions(struct mtd_info *master)
 550{
 551        int ret;
 552
 553        debug("Deleting MTD partitions on \"%s\":\n", master->name);
 554
 555        mutex_lock(&mtd_partitions_mutex);
 556        ret = do_del_mtd_partitions(master);
 557        mutex_unlock(&mtd_partitions_mutex);
 558
 559        return ret;
 560}
 561
 562static struct mtd_info *allocate_partition(struct mtd_info *master,
 563                                           const struct mtd_partition *part,
 564                                           int partno, uint64_t cur_offset)
 565{
 566        struct mtd_info *slave;
 567        char *name;
 568
 569        /* allocate the partition structure */
 570        slave = kzalloc(sizeof(*slave), GFP_KERNEL);
 571        name = kstrdup(part->name, GFP_KERNEL);
 572        if (!name || !slave) {
 573                printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",
 574                       master->name);
 575                kfree(name);
 576                kfree(slave);
 577                return ERR_PTR(-ENOMEM);
 578        }
 579
 580        /* set up the MTD object for this partition */
 581        slave->type = master->type;
 582        slave->flags = master->flags & ~part->mask_flags;
 583        slave->size = part->size;
 584        slave->writesize = master->writesize;
 585        slave->writebufsize = master->writebufsize;
 586        slave->oobsize = master->oobsize;
 587        slave->oobavail = master->oobavail;
 588        slave->subpage_sft = master->subpage_sft;
 589
 590        slave->name = name;
 591        slave->owner = master->owner;
 592#ifndef __UBOOT__
 593        slave->backing_dev_info = master->backing_dev_info;
 594
 595        /* NOTE:  we don't arrange MTDs as a tree; it'd be error-prone
 596         * to have the same data be in two different partitions.
 597         */
 598        slave->dev.parent = master->dev.parent;
 599#endif
 600
 601        if (master->_read)
 602                slave->_read = part_read;
 603        if (master->_write)
 604                slave->_write = part_write;
 605
 606        if (master->_panic_write)
 607                slave->_panic_write = part_panic_write;
 608
 609#ifndef __UBOOT__
 610        if (master->_point && master->_unpoint) {
 611                slave->_point = part_point;
 612                slave->_unpoint = part_unpoint;
 613        }
 614#endif
 615
 616        if (master->_get_unmapped_area)
 617                slave->_get_unmapped_area = part_get_unmapped_area;
 618        if (master->_read_oob)
 619                slave->_read_oob = part_read_oob;
 620        if (master->_write_oob)
 621                slave->_write_oob = part_write_oob;
 622        if (master->_read_user_prot_reg)
 623                slave->_read_user_prot_reg = part_read_user_prot_reg;
 624        if (master->_read_fact_prot_reg)
 625                slave->_read_fact_prot_reg = part_read_fact_prot_reg;
 626        if (master->_write_user_prot_reg)
 627                slave->_write_user_prot_reg = part_write_user_prot_reg;
 628        if (master->_lock_user_prot_reg)
 629                slave->_lock_user_prot_reg = part_lock_user_prot_reg;
 630        if (master->_get_user_prot_info)
 631                slave->_get_user_prot_info = part_get_user_prot_info;
 632        if (master->_get_fact_prot_info)
 633                slave->_get_fact_prot_info = part_get_fact_prot_info;
 634        if (master->_sync)
 635                slave->_sync = part_sync;
 636#ifndef __UBOOT__
 637        if (!partno && !master->dev.class && master->_suspend &&
 638            master->_resume) {
 639                slave->_suspend = part_suspend;
 640                slave->_resume = part_resume;
 641        }
 642        if (master->_writev)
 643                slave->_writev = part_writev;
 644#endif
 645        if (master->_lock)
 646                slave->_lock = part_lock;
 647        if (master->_unlock)
 648                slave->_unlock = part_unlock;
 649        if (master->_is_locked)
 650                slave->_is_locked = part_is_locked;
 651        if (master->_block_isreserved)
 652                slave->_block_isreserved = part_block_isreserved;
 653        if (master->_block_isbad)
 654                slave->_block_isbad = part_block_isbad;
 655        if (master->_block_markbad)
 656                slave->_block_markbad = part_block_markbad;
 657        slave->_erase = part_erase;
 658        slave->parent = master;
 659        slave->offset = part->offset;
 660        INIT_LIST_HEAD(&slave->partitions);
 661        INIT_LIST_HEAD(&slave->node);
 662
 663        if (slave->offset == MTDPART_OFS_APPEND)
 664                slave->offset = cur_offset;
 665        if (slave->offset == MTDPART_OFS_NXTBLK) {
 666                slave->offset = cur_offset;
 667                if (mtd_mod_by_eb(cur_offset, master) != 0) {
 668                        /* Round up to next erasesize */
 669                        slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize;
 670                        debug("Moving partition %d: "
 671                               "0x%012llx -> 0x%012llx\n", partno,
 672                               (unsigned long long)cur_offset, (unsigned long long)slave->offset);
 673                }
 674        }
 675        if (slave->offset == MTDPART_OFS_RETAIN) {
 676                slave->offset = cur_offset;
 677                if (master->size - slave->offset >= slave->size) {
 678                        slave->size = master->size - slave->offset
 679                                                        - slave->size;
 680                } else {
 681                        debug("mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n",
 682                                part->name, master->size - slave->offset,
 683                                slave->size);
 684                        /* register to preserve ordering */
 685                        goto out_register;
 686                }
 687        }
 688        if (slave->size == MTDPART_SIZ_FULL)
 689                slave->size = master->size - slave->offset;
 690
 691        debug("0x%012llx-0x%012llx : \"%s\"\n", (unsigned long long)slave->offset,
 692                (unsigned long long)(slave->offset + slave->size), slave->name);
 693
 694        /* let's do some sanity checks */
 695        if (slave->offset >= master->size) {
 696                /* let's register it anyway to preserve ordering */
 697                slave->offset = 0;
 698                slave->size = 0;
 699                printk(KERN_ERR"mtd: partition \"%s\" is out of reach -- disabled\n",
 700                        part->name);
 701                goto out_register;
 702        }
 703        if (slave->offset + slave->size > master->size) {
 704                slave->size = master->size - slave->offset;
 705                printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n",
 706                       part->name, master->name, slave->size);
 707        }
 708        if (master->numeraseregions > 1) {
 709                /* Deal with variable erase size stuff */
 710                int i, max = master->numeraseregions;
 711                u64 end = slave->offset + slave->size;
 712                struct mtd_erase_region_info *regions = master->eraseregions;
 713
 714                /* Find the first erase regions which is part of this
 715                 * partition. */
 716                for (i = 0; i < max && regions[i].offset <= slave->offset; i++)
 717                        ;
 718                /* The loop searched for the region _behind_ the first one */
 719                if (i > 0)
 720                        i--;
 721
 722                /* Pick biggest erasesize */
 723                for (; i < max && regions[i].offset < end; i++) {
 724                        if (slave->erasesize < regions[i].erasesize)
 725                                slave->erasesize = regions[i].erasesize;
 726                }
 727                WARN_ON(slave->erasesize == 0);
 728        } else {
 729                /* Single erase size */
 730                slave->erasesize = master->erasesize;
 731        }
 732
 733        if ((slave->flags & MTD_WRITEABLE) &&
 734            mtd_mod_by_eb(slave->offset, slave)) {
 735                /* Doesn't start on a boundary of major erase size */
 736                /* FIXME: Let it be writable if it is on a boundary of
 737                 * _minor_ erase size though */
 738                slave->flags &= ~MTD_WRITEABLE;
 739                printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
 740                        part->name);
 741        }
 742        if ((slave->flags & MTD_WRITEABLE) &&
 743            mtd_mod_by_eb(slave->size, slave)) {
 744                slave->flags &= ~MTD_WRITEABLE;
 745                printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
 746                        part->name);
 747        }
 748
 749        slave->ecclayout = master->ecclayout;
 750        slave->ecc_step_size = master->ecc_step_size;
 751        slave->ecc_strength = master->ecc_strength;
 752        slave->bitflip_threshold = master->bitflip_threshold;
 753
 754        if (master->_block_isbad) {
 755                uint64_t offs = 0;
 756
 757                while (offs < slave->size) {
 758                        if (mtd_block_isbad(master, offs + slave->offset))
 759                                slave->ecc_stats.badblocks++;
 760                        offs += slave->erasesize;
 761                }
 762        }
 763
 764out_register:
 765        return slave;
 766}
 767
 768#ifndef __UBOOT__
 769int mtd_add_partition(struct mtd_info *master, const char *name,
 770                      long long offset, long long length)
 771{
 772        struct mtd_partition part;
 773        struct mtd_info *p, *new;
 774        uint64_t start, end;
 775        int ret = 0;
 776
 777        /* the direct offset is expected */
 778        if (offset == MTDPART_OFS_APPEND ||
 779            offset == MTDPART_OFS_NXTBLK)
 780                return -EINVAL;
 781
 782        if (length == MTDPART_SIZ_FULL)
 783                length = master->size - offset;
 784
 785        if (length <= 0)
 786                return -EINVAL;
 787
 788        part.name = name;
 789        part.size = length;
 790        part.offset = offset;
 791        part.mask_flags = 0;
 792        part.ecclayout = NULL;
 793
 794        new = allocate_partition(master, &part, -1, offset);
 795        if (IS_ERR(new))
 796                return PTR_ERR(new);
 797
 798        start = offset;
 799        end = offset + length;
 800
 801        mutex_lock(&mtd_partitions_mutex);
 802        list_for_each_entry(p, &master->partitions, node) {
 803                if (start >= p->offset &&
 804                    (start < (p->offset + p->size)))
 805                        goto err_inv;
 806
 807                if (end >= p->offset &&
 808                    (end < (p->offset + p->size)))
 809                        goto err_inv;
 810        }
 811
 812        list_add_tail(&new->node, &master->partitions);
 813        mutex_unlock(&mtd_partitions_mutex);
 814
 815        add_mtd_device(new);
 816
 817        return ret;
 818err_inv:
 819        mutex_unlock(&mtd_partitions_mutex);
 820        free_partition(new);
 821        return -EINVAL;
 822}
 823EXPORT_SYMBOL_GPL(mtd_add_partition);
 824
 825int mtd_del_partition(struct mtd_info *master, int partno)
 826{
 827        struct mtd_info *slave, *next;
 828        int ret = -EINVAL;
 829
 830        mutex_lock(&mtd_partitions_mutex);
 831        list_for_each_entry_safe(slave, next, &master->partitions, node)
 832                if (slave->index == partno) {
 833                        ret = del_mtd_device(slave);
 834                        if (ret < 0)
 835                                break;
 836
 837                        list_del(&slave->node);
 838                        free_partition(slave);
 839                        break;
 840                }
 841        mutex_unlock(&mtd_partitions_mutex);
 842
 843        return ret;
 844}
 845EXPORT_SYMBOL_GPL(mtd_del_partition);
 846#endif
 847
 848/*
 849 * This function, given a master MTD object and a partition table, creates
 850 * and registers slave MTD objects which are bound to the master according to
 851 * the partition definitions.
 852 *
 853 * We don't register the master, or expect the caller to have done so,
 854 * for reasons of data integrity.
 855 */
 856
 857int add_mtd_partitions(struct mtd_info *master,
 858                       const struct mtd_partition *parts,
 859                       int nbparts)
 860{
 861        struct mtd_info *slave;
 862        uint64_t cur_offset = 0;
 863        int i;
 864
 865        debug("Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
 866
 867        for (i = 0; i < nbparts; i++) {
 868                slave = allocate_partition(master, parts + i, i, cur_offset);
 869                if (IS_ERR(slave))
 870                        return PTR_ERR(slave);
 871
 872                mutex_lock(&mtd_partitions_mutex);
 873                list_add_tail(&slave->node, &master->partitions);
 874                mutex_unlock(&mtd_partitions_mutex);
 875
 876                add_mtd_device(slave);
 877
 878                cur_offset = slave->offset + slave->size;
 879        }
 880
 881        return 0;
 882}
 883
 884#if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(OF_CONTROL)
 885int add_mtd_partitions_of(struct mtd_info *master)
 886{
 887        ofnode parts, child;
 888        int i = 0;
 889
 890        if (!master->dev && !ofnode_valid(master->flash_node))
 891                return 0;
 892
 893        if (master->dev)
 894                parts = ofnode_find_subnode(mtd_get_ofnode(master), "partitions");
 895        else
 896                parts = ofnode_find_subnode(master->flash_node, "partitions");
 897
 898        if (!ofnode_valid(parts) || !ofnode_is_available(parts) ||
 899            !ofnode_device_is_compatible(parts, "fixed-partitions"))
 900                return 0;
 901
 902        ofnode_for_each_subnode(child, parts) {
 903                struct mtd_partition part = { 0 };
 904                struct mtd_info *slave;
 905                fdt_addr_t offset;
 906                fdt_size_t size;
 907
 908                if (!ofnode_is_available(child))
 909                        continue;
 910
 911                offset = ofnode_get_addr_size_index_notrans(child, 0, &size);
 912                if (offset == FDT_ADDR_T_NONE || !size) {
 913                        debug("Missing partition offset/size on \"%s\" partition\n",
 914                              master->name);
 915                        continue;
 916                }
 917
 918                part.name = ofnode_read_string(child, "label");
 919                if (!part.name)
 920                        part.name = ofnode_read_string(child, "name");
 921
 922                /*
 923                 * .mask_flags is used to remove flags in allocate_partition(),
 924                 * so when "read-only" is present, we add MTD_WRITABLE to the
 925                 * mask, and so MTD_WRITABLE will be removed on partition
 926                 * allocation
 927                 */
 928                if (ofnode_read_bool(child, "read-only"))
 929                        part.mask_flags |= MTD_WRITEABLE;
 930                if (ofnode_read_bool(child, "lock"))
 931                        part.mask_flags |= MTD_POWERUP_LOCK;
 932
 933                part.offset = offset;
 934                part.size = size;
 935                part.ecclayout = master->ecclayout;
 936
 937                slave = allocate_partition(master, &part, i++, 0);
 938                if (IS_ERR(slave))
 939                        return PTR_ERR(slave);
 940
 941                mutex_lock(&mtd_partitions_mutex);
 942                list_add_tail(&slave->node, &master->partitions);
 943                mutex_unlock(&mtd_partitions_mutex);
 944
 945                add_mtd_device(slave);
 946        }
 947
 948        return 0;
 949}
 950#endif /* CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(OF_CONTROL) */
 951
 952#ifndef __UBOOT__
 953static DEFINE_SPINLOCK(part_parser_lock);
 954static LIST_HEAD(part_parsers);
 955
 956static struct mtd_part_parser *get_partition_parser(const char *name)
 957{
 958        struct mtd_part_parser *p, *ret = NULL;
 959
 960        spin_lock(&part_parser_lock);
 961
 962        list_for_each_entry(p, &part_parsers, list)
 963                if (!strcmp(p->name, name) && try_module_get(p->owner)) {
 964                        ret = p;
 965                        break;
 966                }
 967
 968        spin_unlock(&part_parser_lock);
 969
 970        return ret;
 971}
 972
 973#define put_partition_parser(p) do { module_put((p)->owner); } while (0)
 974
 975void register_mtd_parser(struct mtd_part_parser *p)
 976{
 977        spin_lock(&part_parser_lock);
 978        list_add(&p->list, &part_parsers);
 979        spin_unlock(&part_parser_lock);
 980}
 981EXPORT_SYMBOL_GPL(register_mtd_parser);
 982
 983void deregister_mtd_parser(struct mtd_part_parser *p)
 984{
 985        spin_lock(&part_parser_lock);
 986        list_del(&p->list);
 987        spin_unlock(&part_parser_lock);
 988}
 989EXPORT_SYMBOL_GPL(deregister_mtd_parser);
 990
 991/*
 992 * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
 993 * are changing this array!
 994 */
 995static const char * const default_mtd_part_types[] = {
 996        "cmdlinepart",
 997        "ofpart",
 998        NULL
 999};
1000
1001/**
1002 * parse_mtd_partitions - parse MTD partitions
1003 * @master: the master partition (describes whole MTD device)
1004 * @types: names of partition parsers to try or %NULL
1005 * @pparts: array of partitions found is returned here
1006 * @data: MTD partition parser-specific data
1007 *
1008 * This function tries to find partition on MTD device @master. It uses MTD
1009 * partition parsers, specified in @types. However, if @types is %NULL, then
1010 * the default list of parsers is used. The default list contains only the
1011 * "cmdlinepart" and "ofpart" parsers ATM.
1012 * Note: If there are more then one parser in @types, the kernel only takes the
1013 * partitions parsed out by the first parser.
1014 *
1015 * This function may return:
1016 * o a negative error code in case of failure
1017 * o zero if no partitions were found
1018 * o a positive number of found partitions, in which case on exit @pparts will
1019 *   point to an array containing this number of &struct mtd_info objects.
1020 */
1021int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
1022                         struct mtd_partition **pparts,
1023                         struct mtd_part_parser_data *data)
1024{
1025        struct mtd_part_parser *parser;
1026        int ret = 0;
1027
1028        if (!types)
1029                types = default_mtd_part_types;
1030
1031        for ( ; ret <= 0 && *types; types++) {
1032                parser = get_partition_parser(*types);
1033                if (!parser && !request_module("%s", *types))
1034                        parser = get_partition_parser(*types);
1035                if (!parser)
1036                        continue;
1037                ret = (*parser->parse_fn)(master, pparts, data);
1038                put_partition_parser(parser);
1039                if (ret > 0) {
1040                        printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
1041                               ret, parser->name, master->name);
1042                        break;
1043                }
1044        }
1045        return ret;
1046}
1047#endif
1048
1049/* Returns the size of the entire flash chip */
1050uint64_t mtd_get_device_size(const struct mtd_info *mtd)
1051{
1052        if (mtd_is_partition(mtd))
1053                return mtd->parent->size;
1054
1055        return mtd->size;
1056}
1057EXPORT_SYMBOL_GPL(mtd_get_device_size);
1058