summaryrefslogtreecommitdiffstats
path: root/main/common/nand.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/common/nand.c')
-rw-r--r--main/common/nand.c559
1 files changed, 287 insertions, 272 deletions
diff --git a/main/common/nand.c b/main/common/nand.c
index 45e7483..d23564b 100644
--- a/main/common/nand.c
+++ b/main/common/nand.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
@@ -44,307 +44,322 @@ int nandVerbose;
#endif
char *nandHelp[] = {
- "Interface with Nand-Flash",
- "-[v] {cmd} [cmd-specific args]",
+ "Interface with Nand-Flash",
+ "-[v] {cmd} [cmd-specific args]",
#if INCLUDE_VERBOSEHELP
- "Options:",
- " -v incrementing verbosity level",
- "",
- "Cmds:",
- " init initialize interface",
- " info show device info",
+ "Options:",
+ " -v incrementing verbosity level",
+ "",
+ "Cmds:",
+ " init initialize interface",
+ " info show device info",
#ifdef FLASHRAM_BASE
- " tfsls list files directly out of SPI flash",
- " tfsload copy NAND to TFSRAM",
- " tfsstat show state of SPI flash",
- " tfsstore copy TFSRAM to NAND",
- " tfserase erase NAND space allocated to TFS",
- " tfsrm {name} remove file directly out of NAND flash",
- " tfsadd {name} [src sz] add file directly to NAND flash",
+ " tfsls list files directly out of SPI flash",
+ " tfsload copy NAND to TFSRAM",
+ " tfsstat show state of SPI flash",
+ " tfsstore copy TFSRAM to NAND",
+ " tfserase erase NAND space allocated to TFS",
+ " tfsrm {name} remove file directly out of NAND flash",
+ " tfsadd {name} [src sz] add file directly to NAND flash",
#endif
- " erase {addr len} erase block",
- " read {addr dest len} read block",
- " write {addr src len} write block",
+ " erase {addr len} erase block",
+ " read {addr dest len} read block",
+ " write {addr src len} write block",
#endif
- 0,
+ 0,
};
int
nandCmd(int argc,char *argv[])
{
- unsigned long addr;
- char *cmd, *dest, *src;
- int opt, len, rc;
+ unsigned long addr;
+ char *cmd, *dest, *src;
+ int opt, len, rc;
+
+ rc = 0;
+ nandVerbose = 0;
+ while((opt=getopt(argc,argv,"v")) != -1) {
+ switch(opt) {
+ case 'v':
+ nandVerbose++;
+ break;
+ default:
+ return(CMD_PARAM_ERROR);
+ }
+ }
- rc = 0;
- nandVerbose = 0;
- while((opt=getopt(argc,argv,"v")) != -1) {
- switch(opt) {
- case 'v':
- nandVerbose++;
- break;
- default:
- return(CMD_PARAM_ERROR);
- }
- }
-
- if (argc < optind+1)
- return(CMD_PARAM_ERROR);
+ if(argc < optind+1) {
+ return(CMD_PARAM_ERROR);
+ }
- cmd = argv[optind];
+ cmd = argv[optind];
- if (nandVerbose)
- printf("CMD: %s\n",cmd);
+ if(nandVerbose) {
+ printf("CMD: %s\n",cmd);
+ }
- if (strcmp(cmd,"init") == 0) {
- nandInit();
- }
- else if (strcmp(cmd,"info") == 0) {
- nandInfo();
- }
- else if (strcmp(cmd,"erase") == 0) {
- if (argc != optind+3)
- return(CMD_PARAM_ERROR);
- addr = strtoul(argv[optind+1],0,0);
- len = (int)strtol(argv[optind+2],0,0);
- nandEraseChunk((char *)addr,len);
- }
- else if (strcmp(cmd,"write") == 0) {
- if (argc != optind+4)
- return(CMD_PARAM_ERROR);
- addr = strtoul(argv[optind+1],0,0);
- src = (char *)strtoul(argv[optind+2],0,0);
- len = (int)strtol(argv[optind+3],0,0);
- nandWriteChunk((char *)addr,src,len);
- }
- else if (strcmp(cmd,"read") == 0) {
- if (argc != optind+4)
- return(CMD_PARAM_ERROR);
- addr = strtoul(argv[optind+1],0,0);
- dest = (char *)strtoul(argv[optind+2],0,0);
- len = (int)strtol(argv[optind+3],0,0);
- nandReadChunk((char *)addr,dest,len);
- }
+ if(strcmp(cmd,"init") == 0) {
+ nandInit();
+ } else if(strcmp(cmd,"info") == 0) {
+ nandInfo();
+ } else if(strcmp(cmd,"erase") == 0) {
+ if(argc != optind+3) {
+ return(CMD_PARAM_ERROR);
+ }
+ addr = strtoul(argv[optind+1],0,0);
+ len = (int)strtol(argv[optind+2],0,0);
+ nandEraseChunk((char *)addr,len);
+ } else if(strcmp(cmd,"write") == 0) {
+ if(argc != optind+4) {
+ return(CMD_PARAM_ERROR);
+ }
+ addr = strtoul(argv[optind+1],0,0);
+ src = (char *)strtoul(argv[optind+2],0,0);
+ len = (int)strtol(argv[optind+3],0,0);
+ nandWriteChunk((char *)addr,src,len);
+ } else if(strcmp(cmd,"read") == 0) {
+ if(argc != optind+4) {
+ return(CMD_PARAM_ERROR);
+ }
+ addr = strtoul(argv[optind+1],0,0);
+ dest = (char *)strtoul(argv[optind+2],0,0);
+ len = (int)strtol(argv[optind+3],0,0);
+ nandReadChunk((char *)addr,dest,len);
+ }
#ifdef FLASHRAM_BASE
- else if (strcmp(cmd,"tfsload") == 0) {
- }
- else if (strcmp(cmd,"tfsstore") == 0) {
- }
- else if (strcmp(cmd,"tfserase") == 0) {
- }
- else if (strcmp(cmd, "tfsls") == 0) {
- int ftot;
- char *addr;
- TFILE tfshdr, *fp;
+ else if(strcmp(cmd,"tfsload") == 0) {
+ } else if(strcmp(cmd,"tfsstore") == 0) {
+ } else if(strcmp(cmd,"tfserase") == 0) {
+ } else if(strcmp(cmd, "tfsls") == 0) {
+ int ftot;
+ char *addr;
+ TFILE tfshdr, *fp;
- ftot = 0;
- fp = &tfshdr;
- addr = (char *)BASE_OF_NAND;
- while(addr < (char *)END_OF_NAND) {
- char fbuf[32], *flags;
+ ftot = 0;
+ fp = &tfshdr;
+ addr = (char *)BASE_OF_NAND;
+ while(addr < (char *)END_OF_NAND) {
+ char fbuf[32], *flags;
- if ((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
- printf("nandReadChunk failed %d\n",rc);
- break;
- }
- if (fp->hdrsize == 0xffff)
- break;
- if (TFS_FILEEXISTS(fp)) {
- if (ftot == 0)
- printf(" Name Size Offset Flags Info\n");
- ftot++;
- flags = tfsflagsbtoa(TFS_FLAGS(fp),fbuf);
- if ((!flags) || (!fbuf[0]))
- flags = " ";
- printf(" %-23s %7ld 0x%08lx %-5s %s\n",TFS_NAME(fp),
- TFS_SIZE(fp),(unsigned long)(addr+TFSHDRSIZ),
- flags,TFS_INFO(fp));
- }
- addr += TFS_SIZE(fp);
- addr += TFSHDRSIZ;
- while((long)addr & 0xf) addr++;
- }
- }
- else if (strcmp(cmd, "tfsrm") == 0) {
- char *addr;
- TFILE tfshdr, *fp;
- char *arg2 = argv[optind+1];
+ if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ printf("nandReadChunk failed %d\n",rc);
+ break;
+ }
+ if(fp->hdrsize == 0xffff) {
+ break;
+ }
+ if(TFS_FILEEXISTS(fp)) {
+ if(ftot == 0) {
+ printf(" Name Size Offset Flags Info\n");
+ }
+ ftot++;
+ flags = tfsflagsbtoa(TFS_FLAGS(fp),fbuf);
+ if((!flags) || (!fbuf[0])) {
+ flags = " ";
+ }
+ printf(" %-23s %7ld 0x%08lx %-5s %s\n",TFS_NAME(fp),
+ TFS_SIZE(fp),(unsigned long)(addr+TFSHDRSIZ),
+ flags,TFS_INFO(fp));
+ }
+ addr += TFS_SIZE(fp);
+ addr += TFSHDRSIZ;
+ while((long)addr & 0xf) {
+ addr++;
+ }
+ }
+ } else if(strcmp(cmd, "tfsrm") == 0) {
+ char *addr;
+ TFILE tfshdr, *fp;
+ char *arg2 = argv[optind+1];
- fp = &tfshdr;
- addr = (char *)BASE_OF_NAND;
- while(addr < (char *)END_OF_NAND) {
- if ((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
- printf("nandReadChunk failed %d\n",rc);
- break;
- }
- if (fp->hdrsize == 0xffff) {
- printf("%s not found\n",arg2);
- break;
- }
- if (strcmp(TFS_NAME(fp),arg2) == 0) {
- if (TFS_FILEEXISTS(fp)) {
- fp->flags &= ~TFS_ACTIVE;
- if ((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0)
- printf(" write_hdr failed %d\n",rc);
- break;
- }
- }
- addr += TFS_SIZE(fp);
- addr += TFSHDRSIZ;
- while((long)addr & 0xf) addr++;
- }
- }
- else if (strcmp(cmd, "tfsadd") == 0) {
- int size;
- long bflags;
- TFILE tfshdr, *fp;
- char *addr;
- char *src, *name, *info;
- char *arg2 = argv[optind+1];
- char *arg3 = argv[optind+2];
- char *arg4 = argv[optind+3];
- char *icomma, *fcomma;
+ fp = &tfshdr;
+ addr = (char *)BASE_OF_NAND;
+ while(addr < (char *)END_OF_NAND) {
+ if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ printf("nandReadChunk failed %d\n",rc);
+ break;
+ }
+ if(fp->hdrsize == 0xffff) {
+ printf("%s not found\n",arg2);
+ break;
+ }
+ if(strcmp(TFS_NAME(fp),arg2) == 0) {
+ if(TFS_FILEEXISTS(fp)) {
+ fp->flags &= ~TFS_ACTIVE;
+ if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ printf(" write_hdr failed %d\n",rc);
+ }
+ break;
+ }
+ }
+ addr += TFS_SIZE(fp);
+ addr += TFSHDRSIZ;
+ while((long)addr & 0xf) {
+ addr++;
+ }
+ }
+ } else if(strcmp(cmd, "tfsadd") == 0) {
+ int size;
+ long bflags;
+ TFILE tfshdr, *fp;
+ char *addr;
+ char *src, *name, *info;
+ char *arg2 = argv[optind+1];
+ char *arg3 = argv[optind+2];
+ char *arg4 = argv[optind+3];
+ char *icomma, *fcomma;
- info = "";
- bflags = 0;
- name = arg2;
- addr = (char *)BASE_OF_NAND;
+ info = "";
+ bflags = 0;
+ name = arg2;
+ addr = (char *)BASE_OF_NAND;
- /* The incoming arguments can be either just the filename (in which
- * case we assume the source is the file in TFS with the same name),
- * or the filename, source address and size...
- */
- if (argc == optind+2) { // Just filename?
- if ((fp = tfsstat(name)) == (TFILE *)0) {
- printf("File '%s' not in TFS\n",name);
- return(CMD_FAILURE);
- }
- name = fp->name;
- info = fp->info;
- bflags = fp->flags;
- size = fp->filsize;
- src = (char *)(fp + 1);
- fp = &tfshdr;
- memset((char *)fp,0,TFSHDRSIZ);
- }
- else if (argc == optind+4) { // Filename with addr and len
- // Extract flags and info fields (if any) from the name...
- fcomma = strchr(name,',');
- if (fcomma) {
- icomma = strchr(fcomma+1,',');
- if (icomma) {
- *icomma = 0;
- info = icomma+1;
- }
- *fcomma = 0;
- bflags = tfsctrl(TFS_FATOB,(long)(fcomma+1),0);
- }
-
- fp = &tfshdr;
- memset((char *)fp,0,TFSHDRSIZ);
- size = (int)strtol(arg4,0,0);
- src = (char *)strtoul(arg3,0,0);
- }
- else
- return(CMD_PARAM_ERROR);
+ /* The incoming arguments can be either just the filename (in which
+ * case we assume the source is the file in TFS with the same name),
+ * or the filename, source address and size...
+ */
+ if(argc == optind+2) { // Just filename?
+ if((fp = tfsstat(name)) == (TFILE *)0) {
+ printf("File '%s' not in TFS\n",name);
+ return(CMD_FAILURE);
+ }
+ name = fp->name;
+ info = fp->info;
+ bflags = fp->flags;
+ size = fp->filsize;
+ src = (char *)(fp + 1);
+ fp = &tfshdr;
+ memset((char *)fp,0,TFSHDRSIZ);
+ } else if(argc == optind+4) { // Filename with addr and len
+ // Extract flags and info fields (if any) from the name...
+ fcomma = strchr(name,',');
+ if(fcomma) {
+ icomma = strchr(fcomma+1,',');
+ if(icomma) {
+ *icomma = 0;
+ info = icomma+1;
+ }
+ *fcomma = 0;
+ bflags = tfsctrl(TFS_FATOB,(long)(fcomma+1),0);
+ }
- while(addr < (char *)END_OF_NAND) {
- if ((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0)
- break;
- if (fp->hdrsize == 0xffff) {
- unsigned long nextfileaddr;
+ fp = &tfshdr;
+ memset((char *)fp,0,TFSHDRSIZ);
+ size = (int)strtol(arg4,0,0);
+ src = (char *)strtoul(arg3,0,0);
+ } else {
+ return(CMD_PARAM_ERROR);
+ }
- /* We're at the address in NAND where we can add the new
- * file, but first we need to make sure there's enough
- * room...
- */
- if ((TFSHDRSIZ + size + 16) >= ((char *)END_OF_NAND - addr)) {
- printf(" not enough space\n");
- return(CMD_FAILURE);
- }
+ while(addr < (char *)END_OF_NAND) {
+ if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ break;
+ }
+ if(fp->hdrsize == 0xffff) {
+ unsigned long nextfileaddr;
- /* Copy name and info data to header.
- */
- strcpy(fp->name, name);
- strcpy(fp->info, info);
- fp->hdrsize = TFSHDRSIZ;
- fp->hdrvrsn = TFSHDRVERSION;
- fp->filsize = size;
- fp->flags = bflags;
- fp->flags |= (TFS_ACTIVE | TFS_NSTALE);
- fp->filcrc = crc32((unsigned char *)src,size);
- fp->modtime = tfsGetLtime();
+ /* We're at the address in NAND where we can add the new
+ * file, but first we need to make sure there's enough
+ * room...
+ */
+ if((TFSHDRSIZ + size + 16) >= ((char *)END_OF_NAND - addr)) {
+ printf(" not enough space\n");
+ return(CMD_FAILURE);
+ }
+
+ /* Copy name and info data to header.
+ */
+ strcpy(fp->name, name);
+ strcpy(fp->info, info);
+ fp->hdrsize = TFSHDRSIZ;
+ fp->hdrvrsn = TFSHDRVERSION;
+ fp->filsize = size;
+ fp->flags = bflags;
+ fp->flags |= (TFS_ACTIVE | TFS_NSTALE);
+ fp->filcrc = crc32((unsigned char *)src,size);
+ fp->modtime = tfsGetLtime();
#if TFS_RESERVED
- {
- int rsvd;
- for(rsvd=0;rsvd<TFS_RESERVED;rsvd++)
- fp->rsvd[rsvd] = 0xffffffff;
- }
+ {
+ int rsvd;
+ for(rsvd=0; rsvd<TFS_RESERVED; rsvd++) {
+ fp->rsvd[rsvd] = 0xffffffff;
+ }
+ }
#endif
- fp->next = 0;
- fp->hdrcrc = 0;
- fp->hdrcrc = crc32((unsigned char *)fp,TFSHDRSIZ);
- nextfileaddr = NAND_TFSRAM_BASE - NAND_TFS_BASE + (long)addr + TFSHDRSIZ + size;
- if (nextfileaddr & 0xf)
- nextfileaddr = (nextfileaddr | 0xf) + 1;
-
- fp->next = (TFILE *)nextfileaddr;
+ fp->next = 0;
+ fp->hdrcrc = 0;
+ fp->hdrcrc = crc32((unsigned char *)fp,TFSHDRSIZ);
+ nextfileaddr = NAND_TFSRAM_BASE - NAND_TFS_BASE + (long)addr + TFSHDRSIZ + size;
+ if(nextfileaddr & 0xf) {
+ nextfileaddr = (nextfileaddr | 0xf) + 1;
+ }
+
+ fp->next = (TFILE *)nextfileaddr;
- printf(" writing %s...\n",arg2);
- if ((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0)
- printf(" write_hdr failed %d\n",rc);
+ printf(" writing %s...\n",arg2);
+ if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ printf(" write_hdr failed %d\n",rc);
+ }
- if ((rc = nandWriteChunk(addr+TFSHDRSIZ,src,size)) < 0)
- printf(" write_file failed %d\n",rc);
- break;
- }
- if (strcmp(TFS_NAME(fp),arg2) == 0) {
- if (TFS_FILEEXISTS(fp)) {
- printf(" removing %s...\n",arg2);
- fp->flags &= ~TFS_ACTIVE;
- if ((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0)
- printf(" write_hdr failed %d\n",rc);
- }
- }
- addr += TFS_SIZE(fp);
- addr += TFSHDRSIZ;
- while((long)addr & 0xf) addr++;
- }
- }
- else if (strcmp(cmd, "tfsstat") == 0) {
- char *addr, *oaddr;
- TFILE tfshdr, *fp;
- unsigned long meminuse, memdead;
+ if((rc = nandWriteChunk(addr+TFSHDRSIZ,src,size)) < 0) {
+ printf(" write_file failed %d\n",rc);
+ }
+ break;
+ }
+ if(strcmp(TFS_NAME(fp),arg2) == 0) {
+ if(TFS_FILEEXISTS(fp)) {
+ printf(" removing %s...\n",arg2);
+ fp->flags &= ~TFS_ACTIVE;
+ if((rc = nandWriteChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ printf(" write_hdr failed %d\n",rc);
+ }
+ }
+ }
+ addr += TFS_SIZE(fp);
+ addr += TFSHDRSIZ;
+ while((long)addr & 0xf) {
+ addr++;
+ }
+ }
+ } else if(strcmp(cmd, "tfsstat") == 0) {
+ char *addr, *oaddr;
+ TFILE tfshdr, *fp;
+ unsigned long meminuse, memdead;
- fp = &tfshdr;
- meminuse = memdead = 0;
- addr = (char *)BASE_OF_NAND;
- while(addr < (char *)END_OF_NAND) {
- if ((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
- printf("nandReadChunk failed %d\n",rc);
- break;
- }
- if (fp->hdrsize == 0xffff)
- break;
+ fp = &tfshdr;
+ meminuse = memdead = 0;
+ addr = (char *)BASE_OF_NAND;
+ while(addr < (char *)END_OF_NAND) {
+ if((rc = nandReadChunk(addr,(char *)fp,TFSHDRSIZ)) < 0) {
+ printf("nandReadChunk failed %d\n",rc);
+ break;
+ }
+ if(fp->hdrsize == 0xffff) {
+ break;
+ }
- oaddr = addr;
- addr += TFS_SIZE(fp);
- addr += TFSHDRSIZ;
- while((long)addr & 0xf) addr++;
+ oaddr = addr;
+ addr += TFS_SIZE(fp);
+ addr += TFSHDRSIZ;
+ while((long)addr & 0xf) {
+ addr++;
+ }
- if (TFS_FILEEXISTS(fp))
- meminuse += addr - oaddr;
- else
- memdead += addr - oaddr;
- }
- printf("Total: 0x%x, used: 0x%x, dead: 0x%x, avail: 0x%x\n",
- SIZE_OF_NAND, meminuse, memdead,
- SIZE_OF_NAND - (meminuse + memdead));
- }
+ if(TFS_FILEEXISTS(fp)) {
+ meminuse += addr - oaddr;
+ } else {
+ memdead += addr - oaddr;
+ }
+ }
+ printf("Total: 0x%x, used: 0x%x, dead: 0x%x, avail: 0x%x\n",
+ SIZE_OF_NAND, meminuse, memdead,
+ SIZE_OF_NAND - (meminuse + memdead));
+ }
#endif
- else
- return(CMD_PARAM_ERROR);
+ else {
+ return(CMD_PARAM_ERROR);
+ }
- return(CMD_SUCCESS);
+ return(CMD_SUCCESS);
}
#endif