From 2318531d931431b7a145a40243bca8d8d97c8a31 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 3 Dec 2013 13:11:11 -0600 Subject: [PATCH] Condition out most of the recent NXFFS changes for NAND. NXFFS will never be able to support NAND --- arch/arm/src/sama5/sam_dmac.c | 6 +- configs/sama5d3x-ek/README.txt | 78 ++++++++++++++++------ configs/sim/nxffs/defconfig | 118 +++++++++++++++++++++++++-------- fs/nxffs/Kconfig | 27 ++++++++ fs/nxffs/nxffs_blockstats.c | 83 +++++++++++++++++++++-- fs/nxffs/nxffs_cache.c | 7 ++ fs/nxffs/nxffs_dump.c | 9 ++- fs/nxffs/nxffs_inode.c | 2 - fs/nxffs/nxffs_pack.c | 17 ++++- fs/nxffs/nxffs_reformat.c | 50 ++++++++++---- 10 files changed, 324 insertions(+), 73 deletions(-) diff --git a/arch/arm/src/sama5/sam_dmac.c b/arch/arm/src/sama5/sam_dmac.c index 9c0b3940ac..d6831210e4 100644 --- a/arch/arm/src/sama5/sam_dmac.c +++ b/arch/arm/src/sama5/sam_dmac.c @@ -1482,12 +1482,14 @@ static void sam_freelinklist(struct sam_dmach_s *dmach) while (desc != NULL) { + /* Valid, in-use descriptors never have saddr == 0 */ + + DEBUGASSERT(desc->saddr != 0); + /* Get the physical address of the next desriptor in the list */ paddr = desc->dscr; - DEBUGASSERT(desc->saddr != 0); - /* Free the descriptor by simply nullifying it */ memset(desc, 0, sizeof(struct dma_linklist_s)); diff --git a/configs/sama5d3x-ek/README.txt b/configs/sama5d3x-ek/README.txt index 99f83ebe9d..0517180e17 100644 --- a/configs/sama5d3x-ek/README.txt +++ b/configs/sama5d3x-ek/README.txt @@ -1351,6 +1351,10 @@ SDRAM Support NAND Support ============ + NAND support is only partial and there is no file system that works with + it properly. It should be considered a work in progress. You will not + want to use NAND unless you are interested in investing a little effort. + See the STATUS section below. NAND Support ------------ @@ -1358,6 +1362,10 @@ NAND Support NAND Support can be added to the NSH configuration by modifying the NuttX configuration file as follows: + Build Setup + CONFIG_EXPERIMENTAL=y : NXFFS implemention is incomplete and + : not yet fully functional. + System Type -> SAMA5 Peripheal support CONFIG_SAMA5_DMAC1=y : Use DMA1 for memory-to-memory DMA CONFIG_SAMA5_HSMC=y : Make sure that the SMC is enabled @@ -1366,7 +1374,7 @@ NAND Support CONFIG_MTD=y : Enable MTD support CONFIG_MTD_NAND=y : Enable NAND support CONFIG_MTD_NAND_BLOCKCHECK=n : Interferes with NXFFS bad block checking - CONFIG_MTD_NAND_HWECC=y : Use H/W ECC calculation + CONFIG_MTD_NAND_SWECC=y : Use S/W ECC calculation Defaults for all other NAND settings should be okay @@ -1374,9 +1382,7 @@ NAND Support CONFIG_SAMA5_EBICS3=y : Enable External CS3 memory CONFIG_SAMA5_EBICS3_NAND=y : Select NAND memory type CONFIG_SAMA5_EBICS3_SIZE=8388608 : Use this size - CONFIG_SAMA5_EBICS3_PMECC=y : Use H/W ECC calculation - CONFIG_SAMA5_PMECC_EMBEDDEDALGO=n : Use the software PMECC algorithm - CONFIG_SAMA5_PMECC_GALOIS_ROMTABLES=y : use the ROM Galois tables + CONFIG_SAMA5_EBICS3_SWECC=y : Use S/W ECC calculation Defaults for ROM page table addresses should be okay @@ -1423,25 +1429,25 @@ NAND Support does the job a little-at-a-time so that there is no massive clean-up when the FLASH becomes full. - WARNING: This will wipe out everything that you may have on the NAND - FLASH! I have found that using the JTAG with no valid image on NAND - or Serial FLASH is a problem: In that case, the code always ends up - in the SAM-BA bootloader. - - The work around for this case is to put the NORBOOT image into Serial - FLASH. Then, the system will boot from Serial FLASH by copying the - NORBOOT image in SRAM which will run and then start the image in NOR - FLASH. See the discussion of the NORBOOT configuration in the - "Creating and Using NORBOOT" section above. - - NOTES: (1) There is jumper on the CM module that must be closed to - enable use of the AT25 Serial Flash. (2) If using SAM-BA, make sure - that you load the NOR boot program into the boot area via the pull- - down menu. - Application Configuration -> NSH Library CONFIG_NSH_ARCHINIT=y : Use architecture-specific initialization + WARNING: This will wipe out everything that you may have on the NAND + FLASH! I have found that using the JTAG with no valid image on NAND + or Serial FLASH is a problem: In that case, the code always ends up + in the SAM-BA bootloader. + + The work around for this case is to put the NORBOOT image into Serial + FLASH. Then, the system will boot from Serial FLASH by copying the + NORBOOT image in SRAM which will run and then start the image in NOR + FLASH. See the discussion of the NORBOOT configuration in the + "Creating and Using NORBOOT" section above. + + NOTES: (1) There is jumper on the CM module that must be closed to + enable use of the AT25 Serial Flash. (2) If using SAM-BA, make sure + that you load the NOR boot program into the boot area via the pull- + down menu. + Using NAND ---------- @@ -1474,6 +1480,38 @@ NAND Support nsh> mount /mnt/mystuff type nxffs + STATUS + ------ + + 1. PMECC has not been test and is, most likely, non-functional. + + 2. DMA works (with software ECC), but is see occasional wild memory + clobbering. DMA should not be used until this problem can be + worked out. + + 3. NXFFS does not work with NAND. NAND differs from other other FLASH + types several ways. For one thing, NAND requires error correction + (ECC) bytes that must be set in order to work around bit failures. + This affects NXFFS in two ways: + + a. First, write failures are not fatal. Rather, they should be tried by + bad blocks and simply ignored. This is because unrecoverable bit + failures will cause read failures when reading from NAND. Setting + the CONFIG_EXPERIMENTAL+CONFIG_NXFFS_NANDs option will enable this + behavior. + + b. Secondly, NXFFS will write a block many times. It tries to keep + bits in the erased state and assumes that it can overwrite those bits + to change them from the erased to the non-erased state. This works + will with NOR-like FLASH. NAND behaves this way too. But the + problem with NAND is that the ECC bits cannot be re-written in this + way. So once a block has been written, it cannot be modified. This + behavior has NOT been fixed in NXFFS. Currently, NXFFS will attempt + to re-write the ECC bits causing the ECC to become corrupted because + the ECC bits cannot be overwritten without erasing the entire block. + + This may prohibit NXFFS from ever being used with NAND. + AT24 Serial EEPROM ================== diff --git a/configs/sim/nxffs/defconfig b/configs/sim/nxffs/defconfig index a55e12bb84..bb49dba37c 100644 --- a/configs/sim/nxffs/defconfig +++ b/configs/sim/nxffs/defconfig @@ -38,24 +38,9 @@ CONFIG_HOST_LINUX=y # # Debug Options # -CONFIG_DEBUG=y -# CONFIG_DEBUG_VERBOSE is not set - -# -# Subsystem Debug Options -# -# CONFIG_DEBUG_MM is not set -# CONFIG_DEBUG_SCHED is not set -CONFIG_DEBUG_FS=y -# CONFIG_DEBUG_LIB is not set -# CONFIG_DEBUG_BINFMT is not set -# CONFIG_DEBUG_GRAPHICS is not set - -# -# Driver Debug Options -# -# CONFIG_DEBUG_ANALOG is not set -# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG is not set +# CONFIG_ARCH_HAVE_STACKCHECK is not set +# CONFIG_ARCH_HAVE_HEAPCHECK is not set CONFIG_DEBUG_SYMBOLS=y # @@ -80,10 +65,6 @@ CONFIG_ARCH="sim" # CONFIG_SIM_M32 is not set # CONFIG_SIM_WALLTIME is not set -# -# External Memory Configuration -# - # # Architecture Options # @@ -104,8 +85,6 @@ CONFIG_ARCH="sim" # CONFIG_BOARD_LOOPSPERMSEC=5000 # CONFIG_ARCH_CALIBRATION is not set -CONFIG_RAM_START= -CONFIG_RAM_SIZE= # # Boot options @@ -116,6 +95,12 @@ CONFIG_BOOT_RUNFROMFLASH=y # CONFIG_BOOT_RUNFROMSDRAM is not set # CONFIG_BOOT_COPYTORAM is not set +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x0 +CONFIG_RAM_SIZE=0 + # # Board Selection # @@ -195,28 +180,48 @@ CONFIG_DEV_NULL=y # CONFIG_LOOP is not set # CONFIG_RAMDISK is not set # CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set # CONFIG_PWM is not set +# CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_I2S is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set # CONFIG_BCH is not set # CONFIG_INPUT is not set # CONFIG_LCD is not set # CONFIG_MMCSD is not set CONFIG_MTD=y + +# +# MTD Configuration +# # CONFIG_MTD_PARTITION is not set +# CONFIG_MTD_BYTE_WRITE is not set +# CONFIG_MTD_CONFIG is not set +# CONFIG_MTD_CONFIG_RAM_CONSOLIDATE is not set + +# +# MTD Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_ARCH_NAND_HWECC is not set CONFIG_RAMMTD=y CONFIG_RAMMTD_BLOCKSIZE=512 CONFIG_RAMMTD_ERASESIZE=4096 CONFIG_RAMMTD_ERASESTATE=0xff CONFIG_RAMMTD_FLASHSIM=y # CONFIG_MTD_AT24XX is not set +# CONFIG_MTD_AT25 is not set # CONFIG_MTD_AT45DB is not set # CONFIG_MTD_M25P is not set +# CONFIG_MTD_SMART is not set # CONFIG_MTD_RAMTRON is not set # CONFIG_MTD_SST25 is not set +# CONFIG_MTD_SST25XX is not set # CONFIG_MTD_SST39FV is not set # CONFIG_MTD_W25 is not set # CONFIG_PIPES is not set @@ -227,7 +232,13 @@ CONFIG_RAMMTD_FLASHSIM=y CONFIG_SERIAL=y # CONFIG_DEV_LOWCONSOLE is not set # CONFIG_16550_UART is not set + +# +# USART Configuration +# # CONFIG_STANDARD_SERIAL is not set +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set # CONFIG_WIRELESS is not set @@ -244,6 +255,8 @@ CONFIG_SERIAL=y # # Networking Support # +# CONFIG_ARCH_HAVE_NET is not set +# CONFIG_ARCH_HAVE_PHY is not set # CONFIG_NET is not set # @@ -254,6 +267,8 @@ CONFIG_SERIAL=y # File system configuration # # CONFIG_DISABLE_MOUNTPOINT is not set +CONFIG_FS_READABLE=y +CONFIG_FS_WRITABLE=y # CONFIG_FS_RAMMAP is not set CONFIG_FS_FAT=y # CONFIG_FAT_LCNAMES is not set @@ -261,12 +276,16 @@ CONFIG_FS_FAT=y # CONFIG_FS_FATTIME is not set # CONFIG_FAT_DMAMEMORY is not set CONFIG_FS_NXFFS=y +CONFIG_NXFFS_SCAN_VOLUME=y +CONFIG_NXFFS_REFORMAT_THRESH=20 CONFIG_NXFFS_PREALLOCATED=y CONFIG_NXFFS_ERASEDSTATE=0xff CONFIG_NXFFS_PACKTHRESHOLD=32 CONFIG_NXFFS_MAXNAMLEN=255 CONFIG_NXFFS_TAILTHRESHOLD=8192 # CONFIG_FS_ROMFS is not set +# CONFIG_FS_SMARTFS is not set +# CONFIG_FS_PROCFS is not set # # System Logging @@ -287,6 +306,11 @@ CONFIG_NXFFS_TAILTHRESHOLD=8192 CONFIG_MM_REGIONS=1 # CONFIG_GRAN is not set +# +# Audio Support +# +# CONFIG_AUDIO is not set + # # Binary Formats # @@ -331,6 +355,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # Non-standard Library Support # # CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set # # Basic CXX Support @@ -351,7 +376,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_EXAMPLES_BUTTONS is not set # CONFIG_EXAMPLES_CAN is not set -# CONFIG_SYSTEM_COMPOSITE is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set # CONFIG_EXAMPLES_FTPC is not set @@ -366,7 +391,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MM is not set # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set -# CONFIG_EXAMPLES_MTDPART is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -396,6 +421,9 @@ CONFIG_EXAMPLES_NXFFS_NLOOPS=100 # CONFIG_EXAMPLES_ROMFS is not set # CONFIG_EXAMPLES_SENDMAIL is not set # CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_TCPECHO is not set # CONFIG_EXAMPLES_TELNETD is not set # CONFIG_EXAMPLES_THTTPD is not set # CONFIG_EXAMPLES_TIFF is not set @@ -403,7 +431,6 @@ CONFIG_EXAMPLES_NXFFS_NLOOPS=100 # CONFIG_EXAMPLES_UDP is not set # CONFIG_EXAMPLES_UIP is not set # CONFIG_EXAMPLES_USBSERIAL is not set -# CONFIG_SYSTEM_USBMSC is not set # CONFIG_EXAMPLES_USBTERM is not set # CONFIG_EXAMPLES_WATCHDOG is not set @@ -453,10 +480,23 @@ CONFIG_EXAMPLES_NXFFS_NLOOPS=100 # NxWidgets/NxWM # +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set + # # System NSH Add-Ons # +# +# USB CDC/ACM Device Commands +# + +# +# USB Composite Device Commands +# + # # Custom Free Memory Command # @@ -472,7 +512,16 @@ CONFIG_EXAMPLES_NXFFS_NLOOPS=100 # CONFIG_SYSTEM_INSTALL is not set # -# RAM Test +# FLASH Erase-all Command +# + +# +# NxPlayer media player library / command Line +# +# CONFIG_SYSTEM_NXPLAYER is not set + +# +# RAM test # # CONFIG_SYSTEM_RAMTEST is not set @@ -504,3 +553,16 @@ CONFIG_EXAMPLES_NXFFS_NLOOPS=100 # # USB Monitor # + +# +# Stack Monitor +# + +# +# USB Mass Storage Device Commands +# + +# +# Zmodem Commands +# +# CONFIG_SYSTEM_ZMODEM is not set diff --git a/fs/nxffs/Kconfig b/fs/nxffs/Kconfig index e9528c8ab1..b666bb1c76 100644 --- a/fs/nxffs/Kconfig +++ b/fs/nxffs/Kconfig @@ -34,6 +34,33 @@ config NXFFS_SCAN_VOLUME reboot in these cases. That can be done with apps/system/flash_eraseall. +config NXFFS_NAND + bool "Enable NAND support" + default n + depends on EXPERIMENTAL + ---help--- + NAND differs from other other FLASH types several ways. For one + thing, NAND requires error correction (ECC) bytes that must be set + in order to work around bit failures. This affects NXFFS in two + ways: + + First, write failures are not fatal. Rather, they should be tried by + bad blocks and simply ignored. This is because unrecoverable bit + failures will cause read failures when reading from NAND. Setting + this option will enable this behavior. + + Secondly, NXFFS will write a block many times. It tries to keep + bits in the erased state and assumes that it can overwrite those + bits to change them from the erased to the non-erased state. This + works will with NOR-like FLASH. NAND behaves this way too. But the + problem with NAND is that the ECC bits cannot be re-written in this + way. So once a block has been written, it cannot be modified. This + behavior has NOT been fixed in NXFFS. Currently, NXFFS will attempt + to re-write the ECC bits causing the ECC to become corrupted because + the ECC bits cannot be overwritten without erasing the entire block. + + This may prohibit NXFFS from ever being used with NAND. + config NXFFS_REFORMAT_THRESH int "Reformat percentage" default 20 diff --git a/fs/nxffs/nxffs_blockstats.c b/fs/nxffs/nxffs_blockstats.c index 785dcea8d7..62753e5a87 100644 --- a/fs/nxffs/nxffs_blockstats.c +++ b/fs/nxffs/nxffs_blockstats.c @@ -91,14 +91,85 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume, FAR struct nxffs_blkstats_s *stats) { - FAR struct nxffs_block_s *blkhdr; /* Pointer to FLASH block header */ - off_t ioblock; /* I/O block number */ +#ifndef CONFIG_NXFFS_NAND + FAR uint8_t *bptr; /* Pointer to next block data */ + int lblock; /* Logical block index */ +#endif + off_t ioblock; /* I/O block number */ int ret; /* Process each erase block */ memset(stats, 0, sizeof(struct nxffs_blkstats_s)); +#ifndef CONFIG_NXFFS_NAND + for (ioblock = 0; ioblock < volume->nblocks; ioblock += volume->blkper) + { + /* Read the full erase block */ + + ret = MTD_BREAD(volume->mtd, ioblock, volume->blkper, volume->pack); + if (ret < volume->blkper) + { + fdbg("ERROR: Failed to read erase block %d: %d\n", + ioblock / volume->blkper, ret); + return ret; + } + + /* Then examine each logical block in the erase block */ + + for (bptr = volume->pack, lblock = 0; + lblock < volume->blkper; + bptr += volume->geo.blocksize, lblock++) + { + /* We read the block successfully, now check for errors tagged + * in the NXFFS data. + */ + + FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)bptr; + + /* Increment the total count of blocks examined */ + + stats->nblocks++; + + /* Collect statistics */ + /* Check if this is a block that should be recognized by NXFFS */ + + if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0) + { + /* Nope.. block must not be formatted */ + + stats->nunformat++; + } + else if (blkhdr->state == BLOCK_STATE_BAD) + { + /* The block is marked as bad */ + + stats->nbad++; + } + else if (blkhdr->state == BLOCK_STATE_GOOD) + { + /* The block is marked as good */ + + stats-> ngood++; + } + else + { + /* The good/bad mark is not recognized. Let's call this + * corrupt (vs. unformatted). + */ + + stats->ncorrupt++; + } + } + } + + fdbg("Number blocks: %d\n", stats->nblocks); + fdbg(" Good blocks: %d\n", stats->ngood); + fdbg(" Bad blocks: %d\n", stats->nbad); + fdbg(" Unformatted blocks: %d\n", stats->nunformat); + fdbg(" Corrupt blocks: %d\n", stats->ncorrupt); + +#else for (ioblock = 0; ioblock < volume->nblocks; ioblock++) { /* Increment the total count of blocks examined */ @@ -132,7 +203,7 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume, * in the NXFFS data. */ - blkhdr = (FAR struct nxffs_block_s*)volume->pack; + FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)volume->pack; /* Collect statistics */ /* Check if this is a block that should be recognized by NXFFS */ @@ -151,9 +222,9 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume, } else if (blkhdr->state == BLOCK_STATE_GOOD) { - /* The block is marked as good */ + /* The block is marked as good */ - stats-> ngood++; + stats-> ngood++; } else { @@ -172,5 +243,7 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume, fdbg(" Unformatted blocks: %d\n", stats->nunformat); fdbg(" Corrupt blocks: %d\n", stats->ncorrupt); fdbg(" Unreadable blocks: %d\n", stats->nbadread); + +#endif return OK; } diff --git a/fs/nxffs/nxffs_cache.c b/fs/nxffs/nxffs_cache.c index b5a1749db6..72b2ac0a64 100644 --- a/fs/nxffs/nxffs_cache.c +++ b/fs/nxffs/nxffs_cache.c @@ -246,6 +246,12 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume, uint16_t reserve) ret = nxffs_verifyblock(volume, volume->ioblock); if (ret < 0 && ret != -ENOENT) { +#ifndef CONFIG_NXFFS_NAND + /* Read errors are fatal */ + + fdbg("ERROR: Failed to read valid data into cache: %d\n", ret); + return ret; +#else /* A read error occurred. This probably means that we are * using NAND memory this block has an uncorrectable bit error. * Ignore the error (after complaining) and try the next @@ -253,6 +259,7 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume, uint16_t reserve) */ fdbg("ERROR: Failed to read valid data into cache: %d\n", ret); +#endif } } while (ret != OK); diff --git a/fs/nxffs/nxffs_dump.c b/fs/nxffs/nxffs_dump.c index a86fd0c2d8..c42a007dbf 100644 --- a/fs/nxffs/nxffs_dump.c +++ b/fs/nxffs/nxffs_dump.c @@ -389,7 +389,6 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) } } } - } #endif @@ -462,6 +461,13 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose) ret = MTD_BREAD(mtd, blkinfo.block, 1, blkinfo.buffer); if (ret < 0) { +#ifndef CONFIG_NXFFS_NAND + /* Read errors are fatal */ + + fdbg("ERROR: Failed to read block %d\n", blkinfo.block); + kfree(blkinfo.buffer); + return ret; +#else /* A read error is probably fatal on all media but NAND. * On NAND, the read error probably just signifies a block * with an uncorrectable ECC failure. So, to handle NAND, @@ -470,6 +476,7 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd, bool verbose) fdbg(g_format, blkinfo.block, 0, "BLOCK", "RD FAIL", blkinfo.geo.blocksize); +#endif } else { diff --git a/fs/nxffs/nxffs_inode.c b/fs/nxffs/nxffs_inode.c index d87729dd73..7efcbd5f2f 100644 --- a/fs/nxffs/nxffs_inode.c +++ b/fs/nxffs/nxffs_inode.c @@ -85,8 +85,6 @@ * Zero on success. Otherwise, a negated errno value is returned * indicating the nature of the failure. * - * On return, the - * ****************************************************************************/ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, diff --git a/fs/nxffs/nxffs_pack.c b/fs/nxffs/nxffs_pack.c index 8663e3a7b6..2f3461aad6 100644 --- a/fs/nxffs/nxffs_pack.c +++ b/fs/nxffs/nxffs_pack.c @@ -1413,6 +1413,20 @@ start_pack: pack.block0 = eblock * volume->blkper; +#ifndef CONFIG_NXFFS_NAND + /* Read the erase block into the pack buffer. We need to do this even + * if we are overwriting the entire block so that we skip over + * previously marked bad blocks. + */ + + ret = MTD_BREAD(volume->mtd, pack.block0, volume->blkper, volume->pack); + if (ret < 0) + { + fdbg("ERROR: Failed to read erase block %d: %d\n", eblock,-ret); + goto errout_with_pack; + } + +#else /* Read the entire erase block into the pack buffer, one-block-at-a- * time. We need to do this even if we are overwriting the entire * block so that (1) we skip over previously marked bad blocks, and @@ -1440,6 +1454,7 @@ start_pack: nxffs_blkinit(volume, pack.iobuffer, BLOCK_STATE_BAD); } } +#endif /* Now pack each I/O block */ @@ -1579,7 +1594,7 @@ start_pack: ret = MTD_BWRITE(volume->mtd, pack.block0, volume->blkper, volume->pack); if (ret < 0) { - fdbg("ERROR: Failed to write erase block %d [%]: %d\n", + fdbg("ERROR: Failed to write erase block %d [%d]: %d\n", eblock, pack.block0, -ret); goto errout_with_pack; } diff --git a/fs/nxffs/nxffs_reformat.c b/fs/nxffs/nxffs_reformat.c index 2b6e7c267f..ec85ee05c9 100644 --- a/fs/nxffs/nxffs_reformat.c +++ b/fs/nxffs/nxffs_reformat.c @@ -147,7 +147,9 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume) FAR uint8_t *blkptr; /* Pointer to next block data */ off_t eblock; /* Erase block number */ off_t lblock; /* Logical block number of the erase block */ +#ifdef CONFIG_NXFFS_NAND off_t block; /* Working block number */ +#endif ssize_t nxfrd; /* Number of blocks transferred */ bool good; /* TRUE: block is good */ bool modified; /* TRUE: The erase block has been modified */ @@ -161,24 +163,43 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume) lblock = eblock * volume->blkper; - /* Read the entire erase block into memory, processing each block one- - * at-a-time. We could read the entire erase block at once. That - * would be more efficient. However, for the case of NAND FLASH, each - * individual block can fail independently due to uncorrectable bit - * errors in that block. - */ +#ifndef CONFIG_NXFFS_NAND + /* Read the entire erase block */ - modified = false; + nxfrd = MTD_BREAD(volume->mtd, lblock, volume->blkper, volume->pack); + if (nxfrd != volume->blkper) + { + fdbg("ERROR: Read erase block %d failed: %d\n", lblock, nxfrd); + return -EIO; + } +#endif + + /* Keep track if any part of the erase block gets modified */ + + modified = false; + + /* Process each logical block */ + +#ifndef CONFIG_NXFFS_NAND + for (blkptr = volume->pack, i = 0; + i < volume->blkper; + blkptr += volume->geo.blocksize, i++) +#else for (i = 0, block = lblock, blkptr = volume->pack; i < volume->blkper; i++, block++, blkptr += volume->geo.blocksize) +#endif { FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)blkptr; + /* Assume that this is a good block until we learn otherwise */ + + good = true; + +#ifdef CONFIG_NXFFS_NAND /* Read the next block in the erase block */ - good = true; - nxfrd = MTD_BREAD(volume->mtd, block, i, blkptr); + nxfrd = MTD_BREAD(volume->mtd, block, 1, blkptr); if (nxfrd < 0) { /* Failed to read the block. This should never happen with @@ -191,11 +212,12 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume) good = false; } + else +#endif + /* Check block header */ - /* Check the block header */ - - else if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0 || - blkhdr->state != BLOCK_STATE_GOOD) + if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0 || + blkhdr->state != BLOCK_STATE_GOOD) { /* The block is not formated with the NXFFS magic bytes or else * the block is specifically marked bad. @@ -313,4 +335,4 @@ void nxffs_blkinit(FAR struct nxffs_volume_s *volume, FAR uint8_t *blkptr, memset(blkptr, CONFIG_NXFFS_ERASEDSTATE, volume->geo.blocksize); memcpy(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE); blkhdr->state = state; -} \ No newline at end of file +}