diff options
Diffstat (limited to 'main/common/tfsclean1.c')
-rw-r--r-- | main/common/tfsclean1.c | 3564 |
1 files changed, 1809 insertions, 1755 deletions
diff --git a/main/common/tfsclean1.c b/main/common/tfsclean1.c index 801db29..6af7145 100644 --- a/main/common/tfsclean1.c +++ b/main/common/tfsclean1.c @@ -1,7 +1,7 @@ /************************************************************************** * * Copyright (c) 2013 Alcatel-Lucent - * + * * Alcatel Lucent licenses this file to You under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. A copy of the License is contained the @@ -48,10 +48,10 @@ void defragExitTestPoint(int val) { - if ((DefragTestType == DEFRAG_TEST_EXIT) && (DefragTestPoint == val)) { - printf("\n+++++++++ EXIT @ TEST POINT(%d)\n",val); - CommandLoop(); - } + if((DefragTestType == DEFRAG_TEST_EXIT) && (DefragTestPoint == val)) { + printf("\n+++++++++ EXIT @ TEST POINT(%d)\n",val); + CommandLoop(); + } } #else #define defragExitTestPoint(val) @@ -71,14 +71,15 @@ int DefragTestSector; static void defragTick(int verbose) { - static int tick; - static char clockhand[] = { '|', '/', '-', '\\' }; - - if (!verbose && (!MFLAGS_NODEFRAGPRN())) { - if (tick > 3) - tick = 0; - printf("%c\b",clockhand[tick++]); - } + static int tick; + static char clockhand[] = { '|', '/', '-', '\\' }; + + if(!verbose && (!MFLAGS_NODEFRAGPRN())) { + if(tick > 3) { + tick = 0; + } + printf("%c\b",clockhand[tick++]); + } } /* defragCrcTable(): @@ -87,7 +88,7 @@ defragTick(int verbose) struct sectorcrc * defragCrcTable(TDEV *tdp) { - return((struct sectorcrc *)(tdp->end+1) - tdp->sectorcount); + return((struct sectorcrc *)(tdp->end+1) - tdp->sectorcount); } /* defragSerase(): @@ -101,71 +102,69 @@ defragCrcTable(TDEV *tdp) static int defragSerase(int tag, int snum) { - int ret = 0; + int ret = 0; #if DEFRAG_TEST_ENABLED - int ssize; - uchar *sbase, *send, zero; - - printf(" serase_%02d(%02d)\n",tag,snum); - - if ((DefragTestType == DEFRAG_TEST_SERASE) && - (DefragTestSector == snum) && (DefragTestPoint == tag)) { - sectortoaddr(snum,&ssize,&sbase); - send = sbase+ssize; - zero = 0; - while(sbase < send) { - if (*sbase != 0) { - tfsflashwrite((ulong *)sbase,(ulong *)&zero,1); - break; - } - sbase++; - } - printf("DEFRAG_TEST_SERASE activated @ %d sector %d\n",tag,snum); - CommandLoop(); - } - else + int ssize; + uchar *sbase, *send, zero; + + printf(" serase_%02d(%02d)\n",tag,snum); + + if((DefragTestType == DEFRAG_TEST_SERASE) && + (DefragTestSector == snum) && (DefragTestPoint == tag)) { + sectortoaddr(snum,&ssize,&sbase); + send = sbase+ssize; + zero = 0; + while(sbase < send) { + if(*sbase != 0) { + tfsflashwrite((ulong *)sbase,(ulong *)&zero,1); + break; + } + sbase++; + } + printf("DEFRAG_TEST_SERASE activated @ %d sector %d\n",tag,snum); + CommandLoop(); + } else #endif - ret = tfsflasherase(snum); - if (ret <= 0) { - printf("tfsclean() serase erase failed: %d,%d,%d\n",snum,tag,ret); - } - return(ret); + ret = tfsflasherase(snum); + if(ret <= 0) { + printf("tfsclean() serase erase failed: %d,%d,%d\n",snum,tag,ret); + } + return(ret); } /* defragFwrite(): * Common function to call from within tfsclean() to write to flash * and generate an error message if necessary. - * If DEFRAG_TEST_ENABLED is defined and the test type is set to + * If DEFRAG_TEST_ENABLED is defined and the test type is set to * DEFRAG_TEST_FWRITE, then use APPRAMBASE as the source of the data * so that the end result is an errored flash write. */ static int defragFwrite(int tag, uchar *dest,uchar *src,int size) { - int ret = 0; + int ret = 0; #if DEFRAG_TEST_ENABLED - int snum; - - addrtosector((char *)dest,&snum,0,0); - printf(" fwrite_%02d(%d,0x%lx,0x%lx,%d)\n", - tag,snum,(ulong)dest,(ulong)src,size); - - if ((DefragTestType == DEFRAG_TEST_FWRITE) && - (DefragTestSector == snum) && (DefragTestPoint == tag)) { - tfsflashwrite((ulong *)dest,(ulong *)getAppRamStart(),size/2); - printf("DEFRAG_TEST_FWRITE activated @ %d sector %d\n",tag,snum); - CommandLoop(); - } - else + int snum; + + addrtosector((char *)dest,&snum,0,0); + printf(" fwrite_%02d(%d,0x%lx,0x%lx,%d)\n", + tag,snum,(ulong)dest,(ulong)src,size); + + if((DefragTestType == DEFRAG_TEST_FWRITE) && + (DefragTestSector == snum) && (DefragTestPoint == tag)) { + tfsflashwrite((ulong *)dest,(ulong *)getAppRamStart(),size/2); + printf("DEFRAG_TEST_FWRITE activated @ %d sector %d\n",tag,snum); + CommandLoop(); + } else #endif - ret = tfsflashwrite(dest,src,size); - if (ret != TFS_OKAY) { - printf("tfsclean() fwrite failed: 0x%lx,0x%lx,%d,%d\n", - (ulong)dest,(ulong)src,size,tag); - } - return(ret); + ret = tfsflashwrite(dest,src,size); + if(ret != TFS_OKAY) { + printf("tfsclean() fwrite failed: 0x%lx,0x%lx,%d,%d\n", + (ulong)dest,(ulong)src,size,tag); + } + return(ret); } /* defragGetSpantype(): @@ -183,25 +182,26 @@ defragFwrite(int tag, uchar *dest,uchar *src,int size) static int defragGetSpantype(char *s_base,char *s_end,char *f_base,char *f_end) { - int spantype; - - if (f_base < s_base) { - if ((f_end > s_base) && (f_end <= s_end)) - spantype = SPANTYPE_BPEC; - else if (f_end > s_end) - spantype = SPANTYPE_BPEL; - else - spantype = SPANTYPE_BPEP; - } - else { - if (f_base > s_end) - spantype = SPANTYPE_BLEL; - else if (f_end <= s_end) - spantype = SPANTYPE_BCEC; - else - spantype = SPANTYPE_BCEL; - } - return(spantype); + int spantype; + + if(f_base < s_base) { + if((f_end > s_base) && (f_end <= s_end)) { + spantype = SPANTYPE_BPEC; + } else if(f_end > s_end) { + spantype = SPANTYPE_BPEL; + } else { + spantype = SPANTYPE_BPEP; + } + } else { + if(f_base > s_end) { + spantype = SPANTYPE_BLEL; + } else if(f_end <= s_end) { + spantype = SPANTYPE_BCEC; + } else { + spantype = SPANTYPE_BCEL; + } + } + return(spantype); } /* defragGetSpantypeStr(): @@ -210,32 +210,32 @@ defragGetSpantype(char *s_base,char *s_end,char *f_base,char *f_end) static char * defragGetSpantypeStr(int spantype) { - char *str; - - switch(spantype) { - case SPANTYPE_BPEC: - str = "BPEC"; - break; - case SPANTYPE_BLEL: - str = "BLEL"; - break; - case SPANTYPE_BPEL: - str = "BPEL"; - break; - case SPANTYPE_BPEP: - str = "BPEP"; - break; - case SPANTYPE_BCEC: - str = "BCEC"; - break; - case SPANTYPE_BCEL: - str = "BCEL"; - break; - default: - str = "???"; - break; - } - return(str); + char *str; + + switch(spantype) { + case SPANTYPE_BPEC: + str = "BPEC"; + break; + case SPANTYPE_BLEL: + str = "BLEL"; + break; + case SPANTYPE_BPEL: + str = "BPEL"; + break; + case SPANTYPE_BPEP: + str = "BPEP"; + break; + case SPANTYPE_BCEC: + str = "BCEC"; + break; + case SPANTYPE_BCEL: + str = "BCEL"; + break; + default: + str = "???"; + break; + } + return(str); } /* defragEraseSpare(): @@ -248,18 +248,19 @@ defragGetSpantypeStr(int spantype) static int defragEraseSpare(TDEV *tdp) { - int snum, ssize; - uchar *sbase; - - if (addrtosector((unsigned char *)tdp->spare,&snum,&ssize,&sbase) < 0) - return(TFSERR_FLASHFAILURE); - - if (!flasherased(sbase,sbase+(ssize-1))) { - if (defragSerase(1,snum) < 0) { - return(TFSERR_FLASHFAILURE); - } - } - return(TFS_OKAY); + int snum, ssize; + uchar *sbase; + + if(addrtosector((unsigned char *)tdp->spare,&snum,&ssize,&sbase) < 0) { + return(TFSERR_FLASHFAILURE); + } + + if(!flasherased(sbase,sbase+(ssize-1))) { + if(defragSerase(1,snum) < 0) { + return(TFSERR_FLASHFAILURE); + } + } + return(TFS_OKAY); } /* defragValidDSI(): @@ -274,60 +275,62 @@ defragEraseSpare(TDEV *tdp) * If it matches, then we can be sure that the DSI is valid. * Return total number of files in header if the defrag header * table appears to be sane, else 0. - */ + */ static int defragValidDSI(TDEV *tdp, struct sectorcrc **scp) { - int ftot, valid, lastssize; - uchar *lastsbase; - struct sectorcrc *crctbl; - ulong hdrcrc, *crc; - struct defraghdr *dhp, dfhcpy; - - ftot = valid = 0; - crctbl = defragCrcTable(tdp); - dhp = (struct defraghdr *)crctbl - 1; - /* next line was <dfhcpy = *dhp> ... */ - memcpy((char *)&dfhcpy,(char *)dhp,sizeof(struct defraghdr)); - hdrcrc = dfhcpy.crc; - dfhcpy.crc = 0; - if (crc32((uchar *)&dfhcpy,DEFRAGHDRSIZ) == hdrcrc) { - ftot = dhp->idx + 1; - dhp = (struct defraghdr *)crctbl - ftot; - crc = (ulong *)dhp - 1; - if (crc32((uchar *)dhp,(uchar *)tdp->end-(uchar *)dhp) == *crc) { - if (scp) - *scp = crctbl; - return(ftot); - } - } - - /* It's possible that the DSI space has been relocated to the spare - * sector, so check for that here... - */ - addrtosector((unsigned char *)tdp->end,0,&lastssize,&lastsbase); - - crctbl = ((struct sectorcrc *)(tdp->spare+lastssize) - tdp->sectorcount); - dhp = (struct defraghdr *)crctbl - 1; - /* next line was <dfhcpy = *dhp> ... */ - memcpy((char *)&dfhcpy,(char *)dhp,sizeof(struct defraghdr)); - hdrcrc = dfhcpy.crc; - dfhcpy.crc = 0; - if (crc32((uchar *)&dfhcpy,DEFRAGHDRSIZ) == hdrcrc) { - ftot = dhp->idx + 1; - dhp = (struct defraghdr *)crctbl - ftot; - crc = (ulong *)dhp - 1; - if (crc32((uchar *)dhp, - (uchar *)(tdp->spare+lastssize-1) - (uchar *)dhp) == *crc) { + int ftot, valid, lastssize; + uchar *lastsbase; + struct sectorcrc *crctbl; + ulong hdrcrc, *crc; + struct defraghdr *dhp, dfhcpy; + + ftot = valid = 0; + crctbl = defragCrcTable(tdp); + dhp = (struct defraghdr *)crctbl - 1; + /* next line was <dfhcpy = *dhp> ... */ + memcpy((char *)&dfhcpy,(char *)dhp,sizeof(struct defraghdr)); + hdrcrc = dfhcpy.crc; + dfhcpy.crc = 0; + if(crc32((uchar *)&dfhcpy,DEFRAGHDRSIZ) == hdrcrc) { + ftot = dhp->idx + 1; + dhp = (struct defraghdr *)crctbl - ftot; + crc = (ulong *)dhp - 1; + if(crc32((uchar *)dhp,(uchar *)tdp->end-(uchar *)dhp) == *crc) { + if(scp) { + *scp = crctbl; + } + return(ftot); + } + } + + /* It's possible that the DSI space has been relocated to the spare + * sector, so check for that here... + */ + addrtosector((unsigned char *)tdp->end,0,&lastssize,&lastsbase); + + crctbl = ((struct sectorcrc *)(tdp->spare+lastssize) - tdp->sectorcount); + dhp = (struct defraghdr *)crctbl - 1; + /* next line was <dfhcpy = *dhp> ... */ + memcpy((char *)&dfhcpy,(char *)dhp,sizeof(struct defraghdr)); + hdrcrc = dfhcpy.crc; + dfhcpy.crc = 0; + if(crc32((uchar *)&dfhcpy,DEFRAGHDRSIZ) == hdrcrc) { + ftot = dhp->idx + 1; + dhp = (struct defraghdr *)crctbl - ftot; + crc = (ulong *)dhp - 1; + if(crc32((uchar *)dhp, + (uchar *)(tdp->spare+lastssize-1) - (uchar *)dhp) == *crc) { #if DEFRAG_TEST_ENABLED - printf("TFS: DSI in spare\n"); + printf("TFS: DSI in spare\n"); #endif - if (scp) - *scp = crctbl; - return(ftot); - } - } - return(0); + if(scp) { + *scp = crctbl; + } + return(ftot); + } + } + return(0); } /* defragSectorInSpare(): @@ -344,70 +347,72 @@ defragValidDSI(TDEV *tdp, struct sectorcrc **scp) static int defragSectorInSpare(TDEV *tdp, struct sectorcrc *crctbl) { - uchar *sbase; - struct defraghdr *dhp; - int i, ssize, snum, ftot; - - sbase = (uchar *)tdp->start; - dhp = (struct defraghdr *)crctbl - 1; - ftot = dhp->idx + 1; - - for(i=0;i<tdp->sectorcount;i++) { - addrtosector(sbase,&snum,&ssize,0); - if (i == tdp->sectorcount - 1) { - ssize -= /* CRC table */ - (tdp->sectorcount * sizeof(struct sectorcrc)); - ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */ - ssize -= 4; /* Crc of the tables */ - } - if (crc32((uchar *)tdp->spare,ssize) == crctbl[i].precrc) - return(snum); - sbase += ssize; - } - return(-1); + uchar *sbase; + struct defraghdr *dhp; + int i, ssize, snum, ftot; + + sbase = (uchar *)tdp->start; + dhp = (struct defraghdr *)crctbl - 1; + ftot = dhp->idx + 1; + + for(i=0; i<tdp->sectorcount; i++) { + addrtosector(sbase,&snum,&ssize,0); + if(i == tdp->sectorcount - 1) { + ssize -= /* CRC table */ + (tdp->sectorcount * sizeof(struct sectorcrc)); + ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */ + ssize -= 4; /* Crc of the tables */ + } + if(crc32((uchar *)tdp->spare,ssize) == crctbl[i].precrc) { + return(snum); + } + sbase += ssize; + } + return(-1); } /* defragTouchedSectors(): * Step through the crc table and TFS flash space to find the first * and last sectors that have been touched by defragmentation. - * This is used by defragGetState() to recover from an interrupted + * This is used by defragGetState() to recover from an interrupted * defragmentation, so a few verbose messages are useful to indicate * status to the user. */ void defragTouchedSectors(TDEV *tdp,int *first, int *last) { - uchar *sbase; - struct defraghdr *dhp; - struct sectorcrc *crctbl; - int i, ssize, snum, ftot; - - *first = -1; - *last = -1; - sbase = (uchar *)tdp->start; - crctbl = defragCrcTable(tdp); - dhp = (struct defraghdr *)crctbl - 1; - ftot = dhp->idx + 1; - - printf("TFS: calculating per-sector crcs... "); - for(i=0;i<tdp->sectorcount;i++) { - addrtosector(sbase,&snum,&ssize,0); - if (i == tdp->sectorcount - 1) { - ssize -= /* CRC table */ - (tdp->sectorcount * sizeof(struct sectorcrc)); - ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */ - ssize -= 4; /* Crc of the tables */ - } - if (crc32(sbase,ssize) != crctbl[i].precrc) { - if (*first == -1) - *first = snum; - *last = snum; - } - sbase += ssize; - defragTick(0); - } - printf("done\n"); - return; + uchar *sbase; + struct defraghdr *dhp; + struct sectorcrc *crctbl; + int i, ssize, snum, ftot; + + *first = -1; + *last = -1; + sbase = (uchar *)tdp->start; + crctbl = defragCrcTable(tdp); + dhp = (struct defraghdr *)crctbl - 1; + ftot = dhp->idx + 1; + + printf("TFS: calculating per-sector crcs... "); + for(i=0; i<tdp->sectorcount; i++) { + addrtosector(sbase,&snum,&ssize,0); + if(i == tdp->sectorcount - 1) { + ssize -= /* CRC table */ + (tdp->sectorcount * sizeof(struct sectorcrc)); + ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */ + ssize -= 4; /* Crc of the tables */ + } + if(crc32(sbase,ssize) != crctbl[i].precrc) { + if(*first == -1) { + *first = snum; + } + *last = snum; + } + sbase += ssize; + defragTick(0); + } + printf("done\n"); + return; } /* defragPostCrcCheck(): @@ -417,33 +422,35 @@ defragTouchedSectors(TDEV *tdp,int *first, int *last) int defragPostCrcCheck(TDEV *tdp, int isnum) { - uchar *sbase; - struct defraghdr *dhp; - struct sectorcrc *crctbl; - int ftot, i, snum, ssize, lastsnum, lastssize; - - sbase = (uchar *)tdp->start; - crctbl = defragCrcTable(tdp); - dhp = (struct defraghdr *)crctbl - 1; - ftot = dhp->idx + 1; - - addrtosector((uchar *)tdp->end,&lastsnum,&lastssize,0); - - for(i=0;i<tdp->sectorcount;i++) { - addrtosector(sbase,&snum,&ssize,0); - if (snum == isnum) - break; - sbase += ssize; - } - if (isnum == lastsnum) { - ssize -= (tdp->sectorcount * sizeof(struct sectorcrc)); - ssize -= (ftot * DEFRAGHDRSIZ); - ssize -= 4; - } - if (crctbl[i].postcrc == crc32(sbase,ssize)) - return(1); - else - return(0); + uchar *sbase; + struct defraghdr *dhp; + struct sectorcrc *crctbl; + int ftot, i, snum, ssize, lastsnum, lastssize; + + sbase = (uchar *)tdp->start; + crctbl = defragCrcTable(tdp); + dhp = (struct defraghdr *)crctbl - 1; + ftot = dhp->idx + 1; + + addrtosector((uchar *)tdp->end,&lastsnum,&lastssize,0); + + for(i=0; i<tdp->sectorcount; i++) { + addrtosector(sbase,&snum,&ssize,0); + if(snum == isnum) { + break; + } + sbase += ssize; + } + if(isnum == lastsnum) { + ssize -= (tdp->sectorcount * sizeof(struct sectorcrc)); + ssize -= (ftot * DEFRAGHDRSIZ); + ssize -= 4; + } + if(crctbl[i].postcrc == crc32(sbase,ssize)) { + return(1); + } else { + return(0); + } } /* defragGetStateStr(): @@ -452,38 +459,38 @@ defragPostCrcCheck(TDEV *tdp, int isnum) static char * defragGetStateStr(int state) { - char *str; - - switch(state) { - case SECTOR_DEFRAG_INACTIVE: - str = "SectorDefragInactive"; - break; - case SECTOR_DEFRAG_ABORT_RESTART: - str = "DefragRestartAborted"; - break; - case SCANNING_ACTIVE_SECTOR_1: - str = "ScanningActiveSector1"; - break; - case SCANNING_ACTIVE_SECTOR_2: - str = "ScanningActiveSector2"; - break; - case SCANNING_ACTIVE_SECTOR_3: - str = "ScanningActiveSector3"; - break; - case SCANNING_ACTIVE_SECTOR_4: - str = "ScanningActiveSector4"; - break; - case SCANNING_ACTIVE_SECTOR_5: - str = "ScanningActiveSector5"; - break; - case SECTOR_DEFRAG_ALMOST_DONE: - str = "DefragAlmostDone"; - break; - default: - str = "???"; - break; - } - return(str); + char *str; + + switch(state) { + case SECTOR_DEFRAG_INACTIVE: + str = "SectorDefragInactive"; + break; + case SECTOR_DEFRAG_ABORT_RESTART: + str = "DefragRestartAborted"; + break; + case SCANNING_ACTIVE_SECTOR_1: + str = "ScanningActiveSector1"; + break; + case SCANNING_ACTIVE_SECTOR_2: + str = "ScanningActiveSector2"; + break; + case SCANNING_ACTIVE_SECTOR_3: + str = "ScanningActiveSector3"; + break; + case SCANNING_ACTIVE_SECTOR_4: + str = "ScanningActiveSector4"; + break; + case SCANNING_ACTIVE_SECTOR_5: + str = "ScanningActiveSector5"; + break; + case SECTOR_DEFRAG_ALMOST_DONE: + str = "DefragAlmostDone"; + break; + default: + str = "???"; + break; + } + return(str); } /* defragRestart(): @@ -495,11 +502,12 @@ defragGetStateStr(int state) int defragRestart(int state,int snum) { - printf("TFS defrag restart state: %s sector %d\n", - defragGetStateStr(state),snum); - if (pollConsole("Hit any key to abort...")) - return(0); - return(1); + printf("TFS defrag restart state: %s sector %d\n", + defragGetStateStr(state),snum); + if(pollConsole("Hit any key to abort...")) { + return(0); + } + return(1); } /* defragGetState(): @@ -517,367 +525,369 @@ defragRestart(int state,int snum) * to be much faster for systems that have a lot of empty TFS * space. The code was used to verify that all flash space after * the last stored file in TFS was actually erased. If not, then - * it erases it. - * This turns out to not really be necessary because if tfsadd() - * runs and finds that the area it needs isn't erased, it will - * automatically fall into a tfsclean anyway. As a result, to + * it erases it. + * This turns out to not really be necessary because if tfsadd() + * runs and finds that the area it needs isn't erased, it will + * automatically fall into a tfsclean anyway. As a result, to * make startup quicker, this code is not enabled by default. If * it is needed, then just define the macro in config.h. * - * As of Mar 2011, thanks to input from Jamie Randall, I'm essentially - * undoing the previous change by defining the - * ENABLE_FLASHERASED_CHECK_AT_STARTUP right here. Turns out that - * while removal of this snippet of code does make bootup faster for - * those cases where the flash has a large number of sectors, it does - * cause powersafe defrag to fail in certain cases if a hit occurs. + * As of Mar 2011, thanks to input from Jamie Randall, I'm essentially + * undoing the previous change by defining the + * ENABLE_FLASHERASED_CHECK_AT_STARTUP right here. Turns out that + * while removal of this snippet of code does make bootup faster for + * those cases where the flash has a large number of sectors, it does + * cause powersafe defrag to fail in certain cases if a hit occurs. * */ -#define ENABLE_FLASHERASED_CHECK_AT_STARTUP /* see note above */ +#define ENABLE_FLASHERASED_CHECK_AT_STARTUP /* see note above */ static int defragGetState(TDEV *tdp, int *activesnum) { - TFILE *tfp; - struct defraghdr *dhp; - struct sectorcrc *crctbl; - int snum_in_spare, firstsnum; - int first_touched_snum, last_touched_snum; - int break_cause, break1_cause, spare_is_erased, ftot, ftot1, errstate; - - /* Establish state of spare sector: - */ - spare_is_erased = flasherased((uchar *)tdp->spare, - (uchar *)tdp->spare+tdp->sparesize-1); - - ftot = 0; - break_cause = break1_cause = 0; - for(tfp=(TFILE *)tdp->start; tfp < (TFILE *)tdp->end; tfp=tfp->next) { - /* If we are legally at the end of file storage space, then we - * will hit a header size that is ERASED16. If we reach this - * point and the remaining space dedicated to file storage is - * erased and the spare is erased, it is safe to assume that we - * were not in the middle of a defrag. - */ - if (tfp->hdrsize == ERASED16) { -#ifdef ENABLE_FLASHERASED_CHECK_AT_STARTUP /* (see note above) */ - /* Is space from last file to end of TFS space erased? */ - if (!flasherased((uchar *)tfp,(uchar *)tdp->end)) { - break_cause = 1; - break; - } - if (!spare_is_erased) { - break_cause = 2; - break; - } + TFILE *tfp; + struct defraghdr *dhp; + struct sectorcrc *crctbl; + int snum_in_spare, firstsnum; + int first_touched_snum, last_touched_snum; + int break_cause, break1_cause, spare_is_erased, ftot, ftot1, errstate; + + /* Establish state of spare sector: + */ + spare_is_erased = flasherased((uchar *)tdp->spare, + (uchar *)tdp->spare+tdp->sparesize-1); + + ftot = 0; + break_cause = break1_cause = 0; + for(tfp=(TFILE *)tdp->start; tfp < (TFILE *)tdp->end; tfp=tfp->next) { + /* If we are legally at the end of file storage space, then we + * will hit a header size that is ERASED16. If we reach this + * point and the remaining space dedicated to file storage is + * erased and the spare is erased, it is safe to assume that we + * were not in the middle of a defrag. + */ + if(tfp->hdrsize == ERASED16) { +#ifdef ENABLE_FLASHERASED_CHECK_AT_STARTUP /* (see note above) */ + /* Is space from last file to end of TFS space erased? */ + if(!flasherased((uchar *)tfp,(uchar *)tdp->end)) { + break_cause = 1; + break; + } + if(!spare_is_erased) { + break_cause = 2; + break; + } #if DEFRAG_TEST_ENABLED - printf("\ndefragGetState: inactive_1\n"); + printf("\ndefragGetState: inactive_1\n"); #endif #endif - return(SECTOR_DEFRAG_INACTIVE); - } - - /* If the crc32 of the header is corrupt, or if the next pointer - * doesn't make any sense, then we must assume that a defrag - * was in progress... - */ - if (tfshdrcrc(tfp) != tfp->hdrcrc) { - break; - } - - if (!(tfp->next) || (tfp->next <= (TFILE *)tdp->start) || - (tfp->next >= (TFILE *)tdp->end)) { - break; - } - if (TFS_FILEEXISTS(tfp)) - ftot++; - } - /* If we are here, then something is not "perfect" with the flash - * space used by TFS. If break_cause is non-zero, there is a chance - * that the only problem is that a file-write was interrupted and - * we did not actually interrupt an in-progress-defrag. An interrupted - * file write would place some incomplete data after the last file. - */ - ftot1 = defragValidDSI(tdp,&crctbl); - - /* If we don't have valid defrag state info (DSI), then we can assume - * that the files in TFS have not yet been touched (since if we had - * touched them, we would have already successfully created the DSI). - * This being the case, then we will not continue with any defrag, - * let TFS clean things up when the space is needed. - */ - if (!ftot1) { - if (break_cause) { - /* Hmmm... Should something be done here? */ - } + return(SECTOR_DEFRAG_INACTIVE); + } + + /* If the crc32 of the header is corrupt, or if the next pointer + * doesn't make any sense, then we must assume that a defrag + * was in progress... + */ + if(tfshdrcrc(tfp) != tfp->hdrcrc) { + break; + } + + if(!(tfp->next) || (tfp->next <= (TFILE *)tdp->start) || + (tfp->next >= (TFILE *)tdp->end)) { + break; + } + if(TFS_FILEEXISTS(tfp)) { + ftot++; + } + } + /* If we are here, then something is not "perfect" with the flash + * space used by TFS. If break_cause is non-zero, there is a chance + * that the only problem is that a file-write was interrupted and + * we did not actually interrupt an in-progress-defrag. An interrupted + * file write would place some incomplete data after the last file. + */ + ftot1 = defragValidDSI(tdp,&crctbl); + + /* If we don't have valid defrag state info (DSI), then we can assume + * that the files in TFS have not yet been touched (since if we had + * touched them, we would have already successfully created the DSI). + * This being the case, then we will not continue with any defrag, + * let TFS clean things up when the space is needed. + */ + if(!ftot1) { + if(break_cause) { + /* Hmmm... Should something be done here? */ + } #if DEFRAG_TEST_ENABLED - printf("\ndefragGetState: inactive_2\n"); + printf("\ndefragGetState: inactive_2\n"); #endif - return(SECTOR_DEFRAG_INACTIVE); - } - - /* If we get here, then we have a valid defrag header table, so we - * can use it and the state of each of the sectors to figure out - * where we are in the defragmentation process. We need to determine - * which sector was being worked on at the point in time when the - * defragmentation was interrupted. A sector is in the "touched" - * state if a crc32 on its content does not match the crc32 stored - * in the crc table above the defrag header table. - * - * Here we step through the defrag header table and see if each file - * in the header table exists in TFS. If all files exist, then we - * must have been very close to completion of the defrag process. - */ - printf("TFS: scanning DSI space... "); - dhp = (struct defraghdr *)crctbl - ftot1; - while(dhp < (struct defraghdr *)crctbl) { - tfp = (TFILE *)dhp->nda; - if (tfp->hdrcrc != dhp->ohdrcrc) - break; - - if (tfshdrcrc(tfp) != tfp->hdrcrc) { - break1_cause = 1; - break; - } - if (crc32((uchar *)(tfp+1),tfp->filsize) != tfp->filcrc) { - break1_cause = 2; - break; - } - dhp++; - defragTick(0); - } - printf("done\n"); - - /* If we stepped through the entire table, then we've completed the - * file relocation process, but we still have to clean up... - */ - if (dhp >= (struct defraghdr *)crctbl) { - if (defragRestart(SECTOR_DEFRAG_ALMOST_DONE,0)) { - return(SECTOR_DEFRAG_ALMOST_DONE); - } - else { - return(SECTOR_DEFRAG_ABORT_RESTART); - } - } - - if (addrtosector((unsigned char *)tdp->start,&firstsnum,0,0) < 0) { - errstate = 50; - goto state_error; - } - defragTouchedSectors(tdp,&first_touched_snum,&last_touched_snum); - - /* If there are no touched sectors, then we will not continue with - * the defrag because we didn't start relocation of any of the files - * yet. - */ - if (first_touched_snum == -1) { + return(SECTOR_DEFRAG_INACTIVE); + } + + /* If we get here, then we have a valid defrag header table, so we + * can use it and the state of each of the sectors to figure out + * where we are in the defragmentation process. We need to determine + * which sector was being worked on at the point in time when the + * defragmentation was interrupted. A sector is in the "touched" + * state if a crc32 on its content does not match the crc32 stored + * in the crc table above the defrag header table. + * + * Here we step through the defrag header table and see if each file + * in the header table exists in TFS. If all files exist, then we + * must have been very close to completion of the defrag process. + */ + printf("TFS: scanning DSI space... "); + dhp = (struct defraghdr *)crctbl - ftot1; + while(dhp < (struct defraghdr *)crctbl) { + tfp = (TFILE *)dhp->nda; + if(tfp->hdrcrc != dhp->ohdrcrc) { + break; + } + + if(tfshdrcrc(tfp) != tfp->hdrcrc) { + break1_cause = 1; + break; + } + if(crc32((uchar *)(tfp+1),tfp->filsize) != tfp->filcrc) { + break1_cause = 2; + break; + } + dhp++; + defragTick(0); + } + printf("done\n"); + + /* If we stepped through the entire table, then we've completed the + * file relocation process, but we still have to clean up... + */ + if(dhp >= (struct defraghdr *)crctbl) { + if(defragRestart(SECTOR_DEFRAG_ALMOST_DONE,0)) { + return(SECTOR_DEFRAG_ALMOST_DONE); + } else { + return(SECTOR_DEFRAG_ABORT_RESTART); + } + } + + if(addrtosector((unsigned char *)tdp->start,&firstsnum,0,0) < 0) { + errstate = 50; + goto state_error; + } + defragTouchedSectors(tdp,&first_touched_snum,&last_touched_snum); + + /* If there are no touched sectors, then we will not continue with + * the defrag because we didn't start relocation of any of the files + * yet. + */ + if(first_touched_snum == -1) { #if DEFRAG_TEST_ENABLED - printf("\ndefragGetState: inactive_3\n"); + printf("\ndefragGetState: inactive_3\n"); #endif - return(SECTOR_DEFRAG_INACTIVE); - } + return(SECTOR_DEFRAG_INACTIVE); + } - if (spare_is_erased) - snum_in_spare = -1; - else - snum_in_spare = defragSectorInSpare(tdp,crctbl); + if(spare_is_erased) { + snum_in_spare = -1; + } else { + snum_in_spare = defragSectorInSpare(tdp,crctbl); + } #if DEFRAG_TEST_ENABLED - printf("\ndefragGetState info: %d %d %d\n", - first_touched_snum, last_touched_snum, snum_in_spare); + printf("\ndefragGetState info: %d %d %d\n", + first_touched_snum, last_touched_snum, snum_in_spare); #endif - /* At this point we know what sector was the last to be touched. - * What we don't know is whether or not the "touch" was completed. - * So we don't know if the active sector is last_touched_snum or - * last_touched_snum+1. - * The only useful piece of data we 'might' have is the fact that - * the spare may contain the content of the last touched sector. - */ - - /* If the spare is erased, it may be because defrag was just getting - * ready to start working on the next sector (meaning that the active - * sector is last_touched_snum+1) or the sector was in the process of - * being modified. We use the post-crc in the DHT to determine what - * the active sector is... - */ - if (spare_is_erased) { - if (last_touched_snum >= 0) { - if (defragPostCrcCheck(tdp,last_touched_snum)) { - *activesnum = last_touched_snum + 1; - - if (defragRestart(SCANNING_ACTIVE_SECTOR_1,*activesnum)) - return(SCANNING_ACTIVE_SECTOR_1); - else - return(SECTOR_DEFRAG_ABORT_RESTART); - } - else { - if (defragSerase(2,last_touched_snum) < 0) { - errstate = 51; - goto state_error; - } - *activesnum = last_touched_snum; - - if (defragRestart(SCANNING_ACTIVE_SECTOR_2,*activesnum)) - return(SCANNING_ACTIVE_SECTOR_2); - else - return(SECTOR_DEFRAG_ABORT_RESTART); - } - - } - else { - errstate = 52; - goto state_error; - } - } - - /* If the sector copied to spare is one greater than the last touched - * sector, then the active sector is last_touched_snum+1 and it was - * just copied to the spare. In this case we erase the spare and - * return indicating the active sector. - */ - if (snum_in_spare == last_touched_snum+1) { - if (defragEraseSpare(tdp) < 0) { - errstate = 53; - goto state_error; - } - *activesnum = snum_in_spare; - - if (defragRestart(SCANNING_ACTIVE_SECTOR_3,*activesnum)) - return(SCANNING_ACTIVE_SECTOR_3); - else - return(SECTOR_DEFRAG_ABORT_RESTART); - } - - /* If the spare is not erased, but it does not match any of the - * sector CRCs, then we must have been in the process of copying - * the active sector to the spare, so we can erase it and return - * to the SCANNING_ACTIVE_SECTOR state. - */ - if (snum_in_spare == -1) { - if (last_touched_snum >= 0) { - *activesnum = last_touched_snum + 1; - - if (!defragRestart(SCANNING_ACTIVE_SECTOR_4,*activesnum)) - return(SECTOR_DEFRAG_ABORT_RESTART); - - if (defragEraseSpare(tdp) < 0) { - errstate = 54; - goto state_error; - } - return(SCANNING_ACTIVE_SECTOR_4); - } - else { - errstate = 55; - goto state_error; - } - } - - /* If the sector copied to spare is the number of the last touched - * sector, then we were in the middle of modifying the sector, so - * we have to erase that sector, copy the spare to it and return - * to the scanning state. - */ - if (snum_in_spare == last_touched_snum) { - int ssize; - uchar *sbase; - - *activesnum = snum_in_spare; - - if (!defragRestart(SCANNING_ACTIVE_SECTOR_5,*activesnum)) - return(SECTOR_DEFRAG_ABORT_RESTART); - - if (defragSerase(3,snum_in_spare) < 0) { - errstate = 56; - goto state_error; - } - if (sectortoaddr(snum_in_spare,&ssize,&sbase) < 0) { - errstate = 57; - goto state_error; - } - if (defragFwrite(1,sbase,(uchar *)tdp->spare,ssize) < 0) { - errstate = 58; - goto state_error; - } - if (defragEraseSpare(tdp) < 0) { - errstate = 59; - goto state_error; - } - return(SCANNING_ACTIVE_SECTOR_5); - } - - /* If we got here, then we are confused, so don't do any defrag - * continuation... - */ - errstate = 90; + /* At this point we know what sector was the last to be touched. + * What we don't know is whether or not the "touch" was completed. + * So we don't know if the active sector is last_touched_snum or + * last_touched_snum+1. + * The only useful piece of data we 'might' have is the fact that + * the spare may contain the content of the last touched sector. + */ + + /* If the spare is erased, it may be because defrag was just getting + * ready to start working on the next sector (meaning that the active + * sector is last_touched_snum+1) or the sector was in the process of + * being modified. We use the post-crc in the DHT to determine what + * the active sector is... + */ + if(spare_is_erased) { + if(last_touched_snum >= 0) { + if(defragPostCrcCheck(tdp,last_touched_snum)) { + *activesnum = last_touched_snum + 1; + + if(defragRestart(SCANNING_ACTIVE_SECTOR_1,*activesnum)) { + return(SCANNING_ACTIVE_SECTOR_1); + } else { + return(SECTOR_DEFRAG_ABORT_RESTART); + } + } else { + if(defragSerase(2,last_touched_snum) < 0) { + errstate = 51; + goto state_error; + } + *activesnum = last_touched_snum; + + if(defragRestart(SCANNING_ACTIVE_SECTOR_2,*activesnum)) { + return(SCANNING_ACTIVE_SECTOR_2); + } else { + return(SECTOR_DEFRAG_ABORT_RESTART); + } + } + + } else { + errstate = 52; + goto state_error; + } + } + + /* If the sector copied to spare is one greater than the last touched + * sector, then the active sector is last_touched_snum+1 and it was + * just copied to the spare. In this case we erase the spare and + * return indicating the active sector. + */ + if(snum_in_spare == last_touched_snum+1) { + if(defragEraseSpare(tdp) < 0) { + errstate = 53; + goto state_error; + } + *activesnum = snum_in_spare; + + if(defragRestart(SCANNING_ACTIVE_SECTOR_3,*activesnum)) { + return(SCANNING_ACTIVE_SECTOR_3); + } else { + return(SECTOR_DEFRAG_ABORT_RESTART); + } + } + + /* If the spare is not erased, but it does not match any of the + * sector CRCs, then we must have been in the process of copying + * the active sector to the spare, so we can erase it and return + * to the SCANNING_ACTIVE_SECTOR state. + */ + if(snum_in_spare == -1) { + if(last_touched_snum >= 0) { + *activesnum = last_touched_snum + 1; + + if(!defragRestart(SCANNING_ACTIVE_SECTOR_4,*activesnum)) { + return(SECTOR_DEFRAG_ABORT_RESTART); + } + + if(defragEraseSpare(tdp) < 0) { + errstate = 54; + goto state_error; + } + return(SCANNING_ACTIVE_SECTOR_4); + } else { + errstate = 55; + goto state_error; + } + } + + /* If the sector copied to spare is the number of the last touched + * sector, then we were in the middle of modifying the sector, so + * we have to erase that sector, copy the spare to it and return + * to the scanning state. + */ + if(snum_in_spare == last_touched_snum) { + int ssize; + uchar *sbase; + + *activesnum = snum_in_spare; + + if(!defragRestart(SCANNING_ACTIVE_SECTOR_5,*activesnum)) { + return(SECTOR_DEFRAG_ABORT_RESTART); + } + + if(defragSerase(3,snum_in_spare) < 0) { + errstate = 56; + goto state_error; + } + if(sectortoaddr(snum_in_spare,&ssize,&sbase) < 0) { + errstate = 57; + goto state_error; + } + if(defragFwrite(1,sbase,(uchar *)tdp->spare,ssize) < 0) { + errstate = 58; + goto state_error; + } + if(defragEraseSpare(tdp) < 0) { + errstate = 59; + goto state_error; + } + return(SCANNING_ACTIVE_SECTOR_5); + } + + /* If we got here, then we are confused, so don't do any defrag + * continuation... + */ + errstate = 90; state_error: - printf("DEFRAG_STATE_ERROR: #%d.\n",errstate); - return(SECTOR_DEFRAG_INACTIVE); + printf("DEFRAG_STATE_ERROR: #%d.\n",errstate); + return(SECTOR_DEFRAG_INACTIVE); } /* inSector(): * We are trying to figure out if the address space that we want to copy * from is within the active sector. If it is, then we need to adjust * our pointers so that we retrieve the at least some of data from the - * spare. + * spare. * If the range specified by 'i_base' and 'i_size' overlays (in any way) - * the address space used by the sector specified by 'snum', + * the address space used by the sector specified by 'snum', * then return the address in the spare and the size of the overlay. */ static int inSector(TDEV *tdp,int snum,uchar *i_base,int i_size,uchar **saddr,int *ovlysz) { - int s_size; - uchar *s_base, *s_end, *i_end; - - /* Retrieve information about the sector: */ - if (sectortoaddr(snum,&s_size,&s_base) == -1) - return(TFSERR_MEMFAIL); - - i_end = i_base + i_size; - s_end = s_base + s_size; - - if ((i_end < s_base) || (i_base > s_end)) { - *ovlysz = 0; - return(0); - } - - if (i_base < s_base) { - if (i_end > s_end) { - *ovlysz = s_size; - } - else { - *ovlysz = (i_size - (s_base - i_base)); - } - *saddr = (uchar *)tdp->spare; - } - else { - if (i_end > s_end) { - *ovlysz = (i_size - (i_end - s_end)); - } - else { - *ovlysz = i_size; - } - *saddr = (uchar *)tdp->spare + (i_base - s_base); - } - return(0); + int s_size; + uchar *s_base, *s_end, *i_end; + + /* Retrieve information about the sector: */ + if(sectortoaddr(snum,&s_size,&s_base) == -1) { + return(TFSERR_MEMFAIL); + } + + i_end = i_base + i_size; + s_end = s_base + s_size; + + if((i_end < s_base) || (i_base > s_end)) { + *ovlysz = 0; + return(0); + } + + if(i_base < s_base) { + if(i_end > s_end) { + *ovlysz = s_size; + } else { + *ovlysz = (i_size - (s_base - i_base)); + } + *saddr = (uchar *)tdp->spare; + } else { + if(i_end > s_end) { + *ovlysz = (i_size - (i_end - s_end)); + } else { + *ovlysz = i_size; + } + *saddr = (uchar *)tdp->spare + (i_base - s_base); + } + return(0); } /* struct fillinfo & FILLMODE definitions: * Structure used by the "Fill" functions below. */ -#define FILLMODE_FWRITE 1 /* Do the flash write */ -#define FILLMODE_SPAREOVERLAP 2 /* Determine if there is SPARE overlap */ -#define FILLMODE_CRCONLY 3 /* Calculate a 32-bit crc on the data */ +#define FILLMODE_FWRITE 1 /* Do the flash write */ +#define FILLMODE_SPAREOVERLAP 2 /* Determine if there is SPARE overlap */ +#define FILLMODE_CRCONLY 3 /* Calculate a 32-bit crc on the data */ struct fillinfo { - struct defraghdr *dhp; /* pointer to defrag header table */ - TDEV *tdp; /* pointer to TFS device */ - ulong crc; /* used in FILLMODE_CRCONLY mode */ - int crcsz; /* size of crc calculation */ - int fhdr; /* set if we're working on a file header */ - int asnum; /* the active sector */ - int mode; /* see FILLMODE_xxx definitions */ + struct defraghdr *dhp; /* pointer to defrag header table */ + TDEV *tdp; /* pointer to TFS device */ + ulong crc; /* used in FILLMODE_CRCONLY mode */ + int crcsz; /* size of crc calculation */ + int fhdr; /* set if we're working on a file header */ + int asnum; /* the active sector */ + int mode; /* see FILLMODE_xxx definitions */ }; /* defragFillFlash(): @@ -888,8 +898,8 @@ struct fillinfo { * the source is taken from the spare). It is within this function that * the active sector is actually modified and it assumes that the portion * of the active sector to be written to is already erased. - * - * + * + * * SPANTYPE_BCEC: * In this case, the file starts in the active sector and ends in * the active sector... @@ -902,7 +912,7 @@ struct fillinfo { * | | | |<-->| | | | | | * -----------|----------|----------|----------|---------|---------|---------- * - * + * * SPANTYPE_BPEC: * In this case, the file starts in a sector prior to the currently active * sector and ends in the active sector... @@ -915,7 +925,7 @@ struct fillinfo { * | | | | | | | | * -----------|----------|----------|----------|---------|---------|---------- * - * + * * SPANTYPE_BPEL: * In this case, the file starts in some sector prior to the currently * active sector and ends in some sector after the currently active @@ -945,222 +955,217 @@ struct fillinfo { static int defragFillFlash(struct fillinfo *fip,int spantype,char **activeaddr,int verbose) { - char *hp; - TFILE nfhdr; - struct defraghdr *dhp; - int ohdroffset, nhdroffset; - uchar *ovly, *src, *activesbase; - int ovlysz, srcsz, activessize; - - src = 0; - ovly = 0; - srcsz = 0; - nhdroffset = ohdroffset = 0; - dhp = fip->dhp; - - if (verbose >= 2) { - printf(" defragFillFlash %s %s (%s %d)\n",fip->fhdr ? "hdr" : "dat", - defragGetSpantypeStr(spantype), dhp->fname,fip->asnum); - } - - if (spantype == SPANTYPE_BCEC) { - if (fip->fhdr) { - src = (uchar *)dhp->ohdr; - srcsz = TFSHDRSIZ; - } - else { - src = (uchar *)dhp->ohdr+TFSHDRSIZ; - srcsz = dhp->filsize; - } - } - else if (spantype == SPANTYPE_BPEC) { - if (fip->fhdr) { - /* Calculate the offset into the header at which point a - * sector boundary occurs. Do this for both the old (before - * defrag relocation) and new (after defrag relocation) - * location of the header. - */ - /* Changed as of Dec 2010, based on error found by Leon... - * We need to figure out how the header overlaps the sector - * boundary. Prior to 12/2010, this code did not account for - * the case where the file size spans beyond the currently - * active sector. - */ - if ((dhp->neso > dhp->filsize) && (dhp->oeso > dhp->filsize)) { - nhdroffset = TFSHDRSIZ - (dhp->neso - dhp->filsize); - ohdroffset = TFSHDRSIZ - (dhp->oeso - dhp->filsize); - srcsz = (dhp->oeso - dhp->filsize) + (ohdroffset - nhdroffset); - src = (uchar *)dhp->ohdr + nhdroffset; - } - else { - int ssz; - int sno = dhp->nesn; - int fsz = dhp->filsize; - while(sno > fip->asnum) { - if (sectortoaddr(sno,&ssz,0) < 0) - return(TFSERR_MEMFAIL); - if (fsz == dhp->filsize) - fsz -= dhp->neso; - else - fsz -= ssz; - sno--; - } - if (sectortoaddr(fip->asnum,&ssz,0) < 0) - return(TFSERR_MEMFAIL); - srcsz = ssz - fsz; - src = (uchar *)dhp->ohdr; - src += (TFSHDRSIZ-srcsz); - nhdroffset = (TFSHDRSIZ-srcsz); - } - } - else { - src = (uchar *)dhp->ohdr + TFSHDRSIZ + (dhp->filsize - dhp->neso); - srcsz = dhp->neso; - } - } - else if (spantype == SPANTYPE_BCEL) { - if (sectortoaddr(fip->asnum,&activessize,&activesbase) == -1) - return(TFSERR_MEMFAIL); - - if (fip->fhdr) { - src = (uchar *)dhp->ohdr; - } - else { - src = (uchar *)dhp->ohdr+TFSHDRSIZ; - } - srcsz = (activesbase + activessize) - (uchar *)*activeaddr; - } - else if (spantype == SPANTYPE_BPEL) { - if (sectortoaddr(fip->asnum,&activessize,0) == -1) - return(TFSERR_MEMFAIL); - - if (fip->fhdr) { - src = (uchar *)dhp->ohdr; - } - else { - src = (uchar *)dhp->ohdr+TFSHDRSIZ; - } - - src += ((*activeaddr - dhp->nda) - TFSHDRSIZ); - srcsz = activessize; - } - else { - return(0); - } - - /* Do some error checking on the computed size: - */ - if (srcsz < 0) { - printf("defragFillFlash: srcsz < 0\n"); - return(TFSERR_MEMFAIL); - } - - if (fip->fhdr) { - if (srcsz > TFSHDRSIZ) { - printf("defragFillFlash: srcsz > TFSHDRSIZ\n"); - return(TFSERR_MEMFAIL); - } - } - else { - if (srcsz > dhp->filsize) { - printf("defragFillFlash: srcsz > filsize\n"); - return(TFSERR_MEMFAIL); - } - } - - /* Determine if any portion of the source was part of the sector that - * is now the active sector.. If yes (ovlysz > 0), then we must - * deal with the fact that some (or all) of the fill source is in the - * spare sector... - */ - if (inSector(fip->tdp,fip->asnum,src,srcsz,&ovly,&ovlysz) < 0) - return(TFSERR_MEMFAIL); - - /* If the mode is not FILLMODE_FWRITE, then we don't do any of the - * flash operations. We are in this function only to determine - * if we need to copy the active sector to the spare prior to - * starting the modification of the active sector. - */ - if (fip->mode == FILLMODE_FWRITE) { - if (fip->fhdr) { - hp = (char *)&nfhdr; - if (ovlysz) { - memcpy((char *)hp+nhdroffset,(char *)ovly,ovlysz); - if (ovlysz != srcsz) { - memcpy(hp+nhdroffset+ovlysz,(char *)src+ovlysz, - srcsz-ovlysz); - } - } - else { - /* next line was <nfhdr = *dhp->ohdr> ... */ - memcpy((char *)&nfhdr,(char *)dhp->ohdr,sizeof(TFILE)); - } - nfhdr.next = dhp->nextfile; - if (defragFwrite(2,(uchar *)*activeaddr,(uchar *)hp+nhdroffset,srcsz) == -1) - return(TFSERR_FLASHFAILURE); - } - else { - if (ovlysz) { - if (defragFwrite(3,(uchar *)*activeaddr,(uchar *)ovly,ovlysz) == -1) - return(TFSERR_FLASHFAILURE); - if (ovlysz != srcsz) { - if (defragFwrite(4,(uchar *)*activeaddr+ovlysz,(uchar *)src+ovlysz, - srcsz-ovlysz) == -1) - return(TFSERR_FLASHFAILURE); - } - } - else { - if (defragFwrite(5,(uchar *)*activeaddr,(uchar *)src,srcsz) == -1) - return(TFSERR_FLASHFAILURE); - } - } - } - else if (fip->mode == FILLMODE_CRCONLY) { - register uchar *bp; - int sz, temp; - - if (fip->fhdr) { - hp = (char *)&nfhdr; - /* next line was <nfhdr = *dhp->ohdr> ... */ - memcpy((char *)&nfhdr,(char *)dhp->ohdr,sizeof(TFILE)); - nfhdr.next = dhp->nextfile; - bp = (uchar *)hp + nhdroffset; - } - else { - bp = (uchar *)src; - } - sz = srcsz; - fip->crcsz += sz; - while(sz) { - temp = (fip->crc ^ *bp++) & 0x000000FFL; - fip->crc = ((fip->crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; - sz--; - } - } - *activeaddr += srcsz; - - if ((spantype == SPANTYPE_BCEC || spantype == SPANTYPE_BPEC) && - (!fip->fhdr) && ((ulong)*activeaddr & 0xf)) { - int sz, temp, modfixsize; - - modfixsize = (TFS_FSIZEMOD - ((ulong)*activeaddr & (TFS_FSIZEMOD-1))); - *activeaddr += modfixsize; - if (fip->mode == FILLMODE_CRCONLY) { - sz = modfixsize; - fip->crcsz += sz; - while(sz) { - temp = (fip->crc ^ 0xff) & 0x000000FFL; - fip->crc = ((fip->crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; - sz--; - } - } - } - - /* Return ovlysz so that the caller will know if this function - * needed the spare sector. This is used in the "mode = SPARE_OVERLAP" - * pass of defragFillActiveSector(). - */ - return(ovlysz); + char *hp; + TFILE nfhdr; + struct defraghdr *dhp; + int ohdroffset, nhdroffset; + uchar *ovly, *src, *activesbase; + int ovlysz, srcsz, activessize; + + src = 0; + ovly = 0; + srcsz = 0; + nhdroffset = ohdroffset = 0; + dhp = fip->dhp; + + if(verbose >= 2) { + printf(" defragFillFlash %s %s (%s %d)\n",fip->fhdr ? "hdr" : "dat", + defragGetSpantypeStr(spantype), dhp->fname,fip->asnum); + } + + if(spantype == SPANTYPE_BCEC) { + if(fip->fhdr) { + src = (uchar *)dhp->ohdr; + srcsz = TFSHDRSIZ; + } else { + src = (uchar *)dhp->ohdr+TFSHDRSIZ; + srcsz = dhp->filsize; + } + } else if(spantype == SPANTYPE_BPEC) { + if(fip->fhdr) { + /* Calculate the offset into the header at which point a + * sector boundary occurs. Do this for both the old (before + * defrag relocation) and new (after defrag relocation) + * location of the header. + */ + /* Changed as of Dec 2010, based on error found by Leon... + * We need to figure out how the header overlaps the sector + * boundary. Prior to 12/2010, this code did not account for + * the case where the file size spans beyond the currently + * active sector. + */ + if((dhp->neso > dhp->filsize) && (dhp->oeso > dhp->filsize)) { + nhdroffset = TFSHDRSIZ - (dhp->neso - dhp->filsize); + ohdroffset = TFSHDRSIZ - (dhp->oeso - dhp->filsize); + srcsz = (dhp->oeso - dhp->filsize) + (ohdroffset - nhdroffset); + src = (uchar *)dhp->ohdr + nhdroffset; + } else { + int ssz; + int sno = dhp->nesn; + int fsz = dhp->filsize; + while(sno > fip->asnum) { + if(sectortoaddr(sno,&ssz,0) < 0) { + return(TFSERR_MEMFAIL); + } + if(fsz == dhp->filsize) { + fsz -= dhp->neso; + } else { + fsz -= ssz; + } + sno--; + } + if(sectortoaddr(fip->asnum,&ssz,0) < 0) { + return(TFSERR_MEMFAIL); + } + srcsz = ssz - fsz; + src = (uchar *)dhp->ohdr; + src += (TFSHDRSIZ-srcsz); + nhdroffset = (TFSHDRSIZ-srcsz); + } + } else { + src = (uchar *)dhp->ohdr + TFSHDRSIZ + (dhp->filsize - dhp->neso); + srcsz = dhp->neso; + } + } else if(spantype == SPANTYPE_BCEL) { + if(sectortoaddr(fip->asnum,&activessize,&activesbase) == -1) { + return(TFSERR_MEMFAIL); + } + + if(fip->fhdr) { + src = (uchar *)dhp->ohdr; + } else { + src = (uchar *)dhp->ohdr+TFSHDRSIZ; + } + srcsz = (activesbase + activessize) - (uchar *)*activeaddr; + } else if(spantype == SPANTYPE_BPEL) { + if(sectortoaddr(fip->asnum,&activessize,0) == -1) { + return(TFSERR_MEMFAIL); + } + + if(fip->fhdr) { + src = (uchar *)dhp->ohdr; + } else { + src = (uchar *)dhp->ohdr+TFSHDRSIZ; + } + + src += ((*activeaddr - dhp->nda) - TFSHDRSIZ); + srcsz = activessize; + } else { + return(0); + } + + /* Do some error checking on the computed size: + */ + if(srcsz < 0) { + printf("defragFillFlash: srcsz < 0\n"); + return(TFSERR_MEMFAIL); + } + + if(fip->fhdr) { + if(srcsz > TFSHDRSIZ) { + printf("defragFillFlash: srcsz > TFSHDRSIZ\n"); + return(TFSERR_MEMFAIL); + } + } else { + if(srcsz > dhp->filsize) { + printf("defragFillFlash: srcsz > filsize\n"); + return(TFSERR_MEMFAIL); + } + } + + /* Determine if any portion of the source was part of the sector that + * is now the active sector.. If yes (ovlysz > 0), then we must + * deal with the fact that some (or all) of the fill source is in the + * spare sector... + */ + if(inSector(fip->tdp,fip->asnum,src,srcsz,&ovly,&ovlysz) < 0) { + return(TFSERR_MEMFAIL); + } + + /* If the mode is not FILLMODE_FWRITE, then we don't do any of the + * flash operations. We are in this function only to determine + * if we need to copy the active sector to the spare prior to + * starting the modification of the active sector. + */ + if(fip->mode == FILLMODE_FWRITE) { + if(fip->fhdr) { + hp = (char *)&nfhdr; + if(ovlysz) { + memcpy((char *)hp+nhdroffset,(char *)ovly,ovlysz); + if(ovlysz != srcsz) { + memcpy(hp+nhdroffset+ovlysz,(char *)src+ovlysz, + srcsz-ovlysz); + } + } else { + /* next line was <nfhdr = *dhp->ohdr> ... */ + memcpy((char *)&nfhdr,(char *)dhp->ohdr,sizeof(TFILE)); + } + nfhdr.next = dhp->nextfile; + if(defragFwrite(2,(uchar *)*activeaddr,(uchar *)hp+nhdroffset,srcsz) == -1) { + return(TFSERR_FLASHFAILURE); + } + } else { + if(ovlysz) { + if(defragFwrite(3,(uchar *)*activeaddr,(uchar *)ovly,ovlysz) == -1) { + return(TFSERR_FLASHFAILURE); + } + if(ovlysz != srcsz) { + if(defragFwrite(4,(uchar *)*activeaddr+ovlysz,(uchar *)src+ovlysz, + srcsz-ovlysz) == -1) { + return(TFSERR_FLASHFAILURE); + } + } + } else { + if(defragFwrite(5,(uchar *)*activeaddr,(uchar *)src,srcsz) == -1) { + return(TFSERR_FLASHFAILURE); + } + } + } + } else if(fip->mode == FILLMODE_CRCONLY) { + register uchar *bp; + int sz, temp; + + if(fip->fhdr) { + hp = (char *)&nfhdr; + /* next line was <nfhdr = *dhp->ohdr> ... */ + memcpy((char *)&nfhdr,(char *)dhp->ohdr,sizeof(TFILE)); + nfhdr.next = dhp->nextfile; + bp = (uchar *)hp + nhdroffset; + } else { + bp = (uchar *)src; + } + sz = srcsz; + fip->crcsz += sz; + while(sz) { + temp = (fip->crc ^ *bp++) & 0x000000FFL; + fip->crc = ((fip->crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; + sz--; + } + } + *activeaddr += srcsz; + + if((spantype == SPANTYPE_BCEC || spantype == SPANTYPE_BPEC) && + (!fip->fhdr) && ((ulong)*activeaddr & 0xf)) { + int sz, temp, modfixsize; + + modfixsize = (TFS_FSIZEMOD - ((ulong)*activeaddr & (TFS_FSIZEMOD-1))); + *activeaddr += modfixsize; + if(fip->mode == FILLMODE_CRCONLY) { + sz = modfixsize; + fip->crcsz += sz; + while(sz) { + temp = (fip->crc ^ 0xff) & 0x000000FFL; + fip->crc = ((fip->crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; + sz--; + } + } + } + + /* Return ovlysz so that the caller will know if this function + * needed the spare sector. This is used in the "mode = SPARE_OVERLAP" + * pass of defragFillActiveSector(). + */ + return(ovlysz); } /* defragFillActiveSector(): @@ -1178,467 +1183,494 @@ defragFillFlash(struct fillinfo *fip,int spantype,char **activeaddr,int verbose) static int defragFillActiveSector(TDEV *tdp, int ftot, int snum, int verbose) { - int firstsnum; /* number of first TFS sector */ - int activesnum; /* number of sector currently being written to */ - int activessize; /* size of active sector */ - char *activeaddr; /* offset being written to in the active sector */ - uchar *activesbase; /* base address of active sector */ - char *activesend; /* end address of active sector */ - struct defraghdr *sdhp;/* pointer into defrag hdr table in spare */ - struct defraghdr *dhp; /* pointer into defrag header table */ - int fullsize; /* size of file and header */ - char *new_dend; /* new end of data */ - char *new_dbase; /* new base of data */ - char *new_hend; /* new end of header */ - char *new_hbase; /* new base of header */ - char *new_fend; /* new end of file */ - char *new_fbase; /* new base of file */ - int new_fspan; /* span type for new file */ - int new_hspan; /* span type for new header */ - int new_dspan; /* span type for new data */ - int fillstat; /* result of defragFillFlash() function call */ - int noreloctot; /* number of files spanning the active sector */ - /* that do not have to be relocated */ - int tmptot; /* temps used for the "SPARE_OVERLAP" mode */ - char *tmpactiveaddr; - struct defraghdr *tmpdhp; - struct fillinfo finfo; - struct sectorcrc *crctbl; - int lastsnum, tot; - int copytospare; - int lastfileisnotrelocated; - - /* Retrieve number of first TFS sector: */ - if (addrtosector((uchar *)tdp->start,&firstsnum,0,0) < 0) - return(TFSERR_MEMFAIL); - - activesnum = snum + firstsnum; - crctbl = defragCrcTable(tdp); - - /* Retrieve information about active sector: */ - if (sectortoaddr(activesnum,&activessize,&activesbase) == -1) - return(TFSERR_MEMFAIL); - - if (verbose) - printf(" Active sector: %3d @ 0x%lx\n",activesnum,(ulong)activesbase); - - if (addrtosector((uchar *)tdp->end,&lastsnum,0,0) < 0) - return(TFSERR_MEMFAIL); - - /* Establish a pointer to the defrag header table. - * For the case when the active sector is the last sector, the defrag - * header table will be in the spare, so we also establish a pointer - * to that space... - */ - dhp = (struct defraghdr *)crctbl; - dhp -= ftot; - sdhp = (struct defraghdr *)(tdp->spare+activessize - - (tdp->sectorcount * sizeof(struct sectorcrc))); - sdhp -= ftot; - - activeaddr = (char *)activesbase; - tmpactiveaddr = (char *)activesbase; - activesend = (char *)activesbase + activessize - 1; - - /* FIRST LOOP: - * See if we need to do anything... - * In this state, we are simply checking to see if anything is going - * to cause the currently active sector to be written to. - * If yes, then we need to copy it to the spare and start the - * modification process; else, we just return and do nothing - * to this sector. - * For each file in the defrag header table that is destined for - * the address space occupied by the currently active sector, copy - * that file (header and data) to the active sector... - * Note that it may only be a partial copy, depending on the size - * of the file and the amount of space left in the active sector. - */ - - noreloctot = 0; - new_fspan = SPANTYPE_UNDEF; - lastfileisnotrelocated = 0; - for(tot=0;tot<ftot;tot++,dhp++,sdhp++) { - fullsize = TFSHDRSIZ + dhp->filsize; - new_fbase = dhp->nda; - new_fend = (new_fbase + fullsize); - - /* We must figure out how the new version of the file will - * span across the active sector. - * See defragGetSpantype() for details. - */ - new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_fbase,(char *)new_fend); - - /* If the file we are looking at entirely spans a sector that is - * prior to the currently active sector, then we just continue - * through the list. - * If the file entirely spans a sector that is after the - * currently active sector, then we are done with this active sector. - * If the file falls within the active sector in any way, and its - * new location does not match its old location, then we - * break out of this loop and begin the modification of this - * active sector... - */ - if (new_fspan == SPANTYPE_BLEL) - return(0); - - if (new_fspan != SPANTYPE_BPEP) { - if (dhp->nda == (char *)dhp->ohdr) { - noreloctot++; - if (tot == ftot-1) { - lastfileisnotrelocated = 1; - if (verbose > 1) - printf(" last file not relocated\n"); - } - } - else - break; - } - } - - /* If tot == ftot, then we got through the entire loop above without - * finding a file that needs to be relocated into this active sector. - * This means one of two things: either all the files fall into a - * sector prior to this active sector, or the files in this active - * sector do not need to be relocated. In either case, we simply - * return without touching this sector. - * Note that we also keep track of the possibility that the last file - * may not be relocated. If this ends up to be the case, then we are - * simply cleaning up one or more dead files after a full set of active - * files, so we should clean up the sector. - */ - if ((tot == ftot) && (lastfileisnotrelocated == 0)) - return(0); - - /* If tot != ftot, then we must subtract noreloctot from tot so that - * we establish 'tot' as the index into the first file that must be - * copied to the active sector... - */ - if (noreloctot) { - tot -= noreloctot; - dhp -= noreloctot; - sdhp -= noreloctot; - } - - /* Exit immediately before cleaning up the spare... */ - defragExitTestPoint(10000+activesnum); - - /* Since we got here, we know that we have to do some work on the - * currently active sector. We may not have to copy it to the spare, - * but we will erase the spare anyway because the sector erase is - * supposed to be smart enough to avoid the erase if it is already - * erased. This should be handled by the flash driver because in - * ALL cases the erase should be avoided if possible. - */ - if (defragEraseSpare(tdp) < 0) - return(TFSERR_FLASHFAILURE); - - /* Exit immediately after cleaning up the spare... */ - defragExitTestPoint(10001+activesnum); - - /* If the active sector is the last sector (which would contain the - * defrag header table), then we reference the copy of the table that - * is in the spare... - * Also, if this is the last sector, then we HAVE to copy it to - * spare, so we can skip the 2nd loop that attempts to determine - * if we need to do it. - */ - if (activesnum == lastsnum) { - dhp = sdhp; - copytospare = 1; - } - else { - /* SECOND LOOP: - * See if we need to copy the active sector to the spare... - * We do this by continuing the loop we started above. Notice that - * we do an almost identical loop again below this. - * On this pass through the loop we are only checking to see if it is - * necessary to copy this active sector to the spare. - */ - tmptot = tot; - tmpdhp = dhp; - copytospare = 0; - finfo.mode = FILLMODE_SPAREOVERLAP; - for(;tmptot<ftot;tmptot++,tmpdhp++) { - finfo.tdp = tdp; - finfo.dhp = tmpdhp; - finfo.asnum = activesnum; - - fullsize = TFSHDRSIZ + tmpdhp->filsize; - new_fbase = tmpdhp->nda; - new_fend = (new_fbase + fullsize); - - new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_fbase,(char *)new_fend); - - if (new_fspan == SPANTYPE_BPEP) - continue; - else if (new_fspan == SPANTYPE_BLEL) - break; - - /* Now retrieve span information about header and data - * portions of the file (new and orig)... - */ - new_hbase = new_fbase; - new_hend = new_hbase + TFSHDRSIZ; - new_dbase = new_hbase + TFSHDRSIZ; - new_dend = new_fend; - - new_hspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_hbase,(char *)new_hend); - new_dspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_dbase,(char *)new_dend); - - /* If defragFillFlash() returns positive (with mode == - * FILLMODE_SPAREOVERLAP set above), then we know that the - * spare sector must be loaded with a copy of this active - * sector, so we can break out of this loop at that point... - */ - finfo.fhdr = 1; - fillstat = defragFillFlash(&finfo,new_hspan,&tmpactiveaddr,verbose); - if (fillstat < 0) - return(fillstat); - if (fillstat > 0) { - copytospare = 1; - break; - } - if (new_hspan == SPANTYPE_BCEL) - break; - - finfo.fhdr = 0; - fillstat = defragFillFlash(&finfo,new_dspan,&tmpactiveaddr,verbose); - if (fillstat < 0) - return(fillstat); - if (fillstat > 0) { - copytospare = 1; - break; - } - if (new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) - break; - } - } - - finfo.mode = FILLMODE_FWRITE; - - defragExitTestPoint(10002+activesnum); - - if (copytospare) { - defragTick(verbose); + int firstsnum; /* number of first TFS sector */ + int activesnum; /* number of sector currently being written to */ + int activessize; /* size of active sector */ + char *activeaddr; /* offset being written to in the active sector */ + uchar *activesbase; /* base address of active sector */ + char *activesend; /* end address of active sector */ + struct defraghdr *sdhp;/* pointer into defrag hdr table in spare */ + struct defraghdr *dhp; /* pointer into defrag header table */ + int fullsize; /* size of file and header */ + char *new_dend; /* new end of data */ + char *new_dbase; /* new base of data */ + char *new_hend; /* new end of header */ + char *new_hbase; /* new base of header */ + char *new_fend; /* new end of file */ + char *new_fbase; /* new base of file */ + int new_fspan; /* span type for new file */ + int new_hspan; /* span type for new header */ + int new_dspan; /* span type for new data */ + int fillstat; /* result of defragFillFlash() function call */ + int noreloctot; /* number of files spanning the active sector */ + /* that do not have to be relocated */ + int tmptot; /* temps used for the "SPARE_OVERLAP" mode */ + char *tmpactiveaddr; + struct defraghdr *tmpdhp; + struct fillinfo finfo; + struct sectorcrc *crctbl; + int lastsnum, tot; + int copytospare; + int lastfileisnotrelocated; + + /* Retrieve number of first TFS sector: */ + if(addrtosector((uchar *)tdp->start,&firstsnum,0,0) < 0) { + return(TFSERR_MEMFAIL); + } + + activesnum = snum + firstsnum; + crctbl = defragCrcTable(tdp); + + /* Retrieve information about active sector: */ + if(sectortoaddr(activesnum,&activessize,&activesbase) == -1) { + return(TFSERR_MEMFAIL); + } + + if(verbose) { + printf(" Active sector: %3d @ 0x%lx\n",activesnum,(ulong)activesbase); + } + + if(addrtosector((uchar *)tdp->end,&lastsnum,0,0) < 0) { + return(TFSERR_MEMFAIL); + } + + /* Establish a pointer to the defrag header table. + * For the case when the active sector is the last sector, the defrag + * header table will be in the spare, so we also establish a pointer + * to that space... + */ + dhp = (struct defraghdr *)crctbl; + dhp -= ftot; + sdhp = (struct defraghdr *)(tdp->spare+activessize - + (tdp->sectorcount * sizeof(struct sectorcrc))); + sdhp -= ftot; + + activeaddr = (char *)activesbase; + tmpactiveaddr = (char *)activesbase; + activesend = (char *)activesbase + activessize - 1; + + /* FIRST LOOP: + * See if we need to do anything... + * In this state, we are simply checking to see if anything is going + * to cause the currently active sector to be written to. + * If yes, then we need to copy it to the spare and start the + * modification process; else, we just return and do nothing + * to this sector. + * For each file in the defrag header table that is destined for + * the address space occupied by the currently active sector, copy + * that file (header and data) to the active sector... + * Note that it may only be a partial copy, depending on the size + * of the file and the amount of space left in the active sector. + */ + + noreloctot = 0; + new_fspan = SPANTYPE_UNDEF; + lastfileisnotrelocated = 0; + for(tot=0; tot<ftot; tot++,dhp++,sdhp++) { + fullsize = TFSHDRSIZ + dhp->filsize; + new_fbase = dhp->nda; + new_fend = (new_fbase + fullsize); + + /* We must figure out how the new version of the file will + * span across the active sector. + * See defragGetSpantype() for details. + */ + new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_fbase,(char *)new_fend); + + /* If the file we are looking at entirely spans a sector that is + * prior to the currently active sector, then we just continue + * through the list. + * If the file entirely spans a sector that is after the + * currently active sector, then we are done with this active sector. + * If the file falls within the active sector in any way, and its + * new location does not match its old location, then we + * break out of this loop and begin the modification of this + * active sector... + */ + if(new_fspan == SPANTYPE_BLEL) { + return(0); + } + + if(new_fspan != SPANTYPE_BPEP) { + if(dhp->nda == (char *)dhp->ohdr) { + noreloctot++; + if(tot == ftot-1) { + lastfileisnotrelocated = 1; + if(verbose > 1) { + printf(" last file not relocated\n"); + } + } + } else { + break; + } + } + } + + /* If tot == ftot, then we got through the entire loop above without + * finding a file that needs to be relocated into this active sector. + * This means one of two things: either all the files fall into a + * sector prior to this active sector, or the files in this active + * sector do not need to be relocated. In either case, we simply + * return without touching this sector. + * Note that we also keep track of the possibility that the last file + * may not be relocated. If this ends up to be the case, then we are + * simply cleaning up one or more dead files after a full set of active + * files, so we should clean up the sector. + */ + if((tot == ftot) && (lastfileisnotrelocated == 0)) { + return(0); + } + + /* If tot != ftot, then we must subtract noreloctot from tot so that + * we establish 'tot' as the index into the first file that must be + * copied to the active sector... + */ + if(noreloctot) { + tot -= noreloctot; + dhp -= noreloctot; + sdhp -= noreloctot; + } + + /* Exit immediately before cleaning up the spare... */ + defragExitTestPoint(10000+activesnum); + + /* Since we got here, we know that we have to do some work on the + * currently active sector. We may not have to copy it to the spare, + * but we will erase the spare anyway because the sector erase is + * supposed to be smart enough to avoid the erase if it is already + * erased. This should be handled by the flash driver because in + * ALL cases the erase should be avoided if possible. + */ + if(defragEraseSpare(tdp) < 0) { + return(TFSERR_FLASHFAILURE); + } + + /* Exit immediately after cleaning up the spare... */ + defragExitTestPoint(10001+activesnum); + + /* If the active sector is the last sector (which would contain the + * defrag header table), then we reference the copy of the table that + * is in the spare... + * Also, if this is the last sector, then we HAVE to copy it to + * spare, so we can skip the 2nd loop that attempts to determine + * if we need to do it. + */ + if(activesnum == lastsnum) { + dhp = sdhp; + copytospare = 1; + } else { + /* SECOND LOOP: + * See if we need to copy the active sector to the spare... + * We do this by continuing the loop we started above. Notice that + * we do an almost identical loop again below this. + * On this pass through the loop we are only checking to see if it is + * necessary to copy this active sector to the spare. + */ + tmptot = tot; + tmpdhp = dhp; + copytospare = 0; + finfo.mode = FILLMODE_SPAREOVERLAP; + for(; tmptot<ftot; tmptot++,tmpdhp++) { + finfo.tdp = tdp; + finfo.dhp = tmpdhp; + finfo.asnum = activesnum; + + fullsize = TFSHDRSIZ + tmpdhp->filsize; + new_fbase = tmpdhp->nda; + new_fend = (new_fbase + fullsize); + + new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_fbase,(char *)new_fend); + + if(new_fspan == SPANTYPE_BPEP) { + continue; + } else if(new_fspan == SPANTYPE_BLEL) { + break; + } + + /* Now retrieve span information about header and data + * portions of the file (new and orig)... + */ + new_hbase = new_fbase; + new_hend = new_hbase + TFSHDRSIZ; + new_dbase = new_hbase + TFSHDRSIZ; + new_dend = new_fend; + + new_hspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_hbase,(char *)new_hend); + new_dspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_dbase,(char *)new_dend); + + /* If defragFillFlash() returns positive (with mode == + * FILLMODE_SPAREOVERLAP set above), then we know that the + * spare sector must be loaded with a copy of this active + * sector, so we can break out of this loop at that point... + */ + finfo.fhdr = 1; + fillstat = defragFillFlash(&finfo,new_hspan,&tmpactiveaddr,verbose); + if(fillstat < 0) { + return(fillstat); + } + if(fillstat > 0) { + copytospare = 1; + break; + } + if(new_hspan == SPANTYPE_BCEL) { + break; + } + + finfo.fhdr = 0; + fillstat = defragFillFlash(&finfo,new_dspan,&tmpactiveaddr,verbose); + if(fillstat < 0) { + return(fillstat); + } + if(fillstat > 0) { + copytospare = 1; + break; + } + if(new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) { + break; + } + } + } + + finfo.mode = FILLMODE_FWRITE; + + defragExitTestPoint(10002+activesnum); + + if(copytospare) { + defragTick(verbose); #if DEFRAG_TEST_ENABLED - printf(" copying sector %d to spare\n",activesnum); + printf(" copying sector %d to spare\n",activesnum); #endif - if (defragFwrite(6,(uchar *)tdp->spare,activesbase,activessize) == -1) { - printf("Failed to copy active %d to spare\n",activesnum); - return(TFSERR_FLASHFAILURE); - } - } + if(defragFwrite(6,(uchar *)tdp->spare,activesbase,activessize) == -1) { + printf("Failed to copy active %d to spare\n",activesnum); + return(TFSERR_FLASHFAILURE); + } + } #if DEFRAG_TEST_ENABLED - else { - printf(" copy saved\n"); - } + else { + printf(" copy saved\n"); + } #endif - defragTick(verbose); - - /* We can now begin actual modification of the active sector, - * so start off by eraseing it... - */ - defragExitTestPoint(10003+activesnum); - - if (defragSerase(4,activesnum) < 0) - return(TFSERR_FLASHFAILURE); - - defragExitTestPoint(10004+activesnum); - - /* THIRD LOOP: - * Now we pass through the loop to do the real flash modifications... - */ - for(;tot<ftot;tot++,dhp++) { - finfo.tdp = tdp; - finfo.dhp = dhp; - finfo.asnum = activesnum; - - fullsize = TFSHDRSIZ + dhp->filsize; - new_fbase = dhp->nda; - new_fend = (new_fbase + fullsize); - - new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_fbase,(char *)new_fend); - - if (new_fspan == SPANTYPE_BPEP) - continue; - else if (new_fspan == SPANTYPE_BLEL) - break; - - if (verbose) - printf(" File: %s\n",dhp->fname); - - /* Now retrieve span information about header and data - * portions of the file (new and orig)... - */ - new_hbase = new_fbase; - new_hend = new_hbase + TFSHDRSIZ; - new_dbase = new_hbase + TFSHDRSIZ; - new_dend = new_fend; - - new_hspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_hbase,(char *)new_hend); - new_dspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_dbase,(char *)new_dend); - - /* At this point we have all the information we need to copy - * the appropriate amount of the file from orignal space - * to new space. - * We have to break the write up into two parts, the header - * (new_hspan) and the data (new_dspan) so we have to look - * at the spantype for each to determine what part of the - * header and/or data we are going to copy. - * - * Also, we must consider the possibility that the source - * data may be in the spare sector. This would be the case - * if the active sector is the same sector that the original - * data was in. If the source data is in the spare sector, - * then an added complication is the fact that it may not - * all be there, we may have to copy some from the spare, - * then some from the original space. - */ - finfo.fhdr = 1; - fillstat = defragFillFlash(&finfo,new_hspan,&activeaddr,verbose); - if (fillstat < 0) - return(fillstat); - if (new_hspan == SPANTYPE_BCEL) - break; - - finfo.fhdr = 0; - fillstat = defragFillFlash(&finfo,new_dspan,&activeaddr,verbose); - if (fillstat < 0) - return(fillstat); - if (new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) - break; - defragTick(verbose); - } - return(0); + defragTick(verbose); + + /* We can now begin actual modification of the active sector, + * so start off by eraseing it... + */ + defragExitTestPoint(10003+activesnum); + + if(defragSerase(4,activesnum) < 0) { + return(TFSERR_FLASHFAILURE); + } + + defragExitTestPoint(10004+activesnum); + + /* THIRD LOOP: + * Now we pass through the loop to do the real flash modifications... + */ + for(; tot<ftot; tot++,dhp++) { + finfo.tdp = tdp; + finfo.dhp = dhp; + finfo.asnum = activesnum; + + fullsize = TFSHDRSIZ + dhp->filsize; + new_fbase = dhp->nda; + new_fend = (new_fbase + fullsize); + + new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_fbase,(char *)new_fend); + + if(new_fspan == SPANTYPE_BPEP) { + continue; + } else if(new_fspan == SPANTYPE_BLEL) { + break; + } + + if(verbose) { + printf(" File: %s\n",dhp->fname); + } + + /* Now retrieve span information about header and data + * portions of the file (new and orig)... + */ + new_hbase = new_fbase; + new_hend = new_hbase + TFSHDRSIZ; + new_dbase = new_hbase + TFSHDRSIZ; + new_dend = new_fend; + + new_hspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_hbase,(char *)new_hend); + new_dspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_dbase,(char *)new_dend); + + /* At this point we have all the information we need to copy + * the appropriate amount of the file from orignal space + * to new space. + * We have to break the write up into two parts, the header + * (new_hspan) and the data (new_dspan) so we have to look + * at the spantype for each to determine what part of the + * header and/or data we are going to copy. + * + * Also, we must consider the possibility that the source + * data may be in the spare sector. This would be the case + * if the active sector is the same sector that the original + * data was in. If the source data is in the spare sector, + * then an added complication is the fact that it may not + * all be there, we may have to copy some from the spare, + * then some from the original space. + */ + finfo.fhdr = 1; + fillstat = defragFillFlash(&finfo,new_hspan,&activeaddr,verbose); + if(fillstat < 0) { + return(fillstat); + } + if(new_hspan == SPANTYPE_BCEL) { + break; + } + + finfo.fhdr = 0; + fillstat = defragFillFlash(&finfo,new_dspan,&activeaddr,verbose); + if(fillstat < 0) { + return(fillstat); + } + if(new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) { + break; + } + defragTick(verbose); + } + return(0); } static int defragNewSectorCrc(TDEV *tdp, struct defraghdr *dht, int snum, - ulong *newcrc, int verbose) + ulong *newcrc, int verbose) { - int firstsnum; /* number of first TFS sector */ - int activesnum; /* number of sector currently being written to */ - int activessize; /* size of active sector */ - char *activeaddr; /* offset being written to in the active sector */ - uchar *activesbase; /* base address of active sector */ - char *activesend; /* end address of active sector */ - struct defraghdr *dhp; /* pointer into defrag header table */ - int fullsize; /* size of file and header */ - char *new_dend; /* new end of data */ - char *new_dbase; /* new base of data */ - char *new_hend; /* new end of header */ - char *new_hbase; /* new base of header */ - char *new_fend; /* new end of file */ - char *new_fbase; /* new base of file */ - int new_fspan; /* span type for new file */ - int new_hspan; /* span type for new header */ - int new_dspan; /* span type for new data */ - int fillstat; /* result of defragFillFlash() function call */ - int ftot; - struct fillinfo finfo; - struct sectorcrc *crctbl; - int lastsnum, tot, sz, temp; - - /* Retrieve number of first TFS sector: */ - if (addrtosector((uchar *)tdp->start,&firstsnum,0,0) < 0) - return(TFSERR_MEMFAIL); - - activesnum = snum + firstsnum; - crctbl = defragCrcTable(tdp); - - /* Retrieve information about active sector: */ - if (sectortoaddr(activesnum,&activessize,&activesbase) == -1) - return(TFSERR_MEMFAIL); - - if (addrtosector((uchar *)tdp->end,&lastsnum,0,0) < 0) - return(TFSERR_MEMFAIL); - - dhp = (struct defraghdr *)crctbl - 1; - ftot = dhp->idx + 1; - dhp = dht; - activeaddr = (char *)activesbase; - activesend = (char *)activesbase + activessize - 1; - - finfo.tdp = tdp; - finfo.crcsz = 0; - finfo.crc = 0xffffffff; - finfo.asnum = activesnum; - finfo.mode = FILLMODE_CRCONLY; - - for(tot=0;tot<ftot;tot++,dhp++) { - finfo.dhp = dhp; - - fullsize = TFSHDRSIZ + dhp->filsize; - new_fbase = dhp->nda; - new_fend = (new_fbase + fullsize); - - new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_fbase,(char *)new_fend); - - if (new_fspan == SPANTYPE_BPEP) - continue; - else if (new_fspan == SPANTYPE_BLEL) - break; - - /* Now retrieve span information about header and data - * portions of the file (new and orig)... - */ - new_hbase = new_fbase; - new_hend = new_hbase + TFSHDRSIZ; - new_dbase = new_hbase + TFSHDRSIZ; - new_dend = new_fend; - - new_hspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_hbase,(char *)new_hend); - new_dspan = defragGetSpantype((char *)activesbase,(char *)activesend, - (char *)new_dbase,(char *)new_dend); - - finfo.fhdr = 1; - fillstat = defragFillFlash(&finfo,new_hspan,&activeaddr,verbose); - if (fillstat < 0) - return(fillstat); - if (new_hspan == SPANTYPE_BCEL) - break; - - finfo.fhdr = 0; - fillstat = defragFillFlash(&finfo,new_dspan,&activeaddr,verbose); - if (fillstat < 0) - return(fillstat); - if (new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) - break; - } - sz = activessize - finfo.crcsz; - - /* If this is the last sector, then we must not include the space used - * for defrag state storage in the crc calculation. - * We deduct size of CRC table, DHT table and the crc of the DSI space... - */ - if (activesnum == lastsnum) { - sz -= (tdp->sectorcount * sizeof(struct sectorcrc)); - sz -= (ftot * DEFRAGHDRSIZ); - sz -= 4; - } - while(sz) { - temp = (finfo.crc ^ 0xff) & 0x000000FFL; - finfo.crc = ((finfo.crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; - sz--; - } - *newcrc = ~finfo.crc; - return(0); + int firstsnum; /* number of first TFS sector */ + int activesnum; /* number of sector currently being written to */ + int activessize; /* size of active sector */ + char *activeaddr; /* offset being written to in the active sector */ + uchar *activesbase; /* base address of active sector */ + char *activesend; /* end address of active sector */ + struct defraghdr *dhp; /* pointer into defrag header table */ + int fullsize; /* size of file and header */ + char *new_dend; /* new end of data */ + char *new_dbase; /* new base of data */ + char *new_hend; /* new end of header */ + char *new_hbase; /* new base of header */ + char *new_fend; /* new end of file */ + char *new_fbase; /* new base of file */ + int new_fspan; /* span type for new file */ + int new_hspan; /* span type for new header */ + int new_dspan; /* span type for new data */ + int fillstat; /* result of defragFillFlash() function call */ + int ftot; + struct fillinfo finfo; + struct sectorcrc *crctbl; + int lastsnum, tot, sz, temp; + + /* Retrieve number of first TFS sector: */ + if(addrtosector((uchar *)tdp->start,&firstsnum,0,0) < 0) { + return(TFSERR_MEMFAIL); + } + + activesnum = snum + firstsnum; + crctbl = defragCrcTable(tdp); + + /* Retrieve information about active sector: */ + if(sectortoaddr(activesnum,&activessize,&activesbase) == -1) { + return(TFSERR_MEMFAIL); + } + + if(addrtosector((uchar *)tdp->end,&lastsnum,0,0) < 0) { + return(TFSERR_MEMFAIL); + } + + dhp = (struct defraghdr *)crctbl - 1; + ftot = dhp->idx + 1; + dhp = dht; + activeaddr = (char *)activesbase; + activesend = (char *)activesbase + activessize - 1; + + finfo.tdp = tdp; + finfo.crcsz = 0; + finfo.crc = 0xffffffff; + finfo.asnum = activesnum; + finfo.mode = FILLMODE_CRCONLY; + + for(tot=0; tot<ftot; tot++,dhp++) { + finfo.dhp = dhp; + + fullsize = TFSHDRSIZ + dhp->filsize; + new_fbase = dhp->nda; + new_fend = (new_fbase + fullsize); + + new_fspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_fbase,(char *)new_fend); + + if(new_fspan == SPANTYPE_BPEP) { + continue; + } else if(new_fspan == SPANTYPE_BLEL) { + break; + } + + /* Now retrieve span information about header and data + * portions of the file (new and orig)... + */ + new_hbase = new_fbase; + new_hend = new_hbase + TFSHDRSIZ; + new_dbase = new_hbase + TFSHDRSIZ; + new_dend = new_fend; + + new_hspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_hbase,(char *)new_hend); + new_dspan = defragGetSpantype((char *)activesbase,(char *)activesend, + (char *)new_dbase,(char *)new_dend); + + finfo.fhdr = 1; + fillstat = defragFillFlash(&finfo,new_hspan,&activeaddr,verbose); + if(fillstat < 0) { + return(fillstat); + } + if(new_hspan == SPANTYPE_BCEL) { + break; + } + + finfo.fhdr = 0; + fillstat = defragFillFlash(&finfo,new_dspan,&activeaddr,verbose); + if(fillstat < 0) { + return(fillstat); + } + if(new_dspan == SPANTYPE_BCEL || new_dspan == SPANTYPE_BPEL) { + break; + } + } + sz = activessize - finfo.crcsz; + + /* If this is the last sector, then we must not include the space used + * for defrag state storage in the crc calculation. + * We deduct size of CRC table, DHT table and the crc of the DSI space... + */ + if(activesnum == lastsnum) { + sz -= (tdp->sectorcount * sizeof(struct sectorcrc)); + sz -= (ftot * DEFRAGHDRSIZ); + sz -= 4; + } + while(sz) { + temp = (finfo.crc ^ 0xff) & 0x000000FFL; + finfo.crc = ((finfo.crc >> 8) & 0x00FFFFFFL) ^ crc32tab[temp]; + sz--; + } + *newcrc = ~finfo.crc; + return(0); } /* defragBuildCrcTable(): * Build the table of sector crcs. * This consists of a set of CRCs representing each sector - * before defrag starts and after defrag has completed. + * before defrag starts and after defrag has completed. * One set for each sector. This table is then used if the * defrag process is interrupted to determine the state of * the interrupted defragmentation process. @@ -1646,47 +1678,50 @@ defragNewSectorCrc(TDEV *tdp, struct defraghdr *dht, int snum, int defragBuildCrcTable(TDEV *tdp, struct defraghdr *dht, int verbose) { - ulong crc; - uchar *sbase; - int i, ssize, dhstsize; - struct sectorcrc *crctbl; - - dhstsize = (ulong)(tdp->end+1) - (ulong)dht + 4; - crctbl = defragCrcTable(tdp); - - /* The pre-defrag crc table... - * This one's easy because it is simply a crc for each of the current - * sectors. - */ - sbase = (uchar *)tdp->start; - for(i=0;i<tdp->sectorcount;i++) { - if (addrtosector(sbase,0,&ssize,0) < 0) - return(-1); - - if (i == tdp->sectorcount-1) - ssize -= dhstsize; - - /* The pre-defrag crc: */ - crc = crc32(sbase,ssize); - if (defragFwrite(7,(uchar *)&crctbl[i].precrc, - (uchar *)&crc,4) == -1) { - return(-1); - } - - /* The post-defrag crc: */ - if (defragNewSectorCrc(tdp,dht,i,&crc,verbose) < 0) - return(-1); - - if (defragFwrite(8,(uchar *)&crctbl[i].postcrc, - (uchar *)&crc,4) == -1) { - return(-1); - } - - sbase += ssize; - - defragTick(0); - } - return(0); + ulong crc; + uchar *sbase; + int i, ssize, dhstsize; + struct sectorcrc *crctbl; + + dhstsize = (ulong)(tdp->end+1) - (ulong)dht + 4; + crctbl = defragCrcTable(tdp); + + /* The pre-defrag crc table... + * This one's easy because it is simply a crc for each of the current + * sectors. + */ + sbase = (uchar *)tdp->start; + for(i=0; i<tdp->sectorcount; i++) { + if(addrtosector(sbase,0,&ssize,0) < 0) { + return(-1); + } + + if(i == tdp->sectorcount-1) { + ssize -= dhstsize; + } + + /* The pre-defrag crc: */ + crc = crc32(sbase,ssize); + if(defragFwrite(7,(uchar *)&crctbl[i].precrc, + (uchar *)&crc,4) == -1) { + return(-1); + } + + /* The post-defrag crc: */ + if(defragNewSectorCrc(tdp,dht,i,&crc,verbose) < 0) { + return(-1); + } + + if(defragFwrite(8,(uchar *)&crctbl[i].postcrc, + (uchar *)&crc,4) == -1) { + return(-1); + } + + sbase += ssize; + + defragTick(0); + } + return(0); } /* _tfsclean(): @@ -1695,11 +1730,11 @@ defragBuildCrcTable(TDEV *tdp, struct defraghdr *dht, int verbose) * * Build the Defrag State Information (DSI) area: * 1. Create a table of 32-bit CRCs, two for each sector. One is the CRC - * of the sector prior to beginning defragmentation and the other is - * what will be the CRC of the sector after defragmentation has completed. - * These CRCs are used to help recover from an interrupted defragmentation. + * of the sector prior to beginning defragmentation and the other is + * what will be the CRC of the sector after defragmentation has completed. + * These CRCs are used to help recover from an interrupted defragmentation. * 2. Create a table of struct defraghdr structures, one for each file in - * TFS that is currently active (not dead). + * TFS that is currently active (not dead). * 3. Create a CRC of the tables created in steps 1 & 2. * * The data created in steps 1-3 is stored at the end of the last sector @@ -1708,17 +1743,17 @@ defragBuildCrcTable(TDEV *tdp, struct defraghdr *dht, int verbose) * * File relocation: * 4. Step through each sector in TFS flash space, process each file whose - * relocated space overlaps with that sector. As each sector is being - * re-built, the original version of that sector is stored in the spare. + * relocated space overlaps with that sector. As each sector is being + * re-built, the original version of that sector is stored in the spare. * * End of flash cleanup: * 5. Run through the remaining, now unsused, space in TFS flash and make - * sure it is erased. + * sure it is erased. * * File check: * 6. Run a check of all of the relocated files to make sure everything is - * still sane. - * + * still sane. + * * Defragmentation success depends on some coordination with tfsadd()... * Whenever a file is added to TFS, tfsadd() must verify that the space * needed for defrag overhead (defrag state & header tables) will be @@ -1729,467 +1764,486 @@ defragBuildCrcTable(TDEV *tdp, struct defraghdr *dht, int verbose) int _tfsclean(TDEV *tdp, int restart, int verbose) { - int dhstsize; /* Size of state table overhead */ - int firstsnum; /* Number of first sector in TFS device. */ - int lastsnum; /* Number of last sector in TFS device. */ - int lastssize; /* Size of last sector in TFS device. */ - uchar *lastsbase; /* Base address of last sector in TFS device. */ - int sectorcheck; /* Used to verify proper TFS configuration. */ - struct defraghdr *dht; /* Pointer to defrag header table. */ - int chkstat; /* Result of tfscheck() after defrag is done. */ - int ftot; /* Total number of active files in TFS. */ - int dtot; /* Total number of deleted files in TFS. */ - int fcnt; /* Running file total, used in hdrtbl build. */ - TFILE *tfp; /* Misc file pointer */ - char *newaddress; /* Used to calculate "new" location of file. */ - struct defraghdr dfhdr; /* Used to build defrag header table. */ - int activesnum; /* Sector being worked on restarted defrag. */ - struct sectorcrc *crctbl; /* Pointer to table of per-sector crcs. */ - int defrag_state; - int sidx, snum; - char *end; - - if (TfsCleanEnable < 0) - return(TFSERR_CLEANOFF); - - /* If incoming TFS device pointer is NULL, return error - */ - if (!tdp) - return(TFSERR_BADARG); - - activesnum = 0; - - /* If the 'restart' flag is set, then we only want to do a defrag if - * we determine that one is already in progress; so we have to look at - * the current state of the defrag state table to figure out if a defrag - * was active. If not, just return. - */ - if (restart) { - defrag_state = defragGetState(tdp,&activesnum); - switch(defrag_state) { - case SECTOR_DEFRAG_INACTIVE: - case SECTOR_DEFRAG_ABORT_RESTART: - return(TFS_OKAY); - case SCANNING_ACTIVE_SECTOR_1: - case SCANNING_ACTIVE_SECTOR_2: - case SCANNING_ACTIVE_SECTOR_3: - case SCANNING_ACTIVE_SECTOR_4: - case SCANNING_ACTIVE_SECTOR_5: - defrag_state = SCANNING_ACTIVE_SECTOR; - break; - } - } - else { - defrag_state = SECTOR_DEFRAG_INACTIVE; - } - - if (verbose || restart || (!MFLAGS_NODEFRAGPRN())) { - printf("TFS device '%s' powersafe defragmentation\n",tdp->prefix); - if ((restart) && pollConsole("ok?")) { - printf("aborted\n"); - return(TFS_OKAY); - } - } - - if (addrtosector((uchar *)tdp->start,&firstsnum,0,0) < 0) - return(TFSERR_MEMFAIL); - lastsnum = firstsnum + tdp->sectorcount - 1; - if (addrtosector((uchar *)tdp->end,§orcheck,0,0) < 0) - return(TFSERR_MEMFAIL); - if (lastsnum != sectorcheck) { - /* If this error occurs, it is an indication that TFS was not - * properly configured in config.h, this error should not occur - * if TFS is properly configured. - */ - printf("%s: SECTORCOUNT != TFSSTART <-> TFSEND\n", tdp->prefix); - printf("First TFS sector = %d, last = %d\n",firstsnum,sectorcheck); - return(TFSERR_MEMFAIL); - } - - if (defrag_state == SECTOR_DEFRAG_INACTIVE) { - activesnum = firstsnum; - } - - /* Retrieve information about last sector: - */ - if (sectortoaddr(lastsnum,&lastssize,&lastsbase) == -1) - return(TFSERR_MEMFAIL); - - /* Establish a pointer to a table of CRCs that will contain - * one 32-bit CRC for each sector (prior to starting the defrag). - */ - crctbl = defragCrcTable(tdp); - - /* Retrieve the number of "dead" and "living" files: - * If there are no dead files, then there is no need to defrag. - * If there are no "living" files, then we can just init the flash. - */ - ftot = dtot = 0; - if (restart && defragValidDSI(tdp,0)) { - dht = (struct defraghdr *)crctbl - 1; - ftot = dht->idx + 1; - } - else { - tfp = (TFILE *)tdp->start; - while(validtfshdr(tfp)) { - if (TFS_FILEEXISTS(tfp)) - ftot++; - else - dtot++; - tfp = nextfp(tfp,tdp); - } - if (dtot == 0) { - if (verbose) - printf("No dead files in %s.\n",tdp->prefix); - if (tfsflasherased(tdp,verbose)) - return(0); - if (verbose) - printf("Cleaning up end of flash...\n"); - } - } - if (ftot == 0) { - if (verbose) - printf("No active files detected, erasing all %s flash...\n", - tdp->prefix); - _tfsinit(tdp); - return(0); - } - - /* Now that we know how many files are in TFS, we can establish - * a pointer to the defrag header table, and the size of the table... - */ - dht = (struct defraghdr *)crctbl - ftot; - dhstsize = (ulong)(tdp->end+1) - (ulong)dht; - dhstsize += 4; /* Account for the CRC of the state tables. */ - - if (defrag_state == SECTOR_DEFRAG_INACTIVE) { - ulong crc; - - if (verbose) { - printf("TFS defrag: building DSI space...\n"); - } - - /* We start by making sure that the space needed by the - * defrag header and state table at the end of the last - * sector is clear... - */ - if (!flasherased((uchar *)dht, (uchar *)(tdp->end))) { - if (defragEraseSpare(tdp) < 0) - return(TFSERR_FLASHFAILURE); - - if (defragFwrite(9,(uchar *)(tdp->spare),lastsbase, - lastssize-dhstsize) == -1) { - return(TFSERR_FLASHFAILURE); - } - if (defragSerase(5,lastsnum) < 0) { - return(TFSERR_FLASHFAILURE); - } - if (defragFwrite(10,lastsbase,(uchar *)(tdp->spare), - lastssize) == -1) { - return(TFSERR_FLASHFAILURE); - } - } - - /* Erase the spare then copy the portion of the last TFS - * sector that does not overlap with the defrag header and - * state table area to the spare. We do this so that the spare - * sector contains a defrag header and state table area that - * is erased. - */ - if (defragEraseSpare(tdp) < 0) - return(TFSERR_FLASHFAILURE); - - if (defragFwrite(11,(uchar *)tdp->spare, - lastsbase,lastssize-dhstsize) == -1) { - return(TFSERR_FLASHFAILURE); - } - - /* At this point we have a valid copy of the last sector in - * the spare. If any portion of the last sector is not identical - * to what is in the spare, then we need to erase the last sector - * and re-copy what is in the spare to the last sector. This is - * necessary because an interrupt may have occurred while writing - * to the last sector, and it may have corrupted something. - */ - - if ((memcmp((char *)lastsbase,(char *)(tdp->spare),lastssize-dhstsize)) || - (!flasherased((uchar *)dht,(uchar *)tdp->end))) { - if (defragSerase(6,lastsnum) < 0) { - return(TFSERR_FLASHFAILURE); - } - if (defragFwrite(12,lastsbase,(uchar *)(tdp->spare), - lastssize) == -1) { - return(TFSERR_FLASHFAILURE); - } - } - /* Build the header table: - */ - fcnt = 0; - tfp = (TFILE *)tdp->start; - newaddress = (char *)tdp->start; - - if (verbose > 2) { - printf("\nDEFRAG HEADER DATA (dht=0x%lx, ftot=%d):\n", - (ulong)dht,ftot); - } - - while(validtfshdr(tfp)) { - if (TFS_FILEEXISTS(tfp)) { - uchar *base, *eof, *neof, *nbase; - int size, slot; - struct tfsdat *slotptr; - - strcpy(dfhdr.fname,TFS_NAME(tfp)); - dfhdr.ohdr = tfp; - dfhdr.ohdrcrc = tfp->hdrcrc; - dfhdr.filsize = TFS_SIZE(tfp); - if (addrtosector((uchar *)tfp,0,0,&base) < 0) - return(TFSERR_MEMFAIL); - - eof = (uchar *)(tfp+1)+TFS_SIZE(tfp)-1; - if (addrtosector((uchar *)eof,0,0,&base) < 0) - return(TFSERR_MEMFAIL); - dfhdr.oeso = eof - base + 1; - - neof = (uchar *)newaddress+TFSHDRSIZ+TFS_SIZE(tfp)-1; - if (addrtosector((uchar *)neof,&dfhdr.nesn,0,&nbase) < 0) - return(TFSERR_MEMFAIL); - dfhdr.neso = neof - nbase + 1; - - dfhdr.crc = 0; - dfhdr.idx = fcnt; - dfhdr.nda = newaddress; - - /* If the file is currently opened, adjust the base address. */ - slotptr = tfsSlots; - for (slot=0;slot<TFS_MAXOPEN;slot++,slotptr++) { - if (slotptr->offset != -1) { - if (slotptr->base == (uchar *)(TFS_BASE(tfp))) { - slotptr->base = (uchar *)(newaddress+TFSHDRSIZ); - } - } - } - size = TFS_SIZE(tfp) + TFSHDRSIZ; - if (size & 0xf) { - size += TFS_FSIZEMOD; - size &= ~(TFS_FSIZEMOD-1); - } - newaddress += size; - dfhdr.nextfile = (TFILE *)newaddress; - dfhdr.crc = crc32((uchar *)&dfhdr,DEFRAGHDRSIZ); - if (verbose > 2) { - printf(" File %s (sz=%d):\n",TFS_NAME(tfp),TFS_SIZE(tfp)); - printf(" nda= 0x%08lx, ohdr= 0x%08lx, nxt= 0x%08lx\n", - (ulong)(dfhdr.nda),(ulong)(dfhdr.ohdr), - (ulong)(dfhdr.nextfile)); - printf(" oeso= 0x%08lx, nesn= 0x%08lx, neso= 0x%08lx\n", - (ulong)(dfhdr.oeso),(ulong)(dfhdr.nesn), - (ulong)(dfhdr.neso)); - } - if (defragFwrite(13,(uchar *)(&dht[fcnt]), - (uchar *)(&dfhdr),DEFRAGHDRSIZ) == -1) { - return(TFSERR_FLASHFAILURE); - } - fcnt++; - defragTick(0); - } - tfp = nextfp(tfp,tdp); - } - - if (defragBuildCrcTable(tdp,dht,verbose) < 0) - return(TFSERR_FLASHFAILURE); - - /* Now, the last part of the state table build is to store a - * 32-bit crc of the data we just wrote... - */ - crc = crc32((uchar *)dht,(uchar *)tdp->end - (uchar *)dht); - if (defragFwrite(14,(uchar *)((ulong *)dht-1),(uchar *)&crc,4) == -1) { - return(TFSERR_FLASHFAILURE); - } - - defrag_state = SCANNING_ACTIVE_SECTOR; - } - - /* Exit here to have a complete defrag header installed. */ - defragExitTestPoint(1000); - - if (defrag_state == SCANNING_ACTIVE_SECTOR) { - - if (verbose) { - printf("TFS: updating sectors %d-%d...\n", - activesnum,lastsnum); - } - - /* Now we begin the actual defragmentation. We have built enough - * state information (defrag header and state table) into the last - * TFS sector, so now we can start the cleanup. - */ - for(sidx = activesnum - firstsnum; sidx < tdp->sectorcount; sidx++) { - if (defragFillActiveSector(tdp,ftot,sidx,verbose) < 0) - return(TFSERR_FLASHFAILURE); - } - - defrag_state = SECTOR_DEFRAG_ALMOST_DONE; - } - - /* Exit here to test "almost-done" state detection. */ - defragExitTestPoint(1001); - - if (defrag_state == SECTOR_DEFRAG_ALMOST_DONE) { - - /* We've completed the relocation of all files into a defragmented - * area of TFS flash space. Now we have to erase all sectors after - * the sector used by the last file in TFS (including the spare)... - * If the last file in TFS uses the last sector, then the defrag - * header table will be erased and there is nothing left to do - * except erase the spare. - */ - if (verbose) { - printf("TFS: clearing available space...\n"); - } - if (dht[ftot-1].crc != ERASED32) { - end = (dht[ftot-1].nda + dht[ftot-1].filsize + TFSHDRSIZ) - 1; - if (addrtosector((uchar *)end,&snum,0,0) < 0) - return(TFSERR_FLASHFAILURE); - snum++; - while(snum <= lastsnum) { - if (defragSerase(7,snum) < 0) - return(TFSERR_FLASHFAILURE); - snum++; - defragTick(0); - } - } - if (defragEraseSpare(tdp) < 0) - return(TFSERR_FLASHFAILURE); - - /* All defragmentation is done, so verify sanity of files... */ - chkstat = tfscheck(tdp,verbose); - } - else { - chkstat = TFS_OKAY; - } - - if ((verbose) || (!MFLAGS_NODEFRAGPRN())) - printf("Defragmentation complete\n"); - - return(chkstat); + int dhstsize; /* Size of state table overhead */ + int firstsnum; /* Number of first sector in TFS device. */ + int lastsnum; /* Number of last sector in TFS device. */ + int lastssize; /* Size of last sector in TFS device. */ + uchar *lastsbase; /* Base address of last sector in TFS device. */ + int sectorcheck; /* Used to verify proper TFS configuration. */ + struct defraghdr *dht; /* Pointer to defrag header table. */ + int chkstat; /* Result of tfscheck() after defrag is done. */ + int ftot; /* Total number of active files in TFS. */ + int dtot; /* Total number of deleted files in TFS. */ + int fcnt; /* Running file total, used in hdrtbl build. */ + TFILE *tfp; /* Misc file pointer */ + char *newaddress; /* Used to calculate "new" location of file. */ + struct defraghdr dfhdr; /* Used to build defrag header table. */ + int activesnum; /* Sector being worked on restarted defrag. */ + struct sectorcrc *crctbl; /* Pointer to table of per-sector crcs. */ + int defrag_state; + int sidx, snum; + char *end; + + if(TfsCleanEnable < 0) { + return(TFSERR_CLEANOFF); + } + + /* If incoming TFS device pointer is NULL, return error + */ + if(!tdp) { + return(TFSERR_BADARG); + } + + activesnum = 0; + + /* If the 'restart' flag is set, then we only want to do a defrag if + * we determine that one is already in progress; so we have to look at + * the current state of the defrag state table to figure out if a defrag + * was active. If not, just return. + */ + if(restart) { + defrag_state = defragGetState(tdp,&activesnum); + switch(defrag_state) { + case SECTOR_DEFRAG_INACTIVE: + case SECTOR_DEFRAG_ABORT_RESTART: + return(TFS_OKAY); + case SCANNING_ACTIVE_SECTOR_1: + case SCANNING_ACTIVE_SECTOR_2: + case SCANNING_ACTIVE_SECTOR_3: + case SCANNING_ACTIVE_SECTOR_4: + case SCANNING_ACTIVE_SECTOR_5: + defrag_state = SCANNING_ACTIVE_SECTOR; + break; + } + } else { + defrag_state = SECTOR_DEFRAG_INACTIVE; + } + + if(verbose || restart || (!MFLAGS_NODEFRAGPRN())) { + printf("TFS device '%s' powersafe defragmentation\n",tdp->prefix); + if((restart) && pollConsole("ok?")) { + printf("aborted\n"); + return(TFS_OKAY); + } + } + + if(addrtosector((uchar *)tdp->start,&firstsnum,0,0) < 0) { + return(TFSERR_MEMFAIL); + } + lastsnum = firstsnum + tdp->sectorcount - 1; + if(addrtosector((uchar *)tdp->end,§orcheck,0,0) < 0) { + return(TFSERR_MEMFAIL); + } + if(lastsnum != sectorcheck) { + /* If this error occurs, it is an indication that TFS was not + * properly configured in config.h, this error should not occur + * if TFS is properly configured. + */ + printf("%s: SECTORCOUNT != TFSSTART <-> TFSEND\n", tdp->prefix); + printf("First TFS sector = %d, last = %d\n",firstsnum,sectorcheck); + return(TFSERR_MEMFAIL); + } + + if(defrag_state == SECTOR_DEFRAG_INACTIVE) { + activesnum = firstsnum; + } + + /* Retrieve information about last sector: + */ + if(sectortoaddr(lastsnum,&lastssize,&lastsbase) == -1) { + return(TFSERR_MEMFAIL); + } + + /* Establish a pointer to a table of CRCs that will contain + * one 32-bit CRC for each sector (prior to starting the defrag). + */ + crctbl = defragCrcTable(tdp); + + /* Retrieve the number of "dead" and "living" files: + * If there are no dead files, then there is no need to defrag. + * If there are no "living" files, then we can just init the flash. + */ + ftot = dtot = 0; + if(restart && defragValidDSI(tdp,0)) { + dht = (struct defraghdr *)crctbl - 1; + ftot = dht->idx + 1; + } else { + tfp = (TFILE *)tdp->start; + while(validtfshdr(tfp)) { + if(TFS_FILEEXISTS(tfp)) { + ftot++; + } else { + dtot++; + } + tfp = nextfp(tfp,tdp); + } + if(dtot == 0) { + if(verbose) { + printf("No dead files in %s.\n",tdp->prefix); + } + if(tfsflasherased(tdp,verbose)) { + return(0); + } + if(verbose) { + printf("Cleaning up end of flash...\n"); + } + } + } + if(ftot == 0) { + if(verbose) + printf("No active files detected, erasing all %s flash...\n", + tdp->prefix); + _tfsinit(tdp); + return(0); + } + + /* Now that we know how many files are in TFS, we can establish + * a pointer to the defrag header table, and the size of the table... + */ + dht = (struct defraghdr *)crctbl - ftot; + dhstsize = (ulong)(tdp->end+1) - (ulong)dht; + dhstsize += 4; /* Account for the CRC of the state tables. */ + + if(defrag_state == SECTOR_DEFRAG_INACTIVE) { + ulong crc; + + if(verbose) { + printf("TFS defrag: building DSI space...\n"); + } + + /* We start by making sure that the space needed by the + * defrag header and state table at the end of the last + * sector is clear... + */ + if(!flasherased((uchar *)dht, (uchar *)(tdp->end))) { + if(defragEraseSpare(tdp) < 0) { + return(TFSERR_FLASHFAILURE); + } + + if(defragFwrite(9,(uchar *)(tdp->spare),lastsbase, + lastssize-dhstsize) == -1) { + return(TFSERR_FLASHFAILURE); + } + if(defragSerase(5,lastsnum) < 0) { + return(TFSERR_FLASHFAILURE); + } + if(defragFwrite(10,lastsbase,(uchar *)(tdp->spare), + lastssize) == -1) { + return(TFSERR_FLASHFAILURE); + } + } + + /* Erase the spare then copy the portion of the last TFS + * sector that does not overlap with the defrag header and + * state table area to the spare. We do this so that the spare + * sector contains a defrag header and state table area that + * is erased. + */ + if(defragEraseSpare(tdp) < 0) { + return(TFSERR_FLASHFAILURE); + } + + if(defragFwrite(11,(uchar *)tdp->spare, + lastsbase,lastssize-dhstsize) == -1) { + return(TFSERR_FLASHFAILURE); + } + + /* At this point we have a valid copy of the last sector in + * the spare. If any portion of the last sector is not identical + * to what is in the spare, then we need to erase the last sector + * and re-copy what is in the spare to the last sector. This is + * necessary because an interrupt may have occurred while writing + * to the last sector, and it may have corrupted something. + */ + + if((memcmp((char *)lastsbase,(char *)(tdp->spare),lastssize-dhstsize)) || + (!flasherased((uchar *)dht,(uchar *)tdp->end))) { + if(defragSerase(6,lastsnum) < 0) { + return(TFSERR_FLASHFAILURE); + } + if(defragFwrite(12,lastsbase,(uchar *)(tdp->spare), + lastssize) == -1) { + return(TFSERR_FLASHFAILURE); + } + } + /* Build the header table: + */ + fcnt = 0; + tfp = (TFILE *)tdp->start; + newaddress = (char *)tdp->start; + + if(verbose > 2) { + printf("\nDEFRAG HEADER DATA (dht=0x%lx, ftot=%d):\n", + (ulong)dht,ftot); + } + + while(validtfshdr(tfp)) { + if(TFS_FILEEXISTS(tfp)) { + uchar *base, *eof, *neof, *nbase; + int size, slot; + struct tfsdat *slotptr; + + strcpy(dfhdr.fname,TFS_NAME(tfp)); + dfhdr.ohdr = tfp; + dfhdr.ohdrcrc = tfp->hdrcrc; + dfhdr.filsize = TFS_SIZE(tfp); + if(addrtosector((uchar *)tfp,0,0,&base) < 0) { + return(TFSERR_MEMFAIL); + } + + eof = (uchar *)(tfp+1)+TFS_SIZE(tfp)-1; + if(addrtosector((uchar *)eof,0,0,&base) < 0) { + return(TFSERR_MEMFAIL); + } + dfhdr.oeso = eof - base + 1; + + neof = (uchar *)newaddress+TFSHDRSIZ+TFS_SIZE(tfp)-1; + if(addrtosector((uchar *)neof,&dfhdr.nesn,0,&nbase) < 0) { + return(TFSERR_MEMFAIL); + } + dfhdr.neso = neof - nbase + 1; + + dfhdr.crc = 0; + dfhdr.idx = fcnt; + dfhdr.nda = newaddress; + + /* If the file is currently opened, adjust the base address. */ + slotptr = tfsSlots; + for(slot=0; slot<TFS_MAXOPEN; slot++,slotptr++) { + if(slotptr->offset != -1) { + if(slotptr->base == (uchar *)(TFS_BASE(tfp))) { + slotptr->base = (uchar *)(newaddress+TFSHDRSIZ); + } + } + } + size = TFS_SIZE(tfp) + TFSHDRSIZ; + if(size & 0xf) { + size += TFS_FSIZEMOD; + size &= ~(TFS_FSIZEMOD-1); + } + newaddress += size; + dfhdr.nextfile = (TFILE *)newaddress; + dfhdr.crc = crc32((uchar *)&dfhdr,DEFRAGHDRSIZ); + if(verbose > 2) { + printf(" File %s (sz=%d):\n",TFS_NAME(tfp),TFS_SIZE(tfp)); + printf(" nda= 0x%08lx, ohdr= 0x%08lx, nxt= 0x%08lx\n", + (ulong)(dfhdr.nda),(ulong)(dfhdr.ohdr), + (ulong)(dfhdr.nextfile)); + printf(" oeso= 0x%08lx, nesn= 0x%08lx, neso= 0x%08lx\n", + (ulong)(dfhdr.oeso),(ulong)(dfhdr.nesn), + (ulong)(dfhdr.neso)); + } + if(defragFwrite(13,(uchar *)(&dht[fcnt]), + (uchar *)(&dfhdr),DEFRAGHDRSIZ) == -1) { + return(TFSERR_FLASHFAILURE); + } + fcnt++; + defragTick(0); + } + tfp = nextfp(tfp,tdp); + } + + if(defragBuildCrcTable(tdp,dht,verbose) < 0) { + return(TFSERR_FLASHFAILURE); + } + + /* Now, the last part of the state table build is to store a + * 32-bit crc of the data we just wrote... + */ + crc = crc32((uchar *)dht,(uchar *)tdp->end - (uchar *)dht); + if(defragFwrite(14,(uchar *)((ulong *)dht-1),(uchar *)&crc,4) == -1) { + return(TFSERR_FLASHFAILURE); + } + + defrag_state = SCANNING_ACTIVE_SECTOR; + } + + /* Exit here to have a complete defrag header installed. */ + defragExitTestPoint(1000); + + if(defrag_state == SCANNING_ACTIVE_SECTOR) { + + if(verbose) { + printf("TFS: updating sectors %d-%d...\n", + activesnum,lastsnum); + } + + /* Now we begin the actual defragmentation. We have built enough + * state information (defrag header and state table) into the last + * TFS sector, so now we can start the cleanup. + */ + for(sidx = activesnum - firstsnum; sidx < tdp->sectorcount; sidx++) { + if(defragFillActiveSector(tdp,ftot,sidx,verbose) < 0) { + return(TFSERR_FLASHFAILURE); + } + } + + defrag_state = SECTOR_DEFRAG_ALMOST_DONE; + } + + /* Exit here to test "almost-done" state detection. */ + defragExitTestPoint(1001); + + if(defrag_state == SECTOR_DEFRAG_ALMOST_DONE) { + + /* We've completed the relocation of all files into a defragmented + * area of TFS flash space. Now we have to erase all sectors after + * the sector used by the last file in TFS (including the spare)... + * If the last file in TFS uses the last sector, then the defrag + * header table will be erased and there is nothing left to do + * except erase the spare. + */ + if(verbose) { + printf("TFS: clearing available space...\n"); + } + if(dht[ftot-1].crc != ERASED32) { + end = (dht[ftot-1].nda + dht[ftot-1].filsize + TFSHDRSIZ) - 1; + if(addrtosector((uchar *)end,&snum,0,0) < 0) { + return(TFSERR_FLASHFAILURE); + } + snum++; + while(snum <= lastsnum) { + if(defragSerase(7,snum) < 0) { + return(TFSERR_FLASHFAILURE); + } + snum++; + defragTick(0); + } + } + if(defragEraseSpare(tdp) < 0) { + return(TFSERR_FLASHFAILURE); + } + + /* All defragmentation is done, so verify sanity of files... */ + chkstat = tfscheck(tdp,verbose); + } else { + chkstat = TFS_OKAY; + } + + if((verbose) || (!MFLAGS_NODEFRAGPRN())) { + printf("Defragmentation complete\n"); + } + + return(chkstat); } /* tfsfixup(): - * Called at system startup to finish up a TFS defragmentation if one - * was in progress. + * Called at system startup to finish up a TFS defragmentation if one + * was in progress. */ int tfsfixup(int verbose, int dontquery) { - TDEV *tdp; + TDEV *tdp; - /* Clear test data... */ - DefragTestType = 0; - DefragTestPoint = 0; - DefragTestSector = 0; + /* Clear test data... */ + DefragTestType = 0; + DefragTestPoint = 0; + DefragTestSector = 0; #if !DEFRAG_TEST_ENABLED - tfsTrace = 99; + tfsTrace = 99; #endif - /* For each TFS device, run defrag with "fixup" flag set to let - * the defragger know that it should only defrag if a defrag was - * in progress. - */ - for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) { - /* Call tfsclean() with fixup flag set... */ + /* For each TFS device, run defrag with "fixup" flag set to let + * the defragger know that it should only defrag if a defrag was + * in progress. + */ + for(tdp=tfsDeviceTbl; tdp->start != TFSEOT; tdp++) { + /* Call tfsclean() with fixup flag set... */ #if TFS_VERBOSE_STARTUP - if (StateOfMonitor == INITIALIZE) - printf("TFS Scanning %s...\n",tdp->prefix); + if(StateOfMonitor == INITIALIZE) { + printf("TFS Scanning %s...\n",tdp->prefix); + } #endif - _tfsclean(tdp,1,99); - } + _tfsclean(tdp,1,99); + } #if !DEFRAG_TEST_ENABLED - tfsTrace = 0; + tfsTrace = 0; #endif - return(0); + return(0); } #if DEFRAG_TEST_ENABLED int dumpDhdr(DEFRAGHDR *dhp) { - printf("ohdr: 0x%08lx\n",(ulong)dhp->ohdr); - printf("nextfile: 0x%08lx\n",(ulong)dhp->nextfile); - printf("filsize: 0x%08lx\n",(ulong)dhp->filsize); - printf("crc: 0x%08lx\n",(ulong)dhp->crc); - printf("idx: 0x%08lx\n",(ulong)dhp->idx); - printf("nesn: 0x%08lx\n",(ulong)dhp->nesn); - printf("neso: 0x%08lx\n",(ulong)dhp->neso); - printf("nda: 0x%08lx\n",(ulong)dhp->nda); - printf("fname: %s\n",dhp->fname); - return(TFS_OKAY); + printf("ohdr: 0x%08lx\n",(ulong)dhp->ohdr); + printf("nextfile: 0x%08lx\n",(ulong)dhp->nextfile); + printf("filsize: 0x%08lx\n",(ulong)dhp->filsize); + printf("crc: 0x%08lx\n",(ulong)dhp->crc); + printf("idx: 0x%08lx\n",(ulong)dhp->idx); + printf("nesn: 0x%08lx\n",(ulong)dhp->nesn); + printf("neso: 0x%08lx\n",(ulong)dhp->neso); + printf("nda: 0x%08lx\n",(ulong)dhp->nda); + printf("fname: %s\n",dhp->fname); + return(TFS_OKAY); } int dumpDhdrTbl(DEFRAGHDR *dhp, int ftot) { - TDEV *tdp; - uchar *sbase; - ulong *crc, calccrc; - int i, ssize, snum; - struct sectorcrc *crctbl; - - for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) { - - if (!dhp) { - crctbl = defragCrcTable(tdp); - printf("Device %s...\n",tdp->prefix); - dhp = (struct defraghdr *)crctbl - 1; - ftot = dhp->idx + 1; - printf("(%d files):\n",ftot); - dhp = (struct defraghdr *)crctbl - ftot; - crc = (ulong *)dhp-1; - if (*crc != crc32((uchar *)dhp,(uchar *)tdp->end - (uchar *)dhp)) { - printf("Table CRC failure\n"); - return(TFS_OKAY); - } - } - else - crctbl = (struct sectorcrc *)(dhp + ftot); - - printf("dhp=0x%lx, ftot=%d\n",(ulong)dhp,ftot); - - while(dhp < (struct defraghdr *)crctbl) { - printf(" %s (dhp=0x%lx, idx=%ld):\n", - dhp->fname,(ulong)dhp,dhp->idx); - printf(" nda: 0x%08lx, ohdr: 0x%08lx\n", - (ulong)dhp->nda,(ulong)dhp->ohdr); - dhp++; - } - - sbase = (uchar *)tdp->start; - printf("crctbl at 0x%lx\n",(ulong)crctbl); - for(i=0;i<tdp->sectorcount;i++) { - if (addrtosector(sbase,&snum,&ssize,0) < 0) - return(0); - if (i == tdp->sectorcount-1) { - ssize -= /* CRC table */ - (tdp->sectorcount * sizeof(struct sectorcrc)); - ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */ - ssize -= 4; /* Crc of the tables */ - } - calccrc = crc32(sbase,ssize); - if (calccrc == crctbl[i].precrc) - printf("crctbl[%d] (snum=%d) pre-pass\n",i,snum); - else if (calccrc == crctbl[i].postcrc) - printf("crctbl[%d] (snum=%d) post-pass\n",i,snum); - else { - printf("crctbl[%d] (snum=%d) test failed\n",i,snum); - printf("pre: 0x%lx, post: 0x%lx,calc: 0x%lx\n", - crctbl[i].precrc,crctbl[i].postcrc,calccrc); - } - sbase += ssize; - } - } - return(TFS_OKAY); + TDEV *tdp; + uchar *sbase; + ulong *crc, calccrc; + int i, ssize, snum; + struct sectorcrc *crctbl; + + for(tdp=tfsDeviceTbl; tdp->start != TFSEOT; tdp++) { + + if(!dhp) { + crctbl = defragCrcTable(tdp); + printf("Device %s...\n",tdp->prefix); + dhp = (struct defraghdr *)crctbl - 1; + ftot = dhp->idx + 1; + printf("(%d files):\n",ftot); + dhp = (struct defraghdr *)crctbl - ftot; + crc = (ulong *)dhp-1; + if(*crc != crc32((uchar *)dhp,(uchar *)tdp->end - (uchar *)dhp)) { + printf("Table CRC failure\n"); + return(TFS_OKAY); + } + } else { + crctbl = (struct sectorcrc *)(dhp + ftot); + } + + printf("dhp=0x%lx, ftot=%d\n",(ulong)dhp,ftot); + + while(dhp < (struct defraghdr *)crctbl) { + printf(" %s (dhp=0x%lx, idx=%ld):\n", + dhp->fname,(ulong)dhp,dhp->idx); + printf(" nda: 0x%08lx, ohdr: 0x%08lx\n", + (ulong)dhp->nda,(ulong)dhp->ohdr); + dhp++; + } + + sbase = (uchar *)tdp->start; + printf("crctbl at 0x%lx\n",(ulong)crctbl); + for(i=0; i<tdp->sectorcount; i++) { + if(addrtosector(sbase,&snum,&ssize,0) < 0) { + return(0); + } + if(i == tdp->sectorcount-1) { + ssize -= /* CRC table */ + (tdp->sectorcount * sizeof(struct sectorcrc)); + ssize -= (ftot * DEFRAGHDRSIZ); /* DHT table */ + ssize -= 4; /* Crc of the tables */ + } + calccrc = crc32(sbase,ssize); + if(calccrc == crctbl[i].precrc) { + printf("crctbl[%d] (snum=%d) pre-pass\n",i,snum); + } else if(calccrc == crctbl[i].postcrc) { + printf("crctbl[%d] (snum=%d) post-pass\n",i,snum); + } else { + printf("crctbl[%d] (snum=%d) test failed\n",i,snum); + printf("pre: 0x%lx, post: 0x%lx,calc: 0x%lx\n", + crctbl[i].precrc,crctbl[i].postcrc,calccrc); + } + sbase += ssize; + } + } + return(TFS_OKAY); } -#endif /* DEFRAG_TEST_ENABLED */ -#endif /* INCLUDE_TFS */ +#endif /* DEFRAG_TEST_ENABLED */ +#endif /* INCLUDE_TFS */ |