Condition out most of the recent NXFFS changes for NAND. NXFFS will never be able to support NAND
This commit is contained in:
parent
59c4739312
commit
2318531d93
@ -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));
|
||||
|
@ -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
|
||||
==================
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user