From: TaeJun Kwon Date: Tue, 8 Aug 2017 03:52:40 +0000 (+0900) Subject: Apply basic CRC for smartfs [Description] Because of sudden power off, CRC added... X-Git-Tag: 1.1_Public_Release~255^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=035144d904adce78ec8c9c1d79adc4f9cb211983;p=rtos%2Ftinyara.git Apply basic CRC for smartfs [Description] Because of sudden power off, CRC added as a mandatory feature [Module] FS [Board] all [Verification] N/A [Reference] N/A [Author] tj80.kwon --- diff --git a/os/fs/driver/mtd/smart.c b/os/fs/driver/mtd/smart.c index 9ccd50d..2f246bc 100644 --- a/os/fs/driver/mtd/smart.c +++ b/os/fs/driver/mtd/smart.c @@ -173,9 +173,24 @@ #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))) @@ -410,8 +425,10 @@ static int smart_readsector(FAR struct smart_struct_s *dev, unsigned long arg); 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 @@ -1679,11 +1696,9 @@ static int smart_set_wear_level(FAR struct smart_struct_s *dev, uint16_t block, } } } - return 0; } #endif - /**************************************************************************** * Name: smart_scan * @@ -1709,6 +1724,7 @@ static int smart_scan(FAR struct smart_struct_s *dev) 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; @@ -1718,6 +1734,7 @@ static int smart_scan(FAR struct smart_struct_s *dev) char devname[22]; FAR struct smart_multiroot_device_s *rootdirdev; #endif + int i; fvdbg("Entry\n"); @@ -1819,6 +1836,7 @@ static int smart_scan(FAR struct smart_struct_s *dev) for (sector = 0; sector < totalsectors; sector++) { winner = sector; + corrupted = false; fvdbg("Scan sector %d\n", sector); /* Calculate the read address for this sector */ @@ -1827,14 +1845,55 @@ static int smart_scan(FAR struct smart_struct_s *dev) /* 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) { @@ -1844,7 +1903,7 @@ static int smart_scan(FAR struct smart_struct_s *dev) 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 */ @@ -2620,7 +2679,6 @@ errout: * ****************************************************************************/ -#ifdef CONFIG_MTD_SMART_ENABLE_CRC static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev) { crc_t crc = 0; @@ -2661,12 +2719,15 @@ static crc_t smart_calc_sector_crc(FAR struct smart_struct_s *dev) 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 * @@ -2802,11 +2863,9 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a 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; @@ -2855,6 +2914,8 @@ static inline int smart_llformat(FAR struct smart_struct_s *dev, unsigned long a *((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 */ @@ -3017,6 +3078,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev, uint16_t oldsec #else header->status &= ~SMART_STATUS_COMMITTED; #endif + header->crc8 = smart_calc_sector_crc(dev); /* Write the data to the new physical sector location */ @@ -3869,19 +3931,9 @@ static int smart_write_alloc_sector(FAR struct smart_struct_s *dev, uint16_t log 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 @@ -3899,6 +3951,7 @@ static int smart_write_alloc_sector(FAR struct smart_struct_s *dev, uint16_t log /* 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) { @@ -3925,7 +3978,6 @@ static int smart_write_alloc_sector(FAR struct smart_struct_s *dev, uint16_t log * ****************************************************************************/ -#ifdef CONFIG_MTD_SMART_ENABLE_CRC static int smart_validate_crc(FAR struct smart_struct_s *dev) { crc_t crc; @@ -3936,14 +3988,7 @@ static int smart_validate_crc(FAR struct smart_struct_s *dev) 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 */ @@ -3955,13 +4000,19 @@ static int smart_validate_crc(FAR struct smart_struct_s *dev) 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 @@ -4220,8 +4271,9 @@ relocate_good_sector: #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. */