#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
#define SECTOR_IS_RELEASED(h) ((h.status & SMART_STATUS_RELEASED) == 0 ? true : false)
#define SECTOR_IS_COMMITTED(h) ((h.status & SMART_STATUS_COMMITTED) == 0 ? true : false)
+#if SMART_STATUS_VERSION == 1
+#define HEADER_IS_CLEAN(h) ((UINT8TOUINT16(h.logicalsector) == 0xFFFF && h.seq == 0xFF && h.crc8 == 0xFF && h.status == 0xFF))
+#elif SMART_STATUS_VERSION == 2
+#define HEADER_IS_CLEAN(h) ((UINT8TOUINT16(h.logicalsector) == 0xFFFF && h.seq == 0xFF && h.crc16 == 0xFFFF && h.status == 0xFF))
+#elif SMART_STATUS_VERSION == 3
+#define HEADER_IS_CLEAN(h) ((UINT8TOUINT16(h.logicalsector) == 0xFFFFFFFF && h.seq == 0xFF && h.crc32 == 0xFFFFFFFF && h.status == 0xFF))
+#endif
#else
#define SECTOR_IS_RELEASED(h) ((h.status & SMART_STATUS_RELEASED) == SMART_STATUS_RELEASED ? true : false)
#define SECTOR_IS_COMMITTED(h) ((h.status & SMART_STATUS_COMMITTED) == SMART_STATUS_COMMITTED ? true : false)
+#if SMART_STATUS_VERSION == 1
+#define HEADER_IS_CLEAN(h) ((UINT8TOUINT16(h.logicalsector) == 0x0000 && h.seq == 0x00 && h.crc8 == 0x00 && h.status == 0x00))
+#elif SMART_STATUS_VERSION == 2
+#define HEADER_IS_CLEAN(h) ((UINT8TOUINT16(h.logicalsector) == 0x0000 && h.seq == 0x00 && h.crc16 == 0x0000 && h.status == 0x00))
+#elif SMART_STATUS_VERSION == 3
+#define HEADER_IS_CLEAN(h) ((UINT8TOUINT16(h.logicalsector) == 0x00000000 && h.seq == 0x00 && h.crc32 == 0x00000000 && h.status == 0x00))
+#endif
+
#endif
#define SET_TO_TRUE(v, n) v[n/8] |= (1<<(7-(n%8)))
static int smart_read_wearstatus(FAR struct smart_struct_s *dev);
static int smart_relocate_static_data(FAR struct smart_struct_s *dev, uint16_t block);
#endif
-
+static void smart_erase_block_if_empty(FAR struct smart_struct_s *dev, uint16_t block, uint8_t forceerase);
static int smart_relocate_sector(FAR struct smart_struct_s *dev, uint16_t oldsector, uint16_t newsector);
+static int smart_validate_crc(FAR struct smart_struct_s *dev);
+static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev);
/****************************************************************************
* Private Data
}
}
}
-
return 0;
}
#endif
-
/****************************************************************************
* Name: smart_scan
*
struct smart_sect_header_s header;
uint8_t *sector_seq_log = NULL;
bool status_released, status_committed;
+ bool corrupted;
#ifdef CONFIG_MTD_SMART_MINIMIZE_RAM
int dupsector;
uint16_t duplogsector;
char devname[22];
FAR struct smart_multiroot_device_s *rootdirdev;
#endif
+ int i;
fvdbg("Entry\n");
for (sector = 0; sector < totalsectors; sector++) {
winner = sector;
+ corrupted = false;
fvdbg("Scan sector %d\n", sector);
/* Calculate the read address for this sector */
/* Read the header for this sector */
- ret = MTD_READ(dev->mtd, readaddress, sizeof(struct smart_sect_header_s), (FAR uint8_t *)&header);
- if (ret != sizeof(struct smart_sect_header_s)) {
+ ret = MTD_BREAD(dev->mtd, sector * dev->mtdBlksPerSector, dev->mtdBlksPerSector, (uint8_t *)dev->rwbuffer);
+ if (ret != dev->mtdBlksPerSector) {
+ fdbg("Error reading physical sector %d.\n", sector);
goto err_out;
}
- /* Get the logical sector number for this physical sector */
+ memcpy(&header, dev->rwbuffer, sizeof(struct smart_sect_header_s));
+ ret = smart_validate_crc(dev);
+ if (ret != OK) {
+ if (HEADER_IS_CLEAN(header)) {
+ /* Header is cleaned but all block is not cleaned, it means por druing erase */
+ for (i = sizeof(struct smart_sect_header_s); i < dev->sectorsize; i++) {
+ if (dev->rwbuffer[i] != 0xFF) {
+ fdbg("It is not Erased value sector %u, offset %u, %x------------------\n", sector, i, dev->rwbuffer[i]);
+ corrupted = true;
+ break;
+ }
+ }
+ if (corrupted) {
+ fdbg("It seems erase-fail, physical sector : %d eraseblock : %d\n", sector, sector / dev->sectorsPerBlk);
+ smart_erase_block_if_empty(dev, sector / dev->sectorsPerBlk, TRUE);
+ sector = ((sector / dev->sectorsPerBlk) * dev->sectorsPerBlk) + dev->sectorsPerBlk - 1;
+ continue;
+ }
+ } else {
+ fdbg("It seems corrupted, physical sector : %d eraseblock : %d\n", sector, sector / dev->sectorsPerBlk);
+#ifdef CONFIG_DEBUG_FS
+//#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+ for (i = 0; i < sizeof(struct smart_sect_header_s); i++) {
+ fsdbg("%02x ", dev->rwbuffer[i]);
+ }
+ fsdbg("\n");
+#endif
+ fdbg("set Released and commited sector : %d\n", sector);
+#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
+ header.status = header.status & ~(SMART_STATUS_COMMITTED | SMART_STATUS_RELEASED);
+#else
+ header.status = header.status | SMART_STATUS_COMMITTED | SMART_STATUS_RELEASED;
+#endif
+ ret = smart_bytewrite(dev, readaddress + offsetof(struct smart_sect_header_s, status), 1, &header.status);
+ if (ret < 0) {
+ goto err_out;
+ }
- //logicalsector = *((FAR uint16_t *)header.logicalsector);
+ }
+ }
+
+
+ /* Get the logical sector number for this physical sector */
logicalsector = UINT8TOUINT16(header.logicalsector);
#if CONFIG_SMARTFS_ERASEDSTATE == 0x00
if (logicalsector == 0) {
status_released = SECTOR_IS_RELEASED(header);
status_committed = SECTOR_IS_COMMITTED(header);
-
+ fvdbg("released : %d committed : %d logical : %d physical : %d sta :%d seq :%d\n", status_released, status_committed, logicalsector, sector, header.status, header.seq);
if (logicalsector > 0 && header.status != CONFIG_SMARTFS_ERASEDSTATE && !status_released && status_committed) {
/* Map the sector and update the free sector counts */
*
****************************************************************************/
-#ifdef CONFIG_MTD_SMART_ENABLE_CRC
static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev)
{
crc_t crc = 0;
crc = crc32part((uint8_t *)dev->rwbuffer, 6, crc);
#else
-#error "Unknown CRC size!"
+ /* Add logical sector number and seq to the CRC calculation for basic crc */
+
+ crc = crc8((uint8_t *)dev->rwbuffer, 3);
+
#endif
return crc;
}
-#endif /* CONFIG_MTD_SMART_ENABLE_CRC */
+
/*Name: smart_write_bad_sector_info
*
sectorheader->seq = 0;
#else
- /* CRC not enabled. Using a 16-bit sequence number */
+ /* Use Basic CRC, using an 8-bit sequence number */
- sectorheader->crc8 = 0;
sectorheader->seq = 0;
- //*((FAR uint16_t *)§orheader->seq) = 0;
#endif
#else /* SMART_STATUS_VERSION == 1 */
sectorheader->seq = 0;
*((uint16_t *)sectorheader->crc16) = smart_calc_sector_crc(dev);
#elif defined(CONFIG_SMART_CRC_32)
*((uint32_t *)sectorheader->crc32) = smart_calc_sector_crc(dev);
+#else
+ sectorheader->crc8 = smart_calc_sector_crc(dev);
#endif
/* Write the sector to the flash */
#else
header->status &= ~SMART_STATUS_COMMITTED;
#endif
+ header->crc8 = smart_calc_sector_crc(dev);
/* Write the data to the new physical sector location */
header->logicalsector[0] = (uint8_t)(logical & 0x00FF);
header->logicalsector[1] = (uint8_t)(logical >> 8);
//*((FAR uint16_t *)header->logicalsector) = logical;
-#if SMART_STATUS_VERSION == 1
-#ifdef CONFIG_MTD_SMART_ENABLE_CRC
- header->seq = 0;
-#else
- //*((FAR uint16_t *)&header->crc8) = 0;
- uint8_t *tmp = &header->crc8;
- *tmp = 0;
- tmp++;
- *tmp = 0;
-#endif /* CONFIG_MTD_SMART_ENABLE_CRC */
-#else
+
header->seq = 0;
-#endif
+
sectsize = dev->sectorsize >> 7;
#if CONFIG_SMARTFS_ERASEDSTATE == 0xFF
/* Write the header to the physical sector location */
#ifndef CONFIG_MTD_SMART_ENABLE_CRC
+ header->crc8 = smart_calc_sector_crc(dev);
fvdbg("Write MTD block %d\n", physical * dev->mtdBlksPerSector);
ret = MTD_BWRITE(dev->mtd, physical * dev->mtdBlksPerSector, 1, (FAR uint8_t *)dev->rwbuffer);
if (ret != 1) {
*
****************************************************************************/
-#ifdef CONFIG_MTD_SMART_ENABLE_CRC
static int smart_validate_crc(FAR struct smart_struct_s *dev)
{
crc_t crc;
crc = smart_calc_sector_crc(dev);
header = (FAR struct smart_sect_header_s *)dev->rwbuffer;
-#ifdef CONFIG_SMART_CRC_8
-
- /* Test 8-bit CRC */
-
- if (crc != header->crc8) {
- return -EIO;
- }
-#elif defined(CONFIG_SMART_CRC_16)
+#ifdef CONFIG_SMART_CRC_16
/* Test 16-bit CRC */
if (crc != *((uint32_t *)header->crc32)) {
return -EIO;
}
+#else
+ /* Test 8-bit CRC for CRC8 & basic case for smart_scan */
+ if (crc != header->crc8) {
+ return -EIO;
+ }
+
#endif
/* CRC checkout out okay */
return OK;
}
-#endif
+
/****************************************************************************
* Name: smart_writesector
#else /* CONFIG_MTD_SMART_ENABLE_CRC */
/* Now copy the data to the sector buffer. */
- memcpy(&dev->rwbuffer[sizeof(struct smart_sect_header_s) + req->offset], req->buffer, req->count);
-
+ memcpy(&dev->rwbuffer[sizeof(struct smart_sect_header_s) + req->offset],
+ req->buffer, req->count);
+ header->crc8 = smart_calc_sector_crc(dev);
#endif /* CONFIG_MTD_SMART_ENABLE_CRC */
/* Now write the sector buffer to the device. */