summaryrefslogtreecommitdiffstats
path: root/main/common/tfsclean1.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/common/tfsclean1.c')
-rw-r--r--main/common/tfsclean1.c3564
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,&sectorcheck,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,&sectorcheck,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 */