| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) International Business Machines Corp., 2006 |
|---|
| 3 | 4 | * Copyright (c) Nokia Corporation, 2007 |
|---|
| 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 18 | 5 | * |
|---|
| 19 | 6 | * Author: Artem Bityutskiy (Битюцкий Артём), |
|---|
| 20 | 7 | * Frank Haverkamp |
|---|
| .. | .. |
|---|
| 363 | 350 | * we still can use 'ubi->ubi_num'. |
|---|
| 364 | 351 | */ |
|---|
| 365 | 352 | ubi = container_of(dev, struct ubi_device, dev); |
|---|
| 366 | | - ubi = ubi_get_device(ubi->ubi_num); |
|---|
| 367 | | - if (!ubi) |
|---|
| 368 | | - return -ENODEV; |
|---|
| 369 | 353 | |
|---|
| 370 | 354 | if (attr == &dev_eraseblock_size) |
|---|
| 371 | 355 | ret = sprintf(buf, "%d\n", ubi->leb_size); |
|---|
| .. | .. |
|---|
| 394 | 378 | else |
|---|
| 395 | 379 | ret = -EINVAL; |
|---|
| 396 | 380 | |
|---|
| 397 | | - ubi_put_device(ubi); |
|---|
| 398 | 381 | return ret; |
|---|
| 399 | 382 | } |
|---|
| 400 | 383 | |
|---|
| .. | .. |
|---|
| 516 | 499 | } |
|---|
| 517 | 500 | |
|---|
| 518 | 501 | /** |
|---|
| 502 | + * ubi_free_volumes_from - free volumes from specific index. |
|---|
| 503 | + * @ubi: UBI device description object |
|---|
| 504 | + * @from: the start index used for volume free. |
|---|
| 505 | + */ |
|---|
| 506 | +static void ubi_free_volumes_from(struct ubi_device *ubi, int from) |
|---|
| 507 | +{ |
|---|
| 508 | + int i; |
|---|
| 509 | + |
|---|
| 510 | + for (i = from; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { |
|---|
| 511 | + if (!ubi->volumes[i]) |
|---|
| 512 | + continue; |
|---|
| 513 | + ubi_eba_replace_table(ubi->volumes[i], NULL); |
|---|
| 514 | + ubi_fastmap_destroy_checkmap(ubi->volumes[i]); |
|---|
| 515 | + kfree(ubi->volumes[i]); |
|---|
| 516 | + ubi->volumes[i] = NULL; |
|---|
| 517 | + } |
|---|
| 518 | +} |
|---|
| 519 | + |
|---|
| 520 | +/** |
|---|
| 521 | + * ubi_free_all_volumes - free all volumes. |
|---|
| 522 | + * @ubi: UBI device description object |
|---|
| 523 | + */ |
|---|
| 524 | +void ubi_free_all_volumes(struct ubi_device *ubi) |
|---|
| 525 | +{ |
|---|
| 526 | + ubi_free_volumes_from(ubi, 0); |
|---|
| 527 | +} |
|---|
| 528 | + |
|---|
| 529 | +/** |
|---|
| 519 | 530 | * ubi_free_internal_volumes - free internal volumes. |
|---|
| 520 | 531 | * @ubi: UBI device description object |
|---|
| 521 | 532 | */ |
|---|
| 522 | 533 | void ubi_free_internal_volumes(struct ubi_device *ubi) |
|---|
| 523 | 534 | { |
|---|
| 524 | | - int i; |
|---|
| 525 | | - |
|---|
| 526 | | - for (i = ubi->vtbl_slots; |
|---|
| 527 | | - i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { |
|---|
| 528 | | - ubi_eba_replace_table(ubi->volumes[i], NULL); |
|---|
| 529 | | - ubi_fastmap_destroy_checkmap(ubi->volumes[i]); |
|---|
| 530 | | - kfree(ubi->volumes[i]); |
|---|
| 531 | | - } |
|---|
| 535 | + ubi_free_volumes_from(ubi, ubi->vtbl_slots); |
|---|
| 532 | 536 | } |
|---|
| 533 | 537 | |
|---|
| 534 | 538 | static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024) |
|---|
| .. | .. |
|---|
| 859 | 863 | * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. |
|---|
| 860 | 864 | * MLC NAND is different and needs special care, otherwise UBI or UBIFS |
|---|
| 861 | 865 | * will die soon and you will lose all your data. |
|---|
| 866 | + * Relax this rule if the partition we're attaching to operates in SLC |
|---|
| 867 | + * mode. |
|---|
| 862 | 868 | */ |
|---|
| 863 | | - if (mtd->type == MTD_MLCNANDFLASH) { |
|---|
| 869 | + if (mtd->type == MTD_MLCNANDFLASH && |
|---|
| 870 | + !(mtd->flags & MTD_SLC_ON_MLC_EMULATION)) { |
|---|
| 864 | 871 | pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", |
|---|
| 865 | 872 | mtd->index); |
|---|
| 866 | 873 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 969 | 976 | goto out_detach; |
|---|
| 970 | 977 | } |
|---|
| 971 | 978 | |
|---|
| 972 | | - /* Make device "available" before it becomes accessible via sysfs */ |
|---|
| 973 | | - ubi_devices[ubi_num] = ubi; |
|---|
| 974 | | - |
|---|
| 975 | 979 | err = uif_init(ubi); |
|---|
| 976 | 980 | if (err) |
|---|
| 977 | 981 | goto out_detach; |
|---|
| .. | .. |
|---|
| 1016 | 1020 | wake_up_process(ubi->bgt_thread); |
|---|
| 1017 | 1021 | spin_unlock(&ubi->wl_lock); |
|---|
| 1018 | 1022 | |
|---|
| 1023 | + ubi_devices[ubi_num] = ubi; |
|---|
| 1019 | 1024 | ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL); |
|---|
| 1020 | 1025 | return ubi_num; |
|---|
| 1021 | 1026 | |
|---|
| .. | .. |
|---|
| 1024 | 1029 | out_uif: |
|---|
| 1025 | 1030 | uif_close(ubi); |
|---|
| 1026 | 1031 | out_detach: |
|---|
| 1027 | | - ubi_devices[ubi_num] = NULL; |
|---|
| 1028 | 1032 | ubi_wl_close(ubi); |
|---|
| 1029 | | - ubi_free_internal_volumes(ubi); |
|---|
| 1033 | + ubi_free_all_volumes(ubi); |
|---|
| 1030 | 1034 | vfree(ubi->vtbl); |
|---|
| 1031 | 1035 | out_free: |
|---|
| 1032 | 1036 | vfree(ubi->peb_buf); |
|---|
| .. | .. |
|---|
| 1172 | 1176 | * MTD device name. |
|---|
| 1173 | 1177 | */ |
|---|
| 1174 | 1178 | mtd = get_mtd_device_nm(mtd_dev); |
|---|
| 1175 | | - if (IS_ERR(mtd) && PTR_ERR(mtd) == -ENODEV) |
|---|
| 1179 | + if (PTR_ERR(mtd) == -ENODEV) |
|---|
| 1176 | 1180 | /* Probably this is an MTD character device node path */ |
|---|
| 1177 | 1181 | mtd = open_mtd_by_chdev(mtd_dev); |
|---|
| 1178 | 1182 | } else |
|---|
| .. | .. |
|---|
| 1334 | 1338 | switch (*endp) { |
|---|
| 1335 | 1339 | case 'G': |
|---|
| 1336 | 1340 | result *= 1024; |
|---|
| 1341 | + fallthrough; |
|---|
| 1337 | 1342 | case 'M': |
|---|
| 1338 | 1343 | result *= 1024; |
|---|
| 1344 | + fallthrough; |
|---|
| 1339 | 1345 | case 'K': |
|---|
| 1340 | 1346 | result *= 1024; |
|---|
| 1341 | 1347 | if (endp[1] == 'i' && endp[2] == 'B') |
|---|
| .. | .. |
|---|
| 1463 | 1469 | MODULE_DESCRIPTION("UBI - Unsorted Block Images"); |
|---|
| 1464 | 1470 | MODULE_AUTHOR("Artem Bityutskiy"); |
|---|
| 1465 | 1471 | MODULE_LICENSE("GPL"); |
|---|
| 1472 | +MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); |
|---|