1 #include "logfsos.h" 2 #include "logfs.h" 3 #include "nandfs.h" 4 5 static unsigned long row4 = 0x001fffc0; 6 static unsigned long row3 = 0x0fe03fc0; 7 static unsigned long row2 = 0x71e3c3c0; 8 static unsigned long row1 = 0xb66cccc0; 9 static unsigned long row0 = 0xdab55540; 10 11 static char map[] = { 12 -5, -4, 0, -3, 1, 2, 3, -2, 13 4, 5, 6, 7, 8, 9, 10, -1, 11, 14 12, 13, 14, 15, 16, 17, 18, 15 19, 20, 21, 22, 23, 24, 25, 16 }; 17 18 #define mashbits(rown) \ 19 c = (in) & (rown); \ 20 c ^= c >> 16; \ 21 c ^= c >> 8; \ 22 c ^= c >> 4; \ 23 c ^= c >> 2; \ 24 c = (c ^ (c >> 1)) & 1; \ 25 26 static uchar 27 _nandfshamming31_26calcparity(ulong in) 28 { 29 ulong c; 30 uchar out; 31 mashbits(row4); out = c; 32 mashbits(row3); out = (out << 1) | c; 33 mashbits(row2); out = (out << 1) | c; 34 mashbits(row1); out = (out << 1) | c; 35 mashbits(row0); out = (out << 1) | c; 36 return out; 37 } 38 39 ulong 40 _nandfshamming31_26calc(ulong in) 41 { 42 in &= 0xffffffc0; 43 return in | _nandfshamming31_26calcparity(in); 44 } 45 46 int 47 _nandfshamming31_26correct(ulong *in) 48 { 49 uchar eparity, parity; 50 ulong e; 51 eparity = _nandfshamming31_26calcparity(*in); 52 parity = (*in) & 0x1f; 53 e = eparity ^ parity; 54 if (e == 0) 55 return 0; 56 e--; 57 if (map[e] < 0) 58 return 1; // error in parity bits 59 e = map[e]; 60 *in ^= 1 << (31 - e); 61 return 1; 62 } 63