1 /* 2 * Copyright (c) International Business Machines Corp., 2006 3 * Copyright (C) 2009 Nokia Corporation 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * 19 * Author: Artem Bityutskiy 20 * 21 * MTD library. 22 */ 23 24 /* Imported from mtd-utils by dehrenberg */ 25 26 #include <limits.h> 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <errno.h> 30 #include <unistd.h> 31 #include <fcntl.h> 32 #include <dirent.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <sys/ioctl.h> 36 #include <inttypes.h> 37 38 #include <mtd/mtd-user.h> 39 #include "libmtd.h" 40 41 #include "libmtd_int.h" 42 #include "libmtd_common.h" 43 44 /** 45 * mkpath - compose full path from 2 given components. 46 * @path: the first component 47 * @name: the second component 48 * 49 * This function returns the resulting path in case of success and %NULL in 50 * case of failure. 51 */ 52 static char *mkpath(const char *path, const char *name) 53 { 54 char *n; 55 size_t len1 = strlen(path); 56 size_t len2 = strlen(name); 57 58 n = xmalloc(len1 + len2 + 6); 59 60 memcpy(n, path, len1); 61 if (n[len1 - 1] != '/') 62 n[len1++] = '/'; 63 64 memcpy(n + len1, name, len2 + 1); 65 return n; 66 } 67 68 /** 69 * read_data - read data from a file. 70 * @file: the file to read from 71 * @buf: the buffer to read to 72 * @buf_len: buffer length 73 * 74 * This function returns number of read bytes in case of success and %-1 in 75 * case of failure. Note, if the file contains more then @buf_len bytes of 76 * date, this function fails with %EINVAL error code. 77 */ 78 static int read_data(const char *file, void *buf, int buf_len) 79 { 80 int fd, rd, tmp, tmp1; 81 82 fd = open(file, O_RDONLY | O_CLOEXEC); 83 if (fd == -1) 84 return -1; 85 86 rd = read(fd, buf, buf_len); 87 if (rd == -1) { 88 sys_errmsg("cannot read \"%s\"", file); 89 goto out_error; 90 } 91 92 if (rd == buf_len) { 93 errmsg("contents of \"%s\" is too long", file); 94 errno = EINVAL; 95 goto out_error; 96 } 97 98 ((char *)buf)[rd] = '\0'; 99 100 /* Make sure all data is read */ 101 tmp1 = read(fd, &tmp, 1); 102 if (tmp1 == 1) { 103 sys_errmsg("cannot read \"%s\"", file); 104 goto out_error; 105 } 106 if (tmp1) { 107 errmsg("file \"%s\" contains too much data (> %d bytes)", 108 file, buf_len); 109 errno = EINVAL; 110 goto out_error; 111 } 112 113 if (close(fd)) { 114 sys_errmsg("close failed on \"%s\"", file); 115 return -1; 116 } 117 118 return rd; 119 120 out_error: 121 close(fd); 122 return -1; 123 } 124 125 /** 126 * read_major - read major and minor numbers from a file. 127 * @file: name of the file to read from 128 * @major: major number is returned here 129 * @minor: minor number is returned here 130 * 131 * This function returns % in case of success, and %-1 in case of failure. 132 */ 133 static int read_major(const char *file, int *major, int *minor) 134 { 135 int ret; 136 char buf[50]; 137 138 ret = read_data(file, buf, 50); 139 if (ret < 0) 140 return ret; 141 142 ret = sscanf(buf, "%d:%d\n", major, minor); 143 if (ret != 2) { 144 errno = EINVAL; 145 return errmsg("\"%s\" does not have major:minor format", file); 146 } 147 148 if (*major < 0 || *minor < 0) { 149 errno = EINVAL; 150 return errmsg("bad major:minor %d:%d in \"%s\"", 151 *major, *minor, file); 152 } 153 154 return 0; 155 } 156 157 /** 158 * dev_get_major - get major and minor numbers of an MTD device. 159 * @lib: libmtd descriptor 160 * @mtd_num: MTD device number 161 * @major: major number is returned here 162 * @minor: minor number is returned here 163 * 164 * This function returns zero in case of success and %-1 in case of failure. 165 */ 166 static int dev_get_major(struct libmtd *lib, int mtd_num, int *major, int *minor) 167 { 168 char file[strlen(lib->mtd_dev) + 50]; 169 170 sprintf(file, lib->mtd_dev, mtd_num); 171 return read_major(file, major, minor); 172 } 173 174 /** 175 * dev_read_data - read data from an MTD device's sysfs file. 176 * @patt: file pattern to read from 177 * @mtd_num: MTD device number 178 * @buf: buffer to read to 179 * @buf_len: buffer length 180 * 181 * This function returns number of read bytes in case of success and %-1 in 182 * case of failure. 183 */ 184 static int dev_read_data(const char *patt, int mtd_num, void *buf, int buf_len) 185 { 186 char file[strlen(patt) + 100]; 187 188 sprintf(file, patt, mtd_num); 189 return read_data(file, buf, buf_len); 190 } 191 192 /** 193 * read_hex_ll - read a hex 'long long' value from a file. 194 * @file: the file to read from 195 * @value: the result is stored here 196 * 197 * This function reads file @file and interprets its contents as hexadecimal 198 * 'long long' integer. If this is not true, it fails with %EINVAL error code. 199 * Returns %0 in case of success and %-1 in case of failure. 200 */ 201 static int read_hex_ll(const char *file, long long *value) 202 { 203 int fd, rd; 204 char buf[50]; 205 206 fd = open(file, O_RDONLY | O_CLOEXEC); 207 if (fd == -1) 208 return -1; 209 210 rd = read(fd, buf, sizeof(buf)); 211 if (rd == -1) { 212 sys_errmsg("cannot read \"%s\"", file); 213 goto out_error; 214 } 215 if (rd == sizeof(buf)) { 216 errmsg("contents of \"%s\" is too long", file); 217 errno = EINVAL; 218 goto out_error; 219 } 220 buf[rd] = '\0'; 221 222 if (sscanf(buf, "%llx\n", value) != 1) { 223 errmsg("cannot read integer from \"%s\"\n", file); 224 errno = EINVAL; 225 goto out_error; 226 } 227 228 if (*value < 0) { 229 errmsg("negative value %lld in \"%s\"", *value, file); 230 errno = EINVAL; 231 goto out_error; 232 } 233 234 if (close(fd)) 235 return sys_errmsg("close failed on \"%s\"", file); 236 237 return 0; 238 239 out_error: 240 close(fd); 241 return -1; 242 } 243 244 /** 245 * read_pos_ll - read a positive 'long long' value from a file. 246 * @file: the file to read from 247 * @value: the result is stored here 248 * 249 * This function reads file @file and interprets its contents as a positive 250 * 'long long' integer. If this is not true, it fails with %EINVAL error code. 251 * Returns %0 in case of success and %-1 in case of failure. 252 */ 253 static int read_pos_ll(const char *file, long long *value) 254 { 255 int fd, rd; 256 char buf[50]; 257 258 fd = open(file, O_RDONLY | O_CLOEXEC); 259 if (fd == -1) 260 return -1; 261 262 rd = read(fd, buf, 50); 263 if (rd == -1) { 264 sys_errmsg("cannot read \"%s\"", file); 265 goto out_error; 266 } 267 if (rd == 50) { 268 errmsg("contents of \"%s\" is too long", file); 269 errno = EINVAL; 270 goto out_error; 271 } 272 273 if (sscanf(buf, "%lld\n", value) != 1) { 274 errmsg("cannot read integer from \"%s\"\n", file); 275 errno = EINVAL; 276 goto out_error; 277 } 278 279 if (*value < 0) { 280 errmsg("negative value %lld in \"%s\"", *value, file); 281 errno = EINVAL; 282 goto out_error; 283 } 284 285 if (close(fd)) 286 return sys_errmsg("close failed on \"%s\"", file); 287 288 return 0; 289 290 out_error: 291 close(fd); 292 return -1; 293 } 294 295 /** 296 * read_hex_int - read an 'int' value from a file. 297 * @file: the file to read from 298 * @value: the result is stored here 299 * 300 * This function is the same as 'read_pos_ll()', but it reads an 'int' 301 * value, not 'long long'. 302 */ 303 static int read_hex_int(const char *file, int *value) 304 { 305 long long res; 306 307 if (read_hex_ll(file, &res)) 308 return -1; 309 310 /* Make sure the value has correct range */ 311 if (res > INT_MAX || res < INT_MIN) { 312 errmsg("value %lld read from file \"%s\" is out of range", 313 res, file); 314 errno = EINVAL; 315 return -1; 316 } 317 318 *value = res; 319 return 0; 320 } 321 322 /** 323 * read_pos_int - read a positive 'int' value from a file. 324 * @file: the file to read from 325 * @value: the result is stored here 326 * 327 * This function is the same as 'read_pos_ll()', but it reads an 'int' 328 * value, not 'long long'. 329 */ 330 static int read_pos_int(const char *file, int *value) 331 { 332 long long res; 333 334 if (read_pos_ll(file, &res)) 335 return -1; 336 337 /* Make sure the value is not too big */ 338 if (res > INT_MAX) { 339 errmsg("value %lld read from file \"%s\" is out of range", 340 res, file); 341 errno = EINVAL; 342 return -1; 343 } 344 345 *value = res; 346 return 0; 347 } 348 349 /** 350 * dev_read_hex_int - read an hex 'int' value from an MTD device sysfs file. 351 * @patt: file pattern to read from 352 * @mtd_num: MTD device number 353 * @value: the result is stored here 354 * 355 * This function returns %0 in case of success and %-1 in case of failure. 356 */ 357 static int dev_read_hex_int(const char *patt, int mtd_num, int *value) 358 { 359 char file[strlen(patt) + 50]; 360 361 sprintf(file, patt, mtd_num); 362 return read_hex_int(file, value); 363 } 364 365 /** 366 * dev_read_pos_int - read a positive 'int' value from an MTD device sysfs file. 367 * @patt: file pattern to read from 368 * @mtd_num: MTD device number 369 * @value: the result is stored here 370 * 371 * This function returns %0 in case of success and %-1 in case of failure. 372 */ 373 static int dev_read_pos_int(const char *patt, int mtd_num, int *value) 374 { 375 char file[strlen(patt) + 50]; 376 377 sprintf(file, patt, mtd_num); 378 return read_pos_int(file, value); 379 } 380 381 /** 382 * dev_read_pos_ll - read a positive 'long long' value from an MTD device sysfs file. 383 * @patt: file pattern to read from 384 * @mtd_num: MTD device number 385 * @value: the result is stored here 386 * 387 * This function returns %0 in case of success and %-1 in case of failure. 388 */ 389 static int dev_read_pos_ll(const char *patt, int mtd_num, long long *value) 390 { 391 char file[strlen(patt) + 50]; 392 393 sprintf(file, patt, mtd_num); 394 return read_pos_ll(file, value); 395 } 396 397 /** 398 * type_str2int - convert MTD device type to integer. 399 * @str: MTD device type string to convert 400 * 401 * This function converts MTD device type string @str, read from sysfs, into an 402 * integer. 403 */ 404 static int type_str2int(const char *str) 405 { 406 if (!strcmp(str, "nand")) 407 return MTD_NANDFLASH; 408 if (!strcmp(str, "mlc-nand")) 409 return MTD_MLCNANDFLASH; 410 if (!strcmp(str, "nor")) 411 return MTD_NORFLASH; 412 if (!strcmp(str, "rom")) 413 return MTD_ROM; 414 if (!strcmp(str, "absent")) 415 return MTD_ABSENT; 416 if (!strcmp(str, "dataflash")) 417 return MTD_DATAFLASH; 418 if (!strcmp(str, "ram")) 419 return MTD_RAM; 420 if (!strcmp(str, "ubi")) 421 return MTD_UBIVOLUME; 422 return -1; 423 } 424 425 /** 426 * dev_node2num - find UBI device number by its character device node. 427 * @lib: MTD library descriptor 428 * @node: name of the MTD device node 429 * @mtd_num: MTD device number is returned here 430 * 431 * This function returns %0 in case of success and %-1 in case of failure. 432 */ 433 static int dev_node2num(struct libmtd *lib, const char *node, int *mtd_num) 434 { 435 struct stat st; 436 int i, mjr, mnr; 437 struct mtd_info info; 438 439 if (stat(node, &st)) 440 return sys_errmsg("cannot get information about \"%s\"", node); 441 442 if (!S_ISCHR(st.st_mode)) { 443 errmsg("\"%s\" is not a character device", node); 444 errno = EINVAL; 445 return -1; 446 } 447 448 mjr = major(st.st_rdev); 449 mnr = minor(st.st_rdev); 450 451 if (mtd_get_info((libmtd_t *)lib, &info)) 452 return -1; 453 454 for (i = info.lowest_mtd_num; i <= info.highest_mtd_num; i++) { 455 int mjr1, mnr1, ret; 456 457 ret = dev_get_major(lib, i, &mjr1, &mnr1); 458 if (ret) { 459 if (errno == ENOENT) 460 continue; 461 if (!errno) 462 break; 463 return -1; 464 } 465 466 if (mjr1 == mjr && mnr1 == mnr) { 467 errno = 0; 468 *mtd_num = i; 469 return 0; 470 } 471 } 472 473 errno = ENODEV; 474 return -1; 475 } 476 477 /** 478 * sysfs_is_supported - check whether the MTD sub-system supports MTD. 479 * @lib: MTD library descriptor 480 * 481 * The Linux kernel MTD subsystem gained MTD support starting from kernel 482 * 2.6.30 and libmtd tries to use sysfs interface if possible, because the NAND 483 * sub-page size is available there (and not available at all in pre-sysfs 484 * kernels). 485 * 486 * Very old kernels did not have "/sys/class/mtd" directory. Not very old 487 * kernels (e.g., 2.6.29) did have "/sys/class/mtd/mtdX" directories, by there 488 * were no files there, e.g., the "name" file was not present. So all we can do 489 * is to check for a "/sys/class/mtd/mtdX/name" file. But this is not a 490 * reliable check, because if this is a new system with no MTD devices - we'll 491 * treat it as a pre-sysfs system. 492 */ 493 static int sysfs_is_supported(struct libmtd *lib) 494 { 495 int fd, num = -1; 496 DIR *sysfs_mtd; 497 char file[strlen(lib->mtd_name) + 10]; 498 499 sysfs_mtd = opendir(lib->sysfs_mtd); 500 if (!sysfs_mtd) { 501 if (errno == ENOENT) { 502 errno = 0; 503 return 0; 504 } 505 return sys_errmsg("cannot open \"%s\"", lib->sysfs_mtd); 506 } 507 508 /* 509 * First of all find an "mtdX" directory. This is needed because there 510 * may be, for example, mtd1 but no mtd0. 511 */ 512 while (1) { 513 int ret, mtd_num; 514 char tmp_buf[256]; 515 struct dirent *dirent; 516 517 dirent = readdir(sysfs_mtd); 518 if (!dirent) 519 break; 520 521 if (strlen(dirent->d_name) >= 255) { 522 errmsg("invalid entry in %s: \"%s\"", 523 lib->sysfs_mtd, dirent->d_name); 524 errno = EINVAL; 525 closedir(sysfs_mtd); 526 return -1; 527 } 528 529 ret = sscanf(dirent->d_name, MTD_NAME_PATT"%s", 530 &mtd_num, tmp_buf); 531 if (ret == 1) { 532 num = mtd_num; 533 break; 534 } 535 } 536 537 if (closedir(sysfs_mtd)) 538 return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_mtd); 539 540 if (num == -1) 541 /* No mtd device, treat this as pre-sysfs system */ 542 return 0; 543 544 sprintf(file, lib->mtd_name, num); 545 fd = open(file, O_RDONLY | O_CLOEXEC); 546 if (fd == -1) 547 return 0; 548 549 if (close(fd)) { 550 sys_errmsg("close failed on \"%s\"", file); 551 return -1; 552 } 553 554 return 1; 555 } 556 557 libmtd_t libmtd_open(void) 558 { 559 struct libmtd *lib; 560 561 lib = xzalloc(sizeof(*lib)); 562 563 lib->offs64_ioctls = OFFS64_IOCTLS_UNKNOWN; 564 565 lib->sysfs_mtd = mkpath("/sys", SYSFS_MTD); 566 if (!lib->sysfs_mtd) 567 goto out_error; 568 569 lib->mtd = mkpath(lib->sysfs_mtd, MTD_NAME_PATT); 570 if (!lib->mtd) 571 goto out_error; 572 573 lib->mtd_name = mkpath(lib->mtd, MTD_NAME); 574 if (!lib->mtd_name) 575 goto out_error; 576 577 if (!sysfs_is_supported(lib)) { 578 free(lib->mtd); 579 free(lib->sysfs_mtd); 580 free(lib->mtd_name); 581 lib->mtd_name = lib->mtd = lib->sysfs_mtd = NULL; 582 return lib; 583 } 584 585 lib->mtd_dev = mkpath(lib->mtd, MTD_DEV); 586 if (!lib->mtd_dev) 587 goto out_error; 588 589 lib->mtd_type = mkpath(lib->mtd, MTD_TYPE); 590 if (!lib->mtd_type) 591 goto out_error; 592 593 lib->mtd_eb_size = mkpath(lib->mtd, MTD_EB_SIZE); 594 if (!lib->mtd_eb_size) 595 goto out_error; 596 597 lib->mtd_size = mkpath(lib->mtd, MTD_SIZE); 598 if (!lib->mtd_size) 599 goto out_error; 600 601 lib->mtd_min_io_size = mkpath(lib->mtd, MTD_MIN_IO_SIZE); 602 if (!lib->mtd_min_io_size) 603 goto out_error; 604 605 lib->mtd_subpage_size = mkpath(lib->mtd, MTD_SUBPAGE_SIZE); 606 if (!lib->mtd_subpage_size) 607 goto out_error; 608 609 lib->mtd_oob_size = mkpath(lib->mtd, MTD_OOB_SIZE); 610 if (!lib->mtd_oob_size) 611 goto out_error; 612 613 lib->mtd_region_cnt = mkpath(lib->mtd, MTD_REGION_CNT); 614 if (!lib->mtd_region_cnt) 615 goto out_error; 616 617 lib->mtd_flags = mkpath(lib->mtd, MTD_FLAGS); 618 if (!lib->mtd_flags) 619 goto out_error; 620 621 lib->sysfs_supported = 1; 622 return lib; 623 624 out_error: 625 libmtd_close((libmtd_t)lib); 626 return NULL; 627 } 628 629 void libmtd_close(libmtd_t desc) 630 { 631 struct libmtd *lib = (struct libmtd *)desc; 632 633 free(lib->mtd_flags); 634 free(lib->mtd_region_cnt); 635 free(lib->mtd_oob_size); 636 free(lib->mtd_subpage_size); 637 free(lib->mtd_min_io_size); 638 free(lib->mtd_size); 639 free(lib->mtd_eb_size); 640 free(lib->mtd_type); 641 free(lib->mtd_dev); 642 free(lib->mtd_name); 643 free(lib->mtd); 644 free(lib->sysfs_mtd); 645 free(lib); 646 } 647 648 int mtd_dev_present(libmtd_t desc, int mtd_num) { 649 struct stat st; 650 struct libmtd *lib = (struct libmtd *)desc; 651 652 if (!lib->sysfs_supported) { 653 return legacy_dev_present(mtd_num) == 1; 654 } else { 655 char file[strlen(lib->mtd) + 10]; 656 657 sprintf(file, lib->mtd, mtd_num); 658 return !stat(file, &st); 659 } 660 } 661 662 int mtd_get_info(libmtd_t desc, struct mtd_info *info) 663 { 664 DIR *sysfs_mtd; 665 struct dirent *dirent; 666 struct libmtd *lib = (struct libmtd *)desc; 667 668 memset(info, 0, sizeof(struct mtd_info)); 669 670 if (!lib->sysfs_supported) 671 return legacy_mtd_get_info(info); 672 673 info->sysfs_supported = 1; 674 675 /* 676 * We have to scan the MTD sysfs directory to identify how many MTD 677 * devices are present. 678 */ 679 sysfs_mtd = opendir(lib->sysfs_mtd); 680 if (!sysfs_mtd) { 681 if (errno == ENOENT) { 682 errno = ENODEV; 683 return -1; 684 } 685 return sys_errmsg("cannot open \"%s\"", lib->sysfs_mtd); 686 } 687 688 info->lowest_mtd_num = INT_MAX; 689 while (1) { 690 int mtd_num, ret; 691 char tmp_buf[256]; 692 693 errno = 0; 694 dirent = readdir(sysfs_mtd); 695 if (!dirent) 696 break; 697 698 if (strlen(dirent->d_name) >= 255) { 699 errmsg("invalid entry in %s: \"%s\"", 700 lib->sysfs_mtd, dirent->d_name); 701 errno = EINVAL; 702 goto out_close; 703 } 704 705 ret = sscanf(dirent->d_name, MTD_NAME_PATT"%s", 706 &mtd_num, tmp_buf); 707 if (ret == 1) { 708 info->mtd_dev_cnt += 1; 709 if (mtd_num > info->highest_mtd_num) 710 info->highest_mtd_num = mtd_num; 711 if (mtd_num < info->lowest_mtd_num) 712 info->lowest_mtd_num = mtd_num; 713 } 714 } 715 716 if (!dirent && errno) { 717 sys_errmsg("readdir failed on \"%s\"", lib->sysfs_mtd); 718 goto out_close; 719 } 720 721 if (closedir(sysfs_mtd)) 722 return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_mtd); 723 724 if (info->lowest_mtd_num == INT_MAX) 725 info->lowest_mtd_num = 0; 726 727 return 0; 728 729 out_close: 730 closedir(sysfs_mtd); 731 return -1; 732 } 733 734 int mtd_get_dev_info1(libmtd_t desc, int mtd_num, struct mtd_dev_info *mtd) 735 { 736 int ret; 737 struct libmtd *lib = (struct libmtd *)desc; 738 739 memset(mtd, 0, sizeof(struct mtd_dev_info)); 740 mtd->mtd_num = mtd_num; 741 742 if (!mtd_dev_present(desc, mtd_num)) { 743 errno = ENODEV; 744 return -1; 745 } else if (!lib->sysfs_supported) 746 return legacy_get_dev_info1(mtd_num, mtd); 747 748 if (dev_get_major(lib, mtd_num, &mtd->major, &mtd->minor)) 749 return -1; 750 751 ret = dev_read_data(lib->mtd_name, mtd_num, &mtd->name, 752 MTD_NAME_MAX + 1); 753 if (ret < 0) 754 return -1; 755 ((char *)mtd->name)[ret - 1] = '\0'; 756 757 ret = dev_read_data(lib->mtd_type, mtd_num, &mtd->type_str, 758 MTD_TYPE_MAX + 1); 759 if (ret < 0) 760 return -1; 761 ((char *)mtd->type_str)[ret - 1] = '\0'; 762 763 if (dev_read_pos_int(lib->mtd_eb_size, mtd_num, &mtd->eb_size)) 764 return -1; 765 if (dev_read_pos_ll(lib->mtd_size, mtd_num, &mtd->size)) 766 return -1; 767 if (dev_read_pos_int(lib->mtd_min_io_size, mtd_num, &mtd->min_io_size)) 768 return -1; 769 if (dev_read_pos_int(lib->mtd_subpage_size, mtd_num, &mtd->subpage_size)) 770 return -1; 771 if (dev_read_pos_int(lib->mtd_oob_size, mtd_num, &mtd->oob_size)) 772 return -1; 773 if (dev_read_pos_int(lib->mtd_region_cnt, mtd_num, &mtd->region_cnt)) 774 return -1; 775 if (dev_read_hex_int(lib->mtd_flags, mtd_num, &ret)) 776 return -1; 777 mtd->writable = !!(ret & MTD_WRITEABLE); 778 779 mtd->eb_cnt = mtd->size / mtd->eb_size; 780 mtd->type = type_str2int(mtd->type_str); 781 mtd->bb_allowed = !!(mtd->type == MTD_NANDFLASH || 782 mtd->type == MTD_MLCNANDFLASH); 783 784 return 0; 785 } 786 787 int mtd_get_dev_info(libmtd_t desc, const char *node, struct mtd_dev_info *mtd) 788 { 789 int mtd_num; 790 struct libmtd *lib = (struct libmtd *)desc; 791 792 if (!lib->sysfs_supported) 793 return legacy_get_dev_info(node, mtd); 794 795 if (dev_node2num(lib, node, &mtd_num)) 796 return -1; 797 798 return mtd_get_dev_info1(desc, mtd_num, mtd); 799 } 800 801 static inline int mtd_ioctl_error(const struct mtd_dev_info *mtd, int eb, 802 const char *sreq) 803 { 804 return sys_errmsg("%s ioctl failed for eraseblock %d (mtd%d)", 805 sreq, eb, mtd->mtd_num); 806 } 807 808 static int mtd_valid_erase_block(const struct mtd_dev_info *mtd, int eb) 809 { 810 if (eb < 0 || eb >= mtd->eb_cnt) { 811 errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", 812 eb, mtd->mtd_num, mtd->eb_cnt); 813 errno = EINVAL; 814 return -1; 815 } 816 return 0; 817 } 818 819 static int mtd_xlock(const struct mtd_dev_info *mtd, int fd, int eb, int req, 820 const char *sreq) 821 { 822 int ret; 823 struct erase_info_user ei; 824 825 ret = mtd_valid_erase_block(mtd, eb); 826 if (ret) 827 return ret; 828 829 ei.start = eb * mtd->eb_size; 830 ei.length = mtd->eb_size; 831 832 ret = ioctl(fd, req, &ei); 833 if (ret < 0) 834 return mtd_ioctl_error(mtd, eb, sreq); 835 836 return 0; 837 } 838 #define mtd_xlock(mtd, fd, eb, req) mtd_xlock(mtd, fd, eb, req, #req) 839 840 int mtd_lock(const struct mtd_dev_info *mtd, int fd, int eb) 841 { 842 return mtd_xlock(mtd, fd, eb, MEMLOCK); 843 } 844 845 int mtd_unlock(const struct mtd_dev_info *mtd, int fd, int eb) 846 { 847 return mtd_xlock(mtd, fd, eb, MEMUNLOCK); 848 } 849 850 int mtd_erase(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb) 851 { 852 int ret; 853 struct libmtd *lib = (struct libmtd *)desc; 854 struct erase_info_user64 ei64; 855 struct erase_info_user ei; 856 857 ret = mtd_valid_erase_block(mtd, eb); 858 if (ret) 859 return ret; 860 861 ei64.start = (__u64)eb * mtd->eb_size; 862 ei64.length = mtd->eb_size; 863 864 if (lib->offs64_ioctls == OFFS64_IOCTLS_SUPPORTED || 865 lib->offs64_ioctls == OFFS64_IOCTLS_UNKNOWN) { 866 ret = ioctl(fd, MEMERASE64, &ei64); 867 if (ret == 0) 868 return ret; 869 870 if (errno != ENOTTY || 871 lib->offs64_ioctls != OFFS64_IOCTLS_UNKNOWN) 872 return mtd_ioctl_error(mtd, eb, "MEMERASE64"); 873 874 /* 875 * MEMERASE64 support was added in kernel version 2.6.31, so 876 * probably we are working with older kernel and this ioctl is 877 * not supported. 878 */ 879 lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED; 880 } 881 882 if (ei64.start + ei64.length > 0xFFFFFFFF) { 883 errmsg("this system can address only %u eraseblocks", 884 0xFFFFFFFFU / mtd->eb_size); 885 errno = EINVAL; 886 return -1; 887 } 888 889 ei.start = ei64.start; 890 ei.length = ei64.length; 891 ret = ioctl(fd, MEMERASE, &ei); 892 if (ret < 0) 893 return mtd_ioctl_error(mtd, eb, "MEMERASE"); 894 return 0; 895 } 896 897 int mtd_regioninfo(int fd, int regidx, struct region_info_user *reginfo) 898 { 899 int ret; 900 901 if (regidx < 0) { 902 errno = ENODEV; 903 return -1; 904 } 905 906 reginfo->regionindex = regidx; 907 908 ret = ioctl(fd, MEMGETREGIONINFO, reginfo); 909 if (ret < 0) 910 return sys_errmsg("%s ioctl failed for erase region %d", 911 "MEMGETREGIONINFO", regidx); 912 913 return 0; 914 } 915 916 int mtd_is_locked(const struct mtd_dev_info *mtd, int fd, int eb) 917 { 918 int ret; 919 erase_info_t ei; 920 921 ei.start = eb * mtd->eb_size; 922 ei.length = mtd->eb_size; 923 924 ret = ioctl(fd, MEMISLOCKED, &ei); 925 if (ret < 0) { 926 if (errno != ENOTTY && errno != EOPNOTSUPP) 927 return mtd_ioctl_error(mtd, eb, "MEMISLOCKED"); 928 else 929 errno = EOPNOTSUPP; 930 } 931 932 return ret; 933 } 934 935 /* Patterns to write to a physical eraseblock when torturing it */ 936 static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; 937 938 /** 939 * check_pattern - check if buffer contains only a certain byte pattern. 940 * @buf: buffer to check 941 * @patt: the pattern to check 942 * @size: buffer size in bytes 943 * 944 * This function returns %1 in there are only @patt bytes in @buf, and %0 if 945 * something else was also found. 946 */ 947 static int check_pattern(const void *buf, uint8_t patt, int size) 948 { 949 int i; 950 951 for (i = 0; i < size; i++) 952 if (((const uint8_t *)buf)[i] != patt) 953 return 0; 954 return 1; 955 } 956 957 int mtd_torture(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb) 958 { 959 int err, i, patt_count; 960 void *buf; 961 962 normsg("run torture test for PEB %d", eb); 963 patt_count = ARRAY_SIZE(patterns); 964 965 buf = xmalloc(mtd->eb_size); 966 967 for (i = 0; i < patt_count; i++) { 968 err = mtd_erase(desc, mtd, fd, eb); 969 if (err) 970 goto out; 971 972 /* Make sure the PEB contains only 0xFF bytes */ 973 err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size); 974 if (err) 975 goto out; 976 977 err = check_pattern(buf, 0xFF, mtd->eb_size); 978 if (err == 0) { 979 errmsg("erased PEB %d, but a non-0xFF byte found", eb); 980 errno = EIO; 981 goto out; 982 } 983 984 /* Write a pattern and check it */ 985 memset(buf, patterns[i], mtd->eb_size); 986 err = mtd_write(desc, mtd, fd, eb, 0, buf, mtd->eb_size, NULL, 987 0, 0); 988 if (err) 989 goto out; 990 991 memset(buf, ~patterns[i], mtd->eb_size); 992 err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size); 993 if (err) 994 goto out; 995 996 err = check_pattern(buf, patterns[i], mtd->eb_size); 997 if (err == 0) { 998 errmsg("pattern %x checking failed for PEB %d", 999 patterns[i], eb); 1000 errno = EIO; 1001 goto out; 1002 } 1003 } 1004 1005 err = 0; 1006 normsg("PEB %d passed torture test, do not mark it a bad", eb); 1007 1008 out: 1009 free(buf); 1010 return -1; 1011 } 1012 1013 int mtd_is_bad(const struct mtd_dev_info *mtd, int fd, int eb) 1014 { 1015 int ret; 1016 loff_t seek; 1017 1018 ret = mtd_valid_erase_block(mtd, eb); 1019 if (ret) 1020 return ret; 1021 1022 if (!mtd->bb_allowed) 1023 return 0; 1024 1025 seek = (loff_t)eb * mtd->eb_size; 1026 ret = ioctl(fd, MEMGETBADBLOCK, &seek); 1027 if (ret == -1) 1028 return mtd_ioctl_error(mtd, eb, "MEMGETBADBLOCK"); 1029 return ret; 1030 } 1031 1032 int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb) 1033 { 1034 int ret; 1035 loff_t seek; 1036 1037 if (!mtd->bb_allowed) { 1038 errno = EINVAL; 1039 return -1; 1040 } 1041 1042 ret = mtd_valid_erase_block(mtd, eb); 1043 if (ret) 1044 return ret; 1045 1046 seek = (loff_t)eb * mtd->eb_size; 1047 ret = ioctl(fd, MEMSETBADBLOCK, &seek); 1048 if (ret == -1) 1049 return mtd_ioctl_error(mtd, eb, "MEMSETBADBLOCK"); 1050 return 0; 1051 } 1052 1053 int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs, 1054 void *buf, int len) 1055 { 1056 int ret, rd = 0; 1057 off_t seek; 1058 1059 ret = mtd_valid_erase_block(mtd, eb); 1060 if (ret) 1061 return ret; 1062 1063 if (offs < 0 || offs + len > mtd->eb_size) { 1064 errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d", 1065 offs, len, mtd->mtd_num, mtd->eb_size); 1066 errno = EINVAL; 1067 return -1; 1068 } 1069 1070 /* Seek to the beginning of the eraseblock */ 1071 seek = (off_t)eb * mtd->eb_size + offs; 1072 if (lseek(fd, seek, SEEK_SET) != seek) 1073 return sys_errmsg("cannot seek mtd%d to offset %"PRIdoff_t, 1074 mtd->mtd_num, seek); 1075 1076 while (rd < len) { 1077 ret = read(fd, buf, len); 1078 if (ret < 0) 1079 return sys_errmsg("cannot read %d bytes from mtd%d (eraseblock %d, offset %d)", 1080 len, mtd->mtd_num, eb, offs); 1081 rd += ret; 1082 } 1083 1084 return 0; 1085 } 1086 1087 static int legacy_auto_oob_layout(const struct mtd_dev_info *mtd, int fd, 1088 int ooblen, void *oob) { 1089 struct nand_oobinfo old_oobinfo; 1090 int start, len; 1091 uint8_t *tmp_buf; 1092 1093 /* Read the current oob info */ 1094 if (ioctl(fd, MEMGETOOBSEL, &old_oobinfo)) 1095 return sys_errmsg("MEMGETOOBSEL failed"); 1096 1097 tmp_buf = malloc(ooblen); 1098 memcpy(tmp_buf, oob, ooblen); 1099 1100 /* 1101 * We use autoplacement and have the oobinfo with the autoplacement 1102 * information from the kernel available 1103 */ 1104 if (old_oobinfo.useecc == MTD_NANDECC_AUTOPLACE) { 1105 int i, tags_pos = 0; 1106 for (i = 0; old_oobinfo.oobfree[i][1]; i++) { 1107 /* Set the reserved bytes to 0xff */ 1108 start = old_oobinfo.oobfree[i][0]; 1109 len = old_oobinfo.oobfree[i][1]; 1110 memcpy(oob + start, tmp_buf + tags_pos, len); 1111 tags_pos += len; 1112 } 1113 } else { 1114 /* Set at least the ecc byte positions to 0xff */ 1115 start = old_oobinfo.eccbytes; 1116 len = mtd->oob_size - start; 1117 memcpy(oob + start, tmp_buf + start, len); 1118 } 1119 free(tmp_buf); 1120 1121 return 0; 1122 } 1123 1124 int mtd_write(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb, 1125 int offs, void *data, int len, void *oob, int ooblen, 1126 uint8_t mode) 1127 { 1128 int ret; 1129 off_t seek; 1130 struct mtd_write_req ops; 1131 1132 ret = mtd_valid_erase_block(mtd, eb); 1133 if (ret) 1134 return ret; 1135 1136 if (offs < 0 || offs + len > mtd->eb_size) { 1137 errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d", 1138 offs, len, mtd->mtd_num, mtd->eb_size); 1139 errno = EINVAL; 1140 return -1; 1141 } 1142 if (offs % mtd->subpage_size) { 1143 errmsg("write offset %d is not aligned to mtd%d min. I/O size %d", 1144 offs, mtd->mtd_num, mtd->subpage_size); 1145 errno = EINVAL; 1146 return -1; 1147 } 1148 if (len % mtd->subpage_size) { 1149 errmsg("write length %d is not aligned to mtd%d min. I/O size %d", 1150 len, mtd->mtd_num, mtd->subpage_size); 1151 errno = EINVAL; 1152 return -1; 1153 } 1154 1155 /* Calculate seek address */ 1156 seek = (off_t)eb * mtd->eb_size + offs; 1157 1158 if (oob) { 1159 ops.start = seek; 1160 ops.len = len; 1161 ops.ooblen = ooblen; 1162 ops.usr_data = (uint64_t)(unsigned long)data; 1163 ops.usr_oob = (uint64_t)(unsigned long)oob; 1164 ops.mode = mode; 1165 1166 ret = ioctl(fd, MEMWRITE, &ops); 1167 if (ret == 0) 1168 return 0; 1169 else if (errno != ENOTTY && errno != EOPNOTSUPP) 1170 return mtd_ioctl_error(mtd, eb, "MEMWRITE"); 1171 1172 /* Fall back to old OOB ioctl() if necessary */ 1173 if (mode == MTD_OPS_AUTO_OOB) 1174 if (legacy_auto_oob_layout(mtd, fd, ooblen, oob)) 1175 return -1; 1176 if (mtd_write_oob(desc, mtd, fd, seek, ooblen, oob) < 0) 1177 return sys_errmsg("cannot write to OOB"); 1178 } 1179 if (data) { 1180 /* Seek to the beginning of the eraseblock */ 1181 if (lseek(fd, seek, SEEK_SET) != seek) 1182 return sys_errmsg("cannot seek mtd%d to offset %"PRIdoff_t, 1183 mtd->mtd_num, seek); 1184 ret = write(fd, data, len); 1185 if (ret != len) 1186 return sys_errmsg("cannot write %d bytes to mtd%d " 1187 "(eraseblock %d, offset %d)", 1188 len, mtd->mtd_num, eb, offs); 1189 } 1190 1191 return 0; 1192 } 1193 1194 static int do_oob_op(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, 1195 uint64_t start, uint64_t length, void *data, unsigned int cmd64, 1196 unsigned int cmd) 1197 { 1198 int ret, oob_offs; 1199 struct mtd_oob_buf64 oob64; 1200 struct mtd_oob_buf oob; 1201 unsigned long long max_offs; 1202 const char *cmd64_str, *cmd_str; 1203 struct libmtd *lib = (struct libmtd *)desc; 1204 1205 if (cmd64 == MEMREADOOB64) { 1206 cmd64_str = "MEMREADOOB64"; 1207 cmd_str = "MEMREADOOB"; 1208 } else { 1209 cmd64_str = "MEMWRITEOOB64"; 1210 cmd_str = "MEMWRITEOOB"; 1211 } 1212 1213 max_offs = (unsigned long long)mtd->eb_cnt * mtd->eb_size; 1214 if (start >= max_offs) { 1215 errmsg("bad page address %" PRIu64 ", mtd%d has %d eraseblocks (%llu bytes)", 1216 start, mtd->mtd_num, mtd->eb_cnt, max_offs); 1217 errno = EINVAL; 1218 return -1; 1219 } 1220 1221 oob_offs = start & (mtd->min_io_size - 1); 1222 if (oob_offs + length > mtd->oob_size || length == 0) { 1223 errmsg("Cannot write %" PRIu64 " OOB bytes to address %" PRIu64 " (OOB offset %u) - mtd%d OOB size is only %d bytes", 1224 length, start, oob_offs, mtd->mtd_num, mtd->oob_size); 1225 errno = EINVAL; 1226 return -1; 1227 } 1228 1229 oob64.start = start; 1230 oob64.length = length; 1231 oob64.usr_ptr = (uint64_t)(unsigned long)data; 1232 1233 if (lib->offs64_ioctls == OFFS64_IOCTLS_SUPPORTED || 1234 lib->offs64_ioctls == OFFS64_IOCTLS_UNKNOWN) { 1235 ret = ioctl(fd, cmd64, &oob64); 1236 if (ret == 0) 1237 return ret; 1238 1239 if (errno != ENOTTY || 1240 lib->offs64_ioctls != OFFS64_IOCTLS_UNKNOWN) { 1241 sys_errmsg("%s ioctl failed for mtd%d, offset %" PRIu64 " (eraseblock %" PRIu64 ")", 1242 cmd64_str, mtd->mtd_num, start, start / mtd->eb_size); 1243 } 1244 1245 /* 1246 * MEMREADOOB64/MEMWRITEOOB64 support was added in kernel 1247 * version 2.6.31, so probably we are working with older kernel 1248 * and these ioctls are not supported. 1249 */ 1250 lib->offs64_ioctls = OFFS64_IOCTLS_NOT_SUPPORTED; 1251 } 1252 1253 if (oob64.start > 0xFFFFFFFFULL) { 1254 errmsg("this system can address only up to address %lu", 1255 0xFFFFFFFFUL); 1256 errno = EINVAL; 1257 return -1; 1258 } 1259 1260 oob.start = oob64.start; 1261 oob.length = oob64.length; 1262 oob.ptr = data; 1263 1264 ret = ioctl(fd, cmd, &oob); 1265 if (ret < 0) 1266 sys_errmsg("%s ioctl failed for mtd%d, offset %" PRIu64 " (eraseblock %" PRIu64 ")", 1267 cmd_str, mtd->mtd_num, start, start / mtd->eb_size); 1268 return ret; 1269 } 1270 1271 int mtd_read_oob(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, 1272 uint64_t start, uint64_t length, void *data) 1273 { 1274 return do_oob_op(desc, mtd, fd, start, length, data, 1275 MEMREADOOB64, MEMREADOOB); 1276 } 1277 1278 int mtd_write_oob(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, 1279 uint64_t start, uint64_t length, void *data) 1280 { 1281 return do_oob_op(desc, mtd, fd, start, length, data, 1282 MEMWRITEOOB64, MEMWRITEOOB); 1283 } 1284 1285 int mtd_write_img(const struct mtd_dev_info *mtd, int fd, int eb, int offs, 1286 const char *img_name) 1287 { 1288 int tmp, ret, in_fd, len, written = 0; 1289 off_t seek; 1290 struct stat st; 1291 char *buf; 1292 1293 ret = mtd_valid_erase_block(mtd, eb); 1294 if (ret) 1295 return ret; 1296 1297 if (offs < 0 || offs >= mtd->eb_size) { 1298 errmsg("bad offset %d, mtd%d eraseblock size is %d", 1299 offs, mtd->mtd_num, mtd->eb_size); 1300 errno = EINVAL; 1301 return -1; 1302 } 1303 if (offs % mtd->subpage_size) { 1304 errmsg("write offset %d is not aligned to mtd%d min. I/O size %d", 1305 offs, mtd->mtd_num, mtd->subpage_size); 1306 errno = EINVAL; 1307 return -1; 1308 } 1309 1310 in_fd = open(img_name, O_RDONLY | O_CLOEXEC); 1311 if (in_fd == -1) 1312 return sys_errmsg("cannot open \"%s\"", img_name); 1313 1314 if (fstat(in_fd, &st)) { 1315 sys_errmsg("cannot stat %s", img_name); 1316 goto out_close; 1317 } 1318 1319 len = st.st_size; 1320 if (len % mtd->subpage_size) { 1321 errmsg("size of \"%s\" is %d byte, which is not aligned to " 1322 "mtd%d min. I/O size %d", img_name, len, mtd->mtd_num, 1323 mtd->subpage_size); 1324 errno = EINVAL; 1325 goto out_close; 1326 } 1327 tmp = (offs + len + mtd->eb_size - 1) / mtd->eb_size; 1328 if (eb + tmp > mtd->eb_cnt) { 1329 errmsg("\"%s\" image size is %d bytes, mtd%d size is %d " 1330 "eraseblocks, the image does not fit if we write it " 1331 "starting from eraseblock %d, offset %d", 1332 img_name, len, mtd->mtd_num, mtd->eb_cnt, eb, offs); 1333 errno = EINVAL; 1334 goto out_close; 1335 } 1336 1337 /* Seek to the beginning of the eraseblock */ 1338 seek = (off_t)eb * mtd->eb_size + offs; 1339 if (lseek(fd, seek, SEEK_SET) != seek) { 1340 sys_errmsg("cannot seek mtd%d to offset %"PRIdoff_t, 1341 mtd->mtd_num, seek); 1342 goto out_close; 1343 } 1344 1345 buf = xmalloc(mtd->eb_size); 1346 1347 while (written < len) { 1348 int rd = 0; 1349 1350 do { 1351 ret = read(in_fd, buf, mtd->eb_size - offs - rd); 1352 if (ret == -1) { 1353 sys_errmsg("cannot read \"%s\"", img_name); 1354 goto out_free; 1355 } 1356 rd += ret; 1357 } while (ret && rd < mtd->eb_size - offs); 1358 1359 ret = write(fd, buf, rd); 1360 if (ret != rd) { 1361 sys_errmsg("cannot write %d bytes to mtd%d (eraseblock %d, offset %d)", 1362 len, mtd->mtd_num, eb, offs); 1363 goto out_free; 1364 } 1365 1366 offs = 0; 1367 eb += 1; 1368 written += rd; 1369 } 1370 1371 free(buf); 1372 close(in_fd); 1373 return 0; 1374 1375 out_free: 1376 free(buf); 1377 out_close: 1378 close(in_fd); 1379 return -1; 1380 } 1381 1382 int mtd_probe_node(libmtd_t desc, const char *node) 1383 { 1384 struct stat st; 1385 struct mtd_info info; 1386 int i, mjr, mnr; 1387 struct libmtd *lib = (struct libmtd *)desc; 1388 1389 if (stat(node, &st)) 1390 return sys_errmsg("cannot get information about \"%s\"", node); 1391 1392 if (!S_ISCHR(st.st_mode)) { 1393 errmsg("\"%s\" is not a character device", node); 1394 errno = EINVAL; 1395 return -1; 1396 } 1397 1398 mjr = major(st.st_rdev); 1399 mnr = minor(st.st_rdev); 1400 1401 if (mtd_get_info((libmtd_t *)lib, &info)) 1402 return -1; 1403 1404 if (!lib->sysfs_supported) 1405 return 0; 1406 1407 for (i = info.lowest_mtd_num; i <= info.highest_mtd_num; i++) { 1408 int mjr1, mnr1, ret; 1409 1410 ret = dev_get_major(lib, i, &mjr1, &mnr1); 1411 if (ret) { 1412 if (errno == ENOENT) 1413 continue; 1414 if (!errno) 1415 break; 1416 return -1; 1417 } 1418 1419 if (mjr1 == mjr && mnr1 == mnr) 1420 return 1; 1421 } 1422 1423 errno = 0; 1424 return -1; 1425 } 1426