1 #include "logfsos.h" 2 #include "logfs.h" 3 #include "nandfs.h" 4 #include "local.h" 5 6 uchar _nandfsvalidtags[] = { 7 LogfsTnone, 8 LogfsTboot, 9 LogfsTlog, 10 LogfsTdata, 11 }; 12 13 int _nandfsvalidtagscount = nelem(_nandfsvalidtags); 14 15 static int 16 l2(long n) 17 { 18 int i; 19 for (i = 0; i < 32; i++) 20 if ((1 << i) >= n) 21 return i; 22 return 0; 23 } 24 25 char * 26 nandfsinit(void *magic, long rawsize, long rawblocksize, 27 char *(*read)(void *magic, void *buf, long nbytes, ulong offset), 28 char *(*write)(void *magic, void *buf, long nbytes, ulong offset), 29 char *(*erase)(void *magic, long blockaddr), 30 char *(*sync)(void *magic), 31 LogfsLowLevel **llp) 32 { 33 Nandfs *nandfs; 34 nandfs = nandfsrealloc(nil, sizeof(*nandfs)); 35 if (nandfs == nil) 36 return Enomem; 37 if (rawblocksize % NandfsFullSize) 38 return "unsupported block size"; 39 if (rawsize % rawblocksize) 40 return "size not multiple of block size"; 41 nandfs->read = read; 42 nandfs->write = write; 43 nandfs->erase = erase; 44 nandfs->sync = sync; 45 nandfs->magic = magic; 46 nandfs->limitblock = rawsize / rawblocksize; 47 //print("rawsize %ld\n", rawsize); 48 //print("rawblocksize %ld\n", rawblocksize); 49 //print("limitblock %ld\n", nandfs->limitblock); 50 nandfs->rawblocksize = rawblocksize; 51 /* fill in upper interface */ 52 nandfs->ll.pathbits = NandfsPathBits; 53 nandfs->ll.blocks = 0; 54 nandfs->ll.l2pagesize = NandfsL2PageSize; 55 nandfs->ll.l2pagesperblock = l2(rawblocksize / NandfsFullSize); 56 nandfs->ll.open = (LOGFSOPENFN *)nandfsopen; 57 nandfs->ll.getblocktag = (LOGFSGETBLOCKTAGFN *)nandfsgettag; 58 nandfs->ll.setblocktag = (LOGFSSETBLOCKTAGFN *)nandfssettag; 59 nandfs->ll.getblockpath = (LOGFSGETBLOCKPATHFN *)nandfsgetpath; 60 nandfs->ll.setblockpath = (LOGFSSETBLOCKPATHFN *)nandfssetpath; 61 nandfs->ll.getblockpartialformatstatus = (LOGFSGETBLOCKPARTIALFORMATSTATUSFN *)nandfsgetblockpartialformatstatus; 62 nandfs->ll.findfreeblock = (LOGFSFINDFREEBLOCKFN *)nandfsfindfreeblock; 63 nandfs->ll.readpagerange = (LOGFSREADPAGERANGEFN *)nandfsreadpagerange; 64 nandfs->ll.writepage = (LOGFSWRITEPAGEFN *)nandfswritepage; 65 nandfs->ll.readblock = (LOGFSREADBLOCKFN *)nandfsreadblock; 66 nandfs->ll.writeblock = (LOGFSWRITEBLOCKFN *)nandfswriteblock; 67 nandfs->ll.eraseblock = (LOGFSERASEBLOCKFN *)nandfseraseblock; 68 nandfs->ll.formatblock = (LOGFSFORMATBLOCKFN *)nandfsformatblock; 69 nandfs->ll.reformatblock = (LOGFSREFORMATBLOCKFN *)nandfsreformatblock; 70 nandfs->ll.markblockbad = (LOGFSMARKBLOCKBADFN *)nandfsmarkblockbad; 71 nandfs->ll.getbaseblock = (LOGFSGETBASEBLOCKFN *)nandfsgetbaseblock; 72 nandfs->ll.getblocksize = (LOGFSGETBLOCKSIZEFN *)nandfsgetblocksize; 73 nandfs->ll.calcrawaddress = (LOGFSCALCRAWADDRESSFN *)nandfscalcrawaddress; 74 nandfs->ll.getblockstatus = (LOGFSGETBLOCKSTATUSFN *)nandfsgetblockstatus; 75 nandfs->ll.calcformat = (LOGFSCALCFORMATFN *)nandfscalcformat; 76 nandfs->ll.getopenstatus = (LOGFSGETOPENSTATUSFN *)nandfsgetopenstatus; 77 nandfs->ll.free = (LOGFSFREEFN *)nandfsfree; 78 nandfs->ll.sync = (LOGFSSYNCFN *)nandfssync; 79 *llp = (LogfsLowLevel *)nandfs; 80 return nil; 81 } 82 83 void 84 nandfsfree(Nandfs *nandfs) 85 { 86 if (nandfs) { 87 nandfsfreemem(nandfs->blockdata); 88 nandfsfreemem(nandfs); 89 } 90 } 91 92 void 93 nandfssetmagic(Nandfs *nandfs, void *magic) 94 { 95 nandfs->magic = magic; 96 } 97 98 char * 99 nandfssync(Nandfs *nandfs) 100 { 101 return (*nandfs->sync)(nandfs->magic); 102 } 103