linux/drivers/mtd/mtdchar.c
<<
>>
Prefs
   1/*
   2 * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17 *
  18 */
  19
  20#include <linux/device.h>
  21#include <linux/fs.h>
  22#include <linux/mm.h>
  23#include <linux/err.h>
  24#include <linux/init.h>
  25#include <linux/kernel.h>
  26#include <linux/module.h>
  27#include <linux/slab.h>
  28#include <linux/sched.h>
  29#include <linux/mutex.h>
  30#include <linux/backing-dev.h>
  31#include <linux/compat.h>
  32#include <linux/mount.h>
  33#include <linux/blkpg.h>
  34#include <linux/magic.h>
  35#include <linux/mtd/mtd.h>
  36#include <linux/mtd/partitions.h>
  37#include <linux/mtd/map.h>
  38
  39#include <asm/uaccess.h>
  40
  41#include "mtdcore.h"
  42
  43static DEFINE_MUTEX(mtd_mutex);
  44
  45/*
  46 * Data structure to hold the pointer to the mtd device as well
  47 * as mode information of various use cases.
  48 */
  49struct mtd_file_info {
  50        struct mtd_info *mtd;
  51        struct inode *ino;
  52        enum mtd_file_modes mode;
  53};
  54
  55static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
  56{
  57        struct mtd_file_info *mfi = file->private_data;
  58        return fixed_size_llseek(file, offset, orig, mfi->mtd->size);
  59}
  60
  61static int count;
  62static struct vfsmount *mnt;
  63static struct file_system_type mtd_inodefs_type;
  64
  65static int mtdchar_open(struct inode *inode, struct file *file)
  66{
  67        int minor = iminor(inode);
  68        int devnum = minor >> 1;
  69        int ret = 0;
  70        struct mtd_info *mtd;
  71        struct mtd_file_info *mfi;
  72        struct inode *mtd_ino;
  73
  74        pr_debug("MTD_open\n");
  75
  76        /* You can't open the RO devices RW */
  77        if ((file->f_mode & FMODE_WRITE) && (minor & 1))
  78                return -EACCES;
  79
  80        ret = simple_pin_fs(&mtd_inodefs_type, &mnt, &count);
  81        if (ret)
  82                return ret;
  83
  84        mutex_lock(&mtd_mutex);
  85        mtd = get_mtd_device(NULL, devnum);
  86
  87        if (IS_ERR(mtd)) {
  88                ret = PTR_ERR(mtd);
  89                goto out;
  90        }
  91
  92        if (mtd->type == MTD_ABSENT) {
  93                ret = -ENODEV;
  94                goto out1;
  95        }
  96
  97        mtd_ino = iget_locked(mnt->mnt_sb, devnum);
  98        if (!mtd_ino) {
  99                ret = -ENOMEM;
 100                goto out1;
 101        }
 102        if (mtd_ino->i_state & I_NEW) {
 103                mtd_ino->i_private = mtd;
 104                mtd_ino->i_mode = S_IFCHR;
 105                mtd_ino->i_data.backing_dev_info = mtd->backing_dev_info;
 106                unlock_new_inode(mtd_ino);
 107        }
 108        file->f_mapping = mtd_ino->i_mapping;
 109
 110        /* You can't open it RW if it's not a writeable device */
 111        if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
 112                ret = -EACCES;
 113                goto out2;
 114        }
 115
 116        mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
 117        if (!mfi) {
 118                ret = -ENOMEM;
 119                goto out2;
 120        }
 121        mfi->ino = mtd_ino;
 122        mfi->mtd = mtd;
 123        file->private_data = mfi;
 124        mutex_unlock(&mtd_mutex);
 125        return 0;
 126
 127out2:
 128        iput(mtd_ino);
 129out1:
 130        put_mtd_device(mtd);
 131out:
 132        mutex_unlock(&mtd_mutex);
 133        simple_release_fs(&mnt, &count);
 134        return ret;
 135} /* mtdchar_open */
 136
 137/*====================================================================*/
 138
 139static int mtdchar_close(struct inode *inode, struct file *file)
 140{
 141        struct mtd_file_info *mfi = file->private_data;
 142        struct mtd_info *mtd = mfi->mtd;
 143
 144        pr_debug("MTD_close\n");
 145
 146        /* Only sync if opened RW */
 147        if ((file->f_mode & FMODE_WRITE))
 148                mtd_sync(mtd);
 149
 150        iput(mfi->ino);
 151
 152        put_mtd_device(mtd);
 153        file->private_data = NULL;
 154        kfree(mfi);
 155        simple_release_fs(&mnt, &count);
 156
 157        return 0;
 158} /* mtdchar_close */
 159
 160/* Back in June 2001, dwmw2 wrote:
 161 *
 162 *   FIXME: This _really_ needs to die. In 2.5, we should lock the
 163 *   userspace buffer down and use it directly with readv/writev.
 164 *
 165 * The implementation below, using mtd_kmalloc_up_to, mitigates
 166 * allocation failures when the system is under low-memory situations
 167 * or if memory is highly fragmented at the cost of reducing the
 168 * performance of the requested transfer due to a smaller buffer size.
 169 *
 170 * A more complex but more memory-efficient implementation based on
 171 * get_user_pages and iovecs to cover extents of those pages is a
 172 * longer-term goal, as intimated by dwmw2 above. However, for the
 173 * write case, this requires yet more complex head and tail transfer
 174 * handling when those head and tail offsets and sizes are such that
 175 * alignment requirements are not met in the NAND subdriver.
 176 */
 177
 178static ssize_t mtdchar_read(struct file *file, char __user *buf, size_t count,
 179                        loff_t *ppos)
 180{
 181        struct mtd_file_info *mfi = file->private_data;
 182        struct mtd_info *mtd = mfi->mtd;
 183        size_t retlen;
 184        size_t total_retlen=0;
 185        int ret=0;
 186        int len;
 187        size_t size = count;
 188        char *kbuf;
 189
 190        pr_debug("MTD_read\n");
 191
 192        if (*ppos + count > mtd->size)
 193                count = mtd->size - *ppos;
 194
 195        if (!count)
 196                return 0;
 197
 198        kbuf = mtd_kmalloc_up_to(mtd, &size);
 199        if (!kbuf)
 200                return -ENOMEM;
 201
 202        while (count) {
 203                len = min_t(size_t, count, size);
 204
 205                switch (mfi->mode) {
 206                case MTD_FILE_MODE_OTP_FACTORY:
 207                        ret = mtd_read_fact_prot_reg(mtd, *ppos, len,
 208                                                     &retlen, kbuf);
 209                        break;
 210                case MTD_FILE_MODE_OTP_USER:
 211                        ret = mtd_read_user_prot_reg(mtd, *ppos, len,
 212                                                     &retlen, kbuf);
 213                        break;
 214                case MTD_FILE_MODE_RAW:
 215                {
 216                        struct mtd_oob_ops ops;
 217
 218                        ops.mode = MTD_OPS_RAW;
 219                        ops.datbuf = kbuf;
 220                        ops.oobbuf = NULL;
 221                        ops.len = len;
 222
 223                        ret = mtd_read_oob(mtd, *ppos, &ops);
 224                        retlen = ops.retlen;
 225                        break;
 226                }
 227                default:
 228                        ret = mtd_read(mtd, *ppos, len, &retlen, kbuf);
 229                }
 230                /* Nand returns -EBADMSG on ECC errors, but it returns
 231                 * the data. For our userspace tools it is important
 232                 * to dump areas with ECC errors!
 233                 * For kernel internal usage it also might return -EUCLEAN
 234                 * to signal the caller that a bitflip has occurred and has
 235                 * been corrected by the ECC algorithm.
 236                 * Userspace software which accesses NAND this way
 237                 * must be aware of the fact that it deals with NAND
 238                 */
 239                if (!ret || mtd_is_bitflip_or_eccerr(ret)) {
 240                        *ppos += retlen;
 241                        if (copy_to_user(buf, kbuf, retlen)) {
 242                                kfree(kbuf);
 243                                return -EFAULT;
 244                        }
 245                        else
 246                                total_retlen += retlen;
 247
 248                        count -= retlen;
 249                        buf += retlen;
 250                        if (retlen == 0)
 251                                count = 0;
 252                }
 253                else {
 254                        kfree(kbuf);
 255                        return ret;
 256                }
 257
 258        }
 259
 260        kfree(kbuf);
 261        return total_retlen;
 262} /* mtdchar_read */
 263
 264static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t count,
 265                        loff_t *ppos)
 266{
 267        struct mtd_file_info *mfi = file->private_data;
 268        struct mtd_info *mtd = mfi->mtd;
 269        size_t size = count;
 270        char *kbuf;
 271        size_t retlen;
 272        size_t total_retlen=0;
 273        int ret=0;
 274        int len;
 275
 276        pr_debug("MTD_write\n");
 277
 278        if (*ppos == mtd->size)
 279                return -ENOSPC;
 280
 281        if (*ppos + count > mtd->size)
 282                count = mtd->size - *ppos;
 283
 284        if (!count)
 285                return 0;
 286
 287        kbuf = mtd_kmalloc_up_to(mtd, &size);
 288        if (!kbuf)
 289                return -ENOMEM;
 290
 291        while (count) {
 292                len = min_t(size_t, count, size);
 293
 294                if (copy_from_user(kbuf, buf, len)) {
 295                        kfree(kbuf);
 296                        return -EFAULT;
 297                }
 298
 299                switch (mfi->mode) {
 300                case MTD_FILE_MODE_OTP_FACTORY:
 301                        ret = -EROFS;
 302                        break;
 303                case MTD_FILE_MODE_OTP_USER:
 304                        ret = mtd_write_user_prot_reg(mtd, *ppos, len,
 305                                                      &retlen, kbuf);
 306                        break;
 307
 308                case MTD_FILE_MODE_RAW:
 309                {
 310                        struct mtd_oob_ops ops;
 311
 312                        ops.mode = MTD_OPS_RAW;
 313                        ops.datbuf = kbuf;
 314                        ops.oobbuf = NULL;
 315                        ops.ooboffs = 0;
 316                        ops.len = len;
 317
 318                        ret = mtd_write_oob(mtd, *ppos, &ops);
 319                        retlen = ops.retlen;
 320                        break;
 321                }
 322
 323                default:
 324                        ret = mtd_write(mtd, *ppos, len, &retlen, kbuf);
 325                }
 326                if (!ret) {
 327                        *ppos += retlen;
 328                        total_retlen += retlen;
 329                        count -= retlen;
 330                        buf += retlen;
 331                }
 332                else {
 333                        kfree(kbuf);
 334                        return ret;
 335                }
 336        }
 337
 338        kfree(kbuf);
 339        return total_retlen;
 340} /* mtdchar_write */
 341
 342/*======================================================================
 343
 344    IOCTL calls for getting device parameters.
 345
 346======================================================================*/
 347static void mtdchar_erase_callback (struct erase_info *instr)
 348{
 349        wake_up((wait_queue_head_t *)instr->priv);
 350}
 351
 352static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
 353{
 354        struct mtd_info *mtd = mfi->mtd;
 355        size_t retlen;
 356
 357        switch (mode) {
 358        case MTD_OTP_FACTORY:
 359                if (mtd_read_fact_prot_reg(mtd, -1, 0, &retlen, NULL) ==
 360                                -EOPNOTSUPP)
 361                        return -EOPNOTSUPP;
 362
 363                mfi->mode = MTD_FILE_MODE_OTP_FACTORY;
 364                break;
 365        case MTD_OTP_USER:
 366                if (mtd_read_user_prot_reg(mtd, -1, 0, &retlen, NULL) ==
 367                                -EOPNOTSUPP)
 368                        return -EOPNOTSUPP;
 369
 370                mfi->mode = MTD_FILE_MODE_OTP_USER;
 371                break;
 372        case MTD_OTP_OFF:
 373                mfi->mode = MTD_FILE_MODE_NORMAL;
 374                break;
 375        default:
 376                return -EINVAL;
 377        }
 378
 379        return 0;
 380}
 381
 382static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
 383        uint64_t start, uint32_t length, void __user *ptr,
 384        uint32_t __user *retp)
 385{
 386        struct mtd_file_info *mfi = file->private_data;
 387        struct mtd_oob_ops ops;
 388        uint32_t retlen;
 389        int ret = 0;
 390
 391        if (!(file->f_mode & FMODE_WRITE))
 392                return -EPERM;
 393
 394        if (length > 4096)
 395                return -EINVAL;
 396
 397        if (!mtd->_write_oob)
 398                ret = -EOPNOTSUPP;
 399        else
 400                ret = access_ok(VERIFY_READ, ptr, length) ? 0 : -EFAULT;
 401
 402        if (ret)
 403                return ret;
 404
 405        ops.ooblen = length;
 406        ops.ooboffs = start & (mtd->writesize - 1);
 407        ops.datbuf = NULL;
 408        ops.mode = (mfi->mode == MTD_FILE_MODE_RAW) ? MTD_OPS_RAW :
 409                MTD_OPS_PLACE_OOB;
 410
 411        if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
 412                return -EINVAL;
 413
 414        ops.oobbuf = memdup_user(ptr, length);
 415        if (IS_ERR(ops.oobbuf))
 416                return PTR_ERR(ops.oobbuf);
 417
 418        start &= ~((uint64_t)mtd->writesize - 1);
 419        ret = mtd_write_oob(mtd, start, &ops);
 420
 421        if (ops.oobretlen > 0xFFFFFFFFU)
 422                ret = -EOVERFLOW;
 423        retlen = ops.oobretlen;
 424        if (copy_to_user(retp, &retlen, sizeof(length)))
 425                ret = -EFAULT;
 426
 427        kfree(ops.oobbuf);
 428        return ret;
 429}
 430
 431static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
 432        uint64_t start, uint32_t length, void __user *ptr,
 433        uint32_t __user *retp)
 434{
 435        struct mtd_file_info *mfi = file->private_data;
 436        struct mtd_oob_ops ops;
 437        int ret = 0;
 438
 439        if (length > 4096)
 440                return -EINVAL;
 441
 442        if (!access_ok(VERIFY_WRITE, ptr, length))
 443                return -EFAULT;
 444
 445        ops.ooblen = length;
 446        ops.ooboffs = start & (mtd->writesize - 1);
 447        ops.datbuf = NULL;
 448        ops.mode = (mfi->mode == MTD_FILE_MODE_RAW) ? MTD_OPS_RAW :
 449                MTD_OPS_PLACE_OOB;
 450
 451        if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
 452                return -EINVAL;
 453
 454        ops.oobbuf = kmalloc(length, GFP_KERNEL);
 455        if (!ops.oobbuf)
 456                return -ENOMEM;
 457
 458        start &= ~((uint64_t)mtd->writesize - 1);
 459        ret = mtd_read_oob(mtd, start, &ops);
 460
 461        if (put_user(ops.oobretlen, retp))
 462                ret = -EFAULT;
 463        else if (ops.oobretlen && copy_to_user(ptr, ops.oobbuf,
 464                                            ops.oobretlen))
 465                ret = -EFAULT;
 466
 467        kfree(ops.oobbuf);
 468
 469        /*
 470         * NAND returns -EBADMSG on ECC errors, but it returns the OOB
 471         * data. For our userspace tools it is important to dump areas
 472         * with ECC errors!
 473         * For kernel internal usage it also might return -EUCLEAN
 474         * to signal the caller that a bitflip has occured and has
 475         * been corrected by the ECC algorithm.
 476         *
 477         * Note: currently the standard NAND function, nand_read_oob_std,
 478         * does not calculate ECC for the OOB area, so do not rely on
 479         * this behavior unless you have replaced it with your own.
 480         */
 481        if (mtd_is_bitflip_or_eccerr(ret))
 482                return 0;
 483
 484        return ret;
 485}
 486
 487/*
 488 * Copies (and truncates, if necessary) data from the larger struct,
 489 * nand_ecclayout, to the smaller, deprecated layout struct,
 490 * nand_ecclayout_user. This is necessary only to support the deprecated
 491 * API ioctl ECCGETLAYOUT while allowing all new functionality to use
 492 * nand_ecclayout flexibly (i.e. the struct may change size in new
 493 * releases without requiring major rewrites).
 494 */
 495static int shrink_ecclayout(const struct nand_ecclayout *from,
 496                struct nand_ecclayout_user *to)
 497{
 498        int i;
 499
 500        if (!from || !to)
 501                return -EINVAL;
 502
 503        memset(to, 0, sizeof(*to));
 504
 505        to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
 506        for (i = 0; i < to->eccbytes; i++)
 507                to->eccpos[i] = from->eccpos[i];
 508
 509        for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
 510                if (from->oobfree[i].length == 0 &&
 511                                from->oobfree[i].offset == 0)
 512                        break;
 513                to->oobavail += from->oobfree[i].length;
 514                to->oobfree[i] = from->oobfree[i];
 515        }
 516
 517        return 0;
 518}
 519
 520static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
 521                           struct blkpg_ioctl_arg __user *arg)
 522{
 523        struct blkpg_ioctl_arg a;
 524        struct blkpg_partition p;
 525
 526        if (!capable(CAP_SYS_ADMIN))
 527                return -EPERM;
 528
 529        if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
 530                return -EFAULT;
 531
 532        if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
 533                return -EFAULT;
 534
 535        switch (a.op) {
 536        case BLKPG_ADD_PARTITION:
 537
 538                /* Only master mtd device must be used to add partitions */
 539                if (mtd_is_partition(mtd))
 540                        return -EINVAL;
 541
 542                return mtd_add_partition(mtd, p.devname, p.start, p.length);
 543
 544        case BLKPG_DEL_PARTITION:
 545
 546                if (p.pno < 0)
 547                        return -EINVAL;
 548
 549                return mtd_del_partition(mtd, p.pno);
 550
 551        default:
 552                return -EINVAL;
 553        }
 554}
 555
 556static int mtdchar_write_ioctl(struct mtd_info *mtd,
 557                struct mtd_write_req __user *argp)
 558{
 559        struct mtd_write_req req;
 560        struct mtd_oob_ops ops;
 561        void __user *usr_data, *usr_oob;
 562        int ret;
 563
 564        if (copy_from_user(&req, argp, sizeof(req)) ||
 565                        !access_ok(VERIFY_READ, req.usr_data, req.len) ||
 566                        !access_ok(VERIFY_READ, req.usr_oob, req.ooblen))
 567                return -EFAULT;
 568        if (!mtd->_write_oob)
 569                return -EOPNOTSUPP;
 570
 571        ops.mode = req.mode;
 572        ops.len = (size_t)req.len;
 573        ops.ooblen = (size_t)req.ooblen;
 574        ops.ooboffs = 0;
 575
 576        usr_data = (void __user *)(uintptr_t)req.usr_data;
 577        usr_oob = (void __user *)(uintptr_t)req.usr_oob;
 578
 579        if (req.usr_data) {
 580                ops.datbuf = memdup_user(usr_data, ops.len);
 581                if (IS_ERR(ops.datbuf))
 582                        return PTR_ERR(ops.datbuf);
 583        } else {
 584                ops.datbuf = NULL;
 585        }
 586
 587        if (req.usr_oob) {
 588                ops.oobbuf = memdup_user(usr_oob, ops.ooblen);
 589                if (IS_ERR(ops.oobbuf)) {
 590                        kfree(ops.datbuf);
 591                        return PTR_ERR(ops.oobbuf);
 592                }
 593        } else {
 594                ops.oobbuf = NULL;
 595        }
 596
 597        ret = mtd_write_oob(mtd, (loff_t)req.start, &ops);
 598
 599        kfree(ops.datbuf);
 600        kfree(ops.oobbuf);
 601
 602        return ret;
 603}
 604
 605static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 606{
 607        struct mtd_file_info *mfi = file->private_data;
 608        struct mtd_info *mtd = mfi->mtd;
 609        void __user *argp = (void __user *)arg;
 610        int ret = 0;
 611        u_long size;
 612        struct mtd_info_user info;
 613
 614        pr_debug("MTD_ioctl\n");
 615
 616        size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
 617        if (cmd & IOC_IN) {
 618                if (!access_ok(VERIFY_READ, argp, size))
 619                        return -EFAULT;
 620        }
 621        if (cmd & IOC_OUT) {
 622                if (!access_ok(VERIFY_WRITE, argp, size))
 623                        return -EFAULT;
 624        }
 625
 626        switch (cmd) {
 627        case MEMGETREGIONCOUNT:
 628                if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
 629                        return -EFAULT;
 630                break;
 631
 632        case MEMGETREGIONINFO:
 633        {
 634                uint32_t ur_idx;
 635                struct mtd_erase_region_info *kr;
 636                struct region_info_user __user *ur = argp;
 637
 638                if (get_user(ur_idx, &(ur->regionindex)))
 639                        return -EFAULT;
 640
 641                if (ur_idx >= mtd->numeraseregions)
 642                        return -EINVAL;
 643
 644                kr = &(mtd->eraseregions[ur_idx]);
 645
 646                if (put_user(kr->offset, &(ur->offset))
 647                    || put_user(kr->erasesize, &(ur->erasesize))
 648                    || put_user(kr->numblocks, &(ur->numblocks)))
 649                        return -EFAULT;
 650
 651                break;
 652        }
 653
 654        case MEMGETINFO:
 655                memset(&info, 0, sizeof(info));
 656                info.type       = mtd->type;
 657                info.flags      = mtd->flags;
 658                info.size       = mtd->size;
 659                info.erasesize  = mtd->erasesize;
 660                info.writesize  = mtd->writesize;
 661                info.oobsize    = mtd->oobsize;
 662                /* The below field is obsolete */
 663                info.padding    = 0;
 664                if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
 665                        return -EFAULT;
 666                break;
 667
 668        case MEMERASE:
 669        case MEMERASE64:
 670        {
 671                struct erase_info *erase;
 672
 673                if(!(file->f_mode & FMODE_WRITE))
 674                        return -EPERM;
 675
 676                erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL);
 677                if (!erase)
 678                        ret = -ENOMEM;
 679                else {
 680                        wait_queue_head_t waitq;
 681                        DECLARE_WAITQUEUE(wait, current);
 682
 683                        init_waitqueue_head(&waitq);
 684
 685                        if (cmd == MEMERASE64) {
 686                                struct erase_info_user64 einfo64;
 687
 688                                if (copy_from_user(&einfo64, argp,
 689                                            sizeof(struct erase_info_user64))) {
 690                                        kfree(erase);
 691                                        return -EFAULT;
 692                                }
 693                                erase->addr = einfo64.start;
 694                                erase->len = einfo64.length;
 695                        } else {
 696                                struct erase_info_user einfo32;
 697
 698                                if (copy_from_user(&einfo32, argp,
 699                                            sizeof(struct erase_info_user))) {
 700                                        kfree(erase);
 701                                        return -EFAULT;
 702                                }
 703                                erase->addr = einfo32.start;
 704                                erase->len = einfo32.length;
 705                        }
 706                        erase->mtd = mtd;
 707                        erase->callback = mtdchar_erase_callback;
 708                        erase->priv = (unsigned long)&waitq;
 709
 710                        /*
 711                          FIXME: Allow INTERRUPTIBLE. Which means
 712                          not having the wait_queue head on the stack.
 713
 714                          If the wq_head is on the stack, and we
 715                          leave because we got interrupted, then the
 716                          wq_head is no longer there when the
 717                          callback routine tries to wake us up.
 718                        */
 719                        ret = mtd_erase(mtd, erase);
 720                        if (!ret) {
 721                                set_current_state(TASK_UNINTERRUPTIBLE);
 722                                add_wait_queue(&waitq, &wait);
 723                                if (erase->state != MTD_ERASE_DONE &&
 724                                    erase->state != MTD_ERASE_FAILED)
 725                                        schedule();
 726                                remove_wait_queue(&waitq, &wait);
 727                                set_current_state(TASK_RUNNING);
 728
 729                                ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0;
 730                        }
 731                        kfree(erase);
 732                }
 733                break;
 734        }
 735
 736        case MEMWRITEOOB:
 737        {
 738                struct mtd_oob_buf buf;
 739                struct mtd_oob_buf __user *buf_user = argp;
 740
 741                /* NOTE: writes return length to buf_user->length */
 742                if (copy_from_user(&buf, argp, sizeof(buf)))
 743                        ret = -EFAULT;
 744                else
 745                        ret = mtdchar_writeoob(file, mtd, buf.start, buf.length,
 746                                buf.ptr, &buf_user->length);
 747                break;
 748        }
 749
 750        case MEMREADOOB:
 751        {
 752                struct mtd_oob_buf buf;
 753                struct mtd_oob_buf __user *buf_user = argp;
 754
 755                /* NOTE: writes return length to buf_user->start */
 756                if (copy_from_user(&buf, argp, sizeof(buf)))
 757                        ret = -EFAULT;
 758                else
 759                        ret = mtdchar_readoob(file, mtd, buf.start, buf.length,
 760                                buf.ptr, &buf_user->start);
 761                break;
 762        }
 763
 764        case MEMWRITEOOB64:
 765        {
 766                struct mtd_oob_buf64 buf;
 767                struct mtd_oob_buf64 __user *buf_user = argp;
 768
 769                if (copy_from_user(&buf, argp, sizeof(buf)))
 770                        ret = -EFAULT;
 771                else
 772                        ret = mtdchar_writeoob(file, mtd, buf.start, buf.length,
 773                                (void __user *)(uintptr_t)buf.usr_ptr,
 774                                &buf_user->length);
 775                break;
 776        }
 777
 778        case MEMREADOOB64:
 779        {
 780                struct mtd_oob_buf64 buf;
 781                struct mtd_oob_buf64 __user *buf_user = argp;
 782
 783                if (copy_from_user(&buf, argp, sizeof(buf)))
 784                        ret = -EFAULT;
 785                else
 786                        ret = mtdchar_readoob(file, mtd, buf.start, buf.length,
 787                                (void __user *)(uintptr_t)buf.usr_ptr,
 788                                &buf_user->length);
 789                break;
 790        }
 791
 792        case MEMWRITE:
 793        {
 794                ret = mtdchar_write_ioctl(mtd,
 795                      (struct mtd_write_req __user *)arg);
 796                break;
 797        }
 798
 799        case MEMLOCK:
 800        {
 801                struct erase_info_user einfo;
 802
 803                if (copy_from_user(&einfo, argp, sizeof(einfo)))
 804                        return -EFAULT;
 805
 806                ret = mtd_lock(mtd, einfo.start, einfo.length);
 807                break;
 808        }
 809
 810        case MEMUNLOCK:
 811        {
 812                struct erase_info_user einfo;
 813
 814                if (copy_from_user(&einfo, argp, sizeof(einfo)))
 815                        return -EFAULT;
 816
 817                ret = mtd_unlock(mtd, einfo.start, einfo.length);
 818                break;
 819        }
 820
 821        case MEMISLOCKED:
 822        {
 823                struct erase_info_user einfo;
 824
 825                if (copy_from_user(&einfo, argp, sizeof(einfo)))
 826                        return -EFAULT;
 827
 828                ret = mtd_is_locked(mtd, einfo.start, einfo.length);
 829                break;
 830        }
 831
 832        /* Legacy interface */
 833        case MEMGETOOBSEL:
 834        {
 835                struct nand_oobinfo oi;
 836
 837                if (!mtd->ecclayout)
 838                        return -EOPNOTSUPP;
 839                if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
 840                        return -EINVAL;
 841
 842                oi.useecc = MTD_NANDECC_AUTOPLACE;
 843                memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
 844                memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
 845                       sizeof(oi.oobfree));
 846                oi.eccbytes = mtd->ecclayout->eccbytes;
 847
 848                if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
 849                        return -EFAULT;
 850                break;
 851        }
 852
 853        case MEMGETBADBLOCK:
 854        {
 855                loff_t offs;
 856
 857                if (copy_from_user(&offs, argp, sizeof(loff_t)))
 858                        return -EFAULT;
 859                return mtd_block_isbad(mtd, offs);
 860                break;
 861        }
 862
 863        case MEMSETBADBLOCK:
 864        {
 865                loff_t offs;
 866
 867                if (copy_from_user(&offs, argp, sizeof(loff_t)))
 868                        return -EFAULT;
 869                return mtd_block_markbad(mtd, offs);
 870                break;
 871        }
 872
 873        case OTPSELECT:
 874        {
 875                int mode;
 876                if (copy_from_user(&mode, argp, sizeof(int)))
 877                        return -EFAULT;
 878
 879                mfi->mode = MTD_FILE_MODE_NORMAL;
 880
 881                ret = otp_select_filemode(mfi, mode);
 882
 883                file->f_pos = 0;
 884                break;
 885        }
 886
 887        case OTPGETREGIONCOUNT:
 888        case OTPGETREGIONINFO:
 889        {
 890                struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
 891                if (!buf)
 892                        return -ENOMEM;
 893                switch (mfi->mode) {
 894                case MTD_FILE_MODE_OTP_FACTORY:
 895                        ret = mtd_get_fact_prot_info(mtd, buf, 4096);
 896                        break;
 897                case MTD_FILE_MODE_OTP_USER:
 898                        ret = mtd_get_user_prot_info(mtd, buf, 4096);
 899                        break;
 900                default:
 901                        ret = -EINVAL;
 902                        break;
 903                }
 904                if (ret >= 0) {
 905                        if (cmd == OTPGETREGIONCOUNT) {
 906                                int nbr = ret / sizeof(struct otp_info);
 907                                ret = copy_to_user(argp, &nbr, sizeof(int));
 908                        } else
 909                                ret = copy_to_user(argp, buf, ret);
 910                        if (ret)
 911                                ret = -EFAULT;
 912                }
 913                kfree(buf);
 914                break;
 915        }
 916
 917        case OTPLOCK:
 918        {
 919                struct otp_info oinfo;
 920
 921                if (mfi->mode != MTD_FILE_MODE_OTP_USER)
 922                        return -EINVAL;
 923                if (copy_from_user(&oinfo, argp, sizeof(oinfo)))
 924                        return -EFAULT;
 925                ret = mtd_lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
 926                break;
 927        }
 928
 929        /* This ioctl is being deprecated - it truncates the ECC layout */
 930        case ECCGETLAYOUT:
 931        {
 932                struct nand_ecclayout_user *usrlay;
 933
 934                if (!mtd->ecclayout)
 935                        return -EOPNOTSUPP;
 936
 937                usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL);
 938                if (!usrlay)
 939                        return -ENOMEM;
 940
 941                shrink_ecclayout(mtd->ecclayout, usrlay);
 942
 943                if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
 944                        ret = -EFAULT;
 945                kfree(usrlay);
 946                break;
 947        }
 948
 949        case ECCGETSTATS:
 950        {
 951                if (copy_to_user(argp, &mtd->ecc_stats,
 952                                 sizeof(struct mtd_ecc_stats)))
 953                        return -EFAULT;
 954                break;
 955        }
 956
 957        case MTDFILEMODE:
 958        {
 959                mfi->mode = 0;
 960
 961                switch(arg) {
 962                case MTD_FILE_MODE_OTP_FACTORY:
 963                case MTD_FILE_MODE_OTP_USER:
 964                        ret = otp_select_filemode(mfi, arg);
 965                        break;
 966
 967                case MTD_FILE_MODE_RAW:
 968                        if (!mtd_has_oob(mtd))
 969                                return -EOPNOTSUPP;
 970                        mfi->mode = arg;
 971
 972                case MTD_FILE_MODE_NORMAL:
 973                        break;
 974                default:
 975                        ret = -EINVAL;
 976                }
 977                file->f_pos = 0;
 978                break;
 979        }
 980
 981        case BLKPG:
 982        {
 983                ret = mtdchar_blkpg_ioctl(mtd,
 984                      (struct blkpg_ioctl_arg __user *)arg);
 985                break;
 986        }
 987
 988        case BLKRRPART:
 989        {
 990                /* No reread partition feature. Just return ok */
 991                ret = 0;
 992                break;
 993        }
 994
 995        default:
 996                ret = -ENOTTY;
 997        }
 998
 999        return ret;
