24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <asm/errno.h>
28 #include <asm/uaccess.h>
30 #include <linux/slab.h>
32 #include <linux/types.h>
45 #define NN ((1 << MM) - 1)
50 static const int Pp[
MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
74 x = (x >>
MM) + (x &
NN);
81 for(ci=(n)-1;ci >=0;ci--)\
85 #define COPY(a,b,n) {\
87 for(ci=(n)-1;ci >=0;ci--)\
91 #define COPYDOWN(a,b,n) {\
93 for(ci=(n)-1;ci >=0;ci--)\
133 register int i,
mask;
137 for (i = 0; i <
MM; i++) {
139 Index_of[Alpha_to[
i]] =
i;
145 Index_of[Alpha_to[
MM]] =
MM;
152 for (i = MM + 1; i <
NN; i++) {
153 if (Alpha_to[i - 1] >= mask)
154 Alpha_to[
i] = Alpha_to[
MM] ^ ((Alpha_to[i - 1] ^
mask) << 1);
156 Alpha_to[
i] = Alpha_to[i - 1] << 1;
157 Index_of[Alpha_to[
i]] =
i;
210 for(i=1;i<=
NN-
KK;i++){
213 for(j=1;j<
NN-
KK;j++){
216 tmp = Index_of[
bb[
j]];
218 for(i=1;i<=
NN-
KK;i++)
219 s[i] ^= Alpha_to[modnn(tmp + (
B0+i-1)*
PRIM*j)];
225 for(i=1;i<=
NN-
KK;i++) {
226 tmp = Index_of[s[
i]];
228 tmp = modnn(tmp + 2 * KK * (
B0+i-1)*
PRIM);
237 lambda[1] = Alpha_to[modnn(
PRIM * eras_pos[0])];
238 for (i = 1; i < no_eras; i++) {
239 u = modnn(
PRIM*eras_pos[i]);
240 for (j = i+1; j > 0; j--) {
241 tmp = Index_of[lambda[j - 1]];
243 lambda[
j] ^= Alpha_to[modnn(u + tmp)];
251 for(i=1;i<=no_eras;i++)
252 reg[i] = Index_of[lambda[i]];
256 for (j = 1; j <= no_eras; j++)
258 reg[
j] = modnn(reg[j] + j);
259 q ^= Alpha_to[reg[
j]];
268 if (count != no_eras) {
269 printf(
"\n lambda(x) is WRONG\n");
274 printf(
"\n Erasure positions as determined by roots of Eras Loc Poly:\n");
275 for (i = 0; i <
count; i++)
281 for(i=0;i<
NN-KK+1;i++)
282 b[i] = Index_of[lambda[i]];
290 while (++r <=
NN-KK) {
293 for (i = 0; i <
r; i++){
294 if ((lambda[i] != 0) && (s[r - i] !=
A0)) {
295 discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])];
306 for (i = 0 ; i <
NN-
KK; i++) {
308 t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])];
310 t[i+1] = lambda[i+1];
312 if (2 * el <= r + no_eras - 1) {
313 el = r + no_eras -
el;
318 for (i = 0; i <=
NN-
KK; i++)
319 b[i] = (lambda[i] == 0) ?
A0 : modnn(Index_of[lambda[i]] - discr_r +
NN);
331 for(i=0;i<
NN-KK+1;i++){
332 lambda[
i] = Index_of[lambda[
i]];
340 COPY(®[1],&lambda[1],
NN-KK);
344 for (j = deg_lambda; j > 0; j--){
346 reg[
j] = modnn(reg[j] + j);
347 q ^= Alpha_to[reg[
j]];
358 if(++count == deg_lambda)
361 if (deg_lambda != count) {
374 for (i = 0; i <
NN-
KK;i++){
376 j = (deg_lambda <
i) ? deg_lambda : i;
378 if ((s[i + 1 - j] !=
A0) && (lambda[
j] !=
A0))
379 tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])];
383 omega[
i] = Index_of[
tmp];
391 for (j = count-1; j >=0; j--) {
393 for (i = deg_omega; i >= 0; i--) {
395 num1 ^= Alpha_to[modnn(omega[i] + i * root[j])];
397 num2 = Alpha_to[modnn(root[j] * (
B0 - 1) +
NN)];
401 for (i =
min(deg_lambda,
NN-KK-1) & ~1; i >= 0; i -=2) {
402 if(lambda[i+1] !=
A0)
403 den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
407 printf(
"\n ERROR: denominator = 0\n");
415 eras_val[
j] = Alpha_to[modnn(Index_of[num1] + Index_of[num2] +
NN - Index_of[den])];
422 eras_pos[i] = loc[i];
429 #define SECTOR_SIZE 512
431 #define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
445 dtype *Alpha_to, *Index_of;
458 generate_gf(Alpha_to, Index_of);
462 bb[0] = (ecc1[4] & 0xff) | ((ecc1[5] & 0x03) << 8);
463 bb[1] = ((ecc1[5] & 0xfc) >> 2) | ((ecc1[2] & 0x0f) << 6);
464 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
465 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
467 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
468 error_val, error_pos, 0);
473 for(i=0;i<nb_errors;i++) {
475 if (pos >=
NB_DATA && pos < KK) {
484 index = (pos >> 3) ^ 1;
486 if ((index >= 0 && index < SECTOR_SIZE) ||
487 index == (SECTOR_SIZE + 1)) {
488 val = error_val[
i] >> (2 + bitpos);
490 if (index < SECTOR_SIZE)
493 index = ((pos >> 3) + 1) ^ 1;
494 bitpos = (bitpos + 10) & 7;
497 if ((index >= 0 && index < SECTOR_SIZE) ||
498 index == (SECTOR_SIZE + 1)) {
499 val = error_val[
i] << (8 - bitpos);
501 if (index < SECTOR_SIZE)
508 if ((parity & 0xff) != 0)
521 MODULE_DESCRIPTION(
"ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware");