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
l2(long n)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 *
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)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
nandfsfree(Nandfs * nandfs)84 nandfsfree(Nandfs *nandfs)
85 {
86 if (nandfs) {
87 nandfsfreemem(nandfs->blockdata);
88 nandfsfreemem(nandfs);
89 }
90 }
91
92 void
nandfssetmagic(Nandfs * nandfs,void * magic)93 nandfssetmagic(Nandfs *nandfs, void *magic)
94 {
95 nandfs->magic = magic;
96 }
97
98 char *
nandfssync(Nandfs * nandfs)99 nandfssync(Nandfs *nandfs)
100 {
101 return (*nandfs->sync)(nandfs->magic);
102 }
103