1000} /* memory_ioctl */
1001
1002static long mtdchar_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
1003{
1004        int ret;
1005
1006        mutex_lock(&mtd_mutex);
1007        ret = mtdchar_ioctl(file, cmd, arg);
1008        mutex_unlock(&mtd_mutex);
1009
1010        return ret;
1011}
1012
1013#ifdef CONFIG_COMPAT
1014
1015struct mtd_oob_buf32 {
1016        u_int32_t start;
1017        u_int32_t length;
1018        compat_caddr_t ptr;     /* unsigned char* */
1019};
1020
1021#define MEMWRITEOOB32           _IOWR('M', 3, struct mtd_oob_buf32)
1022#define MEMREADOOB32            _IOWR('M', 4, struct mtd_oob_buf32)
1023
1024static long mtdchar_compat_ioctl(struct file *file, unsigned int cmd,
1025        unsigned long arg)
1026{
1027        struct mtd_file_info *mfi = file->private_data;
1028        struct mtd_info *mtd = mfi->mtd;
1029        void __user *argp = compat_ptr(arg);
1030        int ret = 0;
1031
1032        mutex_lock(&mtd_mutex);
1033
1034        switch (cmd) {
1035        case MEMWRITEOOB32:
1036        {
1037                struct mtd_oob_buf32 buf;
1038                struct mtd_oob_buf32 __user *buf_user = argp;
1039
1040                if (copy_from_user(&buf, argp, sizeof(buf)))
1041                        ret = -EFAULT;
1042                else
1043                        ret = mtdchar_writeoob(file, mtd, buf.start,
1044                                buf.length, compat_ptr(buf.ptr),
1045                                &buf_user->length);
1046                break;
1047        }
1048
1049        case MEMREADOOB32:
1050        {
1051                struct mtd_oob_buf32 buf;
1052                struct mtd_oob_buf32 __user *buf_user = argp;
1053
1054                /* NOTE: writes return length to buf->start */
1055                if (copy_from_user(&buf, argp, sizeof(buf)))
1056                        ret = -EFAULT;
1057                else
1058                        ret = mtdchar_readoob(file, mtd, buf.start,
1059                                buf.length, compat_ptr(buf.ptr),
1060                                &buf_user->start);
1061                break;
1062        }
1063        default:
1064                ret = mtdchar_ioctl(file, cmd, (unsigned long)argp);
1065        }
1066
1067        mutex_unlock(&mtd_mutex);
1068
1069        return ret;
1070}
1071
1072#endif /* CONFIG_COMPAT */
1073
1074/*
1075 * try to determine where a shared mapping can be made
1076 * - only supported for NOMMU at the moment (MMU can't doesn't copy private
1077 *   mappings)
1078 */
1079#ifndef CONFIG_MMU
1080static unsigned long mtdchar_get_unmapped_area(struct file *file,
1081                                           unsigned long addr,
1082                                           unsigned long len,
1083                                           unsigned long pgoff,
1084                                           unsigned long flags)
1085{
1086        struct mtd_file_info *mfi = file->private_data;
1087        struct mtd_info *mtd = mfi->mtd;
1088        unsigned long offset;
1089        int ret;
1090
1091        if (addr != 0)
1092                return (unsigned long) -EINVAL;
1093
1094        if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
1095                return (unsigned long) -EINVAL;
1096
1097        offset = pgoff << PAGE_SHIFT;
1098        if (offset > mtd->size - len)
1099                return (unsigned long) -EINVAL;
1100
1101        ret = mtd_get_unmapped_area(mtd, len, offset, flags);
1102        return ret == -EOPNOTSUPP ? -ENOSYS : ret;
1103}
1104#endif
1105
1106/*
1107 * set up a mapping for shared memory segments
1108 */
1109static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
1110{
1111#ifdef CONFIG_MMU
1112        struct mtd_file_info *mfi = file->private_data;
1113        struct mtd_info *mtd = mfi->mtd;
1114        struct map_info *map = mtd->priv;
1115
1116        /* This is broken because it assumes the MTD device is map-based
1117           and that mtd->priv is a valid struct map_info.  It should be
1118           replaced with something that uses the mtd_get_unmapped_area()
1119           operation properly. */
1120        if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
1121#ifdef pgprot_noncached
1122                if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory))
1123                        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1124#endif
1125                return vm_iomap_memory(vma, map->phys, map->size);
1126        }
1127        return -ENOSYS;
1128#else
1129        return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
1130#endif
1131}
1132
1133static const struct file_operations mtd_fops = {
1134        .owner          = THIS_MODULE,
1135        .llseek         = mtdchar_lseek,
1136        .read           = mtdchar_read,
1137        .write          = mtdchar_write,
1138        .unlocked_ioctl = mtdchar_unlocked_ioctl,
1139#ifdef CONFIG_COMPAT
1140        .compat_ioctl   = mtdchar_compat_ioctl,
1141#endif
1142        .open           = mtdchar_open,
1143        .release        = mtdchar_close,
1144        .mmap           = mtdchar_mmap,
1145#ifndef CONFIG_MMU
1146        .get_unmapped_area = mtdchar_get_unmapped_area,
1147#endif
1148};
1149
1150static const struct super_operations mtd_ops = {
1151        .drop_inode = generic_delete_inode,
1152        .statfs = simple_statfs,
1153};
1154
1155static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type,
1156                                int flags, const char *dev_name, void *data)
1157{
1158        return mount_pseudo(fs_type, "mtd_inode:", &mtd_ops, NULL, MTD_INODE_FS_MAGIC);
1159}
1160
1161static struct file_system_type mtd_inodefs_type = {
1162       .name = "mtd_inodefs",
1163       .mount = mtd_inodefs_mount,
1164       .kill_sb = kill_anon_super,
1165};
1166MODULE_ALIAS_FS("mtd_inodefs");
1167
1168int __init init_mtdchar(void)
1169{
1170        int ret;
1171
1172        ret = __register_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS,
1173                                   "mtd", &mtd_fops);
1174        if (ret < 0) {
1175                pr_err("Can't allocate major number %d for MTD\n",
1176                       MTD_CHAR_MAJOR);
1177                return ret;
1178        }
1179
1180        ret = register_filesystem(&mtd_inodefs_type);
1181        if (ret) {
1182                pr_err("Can't register mtd_inodefs filesystem, error %d\n",
1183                       ret);
1184                goto err_unregister_chdev;
1185        }
1186
1187        return ret;
1188
1189err_unregister_chdev:
1190        __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
1191        return ret;
1192}
1193
1194void __exit cleanup_mtdchar(void)
1195{
1196        unregister_filesystem(&mtd_inodefs_type);
1197        __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
1198}
1199
1200MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
1201
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.