xref: /inferno-os/libnandfs/readpage.c (revision 28942ead413418b56c5be78e8c4c400881fba72e)
1*28942eadSforsyth #include "logfsos.h"
237da2899SCharles.Forsyth #include "logfs.h"
337da2899SCharles.Forsyth #include "nandfs.h"
437da2899SCharles.Forsyth #include "nandecc.h"
537da2899SCharles.Forsyth #include "local.h"
637da2899SCharles.Forsyth 
737da2899SCharles.Forsyth char *
nandfsreadpage(Nandfs * nandfs,void * buf,NandfsTags * tags,long block,int page,int reportbad,LogfsLowLevelReadResult * result)837da2899SCharles.Forsyth nandfsreadpage(Nandfs *nandfs, void *buf, NandfsTags *tags, long block, int page, int reportbad, LogfsLowLevelReadResult *result)
937da2899SCharles.Forsyth {
1037da2899SCharles.Forsyth 	ulong ecc1, ecc2, storedecc1, storedecc2;
1137da2899SCharles.Forsyth 	NandEccError e1, e2;
1237da2899SCharles.Forsyth 	ulong rawoffset;
1337da2899SCharles.Forsyth 	NandfsAuxiliary hdr;
1437da2899SCharles.Forsyth 	char *errmsg;
1537da2899SCharles.Forsyth 
1637da2899SCharles.Forsyth 	rawoffset = nandfs->rawblocksize * (nandfs->baseblock + block) + NandfsFullSize * page;
1737da2899SCharles.Forsyth 	errmsg = (*nandfs->read)(nandfs->magic, buf, NandfsPageSize, rawoffset);
1837da2899SCharles.Forsyth 	if (errmsg)
1937da2899SCharles.Forsyth 		return errmsg;
2037da2899SCharles.Forsyth 	errmsg = (*nandfs->read)(nandfs->magic, &hdr, sizeof(hdr), rawoffset + NandfsPageSize);
2137da2899SCharles.Forsyth 	if (errmsg)
2237da2899SCharles.Forsyth 		return errmsg;
2337da2899SCharles.Forsyth 	ecc1 = nandecc(buf);
2437da2899SCharles.Forsyth 	ecc2 = nandecc((uchar *)buf + 256);
2537da2899SCharles.Forsyth 	storedecc1 = getlittle3(hdr.ecc1);
2637da2899SCharles.Forsyth 	storedecc2 = getlittle3(hdr.ecc2);
2737da2899SCharles.Forsyth 	e1 = nandecccorrect(buf, ecc1, &storedecc1, reportbad);
2837da2899SCharles.Forsyth 	e2 = nandecccorrect((uchar *)buf + 256, ecc2, &storedecc2, reportbad);
2937da2899SCharles.Forsyth 	if (e1 == NandEccErrorBad || e2 == NandEccErrorBad)
3037da2899SCharles.Forsyth 		*result = LogfsLowLevelReadResultHardError;
3137da2899SCharles.Forsyth 	else if (e1 != NandEccErrorGood || e2 != NandEccErrorGood)
3237da2899SCharles.Forsyth 		*result = LogfsLowLevelReadResultSoftError;
3337da2899SCharles.Forsyth 	else
3437da2899SCharles.Forsyth 		*result = LogfsLowLevelReadResultOk;
3537da2899SCharles.Forsyth 	if (tags) {
3637da2899SCharles.Forsyth 		*result = _nandfscorrectauxiliary(&hdr);
3737da2899SCharles.Forsyth 		_nandfsextracttags(&hdr, tags);
3837da2899SCharles.Forsyth 	}
3937da2899SCharles.Forsyth 	return nil;
4037da2899SCharles.Forsyth }
4137da2899SCharles.Forsyth 
4237da2899SCharles.Forsyth char *
nandfsreadpagerange(Nandfs * nandfs,void * buf,long block,int page,int offset,int count,LogfsLowLevelReadResult * result)4337da2899SCharles.Forsyth nandfsreadpagerange(Nandfs *nandfs, void *buf, long block, int page, int offset, int count, LogfsLowLevelReadResult *result)
4437da2899SCharles.Forsyth {
4537da2899SCharles.Forsyth 	char *errmsg;
4637da2899SCharles.Forsyth 	uchar tmpbuf[NandfsPageSize];
4737da2899SCharles.Forsyth 	errmsg = nandfsreadpage(nandfs, tmpbuf, nil, block, page, 1, result);
4837da2899SCharles.Forsyth 	if (errmsg == nil)
49*28942eadSforsyth 		memmove(buf, tmpbuf + offset, count);
5037da2899SCharles.Forsyth 	return errmsg;
5137da2899SCharles.Forsyth }
5237da2899SCharles.Forsyth 
53