xref: /inferno-os/libnandfs/readpage.c (revision 6cde411a8ffd477459336cedf48034e46f56f913)
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