diff options
Diffstat (limited to 'libnandfs/init.c')
| -rw-r--r-- | libnandfs/init.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/libnandfs/init.c b/libnandfs/init.c new file mode 100644 index 00000000..ebfd6a67 --- /dev/null +++ b/libnandfs/init.c @@ -0,0 +1,102 @@ +#include "lib9.h" +#include "logfs.h" +#include "nandfs.h" +#include "local.h" + +uchar _nandfsvalidtags[] = { + LogfsTnone, + LogfsTboot, + LogfsTlog, + LogfsTdata, +}; + +int _nandfsvalidtagscount = nelem(_nandfsvalidtags); + +static int +l2(long n) +{ + int i; + for (i = 0; i < 32; i++) + if ((1 << i) >= n) + return i; + return 0; +} + +char * +nandfsinit(void *magic, long rawsize, long rawblocksize, + char *(*read)(void *magic, void *buf, long nbytes, ulong offset), + char *(*write)(void *magic, void *buf, long nbytes, ulong offset), + char *(*erase)(void *magic, long blockaddr), + char *(*sync)(void *magic), + LogfsLowLevel **llp) +{ + Nandfs *nandfs; + nandfs = nandfsrealloc(nil, sizeof(*nandfs)); + if (nandfs == nil) + return Enomem; + if (rawblocksize % NandfsFullSize) + return "unsupported block size"; + if (rawsize % rawblocksize) + return "size not multiple of block size"; + nandfs->read = read; + nandfs->write = write; + nandfs->erase = erase; + nandfs->sync = sync; + nandfs->magic = magic; + nandfs->limitblock = rawsize / rawblocksize; +//print("rawsize %ld\n", rawsize); +//print("rawblocksize %ld\n", rawblocksize); +//print("limitblock %ld\n", nandfs->limitblock); + nandfs->rawblocksize = rawblocksize; + /* fill in upper interface */ + nandfs->ll.pathbits = NandfsPathBits; + nandfs->ll.blocks = 0; + nandfs->ll.l2pagesize = NandfsL2PageSize; + nandfs->ll.l2pagesperblock = l2(rawblocksize / NandfsFullSize); + nandfs->ll.open = (LOGFSOPENFN *)nandfsopen; + nandfs->ll.getblocktag = (LOGFSGETBLOCKTAGFN *)nandfsgettag; + nandfs->ll.setblocktag = (LOGFSSETBLOCKTAGFN *)nandfssettag; + nandfs->ll.getblockpath = (LOGFSGETBLOCKPATHFN *)nandfsgetpath; + nandfs->ll.setblockpath = (LOGFSSETBLOCKPATHFN *)nandfssetpath; + nandfs->ll.getblockpartialformatstatus = (LOGFSGETBLOCKPARTIALFORMATSTATUSFN *)nandfsgetblockpartialformatstatus; + nandfs->ll.findfreeblock = (LOGFSFINDFREEBLOCKFN *)nandfsfindfreeblock; + nandfs->ll.readpagerange = (LOGFSREADPAGERANGEFN *)nandfsreadpagerange; + nandfs->ll.writepage = (LOGFSWRITEPAGEFN *)nandfswritepage; + nandfs->ll.readblock = (LOGFSREADBLOCKFN *)nandfsreadblock; + nandfs->ll.writeblock = (LOGFSWRITEBLOCKFN *)nandfswriteblock; + nandfs->ll.eraseblock = (LOGFSERASEBLOCKFN *)nandfseraseblock; + nandfs->ll.formatblock = (LOGFSFORMATBLOCKFN *)nandfsformatblock; + nandfs->ll.reformatblock = (LOGFSREFORMATBLOCKFN *)nandfsreformatblock; + nandfs->ll.markblockbad = (LOGFSMARKBLOCKBADFN *)nandfsmarkblockbad; + nandfs->ll.getbaseblock = (LOGFSGETBASEBLOCKFN *)nandfsgetbaseblock; + nandfs->ll.getblocksize = (LOGFSGETBLOCKSIZEFN *)nandfsgetblocksize; + nandfs->ll.calcrawaddress = (LOGFSCALCRAWADDRESSFN *)nandfscalcrawaddress; + nandfs->ll.getblockstatus = (LOGFSGETBLOCKSTATUSFN *)nandfsgetblockstatus; + nandfs->ll.calcformat = (LOGFSCALCFORMATFN *)nandfscalcformat; + nandfs->ll.getopenstatus = (LOGFSGETOPENSTATUSFN *)nandfsgetopenstatus; + nandfs->ll.free = (LOGFSFREEFN *)nandfsfree; + nandfs->ll.sync = (LOGFSSYNCFN *)nandfssync; + *llp = (LogfsLowLevel *)nandfs; + return nil; +} + +void +nandfsfree(Nandfs *nandfs) +{ + if (nandfs) { + nandfsfreemem(nandfs->blockdata); + nandfsfreemem(nandfs); + } +} + +void +nandfssetmagic(Nandfs *nandfs, void *magic) +{ + nandfs->magic = magic; +} + +char * +nandfssync(Nandfs *nandfs) +{ + return (*nandfs->sync)(nandfs->magic); +} |
