1 /* 2 * Character-device access to raw MTD devices. 3 * 4 */ 5 6 #include <linux/device.h> 7 #include <linux/fs.h> 8 #include <linux/mm.h> 9 #include <linux/err.h> 10 #include <linux/init.h> 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 #include <linux/sched.h> 15 #include <linux/smp_lock.h> 16 #include <linux/backing-dev.h> 17 18 #include <linux/mtd/mtd.h> 19 #include <linux/mtd/compatmac.h> 20 21 #include <asm/uaccess.h> 22 23 24 /* 25 * Data structure to hold the pointer to the mtd device as well 26 * as mode information ofr various use cases. 27 */ 28 struct mtd_file_info { 29 struct mtd_info *mtd; 30 enum mtd_file_modes mode; 31 }; 32 33 static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) 34 { 35 struct mtd_file_info *mfi = file->private_data; 36 struct mtd_info *mtd = mfi->mtd; 37 38 switch (orig) { 39 case SEEK_SET: 40 break; 41 case SEEK_CUR: 42 offset += file->f_pos; 43 break; 44 case SEEK_END: 45 offset += mtd->size; 46 break; 47 default: 48 return -EINVAL; 49 } 50 51 if (offset >= 0 && offset <= mtd->size) 52 return file->f_pos = offset; 53 54 return -EINVAL; 55 } 56 57 58 59 static int mtd_open(struct inode *inode, struct file *file) 60 { 61 int minor = iminor(inode); 62 int devnum = minor >> 1; 63 int ret = 0; 64 struct mtd_info *mtd; 65 struct mtd_file_info *mfi; 66 67 DEBUG(MTD_DEBUG_LEVEL0, "MTD_open\n"); 68 69 if (devnum >= MAX_MTD_DEVICES) 70 return -ENODEV; 71 72 /* You can't open the RO devices RW */ 73 if ((file->f_mode & FMODE_WRITE) && (minor & 1)) 74 return -EACCES; 75 76 lock_kernel(); 77 mtd = get_mtd_device(NULL, devnum); 78 79 if (IS_ERR(mtd)) { 80 ret = PTR_ERR(mtd); 81 goto out; 82 } 83 84 if (mtd->type == MTD_ABSENT) { 85 put_mtd_device(mtd); 86 ret = -ENODEV; 87 goto out; 88 } 89 90 if (mtd->backing_dev_info) 91 file->f_mapping->backing_dev_info = mtd->backing_dev_info; 92 93 /* You can't open it RW if it's not a writeable device */ 94 if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { 95 put_mtd_device(mtd); 96 ret = -EACCES; 97 goto out; 98 } 99 100 mfi = kzalloc(sizeof(*mfi), GFP_KERNEL); 101 if (!mfi) { 102 put_mtd_device(mtd); 103 ret = -ENOMEM; 104 goto out; 105 } 106 mfi->mtd = mtd; 107 file->private_data = mfi; 108 109 out: 110 unlock_kernel(); 111 return ret; 112 } /* mtd_open */ 113 114 /*====================================================================*/ 115 116 static int mtd_close(struct inode *inode, struct file *file) 117 { 118 struct mtd_file_info *mfi = file->private_data; 119 struct mtd_info *mtd = mfi->mtd; 120 121 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 122 123 /* Only sync if opened RW */ 124 if ((file->f_mode & FMODE_WRITE) && mtd->sync) 125 mtd->sync(mtd); 126 127 put_mtd_device(mtd); 128 file->private_data = NULL; 129 kfree(mfi); 130 131 return 0; 132 } /* mtd_close */ 133 134 /* FIXME: This _really_ needs to die. In 2.5, we should lock the 135 userspace buffer down and use it directly with readv/writev. 136 */ 137 #define MAX_KMALLOC_SIZE 0x20000 138 139 static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) 140 { 141 struct mtd_file_info *mfi = file->private_data; 142 struct mtd_info *mtd = mfi->mtd; 143 size_t retlen=0; 144 size_t total_retlen=0; 145 int ret=0; 146 int len; 147 char *kbuf; 148 149 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); 150 151 if (*ppos + count > mtd->size) 152 count = mtd->size - *ppos; 153 154 if (!count) 155 return 0; 156 157 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers 158 and pass them directly to the MTD functions */ 159 160 if (count > MAX_KMALLOC_SIZE) 161 kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL); 162 else 163 kbuf=kmalloc(count, GFP_KERNEL); 164 165 if (!kbuf) 166 return -ENOMEM; 167 168 while (count) { 169 170 if (count > MAX_KMALLOC_SIZE) 171 len = MAX_KMALLOC_SIZE; 172 else 173 len = count; 174 175 switch (mfi->mode) { 176 case MTD_MODE_OTP_FACTORY: 177 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 178 break; 179 case MTD_MODE_OTP_USER: 180 ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf); 181 break; 182 case MTD_MODE_RAW: 183 { 184 struct mtd_oob_ops ops; 185 186 ops.mode = MTD_OOB_RAW; 187 ops.datbuf = kbuf; 188 ops.oobbuf = NULL; 189 ops.len = len; 190 191 ret = mtd->read_oob(mtd, *ppos, &ops); 192 retlen = ops.retlen; 193 break; 194 } 195 default: 196 ret = mtd->read(mtd, *ppos, len, &retlen, kbuf); 197 } 198 /* Nand returns -EBADMSG on ecc errors, but it returns 199 * the data. For our userspace tools it is important 200 * to dump areas with ecc errors ! 201 * For kernel internal usage it also might return -EUCLEAN 202 * to signal the caller that a bitflip has occured and has 203 * been corrected by the ECC algorithm. 204 * Userspace software which accesses NAND this way 205 * must be aware of the fact that it deals with NAND 206 */ 207 if (!ret || (ret == -EUCLEAN) || (ret == -EBADMSG)) { 208 *ppos += retlen; 209 if (copy_to_user(buf, kbuf, retlen)) { 210 kfree(kbuf); 211 return -EFAULT; 212 } 213 else 214 total_retlen += retlen; 215 216 count -= retlen; 217 buf += retlen; 218 if (retlen == 0) 219 count = 0; 220 } 221 else { 222 kfree(kbuf); 223 return ret; 224 } 225 226 } 227 228 kfree(kbuf); 229 return total_retlen; 230 } /* mtd_read */ 231 232 static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) 233 { 234 struct mtd_file_info *mfi = file->private_data; 235 struct mtd_info *mtd = mfi->mtd; 236 char *kbuf; 237 size_t retlen; 238 size_t total_retlen=0; 239 int ret=0; 240 int len; 241 242 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); 243 244 if (*ppos == mtd->size) 245 return -ENOSPC; 246 247 if (*ppos + count > mtd->size) 248 count = mtd->size - *ppos; 249 250 if (!count) 251 return 0; 252 253 if (count > MAX_KMALLOC_SIZE) 254 kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL); 255 else 256 kbuf=kmalloc(count, GFP_KERNEL); 257 258 if (!kbuf) 259 return -ENOMEM; 260 261 while (count) { 262 263 if (count > MAX_KMALLOC_SIZE) 264 len = MAX_KMALLOC_SIZE; 265 else 266 len = count; 267 268 if (copy_from_user(kbuf, buf, len)) { 269 kfree(kbuf); 270 return -EFAULT; 271 } 272 273 switch (mfi->mode) { 274 case MTD_MODE_OTP_FACTORY: 275 ret = -EROFS; 276 break; 277 case MTD_MODE_OTP_USER: 278 if (!mtd->write_user_prot_reg) { 279 ret = -EOPNOTSUPP; 280 break; 281 } 282 ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf); 283 break; 284 285 case MTD_MODE_RAW: 286 { 287 struct mtd_oob_ops ops; 288 289 ops.mode = MTD_OOB_RAW; 290 ops.datbuf = kbuf; 291 ops.oobbuf = NULL; 292 ops.len = len; 293 294 ret = mtd->write_oob(mtd, *ppos, &ops); 295 retlen = ops.retlen; 296 break; 297 } 298 299 default: 300 ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf); 301 } 302 if (!ret) { 303 *ppos += retlen; 304 total_retlen += retlen; 305 count -= retlen; 306 buf += retlen; 307 } 308 else { 309 kfree(kbuf); 310 return ret; 311 } 312 } 313 314 kfree(kbuf); 315 return total_retlen; 316 } /* mtd_write */ 317 318 /*====================================================================== 319 320 IOCTL calls for getting device parameters. 321 322 ======================================================================*/ 323 static void mtdchar_erase_callback (struct erase_info *instr) 324 { 325 wake_up((wait_queue_head_t *)instr->priv); 326 } 327 328 #ifdef CONFIG_HAVE_MTD_OTP 329 static int otp_select_filemode(struct mtd_file_info *mfi, int mode) 330 { 331 struct mtd_info *mtd = mfi->mtd; 332 int ret = 0; 333 334 switch (mode) { 335 case MTD_OTP_FACTORY: 336 if (!mtd->read_fact_prot_reg) 337 ret = -EOPNOTSUPP; 338 else 339 mfi->mode = MTD_MODE_OTP_FACTORY; 340 break; 341 case MTD_OTP_USER: 342 if (!mtd->read_fact_prot_reg) 343 ret = -EOPNOTSUPP; 344 else 345 mfi->mode = MTD_MODE_OTP_USER; 346 break; 347 default: 348 ret = -EINVAL; 349 case MTD_OTP_OFF: 350 break; 351 } 352 return ret; 353 } 354 #else 355 # define otp_select_filemode(f,m) -EOPNOTSUPP 356 #endif 357 358 static int mtd_ioctl(struct inode *inode, struct file *file, 359 u_int cmd, u_long arg) 360 { 361 struct mtd_file_info *mfi = file->private_data; 362 struct mtd_info *mtd = mfi->mtd; 363 void __user *argp = (void __user *)arg; 364 int ret = 0; 365 u_long size; 366 struct mtd_info_user info; 367 368 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); 369 370 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; 371 if (cmd & IOC_IN) { 372 if (!access_ok(VERIFY_READ, argp, size)) 373 return -EFAULT; 374 } 375 if (cmd & IOC_OUT) { 376 if (!access_ok(VERIFY_WRITE, argp, size)) 377 return -EFAULT; 378 } 379 380 switch (cmd) { 381 case MEMGETREGIONCOUNT: 382 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) 383 return -EFAULT; 384 break; 385 386 case MEMGETREGIONINFO: 387 { 388 uint32_t ur_idx; 389 struct mtd_erase_region_info *kr; 390 struct region_info_user *ur = (struct region_info_user *) argp; 391 392 if (get_user(ur_idx, &(ur->regionindex))) 393 return -EFAULT; 394 395 kr = &(mtd->eraseregions[ur_idx]); 396 397 if (put_user(kr->offset, &(ur->offset)) 398 || put_user(kr->erasesize, &(ur->erasesize)) 399 || put_user(kr->numblocks, &(ur->numblocks))) 400 return -EFAULT; 401 402 break; 403 } 404 405 case MEMGETINFO: 406 info.type = mtd->type; 407 info.flags = mtd->flags; 408 info.size = mtd->size; 409 info.erasesize = mtd->erasesize; 410 info.writesize = mtd->writesize; 411 info.oobsize = mtd->oobsize; 412 /* The below fields are obsolete */ 413 info.ecctype = -1; 414 info.eccsize = 0; 415 if (copy_to_user(argp, &info, sizeof(struct mtd_info_user))) 416 return -EFAULT; 417 break; 418 419 case MEMERASE: 420 { 421 struct erase_info *erase; 422 423 if(!(file->f_mode & FMODE_WRITE)) 424 return -EPERM; 425 426 erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL); 427 if (!erase) 428 ret = -ENOMEM; 429 else { 430 struct erase_info_user einfo; 431 432 wait_queue_head_t waitq; 433 DECLARE_WAITQUEUE(wait, current); 434 435 init_waitqueue_head(&waitq); 436 437 if (copy_from_user(&einfo, argp, 438 sizeof(struct erase_info_user))) { 439 kfree(erase); 440 return -EFAULT; 441 } 442 erase->addr = einfo.start; 443 erase->len = einfo.length; 444 erase->mtd = mtd; 445 erase->callback = mtdchar_erase_callback; 446 erase->priv = (unsigned long)&waitq; 447 448 /* 449 FIXME: Allow INTERRUPTIBLE. Which means 450 not having the wait_queue head on the stack. 451 452 If the wq_head is on the stack, and we 453 leave because we got interrupted, then the 454 wq_head is no longer there when the 455 callback routine tries to wake us up. 456 */ 457 ret = mtd->erase(mtd, erase); 458 if (!ret) { 459 set_current_state(TASK_UNINTERRUPTIBLE); 460 add_wait_queue(&waitq, &wait); 461 if (erase->state != MTD_ERASE_DONE && 462 erase->state != MTD_ERASE_FAILED) 463 schedule(); 464 remove_wait_queue(&waitq, &wait); 465 set_current_state(TASK_RUNNING); 466 467 ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0; 468 } 469 kfree(erase); 470 } 471 break; 472 } 473 474 case MEMWRITEOOB: 475 { 476 struct mtd_oob_buf buf; 477 struct mtd_oob_ops ops; 478 struct mtd_oob_buf __user *user_buf = argp; 479 uint32_t retlen; 480 481 if(!(file->f_mode & FMODE_WRITE)) 482 return -EPERM; 483 484 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 485 return -EFAULT; 486 487 if (buf.length > 4096) 488 return -EINVAL; 489 490 if (!mtd->write_oob) 491 ret = -EOPNOTSUPP; 492 else 493 ret = access_ok(VERIFY_READ, buf.ptr, 494 buf.length) ? 0 : EFAULT; 495 496 if (ret) 497 return ret; 498 499 ops.ooblen = buf.length; 500 ops.ooboffs = buf.start & (mtd->oobsize - 1); 501 ops.datbuf = NULL; 502 ops.mode = MTD_OOB_PLACE; 503 504 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 505 return -EINVAL; 506 507 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 508 if (!ops.oobbuf) 509 return -ENOMEM; 510 511 if (copy_from_user(ops.oobbuf, buf.ptr, buf.length)) { 512 kfree(ops.oobbuf); 513 return -EFAULT; 514 } 515 516 buf.start &= ~(mtd->oobsize - 1); 517 ret = mtd->write_oob(mtd, buf.start, &ops); 518 519 if (ops.oobretlen > 0xFFFFFFFFU) 520 ret = -EOVERFLOW; 521 retlen = ops.oobretlen; 522 if (copy_to_user(&user_buf->length, &retlen, sizeof(buf.length))) 523 ret = -EFAULT; 524 525 kfree(ops.oobbuf); 526 break; 527 528 } 529 530 case MEMREADOOB: 531 { 532 struct mtd_oob_buf buf; 533 struct mtd_oob_ops ops; 534 535 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 536 return -EFAULT; 537 538 if (buf.length > 4096) 539 return -EINVAL; 540 541 if (!mtd->read_oob) 542 ret = -EOPNOTSUPP; 543 else 544 ret = access_ok(VERIFY_WRITE, buf.ptr, 545 buf.length) ? 0 : -EFAULT; 546 if (ret) 547 return ret; 548 549 ops.ooblen = buf.length; 550 ops.ooboffs = buf.start & (mtd->oobsize - 1); 551 ops.datbuf = NULL; 552 ops.mode = MTD_OOB_PLACE; 553 554 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) 555 return -EINVAL; 556 557 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 558 if (!ops.oobbuf) 559 return -ENOMEM; 560 561 buf.start &= ~(mtd->oobsize - 1); 562 ret = mtd->read_oob(mtd, buf.start, &ops); 563 564 if (put_user(ops.oobretlen, (uint32_t __user *)argp)) 565 ret = -EFAULT; 566 else if (ops.oobretlen && copy_to_user(buf.ptr, ops.oobbuf, 567 ops.oobretlen)) 568 ret = -EFAULT; 569 570 kfree(ops.oobbuf); 571 break; 572 } 573 574 case MEMLOCK: 575 { 576 struct erase_info_user einfo; 577 578 if (copy_from_user(&einfo, argp, sizeof(einfo))) 579 return -EFAULT; 580 581 if (!mtd->lock) 582 ret = -EOPNOTSUPP; 583 else 584 ret = mtd->lock(mtd, einfo.start, einfo.length); 585 break; 586 } 587 588 case MEMUNLOCK: 589 { 590 struct erase_info_user einfo; 591 592 if (copy_from_user(&einfo, argp, sizeof(einfo))) 593 return -EFAULT; 594 595 if (!mtd->unlock) 596 ret = -EOPNOTSUPP; 597 else 598 ret = mtd->unlock(mtd, einfo.start, einfo.length); 599 break; 600 } 601 602 /* Legacy interface */ 603 case MEMGETOOBSEL: 604 { 605 struct nand_oobinfo oi; 606 607 if (!mtd->ecclayout) 608 return -EOPNOTSUPP; 609 if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos)) 610 return -EINVAL; 611 612 oi.useecc = MTD_NANDECC_AUTOPLACE; 613 memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos)); 614 memcpy(&oi.oobfree, mtd->ecclayout->oobfree, 615 sizeof(oi.oobfree)); 616 oi.eccbytes = mtd->ecclayout->eccbytes; 617 618 if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo))) 619 return -EFAULT; 620 break; 621 } 622 623 case MEMGETBADBLOCK: 624 { 625 loff_t offs; 626 627 if (copy_from_user(&offs, argp, sizeof(loff_t))) 628 return -EFAULT; 629 if (!mtd->block_isbad) 630 ret = -EOPNOTSUPP; 631 else 632 return mtd->block_isbad(mtd, offs); 633 break; 634 } 635 636 case MEMSETBADBLOCK: 637 { 638 loff_t offs; 639 640 if (copy_from_user(&offs, argp, sizeof(loff_t))) 641 return -EFAULT; 642 if (!mtd->block_markbad) 643 ret = -EOPNOTSUPP; 644 else 645 return mtd->block_markbad(mtd, offs); 646 break; 647 } 648 649 #ifdef CONFIG_HAVE_MTD_OTP 650 case OTPSELECT: 651 { 652 int mode; 653 if (copy_from_user(&mode, argp, sizeof(int))) 654 return -EFAULT; 655 656 mfi->mode = MTD_MODE_NORMAL; 657 658 ret = otp_select_filemode(mfi, mode); 659 660 file->f_pos = 0; 661 break; 662 } 663 664 case OTPGETREGIONCOUNT: 665 case OTPGETREGIONINFO: 666 { 667 struct otp_info *buf = kmalloc(4096, GFP_KERNEL); 668 if (!buf) 669 return -ENOMEM; 670 ret = -EOPNOTSUPP; 671 switch (mfi->mode) { 672 case MTD_MODE_OTP_FACTORY: 673 if (mtd->get_fact_prot_info) 674 ret = mtd->get_fact_prot_info(mtd, buf, 4096); 675 break; 676 case MTD_MODE_OTP_USER: 677 if (mtd->get_user_prot_info) 678 ret = mtd->get_user_prot_info(mtd, buf, 4096); 679 break; 680 default: 681 break; 682 } 683 if (ret >= 0) { 684 if (cmd == OTPGETREGIONCOUNT) { 685 int nbr = ret / sizeof(struct otp_info); 686 ret = copy_to_user(argp, &nbr, sizeof(int)); 687 } else 688 ret = copy_to_user(argp, buf, ret); 689 if (ret) 690 ret = -EFAULT; 691 } 692 kfree(buf); 693 break; 694 } 695 696 case OTPLOCK: 697 { 698 struct otp_info oinfo; 699 700 if (mfi->mode != MTD_MODE_OTP_USER) 701 return -EINVAL; 702 if (copy_from_user(&oinfo, argp, sizeof(oinfo))) 703 return -EFAULT; 704 if (!mtd->lock_user_prot_reg) 705 return -EOPNOTSUPP; 706 ret = mtd->lock_user_prot_reg(mtd, oinfo.start, oinfo.length); 707 break; 708 } 709 #endif 710 711 case ECCGETLAYOUT: 712 { 713 if (!mtd->ecclayout) 714 return -EOPNOTSUPP; 715 716 if (copy_to_user(argp, mtd->ecclayout, 717 sizeof(struct nand_ecclayout))) 718 return -EFAULT; 719 break; 720 } 721 722 case ECCGETSTATS: 723 { 724 if (copy_to_user(argp, &mtd->ecc_stats, 725 sizeof(struct mtd_ecc_stats))) 726 return -EFAULT; 727 break; 728 } 729 730 case MTDFILEMODE: 731 { 732 mfi->mode = 0; 733 734 switch(arg) { 735 case MTD_MODE_OTP_FACTORY: 736 case MTD_MODE_OTP_USER: 737 ret = otp_select_filemode(mfi, arg); 738 break; 739 740 case MTD_MODE_RAW: 741 if (!mtd->read_oob || !mtd->write_oob) 742 return -EOPNOTSUPP; 743 mfi->mode = arg; 744 745 case MTD_MODE_NORMAL: 746 break; 747 default: 748 ret = -EINVAL; 749 } 750 file->f_pos = 0; 751 break; 752 } 753 754 default: 755 ret = -ENOTTY; 756 } 757 758 return ret; 759 } /* memory_ioctl */ 760 761 /* 762 * try to determine where a shared mapping can be made 763 * - only supported for NOMMU at the moment (MMU can't doesn't copy private 764 * mappings) 765 */ 766 #ifndef CONFIG_MMU 767 static unsigned long mtd_get_unmapped_area(struct file *file, 768 unsigned long addr, 769 unsigned long len, 770 unsigned long pgoff, 771 unsigned long flags) 772 { 773 struct mtd_file_info *mfi = file->private_data; 774 struct mtd_info *mtd = mfi->mtd; 775 776 if (mtd->get_unmapped_area) { 777 unsigned long offset; 778 779 if (addr != 0) 780 return (unsigned long) -EINVAL; 781 782 if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT)) 783 return (unsigned long) -EINVAL; 784 785 offset = pgoff << PAGE_SHIFT; 786 if (offset > mtd->size - len) 787 return (unsigned long) -EINVAL; 788 789 return mtd->get_unmapped_area(mtd, len, offset, flags); 790 } 791 792 /* can't map directly */ 793 return (unsigned long) -ENOSYS; 794 } 795 #endif 796 797 /* 798 * set up a mapping for shared memory segments 799 */ 800 static int mtd_mmap(struct file *file, struct vm_area_struct *vma) 801 { 802 #ifdef CONFIG_MMU 803 struct mtd_file_info *mfi = file->private_data; 804 struct mtd_info *mtd = mfi->mtd; 805 806 if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) 807 return 0; 808 return -ENOSYS; 809 #else 810 return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS; 811 #endif 812 } 813 814 static const struct file_operations mtd_fops = { 815 .owner = THIS_MODULE, 816 .llseek = mtd_lseek, 817 .read = mtd_read, 818 .write = mtd_write, 819 .ioctl = mtd_ioctl, 820 .open = mtd_open, 821 .release = mtd_close, 822 .mmap = mtd_mmap, 823 #ifndef CONFIG_MMU 824 .get_unmapped_area = mtd_get_unmapped_area, 825 #endif 826 }; 827 828 static int __init init_mtdchar(void) 829 { 830 int status; 831 832 status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops); 833 if (status < 0) { 834 printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", 835 MTD_CHAR_MAJOR); 836 } 837 838 return status; 839 } 840 841 static void __exit cleanup_mtdchar(void) 842 { 843 unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); 844 } 845 846 module_init(init_mtdchar); 847 module_exit(cleanup_mtdchar); 848 849 MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR); 850 851 MODULE_LICENSE("GPL"); 852 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 853 MODULE_DESCRIPTION("Direct character-device access to MTD devices"); 854 MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR); 855