| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright © 2009 - Maxim Levitsky |
|---|
| 3 | 4 | * SmartMedia/xD translation layer |
|---|
| 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 version 2 as |
|---|
| 7 | | - * published by the Free Software Foundation. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 221 | 218 | { |
|---|
| 222 | 219 | uint8_t ecc[3]; |
|---|
| 223 | 220 | |
|---|
| 224 | | - __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc); |
|---|
| 225 | | - if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE) < 0) |
|---|
| 221 | + __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc, |
|---|
| 222 | + IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
|---|
| 223 | + if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE, |
|---|
| 224 | + IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0) |
|---|
| 226 | 225 | return -EIO; |
|---|
| 227 | 226 | |
|---|
| 228 | 227 | buffer += SM_SMALL_PAGE; |
|---|
| 229 | 228 | |
|---|
| 230 | | - __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc); |
|---|
| 231 | | - if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE) < 0) |
|---|
| 229 | + __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc, |
|---|
| 230 | + IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
|---|
| 231 | + if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE, |
|---|
| 232 | + IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0) |
|---|
| 232 | 233 | return -EIO; |
|---|
| 233 | 234 | return 0; |
|---|
| 234 | 235 | } |
|---|
| .. | .. |
|---|
| 246 | 247 | |
|---|
| 247 | 248 | /* FTL can contain -1 entries that are by default filled with bits */ |
|---|
| 248 | 249 | if (block == -1) { |
|---|
| 249 | | - memset(buffer, 0xFF, SM_SECTOR_SIZE); |
|---|
| 250 | + if (buffer) |
|---|
| 251 | + memset(buffer, 0xFF, SM_SECTOR_SIZE); |
|---|
| 250 | 252 | return 0; |
|---|
| 251 | 253 | } |
|---|
| 252 | 254 | |
|---|
| .. | .. |
|---|
| 393 | 395 | } |
|---|
| 394 | 396 | |
|---|
| 395 | 397 | if (ftl->smallpagenand) { |
|---|
| 396 | | - __nand_calculate_ecc(buf + boffset, |
|---|
| 397 | | - SM_SMALL_PAGE, oob.ecc1); |
|---|
| 398 | + __nand_calculate_ecc(buf + boffset, SM_SMALL_PAGE, |
|---|
| 399 | + oob.ecc1, |
|---|
| 400 | + IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
|---|
| 398 | 401 | |
|---|
| 399 | 402 | __nand_calculate_ecc(buf + boffset + SM_SMALL_PAGE, |
|---|
| 400 | | - SM_SMALL_PAGE, oob.ecc2); |
|---|
| 403 | + SM_SMALL_PAGE, oob.ecc2, |
|---|
| 404 | + IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
|---|
| 401 | 405 | } |
|---|
| 402 | 406 | if (!sm_write_sector(ftl, zone, block, boffset, |
|---|
| 403 | 407 | buf + boffset, &oob)) |
|---|
| .. | .. |
|---|
| 771 | 775 | continue; |
|---|
| 772 | 776 | |
|---|
| 773 | 777 | /* Read the oob of first sector */ |
|---|
| 774 | | - if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob)) |
|---|
| 778 | + if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob)) { |
|---|
| 779 | + kfifo_free(&zone->free_sectors); |
|---|
| 780 | + kfree(zone->lba_to_phys_table); |
|---|
| 775 | 781 | return -EIO; |
|---|
| 782 | + } |
|---|
| 776 | 783 | |
|---|
| 777 | 784 | /* Test to see if block is erased. It is enough to test |
|---|
| 778 | 785 | first sector, because erase happens in one shot */ |
|---|
| .. | .. |
|---|
| 1091 | 1098 | { |
|---|
| 1092 | 1099 | struct sm_ftl *ftl = dev->priv; |
|---|
| 1093 | 1100 | |
|---|
| 1094 | | - mutex_lock(&ftl->mutex); |
|---|
| 1095 | 1101 | del_timer_sync(&ftl->timer); |
|---|
| 1096 | 1102 | cancel_work_sync(&ftl->flush_work); |
|---|
| 1103 | + mutex_lock(&ftl->mutex); |
|---|
| 1097 | 1104 | sm_cache_flush(ftl); |
|---|
| 1098 | 1105 | mutex_unlock(&ftl->mutex); |
|---|
| 1099 | 1106 | } |
|---|