correctauxilliary.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include "logfsos.h"
  2. #include "logfs.h"
  3. #include "nandfs.h"
  4. #include "local.h"
  5. static int
  6. hammingdistance(uchar a, uchar b)
  7. {
  8. uchar c;
  9. int i, k;
  10. if (a == b)
  11. return 0;
  12. c = a ^ b;
  13. for (i = 0x80, k = 0; i; i >>= 1)
  14. if (c & i)
  15. k++;
  16. return k;
  17. }
  18. static int
  19. allones(uchar *data, int len)
  20. {
  21. while (len-- > 0)
  22. if (*data++ != 0xff)
  23. return 0;
  24. return 1;
  25. }
  26. LogfsLowLevelReadResult
  27. _nandfscorrectauxiliary(NandfsAuxiliary *hdr)
  28. {
  29. /*
  30. * correct single bit errors, detect more than 1, in
  31. * tag, signature
  32. * TODO: add nerase and path protection
  33. */
  34. LogfsLowLevelReadResult e;
  35. int x;
  36. int min, minx;
  37. e = LogfsLowLevelReadResultOk;
  38. min = 8;
  39. minx = 0;
  40. for (x = 0; x < _nandfsvalidtagscount; x++) {
  41. int d = hammingdistance(hdr->tag, _nandfsvalidtags[x]);
  42. if (d < min) {
  43. min = d;
  44. minx = x;
  45. if (d == 0)
  46. break;
  47. }
  48. }
  49. if (min == 1) {
  50. hdr->tag = _nandfsvalidtags[minx];
  51. e = LogfsLowLevelReadResultSoftError;
  52. }
  53. else if (min > 1)
  54. e = LogfsLowLevelReadResultHardError;
  55. else {
  56. if (hdr->tag != LogfsTnone) {
  57. ulong tmp = getbig4(hdr->parth);
  58. if (tmp != 0xffffffff && _nandfshamming31_26correct(&tmp)) {
  59. putbig4(hdr->parth, tmp);
  60. if (e != LogfsLowLevelReadResultOk)
  61. e = LogfsLowLevelReadResultSoftError;
  62. }
  63. tmp = (getbig2(hdr->nerasemagicmsw) << 16) | getbig2(hdr->nerasemagiclsw);
  64. if (tmp != 0xffffffff && _nandfshamming31_26correct(&tmp)) {
  65. putbig2(hdr->nerasemagicmsw, tmp >> 16);
  66. putbig2(hdr->nerasemagiclsw, tmp);
  67. if (e != LogfsLowLevelReadResultOk)
  68. e = LogfsLowLevelReadResultSoftError;
  69. }
  70. }
  71. else if (allones((uchar *)hdr, sizeof(*hdr)))
  72. e = LogfsLowLevelReadResultAllOnes;
  73. }
  74. return e;
  75. }