xref: /inferno-os/libnandfs/readpage.c (revision d3641b487cf5cdc46e9b537d30eb37736e5c7b1a)
1 #include "logfsos.h"
2 #include "logfs.h"
3 #include "nandfs.h"
4 #include "nandecc.h"
5 #include "local.h"
6 
7 char *
8 nandfsreadpage(Nandfs *nandfs, void *buf, NandfsTags *tags, long block, int page, int reportbad, LogfsLowLevelReadResult *result)
9 {
10 	ulong ecc1, ecc2, storedecc1, storedecc2;
11 	NandEccError e1, e2;
12 	ulong rawoffset;
13 	NandfsAuxiliary hdr;
14 	char *errmsg;
15 
16 	rawoffset = nandfs->rawblocksize * (nandfs->baseblock + block) + NandfsFullSize * page;
17 	errmsg = (*nandfs->read)(nandfs->magic, buf, NandfsPageSize, rawoffset);
18 	if (errmsg)
19 		return errmsg;
20 	errmsg = (*nandfs->read)(nandfs->magic, &hdr, sizeof(hdr), rawoffset + NandfsPageSize);
21 	if (errmsg)
22 		return errmsg;
23 	ecc1 = nandecc(buf);
24 	ecc2 = nandecc((uchar *)buf + 256);
25 	storedecc1 = getlittle3(hdr.ecc1);
26 	storedecc2 = getlittle3(hdr.ecc2);
27 	e1 = nandecccorrect(buf, ecc1, &storedecc1, reportbad);
28 	e2 = nandecccorrect((uchar *)buf + 256, ecc2, &storedecc2, reportbad);
29 	if (e1 == NandEccErrorBad || e2 == NandEccErrorBad)
30 		*result = LogfsLowLevelReadResultHardError;
31 	else if (e1 != NandEccErrorGood || e2 != NandEccErrorGood)
32 		*result = LogfsLowLevelReadResultSoftError;
33 	else
34 		*result = LogfsLowLevelReadResultOk;
35 	if (tags) {
36 		*result = _nandfscorrectauxiliary(&hdr);
37 		_nandfsextracttags(&hdr, tags);
38 	}
39 	return nil;
40 }
41 
42 char *
43 nandfsreadpagerange(Nandfs *nandfs, void *buf, long block, int page, int offset, int count, LogfsLowLevelReadResult *result)
44 {
45 	char *errmsg;
46 	uchar tmpbuf[NandfsPageSize];
47 	errmsg = nandfsreadpage(nandfs, tmpbuf, nil, block, page, 1, result);
48 	if (errmsg == nil)
49 		memmove(buf, tmpbuf + offset, count);
50 	return errmsg;
51 }
52 
53