xref: /inferno-os/libnandfs/init.c (revision cd03a2dc3bfa8e793b2e4702966706c10d69b314)
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