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