URET uffs_ReleaseDevice(uffs_Device *dev) { URET ret; ret = uffs_BlockInfoReleaseCache(dev); if (ret != U_SUCC) { uffs_Perror(UFFS_MSG_SERIOUS, "fail to release block info."); goto ext; } ret = uffs_BufReleaseAll(dev); if (ret != U_SUCC) { uffs_Perror(UFFS_MSG_SERIOUS, "fail to release page buffers"); goto ext; } ret = uffs_TreeRelease(dev); if (ret != U_SUCC) { uffs_Perror(UFFS_MSG_SERIOUS, "fail to release tree buffers!"); goto ext; } ret = uffs_FlashInterfaceRelease(dev); if (ret != U_SUCC) { uffs_Perror(UFFS_MSG_SERIOUS, "fail to release tree buffers!"); goto ext; } if (dev->mem.release) ret = dev->mem.release(dev); if (ret != U_SUCC) { uffs_Perror(UFFS_MSG_SERIOUS, "fail to release memory allocator!"); } uffs_DeviceReleaseLock(dev); ext: return ret; }
URET uffs_FormatDevice(uffs_Device *dev, UBOOL force) { u16 i, slot; URET ret = U_SUCC; if (dev == NULL) return U_FAIL; if (dev->ops == NULL) return U_FAIL; uffs_GlobalFsLockLock(); ret = uffs_BufFlushAll(dev); if (dev->ref_count > 1 && !force) { uffs_Perror(UFFS_MSG_NORMAL, "can't format when dev->ref_count = %d", dev->ref_count); ret = U_FAIL; } if (ret == U_SUCC && force) { uffs_DirEntryBufPutAll(dev); uffs_PutAllObjectBuf(dev); uffs_FdSignatureIncrease(); } if (ret == U_SUCC && uffs_BufIsAllFree(dev) == U_FALSE && !force) { uffs_Perror(UFFS_MSG_NORMAL, "some page still in used!"); ret = U_FAIL; } if (!force) { for (slot = 0; ret == U_SUCC && slot < dev->cfg.dirty_groups; slot++) { if (dev->buf.dirtyGroup[slot].count > 0) { uffs_Perror(UFFS_MSG_SERIOUS, "there still have dirty pages!"); ret = U_FAIL; } } } if (ret == U_SUCC) uffs_BufSetAllEmpty(dev); if (ret == U_SUCC && uffs_BlockInfoIsAllFree(dev) == U_FALSE && !force) { uffs_Perror(UFFS_MSG_NORMAL, "there still have block info cache ? fail to format"); ret = U_FAIL; } if (ret == U_SUCC) uffs_BlockInfoExpireAll(dev); for (i = dev->par.start; ret == U_SUCC && i <= dev->par.end; i++) { if (uffs_FlashIsBadBlock(dev, i) == U_FALSE) { uffs_FlashEraseBlock(dev, i); if (HAVE_BADBLOCK(dev)) uffs_BadBlockProcess(dev, NULL); } else { #ifdef CONFIG_ENABLE_BAD_BLOCK_VERIFY _ForceFormatAndCheckBlock(dev, i); #endif } } if (ret == U_SUCC && uffs_TreeRelease(dev) == U_FAIL) { ret = U_FAIL; } if (ret == U_SUCC && uffs_TreeInit(dev) == U_FAIL) { ret = U_FAIL; } if (ret == U_SUCC && uffs_BuildTree(dev) == U_FAIL) { ret = U_FAIL; } uffs_GlobalFsLockUnlock(); return ret; }