00001
00006 #include "uffs/uffs_device.h"
00007 #include "uffs/uffs_utils.h"
00008 #include "uffs/uffs_os.h"
00009 #include "uffs/uffs_public.h"
00010 #include "uffs/uffs_version.h"
00011
00012 #include <stdio.h>
00013 #include <string.h>
00014
00015 #define PFX "utils:"
00016
00017 static void _ForceFormatAndCheckBlock(uffs_Device *dev, int block)
00018 {
00019 u8 *pageBuf;
00020 int pageSize;
00021 int i, j;
00022
00023 pageSize = dev->attr.page_data_size + dev->attr.spare_size;
00024 pageBuf = uffs_MemAlloc(dev, pageSize);
00025
00026 if (pageBuf == NULL) {
00027 uffs_Perror(UFFS_ERR_SERIOUS, PFX"Alloc page buffer fail ! Format stoped.\n");
00028 return;
00029 }
00030
00031
00032 dev->ops->EraseBlock(dev, block);
00033 memset(pageBuf, 0, pageSize);
00034 for(i = 0; i < dev->attr.pages_per_block; i++) {
00035 dev->ops->WritePage(dev, block, i, pageBuf, (u8 *)pageBuf + dev->attr.page_data_size);
00036 }
00037 for(i = 0; i < dev->attr.pages_per_block; i++) {
00038 dev->ops->ReadPage(dev, block, i, pageBuf, (u8 *)pageBuf + dev->attr.page_data_size);
00039 for(j = 0; j < pageSize; j++) {
00040 if(pageBuf[j] != 0) goto bad_out;
00041 }
00042 }
00043
00044
00045 dev->ops->EraseBlock(dev, block);
00046 for(i = 0; i < dev->attr.pages_per_block; i++) {
00047 dev->ops->ReadPage(dev, block, i, pageBuf, (u8 *)pageBuf + dev->attr.page_data_size);
00048 for(j = 0; j < pageSize; j++) {
00049 if(pageBuf[j] != 0xff) goto bad_out;
00050 }
00051 }
00052
00053 uffs_MemFree(dev, pageBuf);
00054 return;
00055
00056 bad_out:
00057 dev->ops->EraseBlock(dev, block);
00058 dev->flash->MakeBadBlockMark(dev, block);
00059
00060 uffs_MemFree(dev, pageBuf);
00061 return;
00062 }
00063
00064
00065 URET uffs_FormatDevice(uffs_Device *dev)
00066 {
00067 u16 i;
00068
00069 if(dev == NULL) return U_FAIL;
00070 if(dev->ops == NULL || dev->flash == NULL) return U_FAIL;
00071
00072
00073 if(uffs_BufIsAllFree(dev) == U_FALSE) {
00074 uffs_Perror(UFFS_ERR_NORMAL, PFX"some page still in used!\n");
00075 return U_FAIL;
00076 }
00077
00078 if(dev->buf.dirtyCount > 0) {
00079 uffs_Perror(UFFS_ERR_SERIOUS, PFX"there still have dirty pages!\n");
00080 return U_FAIL;
00081 }
00082
00083 uffs_BufSetAllEmpty(dev);
00084
00085
00086 if(uffs_IsAllBlockInfoFree(dev) == U_FALSE) {
00087 uffs_Perror(UFFS_ERR_NORMAL, PFX"there still have block info cache ? fail to format\n");
00088 return U_FAIL;
00089 }
00090
00091 uffs_ExpireAllBlockInfo(dev);
00092
00093 for(i = dev->par.start; i <= dev->par.end; i++) {
00094 if(dev->ops->IsBlockBad(dev, i) == U_FALSE) {
00095 dev->ops->EraseBlock(dev, i);
00096 }
00097 else {
00098 _ForceFormatAndCheckBlock(dev, i);
00099 }
00100 }
00101
00102 if(uffs_ReleaseTreeBuf(dev) == U_FAIL) {
00103 return U_FAIL;
00104 }
00105
00106 if(uffs_InitTreeBuf(dev) == U_FAIL) {
00107 return U_FAIL;
00108 }
00109
00110 if(uffs_BuildTree(dev) == U_FAIL) {
00111 return U_FAIL;
00112 }
00113
00114 return U_SUCC;
00115 }
00116