]> Pileus Git - ~andy/linux/blob - drivers/mtd/nand/cafe_ecc.c
[MTD] NAND: Café ECC -- remove spurious BUG_ON() in err_pos()
[~andy/linux] / drivers / mtd / nand / cafe_ecc.c
1 /* Error correction for CAFÉ NAND controller 
2  *
3  * © 2006 Marvell, Inc.
4  * Author: Tom Chiou
5  *
6  * This program is free software; you can redistribute it and/or modify it 
7  * under the terms of the GNU General Public License as published by the Free 
8  * Software Foundation; either version 2 of the License, or (at your option) 
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT 
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc., 59 
18  * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23
24 static unsigned short gf4096_mul(unsigned short, unsigned short);
25 static unsigned short gf64_mul(unsigned short, unsigned short);
26 static unsigned short gf4096_inv(unsigned short);
27 static unsigned short err_pos(unsigned short);
28 static void find_4bit_err_coefs(unsigned short, unsigned short, unsigned short,
29                                 unsigned short, unsigned short, unsigned short,
30                                 unsigned short, unsigned short, unsigned short *);
31 static void zero_4x5_col3(unsigned short[4][5]);
32 static void zero_4x5_col2(unsigned short[4][5]);
33 static void zero_4x5_col1(unsigned short[4][5]);
34 static void swap_4x5_rows(unsigned short[4][5], int, int, int);
35 static void swap_2x3_rows(unsigned short m[2][3]);
36 static void solve_4x5(unsigned short m[4][5], unsigned short *, int *);
37 static void sort_coefs(int *, unsigned short *, int);
38 static void find_4bit_err_pats(unsigned short, unsigned short, unsigned short,
39                                unsigned short, unsigned short, unsigned short,
40                                unsigned short, unsigned short, unsigned short *);
41 static void find_3bit_err_coefs(unsigned short, unsigned short, unsigned short,
42                                 unsigned short, unsigned short, unsigned short,
43                                 unsigned short *);
44 static void zero_3x4_col2(unsigned short[3][4]);
45 static void zero_3x4_col1(unsigned short[3][4]);
46 static void swap_3x4_rows(unsigned short[3][4], int, int, int);
47 static void solve_3x4(unsigned short[3][4], unsigned short *, int *);
48 static void find_3bit_err_pats(unsigned short, unsigned short, unsigned short,
49                                unsigned short, unsigned short, unsigned short,
50                                unsigned short *);
51
52 static void find_2bit_err_pats(unsigned short, unsigned short, unsigned short,
53                                unsigned short, unsigned short *);
54 static void find_2x2_soln(unsigned short, unsigned short, unsigned short,
55                           unsigned short, unsigned short, unsigned short,
56                           unsigned short *);
57 static void solve_2x3(unsigned short[2][3], unsigned short *);
58 static int chk_no_err_only(unsigned short *, unsigned short *);
59 static int chk_1_err_only(unsigned short *, unsigned short *);
60 static int chk_2_err_only(unsigned short *, unsigned short *);
61 static int chk_3_err_only(unsigned short *, unsigned short *);
62 static int chk_4_err_only(unsigned short *, unsigned short *);
63
64 static unsigned short gf64_mul(unsigned short a, unsigned short b)
65 {
66         unsigned short tmp1, tmp2, tmp3, tmp4, tmp5;
67         unsigned short c_bit0, c_bit1, c_bit2, c_bit3, c_bit4, c_bit5, c;
68
69         tmp1 = ((a) ^ (a >> 5));
70         tmp2 = ((a >> 4) ^ (a >> 5));
71         tmp3 = ((a >> 3) ^ (a >> 4));
72         tmp4 = ((a >> 2) ^ (a >> 3));
73         tmp5 = ((a >> 1) ^ (a >> 2));
74
75         c_bit0 = ((a & b) ^ ((a >> 5) & (b >> 1)) ^ ((a >> 4) & (b >> 2)) ^
76                   ((a >> 3) & (b >> 3)) ^ ((a >> 2) & (b >> 4)) ^ ((a >> 1) & (b >> 5))) & 0x1;
77
78         c_bit1 = (((a >> 1) & b) ^ (tmp1 & (b >> 1)) ^ (tmp2 & (b >> 2)) ^
79                   (tmp3 & (b >> 3)) ^ (tmp4 & (b >> 4)) ^ (tmp5 & (b >> 5))) & 0x1;
80
81         c_bit2 = (((a >> 2) & b) ^ ((a >> 1) & (b >> 1)) ^ (tmp1 & (b >> 2)) ^
82                   (tmp2 & (b >> 3)) ^ (tmp3 & (b >> 4)) ^ (tmp4 & (b >> 5))) & 0x1;
83
84         c_bit3 = (((a >> 3) & b) ^ ((a >> 2) & (b >> 1)) ^ ((a >> 1) & (b >> 2)) ^
85                   (tmp1 & (b >> 3)) ^ (tmp2 & (b >> 4)) ^ (tmp3 & (b >> 5))) & 0x1;
86
87         c_bit4 = (((a >> 4) & b) ^ ((a >> 3) & (b >> 1)) ^ ((a >> 2) & (b >> 2)) ^
88                   ((a >> 1) & (b >> 3)) ^ (tmp1 & (b >> 4)) ^ (tmp2 & (b >> 5))) & 0x1;
89
90         c_bit5 = (((a >> 5) & b) ^ ((a >> 4) & (b >> 1)) ^ ((a >> 3) & (b >> 2)) ^
91                   ((a >> 2) & (b >> 3)) ^ ((a >> 1) & (b >> 4)) ^ (tmp1 & (b >> 5))) & 0x1;
92
93         c = c_bit0 | (c_bit1 << 1) | (c_bit2 << 2) | (c_bit3 << 3) | (c_bit4 << 4) | (c_bit5 << 5);
94
95         return c;
96 }
97
98 static unsigned short gf4096_mul(unsigned short a, unsigned short b)
99 {
100         unsigned short ah, al, bh, bl, alxah, blxbh, ablh, albl, ahbh, ahbhB, c;
101
102         ah = (a >> 6) & 0x3f;
103         al = a & 0x3f;
104         bh = (b >> 6) & 0x3f;
105         bl = b & 0x3f;
106         alxah = al ^ ah;
107         blxbh = bl ^ bh;
108
109         ablh = gf64_mul(alxah, blxbh);
110         albl = gf64_mul(al, bl);
111         ahbh = gf64_mul(ah, bh);
112
113         ahbhB = ((ahbh & 0x1) << 5) |
114             ((ahbh & 0x20) >> 1) |
115             ((ahbh & 0x10) >> 1) | ((ahbh & 0x8) >> 1) | ((ahbh & 0x4) >> 1) | (((ahbh >> 1) ^ ahbh) & 0x1);
116
117         c = ((ablh ^ albl) << 6) | (ahbhB ^ albl);
118         return c;
119 }
120
121 static void find_2bit_err_pats(unsigned short s0, unsigned short s1, unsigned short r0, unsigned short r1, unsigned short *pats)
122 {
123         find_2x2_soln(0x1, 0x1, r0, r1, s0, s1, pats);
124 }
125
126 static void find_3bit_err_coefs(unsigned short s0, unsigned short s1,
127                                 unsigned short s2, unsigned short s3, unsigned short s4, unsigned short s5, unsigned short *coefs)
128 {
129         unsigned short m[3][4];
130         int row_order[3];
131
132         row_order[0] = 0;
133         row_order[1] = 1;
134         row_order[2] = 2;
135         m[0][0] = s2;
136         m[0][1] = s1;
137         m[0][2] = s0;
138         m[0][3] = s3;
139         m[1][0] = s3;
140         m[1][1] = s2;
141         m[1][2] = s1;
142         m[1][3] = s4;
143         m[2][0] = s4;
144         m[2][1] = s3;
145         m[2][2] = s2;
146         m[2][3] = s5;
147
148         if (m[0][2] != 0x0) {
149                 zero_3x4_col2(m);
150         } else if (m[1][2] != 0x0) {
151                 swap_3x4_rows(m, 0, 1, 4);
152                 zero_3x4_col2(m);
153         } else if (m[2][2] != 0x0) {
154                 swap_3x4_rows(m, 0, 2, 4);
155                 zero_3x4_col2(m);
156         } else {
157                 printk(KERN_ERR "Error: find_3bit_err_coefs, s0,s1,s2 all zeros!\n");
158         }
159
160         if (m[1][1] != 0x0) {
161                 zero_3x4_col1(m);
162         } else if (m[2][1] != 0x0) {
163                 swap_3x4_rows(m, 1, 2, 4);
164                 zero_3x4_col1(m);
165         } else {
166                 printk(KERN_ERR "Error: find_3bit_err_coefs, cannot resolve col 1!\n");
167         }
168
169         /* solve coefs */
170         solve_3x4(m, coefs, row_order);
171 }
172
173 static void zero_3x4_col2(unsigned short m[3][4])
174 {
175         unsigned short minv1, minv2;
176
177         minv1 = gf4096_mul(m[1][2], gf4096_inv(m[0][2]));
178         minv2 = gf4096_mul(m[2][2], gf4096_inv(m[0][2]));
179         m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv1);
180         m[1][1] = m[1][1] ^ gf4096_mul(m[0][1], minv1);
181         m[1][3] = m[1][3] ^ gf4096_mul(m[0][3], minv1);
182         m[2][0] = m[2][0] ^ gf4096_mul(m[0][0], minv2);
183         m[2][1] = m[2][1] ^ gf4096_mul(m[0][1], minv2);
184         m[2][3] = m[2][3] ^ gf4096_mul(m[0][3], minv2);
185 }
186
187 static void zero_3x4_col1(unsigned short m[3][4])
188 {
189         unsigned short minv;
190         minv = gf4096_mul(m[2][1], gf4096_inv(m[1][1]));
191         m[2][0] = m[2][0] ^ gf4096_mul(m[1][0], minv);
192         m[2][3] = m[2][3] ^ gf4096_mul(m[1][3], minv);
193 }
194
195 static void swap_3x4_rows(unsigned short m[3][4], int i, int j, int col_width)
196 {
197         unsigned short tmp0;
198         int cnt;
199         for (cnt = 0; cnt < col_width; cnt++) {
200                 tmp0 = m[i][cnt];
201                 m[i][cnt] = m[j][cnt];
202                 m[j][cnt] = tmp0;
203         }
204 }
205
206 static void solve_3x4(unsigned short m[3][4], unsigned short *coefs, int *row_order)
207 {
208         unsigned short tmp[3];
209         tmp[0] = gf4096_mul(m[2][3], gf4096_inv(m[2][0]));
210         tmp[1] = gf4096_mul((gf4096_mul(tmp[0], m[1][0]) ^ m[1][3]), gf4096_inv(m[1][1]));
211         tmp[2] = gf4096_mul((gf4096_mul(tmp[0], m[0][0]) ^ gf4096_mul(tmp[1], m[0][1]) ^ m[0][3]), gf4096_inv(m[0][2]));
212         sort_coefs(row_order, tmp, 3);
213         coefs[0] = tmp[0];
214         coefs[1] = tmp[1];
215         coefs[2] = tmp[2];
216 }
217
218 static void find_3bit_err_pats(unsigned short s0, unsigned short s1,
219                                unsigned short s2, unsigned short r0,
220                                unsigned short r1, unsigned short r2,
221                                unsigned short *pats)
222 {
223         find_2x2_soln(r0 ^ r2, r1 ^ r2,
224                       gf4096_mul(r0, r0 ^ r2), gf4096_mul(r1, r1 ^ r2),
225                       gf4096_mul(s0, r2) ^ s1, gf4096_mul(s1, r2) ^ s2, pats);
226         pats[2] = s0 ^ pats[0] ^ pats[1];
227 }
228
229 static void find_4bit_err_coefs(unsigned short s0, unsigned short s1,
230                                 unsigned short s2, unsigned short s3,
231                                 unsigned short s4, unsigned short s5,
232                                 unsigned short s6, unsigned short s7,
233                                 unsigned short *coefs)
234 {
235         unsigned short m[4][5];
236         int row_order[4];
237
238         row_order[0] = 0;
239         row_order[1] = 1;
240         row_order[2] = 2;
241         row_order[3] = 3;
242
243         m[0][0] = s3;
244         m[0][1] = s2;
245         m[0][2] = s1;
246         m[0][3] = s0;
247         m[0][4] = s4;
248         m[1][0] = s4;
249         m[1][1] = s3;
250         m[1][2] = s2;
251         m[1][3] = s1;
252         m[1][4] = s5;
253         m[2][0] = s5;
254         m[2][1] = s4;
255         m[2][2] = s3;
256         m[2][3] = s2;
257         m[2][4] = s6;
258         m[3][0] = s6;
259         m[3][1] = s5;
260         m[3][2] = s4;
261         m[3][3] = s3;
262         m[3][4] = s7;
263
264         if (m[0][3] != 0x0) {
265                 zero_4x5_col3(m);
266         } else if (m[1][3] != 0x0) {
267                 swap_4x5_rows(m, 0, 1, 5);
268                 zero_4x5_col3(m);
269         } else if (m[2][3] != 0x0) {
270                 swap_4x5_rows(m, 0, 2, 5);
271                 zero_4x5_col3(m);
272         } else if (m[3][3] != 0x0) {
273                 swap_4x5_rows(m, 0, 3, 5);
274                 zero_4x5_col3(m);
275         } else {
276                 printk(KERN_ERR "Error: find_4bit_err_coefs, s0,s1,s2,s3 all zeros!\n");
277         }
278
279         if (m[1][2] != 0x0) {
280                 zero_4x5_col2(m);
281         } else if (m[2][2] != 0x0) {
282                 swap_4x5_rows(m, 1, 2, 5);
283                 zero_4x5_col2(m);
284         } else if (m[3][2] != 0x0) {
285                 swap_4x5_rows(m, 1, 3, 5);
286                 zero_4x5_col2(m);
287         } else {
288                 printk(KERN_ERR "Error: find_4bit_err_coefs, cannot resolve col 2!\n");
289         }
290
291         if (m[2][1] != 0x0) {
292                 zero_4x5_col1(m);
293         } else if (m[3][1] != 0x0) {
294                 swap_4x5_rows(m, 2, 3, 5);
295                 zero_4x5_col1(m);
296         } else {
297                 printk(KERN_ERR "Error: find_4bit_err_coefs, cannot resolve col 1!\n");
298         }
299
300         solve_4x5(m, coefs, row_order);
301 }
302
303 static void zero_4x5_col3(unsigned short m[4][5])
304 {
305         unsigned short minv1, minv2, minv3;
306
307         minv1 = gf4096_mul(m[1][3], gf4096_inv(m[0][3]));
308         minv2 = gf4096_mul(m[2][3], gf4096_inv(m[0][3]));
309         minv3 = gf4096_mul(m[3][3], gf4096_inv(m[0][3]));
310
311         m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv1);
312         m[1][1] = m[1][1] ^ gf4096_mul(m[0][1], minv1);
313         m[1][2] = m[1][2] ^ gf4096_mul(m[0][2], minv1);
314         m[1][4] = m[1][4] ^ gf4096_mul(m[0][4], minv1);
315         m[2][0] = m[2][0] ^ gf4096_mul(m[0][0], minv2);
316         m[2][1] = m[2][1] ^ gf4096_mul(m[0][1], minv2);
317         m[2][2] = m[2][2] ^ gf4096_mul(m[0][2], minv2);
318         m[2][4] = m[2][4] ^ gf4096_mul(m[0][4], minv2);
319         m[3][0] = m[3][0] ^ gf4096_mul(m[0][0], minv3);
320         m[3][1] = m[3][1] ^ gf4096_mul(m[0][1], minv3);
321         m[3][2] = m[3][2] ^ gf4096_mul(m[0][2], minv3);
322         m[3][4] = m[3][4] ^ gf4096_mul(m[0][4], minv3);
323 }
324
325 static void zero_4x5_col2(unsigned short m[4][5])
326 {
327         unsigned short minv2, minv3;
328
329         minv2 = gf4096_mul(m[2][2], gf4096_inv(m[1][2]));
330         minv3 = gf4096_mul(m[3][2], gf4096_inv(m[1][2]));
331
332         m[2][0] = m[2][0] ^ gf4096_mul(m[1][0], minv2);
333         m[2][1] = m[2][1] ^ gf4096_mul(m[1][1], minv2);
334         m[2][4] = m[2][4] ^ gf4096_mul(m[1][4], minv2);
335         m[3][0] = m[3][0] ^ gf4096_mul(m[1][0], minv3);
336         m[3][1] = m[3][1] ^ gf4096_mul(m[1][1], minv3);
337         m[3][4] = m[3][4] ^ gf4096_mul(m[1][4], minv3);
338 }
339
340 static void zero_4x5_col1(unsigned short m[4][5])
341 {
342         unsigned short minv;
343
344         minv = gf4096_mul(m[3][1], gf4096_inv(m[2][1]));
345
346         m[3][0] = m[3][0] ^ gf4096_mul(m[2][0], minv);
347         m[3][4] = m[3][4] ^ gf4096_mul(m[2][4], minv);
348 }
349
350 static void swap_4x5_rows(unsigned short m[4][5], int i, int j, int col_width)
351 {
352         unsigned short tmp0;
353         int cnt;
354
355         for (cnt = 0; cnt < col_width; cnt++) {
356                 tmp0 = m[i][cnt];
357                 m[i][cnt] = m[j][cnt];
358                 m[j][cnt] = tmp0;
359         }
360 }
361
362 static void solve_4x5(unsigned short m[4][5], unsigned short *coefs, int *row_order)
363 {
364         unsigned short tmp[4];
365
366         tmp[0] = gf4096_mul(m[3][4], gf4096_inv(m[3][0]));
367         tmp[1] = gf4096_mul((gf4096_mul(tmp[0], m[2][0]) ^ m[2][4]), gf4096_inv(m[2][1]));
368         tmp[2] = gf4096_mul((gf4096_mul(tmp[0], m[1][0]) ^ gf4096_mul(tmp[1], m[1][1]) ^ m[1][4]), gf4096_inv(m[1][2]));
369         tmp[3] = gf4096_mul((gf4096_mul(tmp[0], m[0][0]) ^
370                         gf4096_mul(tmp[1], m[0][1]) ^ gf4096_mul(tmp[2], m[0][2]) ^ m[0][4]), gf4096_inv(m[0][3]));
371         sort_coefs(row_order, tmp, 4);
372         coefs[0] = tmp[0];
373         coefs[1] = tmp[1];
374         coefs[2] = tmp[2];
375         coefs[3] = tmp[3];
376 }
377
378 static void sort_coefs(int *order, unsigned short *soln, int len)
379 {
380         int cnt, start_cnt, least_ord, least_cnt;
381         unsigned short tmp0;
382         for (start_cnt = 0; start_cnt < len; start_cnt++) {
383                 for (cnt = start_cnt; cnt < len; cnt++) {
384                         if (cnt == start_cnt) {
385                                 least_ord = order[cnt];
386                                 least_cnt = start_cnt;
387                         } else {
388                                 if (least_ord > order[cnt]) {
389                                         least_ord = order[cnt];
390                                         least_cnt = cnt;
391                                 }
392                         }
393                 }
394                 if (least_cnt != start_cnt) {
395                         tmp0 = order[least_cnt];
396                         order[least_cnt] = order[start_cnt];
397                         order[start_cnt] = tmp0;
398                         tmp0 = soln[least_cnt];
399                         soln[least_cnt] = soln[start_cnt];
400                         soln[start_cnt] = tmp0;
401                 }
402         }
403 }
404
405 static void find_4bit_err_pats(unsigned short s0, unsigned short s1,
406                                unsigned short s2, unsigned short s3,
407                                unsigned short z1, unsigned short z2,
408                                unsigned short z3, unsigned short z4,
409                                unsigned short *pats)
410 {
411         unsigned short z4_z1, z3z4_z3z3, z4_z2, s0z4_s1, z1z4_z1z1,
412                 z4_z3, z2z4_z2z2, s1z4_s2, z3z3z4_z3z3z3, z1z1z4_z1z1z1, z2z2z4_z2z2z2, s2z4_s3;
413         unsigned short tmp0, tmp1, tmp2, tmp3;
414
415         z4_z1 = z4 ^ z1;
416         z3z4_z3z3 = gf4096_mul(z3, z4) ^ gf4096_mul(z3, z3);
417         z4_z2 = z4 ^ z2;
418         s0z4_s1 = gf4096_mul(s0, z4) ^ s1;
419         z1z4_z1z1 = gf4096_mul(z1, z4) ^ gf4096_mul(z1, z1);
420         z4_z3 = z4 ^ z3;
421         z2z4_z2z2 = gf4096_mul(z2, z4) ^ gf4096_mul(z2, z2);
422         s1z4_s2 = gf4096_mul(s1, z4) ^ s2;
423         z3z3z4_z3z3z3 = gf4096_mul(gf4096_mul(z3, z3), z4) ^ gf4096_mul(gf4096_mul(z3, z3), z3);
424         z1z1z4_z1z1z1 = gf4096_mul(gf4096_mul(z1, z1), z4) ^ gf4096_mul(gf4096_mul(z1, z1), z1);
425         z2z2z4_z2z2z2 = gf4096_mul(gf4096_mul(z2, z2), z4) ^ gf4096_mul(gf4096_mul(z2, z2), z2);
426         s2z4_s3 = gf4096_mul(s2, z4) ^ s3;
427
428         //find err pat 0,1
429         find_2x2_soln(gf4096_mul(z4_z1, z3z4_z3z3) ^
430                       gf4096_mul(z1z4_z1z1, z4_z3), gf4096_mul(z4_z2,
431                                                                z3z4_z3z3) ^
432                       gf4096_mul(z2z4_z2z2, z4_z3), gf4096_mul(z1z4_z1z1,
433                                                                z3z3z4_z3z3z3) ^
434                       gf4096_mul(z1z1z4_z1z1z1, z3z4_z3z3),
435                       gf4096_mul(z2z4_z2z2,
436                                  z3z3z4_z3z3z3) ^ gf4096_mul(z2z2z4_z2z2z2,
437                                                              z3z4_z3z3),
438                       gf4096_mul(s0z4_s1, z3z4_z3z3) ^ gf4096_mul(s1z4_s2,
439                                                                   z4_z3),
440                       gf4096_mul(s1z4_s2, z3z3z4_z3z3z3) ^ gf4096_mul(s2z4_s3, z3z4_z3z3), pats);
441         tmp0 = pats[0];
442         tmp1 = pats[1];
443         tmp2 = pats[0] ^ pats[1] ^ s0;
444         tmp3 = gf4096_mul(pats[0], z1) ^ gf4096_mul(pats[1], z2) ^ s1;
445
446         //find err pat 2,3
447         find_2x2_soln(0x1, 0x1, z3, z4, tmp2, tmp3, pats);
448         pats[2] = pats[0];
449         pats[3] = pats[1];
450         pats[0] = tmp0;
451         pats[1] = tmp1;
452 }
453
454 static void find_2x2_soln(unsigned short c00, unsigned short c01,
455                           unsigned short c10, unsigned short c11,
456                           unsigned short lval0, unsigned short lval1,
457                           unsigned short *soln)
458 {
459         unsigned short m[2][3];
460         m[0][0] = c00;
461         m[0][1] = c01;
462         m[0][2] = lval0;
463         m[1][0] = c10;
464         m[1][1] = c11;
465         m[1][2] = lval1;
466
467         if (m[0][1] != 0x0) {
468                 /* */
469         } else if (m[1][1] != 0x0) {
470                 swap_2x3_rows(m);
471         } else {
472                 printk(KERN_ERR "Warning: find_2bit_err_coefs, s0,s1 all zeros!\n");
473         }
474
475         solve_2x3(m, soln);
476 }
477
478 static void swap_2x3_rows(unsigned short m[2][3])
479 {
480         unsigned short tmp0;
481         int cnt;
482
483         for (cnt = 0; cnt < 3; cnt++) {
484                 tmp0 = m[0][cnt];
485                 m[0][cnt] = m[1][cnt];
486                 m[1][cnt] = tmp0;
487         }
488 }
489
490 static void solve_2x3(unsigned short m[2][3], unsigned short *coefs)
491 {
492         unsigned short minv;
493
494         minv = gf4096_mul(m[1][1], gf4096_inv(m[0][1]));
495         m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv);
496         m[1][2] = m[1][2] ^ gf4096_mul(m[0][2], minv);
497         coefs[0] = gf4096_mul(m[1][2], gf4096_inv(m[1][0]));
498         coefs[1] = gf4096_mul((gf4096_mul(coefs[0], m[0][0]) ^ m[0][2]), gf4096_inv(m[0][1]));
499 }
500
501 static unsigned char gf64_inv[64] = {
502          0,  1, 33, 62, 49, 43, 31, 44, 57, 37, 52, 28, 46, 40, 22, 25, 
503         61, 54, 51, 39, 26, 35, 14, 24, 23, 15, 20, 34, 11, 53, 45,  6, 
504         63,  2, 27, 21, 56,  9, 50, 19, 13, 47, 48,  5,  7, 30, 12, 41, 
505         42,  4, 38, 18, 10, 29, 17, 60, 36,  8, 59, 58, 55, 16,  3, 32
506 };
507
508 static unsigned short gf4096_inv(unsigned short din)
509 {
510         unsigned short alahxal, ah2B, deno, inv, bl, bh;
511         unsigned short ah, al, ahxal;
512         unsigned short dout;
513
514         ah = (din >> 6) & 0x3f;
515         al = din & 0x3f;
516         ahxal = ah ^ al;
517         ah2B = (((ah ^ (ah >> 3)) & 0x1) << 5) |
518                 ((ah >> 1) & 0x10) |
519                 ((((ah >> 5) ^ (ah >> 2)) & 0x1) << 3) |
520                 ((ah >> 2) & 0x4) | ((((ah >> 4) ^ (ah >> 1)) & 0x1) << 1) | (ah & 0x1);
521         alahxal = gf64_mul(ahxal, al);
522         deno = alahxal ^ ah2B;
523         inv = gf64_inv[deno];
524         bl = gf64_mul(inv, ahxal);
525         bh = gf64_mul(inv, ah);
526         dout = ((bh & 0x3f) << 6) | (bl & 0x3f);
527         return (((bh & 0x3f) << 6) | (bl & 0x3f));
528 }
529
530 static unsigned short err_pos_lut[4096] = {
531         0xfff, 0x000, 0x451, 0xfff, 0xfff, 0x3cf, 0xfff, 0x041, 
532         0xfff, 0xfff, 0xfff, 0xfff, 0x28a, 0xfff, 0x492, 0xfff, 
533         0x145, 0xfff, 0xfff, 0x514, 0xfff, 0x082, 0xfff, 0xfff, 
534         0xfff, 0x249, 0x38e, 0x410, 0xfff, 0x104, 0x208, 0x1c7, 
535         0xfff, 0xfff, 0xfff, 0xfff, 0x2cb, 0xfff, 0xfff, 0xfff, 
536         0x0c3, 0x34d, 0x4d3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
537         0xfff, 0xfff, 0xfff, 0x186, 0xfff, 0xfff, 0xfff, 0xfff, 
538         0xfff, 0x30c, 0x555, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
539         0xfff, 0xfff, 0xfff, 0x166, 0xfff, 0xfff, 0xfff, 0xfff, 
540         0x385, 0x14e, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e1, 
541         0xfff, 0xfff, 0xfff, 0xfff, 0x538, 0xfff, 0x16d, 0xfff, 
542         0xfff, 0xfff, 0x45b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
543         0xfff, 0xfff, 0xfff, 0x29c, 0x2cc, 0x30b, 0x2b3, 0xfff, 
544         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0b3, 0xfff, 0x2f7, 
545         0xfff, 0x32b, 0xfff, 0xfff, 0xfff, 0xfff, 0x0a7, 0xfff, 
546         0xfff, 0x2da, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
547         0xfff, 0x07e, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
548         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x11c, 0xfff, 0xfff, 
549         0xfff, 0xfff, 0xfff, 0x22f, 0xfff, 0x1f4, 0xfff, 0xfff, 
550         0x2b0, 0x504, 0xfff, 0x114, 0xfff, 0xfff, 0xfff, 0x21d, 
551         0xfff, 0xfff, 0xfff, 0xfff, 0x00d, 0x3c4, 0x340, 0x10f, 
552         0xfff, 0xfff, 0x266, 0x02e, 0xfff, 0xfff, 0xfff, 0x4f8, 
553         0x337, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
554         0xfff, 0xfff, 0xfff, 0x07b, 0x168, 0xfff, 0xfff, 0x0fe, 
555         0xfff, 0xfff, 0x51a, 0xfff, 0x458, 0xfff, 0x36d, 0xfff, 
556         0xfff, 0xfff, 0xfff, 0x073, 0x37d, 0x415, 0x550, 0xfff, 
557         0xfff, 0xfff, 0x23b, 0x4b4, 0xfff, 0xfff, 0xfff, 0x1a1, 
558         0xfff, 0xfff, 0x3aa, 0xfff, 0x117, 0x04d, 0x341, 0xfff, 
559         0xfff, 0xfff, 0xfff, 0x518, 0x03e, 0x0f2, 0xfff, 0xfff, 
560         0xfff, 0xfff, 0xfff, 0x363, 0xfff, 0x0b9, 0xfff, 0xfff, 
561         0x241, 0xfff, 0xfff, 0x049, 0xfff, 0xfff, 0xfff, 0xfff, 
562         0x15f, 0x52d, 0xfff, 0xfff, 0xfff, 0x29e, 0xfff, 0xfff, 
563         0xfff, 0xfff, 0x4cf, 0x0fc, 0xfff, 0x36f, 0x3d3, 0xfff, 
564         0x228, 0xfff, 0xfff, 0x45e, 0xfff, 0xfff, 0xfff, 0xfff, 
565         0x238, 0xfff, 0xfff, 0xfff, 0xfff, 0x47f, 0xfff, 0xfff, 
566         0x43a, 0x265, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3e8, 
567         0xfff, 0xfff, 0x01a, 0xfff, 0xfff, 0xfff, 0xfff, 0x21e, 
568         0x1fc, 0x40b, 0xfff, 0xfff, 0xfff, 0x2d0, 0x159, 0xfff, 
569         0xfff, 0x313, 0xfff, 0xfff, 0x05c, 0x4cc, 0xfff, 0xfff, 
570         0x0f6, 0x3d5, 0xfff, 0xfff, 0xfff, 0x54f, 0xfff, 0xfff, 
571         0xfff, 0x172, 0x1e4, 0x07c, 0xfff, 0xfff, 0xfff, 0xfff, 
572         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x53c, 0x1ad, 0x535, 
573         0x19b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
574         0xfff, 0xfff, 0x092, 0xfff, 0x2be, 0xfff, 0xfff, 0x482, 
575         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0e6, 0xfff, 0xfff, 
576         0xfff, 0xfff, 0xfff, 0x476, 0xfff, 0x51d, 0xfff, 0xfff, 
577         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
578         0xfff, 0xfff, 0x342, 0x2b5, 0x22e, 0x09a, 0xfff, 0x08d, 
579         0x44f, 0x3ed, 0xfff, 0xfff, 0xfff, 0xfff, 0x3d1, 0xfff, 
580         0xfff, 0x543, 0xfff, 0x48f, 0xfff, 0x3d2, 0xfff, 0x0d5, 
581         0x113, 0x0ec, 0x427, 0xfff, 0xfff, 0xfff, 0x4c4, 0xfff, 
582         0xfff, 0x50a, 0xfff, 0x144, 0xfff, 0x105, 0x39f, 0x294, 
583         0x164, 0xfff, 0x31a, 0xfff, 0xfff, 0x49a, 0xfff, 0x130, 
584         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
585         0x1be, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
586         0xfff, 0xfff, 0x49e, 0x371, 0xfff, 0xfff, 0xfff, 0xfff, 
587         0xfff, 0xfff, 0xfff, 0xfff, 0x0e8, 0x49c, 0x0f4, 0xfff, 
588         0x338, 0x1a7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
589         0xfff, 0x36c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
590         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
591         0xfff, 0x1ae, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
592         0xfff, 0x31b, 0xfff, 0xfff, 0x2dd, 0x522, 0xfff, 0xfff, 
593         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2f4, 
594         0x3c6, 0x30d, 0xfff, 0xfff, 0xfff, 0xfff, 0x34c, 0x18f, 
595         0x30a, 0xfff, 0x01f, 0x079, 0xfff, 0xfff, 0x54d, 0x46b, 
596         0x28c, 0x37f, 0xfff, 0xfff, 0xfff, 0xfff, 0x355, 0xfff, 
597         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x14f, 0xfff, 0xfff, 
598         0xfff, 0xfff, 0xfff, 0x359, 0x3fe, 0x3c5, 0xfff, 0xfff, 
599         0xfff, 0xfff, 0x423, 0xfff, 0xfff, 0x34a, 0x22c, 0xfff, 
600         0x25a, 0xfff, 0xfff, 0x4ad, 0xfff, 0x28d, 0xfff, 0xfff, 
601         0xfff, 0xfff, 0xfff, 0x547, 0xfff, 0xfff, 0xfff, 0xfff, 
602         0x2e2, 0xfff, 0xfff, 0x1d5, 0xfff, 0x2a8, 0xfff, 0xfff, 
603         0x03f, 0xfff, 0xfff, 0xfff, 0xfff, 0x3eb, 0x0fa, 0xfff, 
604         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x55b, 0xfff, 
605         0x08e, 0xfff, 0x3ae, 0xfff, 0x3a4, 0xfff, 0x282, 0x158, 
606         0xfff, 0x382, 0xfff, 0xfff, 0x499, 0xfff, 0xfff, 0x08a, 
607         0xfff, 0xfff, 0xfff, 0x456, 0x3be, 0xfff, 0x1e2, 0xfff, 
608         0xfff, 0xfff, 0xfff, 0xfff, 0x559, 0xfff, 0x1a0, 0xfff, 
609         0xfff, 0x0b4, 0xfff, 0xfff, 0xfff, 0x2df, 0xfff, 0xfff, 
610         0xfff, 0x07f, 0x4f5, 0xfff, 0xfff, 0x27c, 0x133, 0x017, 
611         0xfff, 0x3fd, 0xfff, 0xfff, 0xfff, 0x44d, 0x4cd, 0x17a, 
612         0x0d7, 0x537, 0xfff, 0xfff, 0x353, 0xfff, 0xfff, 0x351, 
613         0x366, 0xfff, 0x44a, 0xfff, 0x1a6, 0xfff, 0xfff, 0xfff, 
614         0x291, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1e3, 
615         0xfff, 0xfff, 0xfff, 0xfff, 0x389, 0xfff, 0x07a, 0xfff, 
616         0x1b6, 0x2ed, 0xfff, 0xfff, 0xfff, 0xfff, 0x24e, 0x074, 
617         0xfff, 0xfff, 0x3dc, 0xfff, 0x4e3, 0xfff, 0xfff, 0xfff, 
618         0xfff, 0x4eb, 0xfff, 0xfff, 0x3b8, 0x4de, 0xfff, 0x19c, 
619         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x262, 
620         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x076, 0x4e8, 0x3da, 
621         0xfff, 0x531, 0xfff, 0xfff, 0x14a, 0xfff, 0x0a2, 0x433, 
622         0x3df, 0x1e9, 0xfff, 0xfff, 0xfff, 0xfff, 0x3e7, 0x285, 
623         0x2d8, 0xfff, 0xfff, 0xfff, 0x349, 0x18d, 0x098, 0xfff, 
624         0x0df, 0x4bf, 0xfff, 0xfff, 0x0b2, 0xfff, 0x346, 0x24d, 
625         0xfff, 0xfff, 0xfff, 0x24f, 0x4fa, 0x2f9, 0xfff, 0xfff, 
626         0x3c9, 0xfff, 0x2b4, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
627         0xfff, 0x056, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
628         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
629         0xfff, 0x179, 0xfff, 0x0e9, 0x3f0, 0x33d, 0xfff, 0xfff, 
630         0xfff, 0xfff, 0xfff, 0x1fd, 0xfff, 0xfff, 0x526, 0xfff, 
631         0xfff, 0xfff, 0x53d, 0xfff, 0xfff, 0xfff, 0x170, 0x331, 
632         0xfff, 0x068, 0xfff, 0xfff, 0xfff, 0x3f7, 0xfff, 0x3d8, 
633         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
634         0xfff, 0x09f, 0x556, 0xfff, 0xfff, 0x02d, 0xfff, 0xfff, 
635         0x553, 0xfff, 0xfff, 0xfff, 0x1f0, 0xfff, 0xfff, 0x4d6, 
636         0x41e, 0xfff, 0xfff, 0xfff, 0xfff, 0x4d5, 0xfff, 0xfff, 
637         0xfff, 0xfff, 0xfff, 0x248, 0xfff, 0xfff, 0xfff, 0x0a3, 
638         0xfff, 0x217, 0xfff, 0xfff, 0xfff, 0x4f1, 0x209, 0xfff, 
639         0xfff, 0x475, 0x234, 0x52b, 0x398, 0xfff, 0x08b, 0xfff, 
640         0xfff, 0xfff, 0xfff, 0x2c2, 0xfff, 0xfff, 0xfff, 0xfff, 
641         0xfff, 0xfff, 0x268, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
642         0xfff, 0x4a3, 0xfff, 0x0aa, 0xfff, 0x1d9, 0xfff, 0xfff, 
643         0xfff, 0xfff, 0x155, 0xfff, 0xfff, 0xfff, 0xfff, 0x0bf, 
644         0x539, 0xfff, 0xfff, 0x2f1, 0x545, 0xfff, 0xfff, 0xfff, 
645         0xfff, 0xfff, 0xfff, 0x2a7, 0x06f, 0xfff, 0x378, 0xfff, 
646         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x25e, 0xfff, 
647         0xfff, 0xfff, 0xfff, 0x15d, 0x02a, 0xfff, 0xfff, 0x0bc, 
648         0x235, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
649         0x150, 0xfff, 0x1a9, 0xfff, 0xfff, 0xfff, 0xfff, 0x381, 
650         0xfff, 0x04e, 0x270, 0x13f, 0xfff, 0xfff, 0x405, 0xfff, 
651         0x3cd, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
652         0xfff, 0x2ef, 0xfff, 0x06a, 0xfff, 0xfff, 0xfff, 0x34f, 
653         0x212, 0xfff, 0xfff, 0x0e2, 0xfff, 0x083, 0x298, 0xfff, 
654         0xfff, 0xfff, 0x0c2, 0xfff, 0xfff, 0x52e, 0xfff, 0x488, 
655         0xfff, 0xfff, 0xfff, 0x36b, 0xfff, 0xfff, 0xfff, 0x442, 
656         0x091, 0xfff, 0x41c, 0xfff, 0xfff, 0x3a5, 0xfff, 0x4e6, 
657         0xfff, 0xfff, 0x40d, 0x31d, 0xfff, 0xfff, 0xfff, 0x4c1, 
658         0x053, 0xfff, 0x418, 0x13c, 0xfff, 0x350, 0xfff, 0x0ae, 
659         0xfff, 0xfff, 0x41f, 0xfff, 0x470, 0xfff, 0x4ca, 0xfff, 
660         0xfff, 0xfff, 0x02b, 0x450, 0xfff, 0x1f8, 0xfff, 0xfff, 
661         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x293, 0xfff, 
662         0xfff, 0xfff, 0xfff, 0x411, 0xfff, 0xfff, 0xfff, 0xfff, 
663         0xfff, 0xfff, 0xfff, 0xfff, 0x0b8, 0xfff, 0xfff, 0xfff, 
664         0x3e1, 0xfff, 0xfff, 0xfff, 0xfff, 0x43c, 0xfff, 0x2b2, 
665         0x2ab, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ec, 
666         0xfff, 0xfff, 0xfff, 0x3f8, 0x034, 0xfff, 0xfff, 0xfff, 
667         0xfff, 0xfff, 0xfff, 0x11a, 0xfff, 0x541, 0x45c, 0x134, 
668         0x1cc, 0xfff, 0xfff, 0xfff, 0x469, 0xfff, 0xfff, 0x44b, 
669         0x161, 0xfff, 0xfff, 0xfff, 0x055, 0xfff, 0xfff, 0xfff, 
670         0xfff, 0x307, 0xfff, 0xfff, 0xfff, 0xfff, 0x2d1, 0xfff, 
671         0xfff, 0xfff, 0x124, 0x37b, 0x26b, 0x336, 0xfff, 0xfff, 
672         0x2e4, 0x3cb, 0xfff, 0xfff, 0x0f8, 0x3c8, 0xfff, 0xfff, 
673         0xfff, 0x461, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4b5, 
674         0x2cf, 0xfff, 0xfff, 0xfff, 0x20f, 0xfff, 0x35a, 0xfff, 
675         0x490, 0xfff, 0x185, 0xfff, 0xfff, 0xfff, 0xfff, 0x42e, 
676         0xfff, 0xfff, 0xfff, 0xfff, 0x54b, 0xfff, 0xfff, 0xfff, 
677         0x146, 0xfff, 0x412, 0xfff, 0xfff, 0xfff, 0x1ff, 0xfff, 
678         0xfff, 0x3e0, 0xfff, 0xfff, 0xfff, 0xfff, 0x2d5, 0xfff, 
679         0x4df, 0x505, 0xfff, 0x413, 0xfff, 0x1a5, 0xfff, 0x3b2, 
680         0xfff, 0xfff, 0xfff, 0x35b, 0xfff, 0x116, 0xfff, 0xfff, 
681         0x171, 0x4d0, 0xfff, 0x154, 0x12d, 0xfff, 0xfff, 0xfff, 
682         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x468, 0x4db, 0xfff, 
683         0xfff, 0x1df, 0xfff, 0xfff, 0xfff, 0xfff, 0x05a, 0xfff, 
684         0x0f1, 0x403, 0xfff, 0x22b, 0x2e0, 0xfff, 0xfff, 0xfff, 
685         0x2b7, 0x373, 0xfff, 0xfff, 0xfff, 0xfff, 0x13e, 0xfff, 
686         0xfff, 0xfff, 0x0d0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
687         0x329, 0x1d2, 0x3fa, 0x047, 0xfff, 0x2f2, 0xfff, 0xfff, 
688         0x141, 0x0ac, 0x1d7, 0xfff, 0x07d, 0xfff, 0xfff, 0xfff, 
689         0x1c1, 0xfff, 0x487, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
690         0xfff, 0xfff, 0xfff, 0x045, 0xfff, 0xfff, 0xfff, 0xfff, 
691         0x288, 0x0cd, 0xfff, 0xfff, 0xfff, 0xfff, 0x226, 0x1d8, 
692         0xfff, 0x153, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4cb, 
693         0x528, 0xfff, 0xfff, 0xfff, 0x20a, 0x343, 0x3a1, 0xfff, 
694         0xfff, 0xfff, 0x2d7, 0x2d3, 0x1aa, 0x4c5, 0xfff, 0xfff, 
695         0xfff, 0x42b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
696         0xfff, 0xfff, 0xfff, 0xfff, 0x3e9, 0xfff, 0x20b, 0x260, 
697         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x37c, 0x2fd, 
698         0xfff, 0xfff, 0x2c8, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
699         0xfff, 0x31e, 0xfff, 0x335, 0xfff, 0xfff, 0xfff, 0xfff, 
700         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
701         0xfff, 0xfff, 0x135, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
702         0xfff, 0xfff, 0x35c, 0x4dd, 0x129, 0xfff, 0xfff, 0xfff, 
703         0xfff, 0xfff, 0x1ef, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
704         0xfff, 0x34e, 0xfff, 0xfff, 0xfff, 0xfff, 0x407, 0xfff, 
705         0xfff, 0xfff, 0xfff, 0xfff, 0x3ad, 0xfff, 0xfff, 0xfff, 
706         0x379, 0xfff, 0xfff, 0x1d0, 0x38d, 0xfff, 0xfff, 0x1e8, 
707         0x184, 0x3c1, 0x1c4, 0xfff, 0x1f9, 0xfff, 0xfff, 0x424, 
708         0xfff, 0xfff, 0xfff, 0xfff, 0x1d3, 0x0d4, 0xfff, 0x4e9, 
709         0xfff, 0xfff, 0xfff, 0x530, 0x107, 0xfff, 0x106, 0x04f, 
710         0xfff, 0xfff, 0x4c7, 0x503, 0xfff, 0xfff, 0xfff, 0xfff, 
711         0xfff, 0x15c, 0xfff, 0x23f, 0xfff, 0xfff, 0xfff, 0xfff, 
712         0xfff, 0xfff, 0xfff, 0xfff, 0x4f3, 0xfff, 0xfff, 0x3c7, 
713         0xfff, 0x278, 0xfff, 0xfff, 0x0a6, 0xfff, 0xfff, 0xfff, 
714         0x122, 0x1cf, 0xfff, 0x327, 0xfff, 0x2e5, 0xfff, 0x29d, 
715         0xfff, 0xfff, 0x3f1, 0xfff, 0xfff, 0x48d, 0xfff, 0xfff, 
716         0xfff, 0xfff, 0x054, 0xfff, 0xfff, 0xfff, 0xfff, 0x178, 
717         0x27e, 0x4e0, 0x352, 0x02f, 0x09c, 0xfff, 0x2a0, 0xfff, 
718         0xfff, 0x46a, 0x457, 0xfff, 0xfff, 0x501, 0xfff, 0x2ba, 
719         0xfff, 0xfff, 0xfff, 0x54e, 0x2e7, 0xfff, 0xfff, 0xfff, 
720         0xfff, 0xfff, 0x551, 0xfff, 0xfff, 0x1db, 0x2aa, 0xfff, 
721         0xfff, 0x4bc, 0xfff, 0xfff, 0x395, 0xfff, 0x0de, 0xfff, 
722         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x455, 0xfff, 0x17e, 
723         0xfff, 0x221, 0x4a7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
724         0x388, 0xfff, 0xfff, 0xfff, 0x308, 0xfff, 0xfff, 0xfff, 
725         0x20e, 0x4b9, 0xfff, 0x273, 0x20c, 0x09e, 0xfff, 0x057, 
726         0xfff, 0xfff, 0xfff, 0xfff, 0x3f2, 0xfff, 0x1a8, 0x3a6, 
727         0x14c, 0xfff, 0xfff, 0x071, 0xfff, 0xfff, 0x53a, 0xfff, 
728         0xfff, 0xfff, 0xfff, 0x109, 0xfff, 0xfff, 0x399, 0xfff, 
729         0x061, 0x4f0, 0x39e, 0x244, 0xfff, 0x035, 0xfff, 0xfff, 
730         0x305, 0x47e, 0x297, 0xfff, 0xfff, 0x2b8, 0xfff, 0xfff, 
731         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1bc, 0xfff, 0x2fc, 
732         0xfff, 0xfff, 0x554, 0xfff, 0xfff, 0xfff, 0xfff, 0x3b6, 
733         0xfff, 0xfff, 0xfff, 0x515, 0x397, 0xfff, 0xfff, 0x12f, 
734         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e5, 
735         0xfff, 0x4fc, 0xfff, 0xfff, 0x05e, 0xfff, 0xfff, 0xfff, 
736         0xfff, 0xfff, 0x0a8, 0x3af, 0x015, 0xfff, 0xfff, 0xfff, 
737         0xfff, 0x138, 0xfff, 0xfff, 0xfff, 0x540, 0xfff, 0xfff, 
738         0xfff, 0x027, 0x523, 0x2f0, 0xfff, 0xfff, 0xfff, 0xfff, 
739         0xfff, 0xfff, 0x16c, 0xfff, 0x27d, 0xfff, 0xfff, 0xfff, 
740         0xfff, 0x04c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4dc, 
741         0xfff, 0xfff, 0x059, 0x301, 0xfff, 0xfff, 0xfff, 0xfff, 
742         0xfff, 0xfff, 0xfff, 0x1a3, 0xfff, 0x15a, 0xfff, 0xfff, 
743         0x0a5, 0xfff, 0x435, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
744         0xfff, 0x051, 0xfff, 0xfff, 0x131, 0xfff, 0x4f4, 0xfff, 
745         0xfff, 0xfff, 0xfff, 0x441, 0xfff, 0x4fb, 0xfff, 0x03b, 
746         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ed, 0x274, 
747         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d3, 0x55e, 0x1b3, 
748         0xfff, 0x0bd, 0xfff, 0xfff, 0xfff, 0xfff, 0x225, 0xfff, 
749         0xfff, 0xfff, 0xfff, 0xfff, 0x4b7, 0xfff, 0xfff, 0x2ff, 
750         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4c3, 0xfff, 
751         0x383, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2f6, 
752         0xfff, 0xfff, 0x1ee, 0xfff, 0x03d, 0xfff, 0xfff, 0xfff, 
753         0xfff, 0xfff, 0x26f, 0x1dc, 0xfff, 0x0db, 0xfff, 0xfff, 
754         0xfff, 0xfff, 0xfff, 0x0ce, 0xfff, 0xfff, 0x127, 0x03a, 
755         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x311, 0xfff, 
756         0xfff, 0x13d, 0x09d, 0x47b, 0x2a6, 0x50d, 0x510, 0x19a, 
757         0xfff, 0x354, 0x414, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
758         0xfff, 0xfff, 0x44c, 0x3b0, 0xfff, 0x23d, 0x429, 0xfff, 
759         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
760         0x4c0, 0x416, 0xfff, 0x05b, 0xfff, 0xfff, 0x137, 0xfff, 
761         0x25f, 0x49f, 0xfff, 0x279, 0x013, 0xfff, 0xfff, 0xfff, 
762         0x269, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
763         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3d0, 0xfff, 0xfff, 
764         0xfff, 0xfff, 0xfff, 0xfff, 0x077, 0xfff, 0xfff, 0x3fb, 
765         0xfff, 0xfff, 0xfff, 0xfff, 0x271, 0x3a0, 0xfff, 0xfff, 
766         0x40f, 0xfff, 0xfff, 0x3de, 0xfff, 0xfff, 0xfff, 0xfff, 
767         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ab, 0x26a, 
768         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x489, 0xfff, 0xfff, 
769         0x252, 0xfff, 0xfff, 0xfff, 0xfff, 0x1b7, 0x42f, 0xfff, 
770         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3b7, 
771         0xfff, 0x2bb, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
772         0xfff, 0xfff, 0xfff, 0x0f7, 0x01d, 0xfff, 0x067, 0xfff, 
773         0xfff, 0xfff, 0xfff, 0x4e2, 0xfff, 0xfff, 0x4bb, 0xfff, 
774         0xfff, 0xfff, 0x17b, 0xfff, 0x0ee, 0xfff, 0xfff, 0xfff, 
775         0xfff, 0xfff, 0x36e, 0xfff, 0xfff, 0xfff, 0x533, 0xfff, 
776         0xfff, 0xfff, 0x4d4, 0x356, 0xfff, 0xfff, 0x375, 0xfff, 
777         0xfff, 0xfff, 0xfff, 0x4a4, 0x513, 0xfff, 0xfff, 0xfff, 
778         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4ff, 0xfff, 0x2af, 
779         0xfff, 0xfff, 0x026, 0xfff, 0x0ad, 0xfff, 0xfff, 0xfff, 
780         0xfff, 0x26e, 0xfff, 0xfff, 0xfff, 0xfff, 0x493, 0xfff, 
781         0x463, 0x4d2, 0x4be, 0xfff, 0xfff, 0xfff, 0xfff, 0x4f2, 
782         0x0b6, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
783         0xfff, 0x32d, 0x315, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
784         0xfff, 0x13a, 0x4a1, 0xfff, 0x27a, 0xfff, 0xfff, 0xfff, 
785         0x47a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
786         0x334, 0xfff, 0xfff, 0xfff, 0xfff, 0x54c, 0xfff, 0xfff, 
787         0xfff, 0x0c9, 0x007, 0xfff, 0xfff, 0x12e, 0xfff, 0x0ff, 
788         0xfff, 0xfff, 0x3f5, 0x509, 0xfff, 0xfff, 0xfff, 0xfff, 
789         0x1c3, 0x2ad, 0xfff, 0xfff, 0x47c, 0x261, 0xfff, 0xfff, 
790         0xfff, 0xfff, 0xfff, 0x152, 0xfff, 0xfff, 0xfff, 0x339, 
791         0xfff, 0x243, 0x1c0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
792         0x063, 0xfff, 0xfff, 0x254, 0xfff, 0xfff, 0x173, 0xfff, 
793         0x0c7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
794         0xfff, 0x362, 0x259, 0x485, 0x374, 0x0dc, 0x3ab, 0xfff, 
795         0x1c5, 0x534, 0x544, 0xfff, 0xfff, 0x508, 0xfff, 0x402, 
796         0x408, 0xfff, 0x0e7, 0xfff, 0xfff, 0x00a, 0x205, 0xfff, 
797         0xfff, 0x2b9, 0xfff, 0xfff, 0xfff, 0x465, 0xfff, 0xfff, 
798         0xfff, 0xfff, 0xfff, 0xfff, 0x23a, 0xfff, 0xfff, 0xfff, 
799         0xfff, 0x147, 0x19d, 0x115, 0x214, 0xfff, 0x090, 0x368, 
800         0xfff, 0x210, 0xfff, 0xfff, 0x280, 0x52a, 0x163, 0x148, 
801         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x326, 0xfff, 0xfff, 
802         0xfff, 0xfff, 0xfff, 0x2de, 0xfff, 0xfff, 0xfff, 0xfff, 
803         0x206, 0x2c1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
804         0x189, 0xfff, 0xfff, 0xfff, 0xfff, 0x367, 0xfff, 0x1a4, 
805         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x443, 0xfff, 0x27b, 
806         0xfff, 0xfff, 0x251, 0x549, 0xfff, 0xfff, 0xfff, 0xfff, 
807         0xfff, 0xfff, 0x188, 0x04b, 0xfff, 0xfff, 0xfff, 0x31f, 
808         0x4a6, 0xfff, 0x246, 0x1de, 0x156, 0xfff, 0xfff, 0xfff, 
809         0x3a9, 0xfff, 0xfff, 0xfff, 0x2fa, 0xfff, 0x128, 0x0d1, 
810         0x449, 0x255, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
811         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
812         0xfff, 0xfff, 0xfff, 0xfff, 0x258, 0xfff, 0xfff, 0xfff, 
813         0x532, 0xfff, 0xfff, 0xfff, 0x303, 0x517, 0xfff, 0xfff, 
814         0x2a9, 0x24a, 0xfff, 0xfff, 0x231, 0xfff, 0xfff, 0xfff, 
815         0xfff, 0xfff, 0x4b6, 0x516, 0xfff, 0xfff, 0x0e4, 0x0eb, 
816         0xfff, 0x4e4, 0xfff, 0x275, 0xfff, 0xfff, 0x031, 0xfff, 
817         0xfff, 0xfff, 0xfff, 0xfff, 0x025, 0x21a, 0xfff, 0x0cc, 
818         0x45f, 0x3d9, 0x289, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
819         0xfff, 0xfff, 0x23e, 0xfff, 0xfff, 0xfff, 0x438, 0x097, 
820         0x419, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
821         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
822         0xfff, 0xfff, 0x0a9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
823         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
824         0x37e, 0x0e0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x431, 
825         0x372, 0xfff, 0xfff, 0xfff, 0x1ba, 0x06e, 0xfff, 0x1b1, 
826         0xfff, 0xfff, 0x12a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
827         0xfff, 0xfff, 0x193, 0xfff, 0xfff, 0xfff, 0xfff, 0x10a, 
828         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x048, 0x1b4, 
829         0xfff, 0xfff, 0xfff, 0xfff, 0x295, 0x140, 0x108, 0xfff, 
830         0xfff, 0xfff, 0xfff, 0x16f, 0xfff, 0x0a4, 0x37a, 0xfff, 
831         0x29a, 0xfff, 0x284, 0xfff, 0xfff, 0xfff, 0xfff, 0x4c6, 
832         0x2a2, 0x3a3, 0xfff, 0x201, 0xfff, 0xfff, 0xfff, 0x4bd, 
833         0x005, 0x54a, 0x3b5, 0x204, 0x2ee, 0x11d, 0x436, 0xfff, 
834         0xfff, 0xfff, 0xfff, 0xfff, 0x3ec, 0xfff, 0xfff, 0xfff, 
835         0xfff, 0xfff, 0xfff, 0xfff, 0x11f, 0x498, 0x21c, 0xfff, 
836         0xfff, 0xfff, 0x3d6, 0xfff, 0x4ab, 0xfff, 0x432, 0x2eb, 
837         0x542, 0x4fd, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
838         0xfff, 0xfff, 0xfff, 0x4ce, 0xfff, 0xfff, 0x2fb, 0xfff, 
839         0xfff, 0x2e1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
840         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1b9, 0x037, 0x0dd, 
841         0xfff, 0xfff, 0xfff, 0x2bf, 0x521, 0x496, 0x095, 0xfff, 
842         0xfff, 0x328, 0x070, 0x1bf, 0xfff, 0x393, 0xfff, 0xfff, 
843         0x102, 0xfff, 0xfff, 0x21b, 0xfff, 0x142, 0x263, 0x519, 
844         0xfff, 0x2a5, 0x177, 0xfff, 0x14d, 0x471, 0x4ae, 0xfff, 
845         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
846         0x1f6, 0xfff, 0x481, 0xfff, 0xfff, 0xfff, 0x151, 0xfff, 
847         0xfff, 0xfff, 0x085, 0x33f, 0xfff, 0xfff, 0xfff, 0x084, 
848         0xfff, 0xfff, 0xfff, 0x345, 0x3a2, 0xfff, 0xfff, 0x0a0, 
849         0x0da, 0x024, 0xfff, 0xfff, 0xfff, 0x1bd, 0xfff, 0x55c, 
850         0x467, 0x445, 0xfff, 0xfff, 0xfff, 0x052, 0xfff, 0xfff, 
851         0xfff, 0xfff, 0x51e, 0xfff, 0xfff, 0x39d, 0xfff, 0x35f, 
852         0xfff, 0x376, 0x3ee, 0xfff, 0xfff, 0xfff, 0xfff, 0x448, 
853         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x16a, 
854         0xfff, 0x036, 0x38f, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
855         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x211, 
856         0xfff, 0xfff, 0xfff, 0x230, 0xfff, 0xfff, 0x3ba, 0xfff, 
857         0xfff, 0xfff, 0x3ce, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
858         0xfff, 0xfff, 0xfff, 0x229, 0xfff, 0x176, 0xfff, 0xfff, 
859         0xfff, 0xfff, 0xfff, 0x00b, 0xfff, 0x162, 0x018, 0xfff, 
860         0xfff, 0x233, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
861         0x400, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
862         0xfff, 0xfff, 0xfff, 0x12b, 0xfff, 0xfff, 0xfff, 0xfff, 
863         0xfff, 0x3f4, 0xfff, 0x0f0, 0xfff, 0x1ac, 0xfff, 0xfff, 
864         0x119, 0xfff, 0x2c0, 0xfff, 0xfff, 0xfff, 0x49b, 0xfff, 
865         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x23c, 0xfff, 
866         0x4b3, 0x010, 0x064, 0xfff, 0xfff, 0x4ba, 0xfff, 0xfff, 
867         0xfff, 0xfff, 0xfff, 0x3c2, 0xfff, 0xfff, 0xfff, 0xfff, 
868         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x006, 0x196, 0xfff, 
869         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x100, 0x191, 0xfff, 
870         0x1ea, 0x29f, 0xfff, 0xfff, 0xfff, 0x276, 0xfff, 0xfff, 
871         0x2b1, 0x3b9, 0xfff, 0x03c, 0xfff, 0xfff, 0xfff, 0x180, 
872         0xfff, 0x08f, 0xfff, 0xfff, 0x19e, 0x019, 0xfff, 0x0b0, 
873         0x0fd, 0x332, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
874         0xfff, 0x06b, 0x2e8, 0xfff, 0x446, 0xfff, 0xfff, 0x004, 
875         0x247, 0x197, 0xfff, 0x112, 0x169, 0x292, 0xfff, 0x302, 
876         0xfff, 0xfff, 0x33b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
877         0xfff, 0xfff, 0xfff, 0x287, 0x21f, 0xfff, 0x3ea, 0xfff, 
878         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e7, 0xfff, 0xfff, 
879         0xfff, 0xfff, 0xfff, 0x3a8, 0xfff, 0xfff, 0x2bc, 0xfff, 
880         0x484, 0x296, 0xfff, 0x1c9, 0x08c, 0x1e5, 0x48a, 0xfff, 
881         0x360, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
882         0x1ca, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
883         0xfff, 0xfff, 0xfff, 0x10d, 0xfff, 0xfff, 0xfff, 0xfff, 
884         0xfff, 0xfff, 0x066, 0x2ea, 0x28b, 0x25b, 0xfff, 0x072, 
885         0xfff, 0xfff, 0xfff, 0xfff, 0x2b6, 0xfff, 0xfff, 0x272, 
886         0xfff, 0xfff, 0x525, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
887         0x2ca, 0xfff, 0xfff, 0xfff, 0x299, 0xfff, 0xfff, 0xfff, 
888         0x558, 0x41a, 0xfff, 0x4f7, 0x557, 0xfff, 0x4a0, 0x344, 
889         0x12c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x125, 
890         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
891         0x40e, 0xfff, 0xfff, 0x502, 0xfff, 0x103, 0x3e6, 0xfff, 
892         0x527, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
893         0xfff, 0xfff, 0xfff, 0x45d, 0xfff, 0xfff, 0xfff, 0xfff, 
894         0x44e, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d2, 0x4c9, 0x35e, 
895         0x459, 0x2d9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x17d, 
896         0x0c4, 0xfff, 0xfff, 0xfff, 0x3ac, 0x390, 0x094, 0xfff, 
897         0x483, 0x0ab, 0xfff, 0x253, 0xfff, 0x391, 0xfff, 0xfff, 
898         0xfff, 0xfff, 0x123, 0x0ef, 0xfff, 0xfff, 0xfff, 0x330, 
899         0x38c, 0xfff, 0xfff, 0x2ae, 0xfff, 0xfff, 0xfff, 0x042, 
900         0x012, 0x06d, 0xfff, 0xfff, 0xfff, 0x32a, 0x3db, 0x364, 
901         0x2dc, 0xfff, 0x30f, 0x3d7, 0x4a5, 0x050, 0xfff, 0xfff, 
902         0x029, 0xfff, 0xfff, 0xfff, 0xfff, 0x1d1, 0xfff, 0xfff, 
903         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x480, 0xfff, 
904         0x4ed, 0x081, 0x0a1, 0xfff, 0xfff, 0xfff, 0x30e, 0x52f, 
905         0x257, 0xfff, 0xfff, 0x447, 0xfff, 0xfff, 0xfff, 0xfff, 
906         0xfff, 0xfff, 0xfff, 0x401, 0x3cc, 0xfff, 0xfff, 0x0fb, 
907         0x2c9, 0x42a, 0x314, 0x33e, 0x3bd, 0x318, 0xfff, 0x10e, 
908         0x2a1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x24c, 
909         0x506, 0xfff, 0x267, 0xfff, 0xfff, 0x219, 0xfff, 0x1eb, 
910         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
911         0x309, 0x3e2, 0x46c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
912         0x384, 0xfff, 0xfff, 0xfff, 0xfff, 0x50c, 0xfff, 0x24b, 
913         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x038, 
914         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x194, 
915         0x143, 0x3e3, 0xfff, 0xfff, 0xfff, 0x4c2, 0xfff, 0xfff, 
916         0x0e1, 0x25c, 0xfff, 0x237, 0xfff, 0x1fe, 0xfff, 0xfff, 
917         0xfff, 0x065, 0x2a4, 0xfff, 0x386, 0x55a, 0x11b, 0xfff, 
918         0xfff, 0x192, 0xfff, 0x183, 0x00e, 0xfff, 0xfff, 0xfff, 
919         0xfff, 0xfff, 0xfff, 0x4b2, 0x18e, 0xfff, 0xfff, 0xfff, 
920         0xfff, 0x486, 0x4ef, 0x0c6, 0x380, 0xfff, 0x4a8, 0xfff, 
921         0x0c5, 0xfff, 0xfff, 0xfff, 0xfff, 0x093, 0x1b8, 0xfff, 
922         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2e6, 
923         0xfff, 0x0f3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
924         0x28e, 0xfff, 0x53b, 0x420, 0x22a, 0x33a, 0xfff, 0x387, 
925         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2a3, 0xfff, 0xfff, 
926         0xfff, 0x428, 0x500, 0xfff, 0xfff, 0x120, 0x2c6, 0x290, 
927         0x2f5, 0x0e3, 0xfff, 0x0b7, 0xfff, 0x319, 0x474, 0xfff, 
928         0xfff, 0xfff, 0x529, 0x014, 0xfff, 0x41b, 0x40a, 0x18b, 
929         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d9, 
930         0xfff, 0x38a, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ce, 0xfff, 
931         0xfff, 0xfff, 0xfff, 0xfff, 0x3b1, 0xfff, 0xfff, 0x05d, 
932         0x2c4, 0xfff, 0xfff, 0x4af, 0xfff, 0x030, 0xfff, 0xfff, 
933         0x203, 0xfff, 0x277, 0x256, 0xfff, 0xfff, 0xfff, 0x4f9, 
934         0xfff, 0x2c7, 0xfff, 0x466, 0x016, 0x1cd, 0xfff, 0x167, 
935         0xfff, 0xfff, 0x0c8, 0xfff, 0x43d, 0xfff, 0xfff, 0x020, 
936         0xfff, 0xfff, 0x232, 0x1cb, 0x1e0, 0xfff, 0xfff, 0x347, 
937         0xfff, 0x478, 0xfff, 0x365, 0xfff, 0xfff, 0xfff, 0xfff, 
938         0x358, 0xfff, 0x10b, 0xfff, 0x35d, 0xfff, 0xfff, 0xfff, 
939         0xfff, 0xfff, 0x452, 0x22d, 0xfff, 0xfff, 0x47d, 0xfff, 
940         0x2f3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x460, 0xfff, 
941         0xfff, 0xfff, 0x50b, 0xfff, 0xfff, 0xfff, 0x2ec, 0xfff, 
942         0xfff, 0xfff, 0xfff, 0xfff, 0x4b1, 0x422, 0xfff, 0xfff, 
943         0xfff, 0x2d4, 0xfff, 0x239, 0xfff, 0xfff, 0xfff, 0x439, 
944         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
945         0xfff, 0x491, 0x075, 0xfff, 0xfff, 0xfff, 0x06c, 0xfff, 
946         0xfff, 0x0f9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
947         0xfff, 0x139, 0xfff, 0x4f6, 0xfff, 0xfff, 0x409, 0xfff, 
948         0xfff, 0x15b, 0xfff, 0xfff, 0x348, 0xfff, 0xfff, 0xfff, 
949         0xfff, 0x4a2, 0x49d, 0xfff, 0x033, 0x175, 0xfff, 0x039, 
950         0xfff, 0x312, 0x40c, 0xfff, 0xfff, 0x325, 0xfff, 0xfff, 
951         0xfff, 0xfff, 0xfff, 0xfff, 0x4aa, 0xfff, 0xfff, 0xfff, 
952         0xfff, 0xfff, 0xfff, 0x165, 0x3bc, 0x48c, 0x310, 0x096, 
953         0xfff, 0xfff, 0x250, 0x1a2, 0xfff, 0xfff, 0xfff, 0xfff, 
954         0x20d, 0x2ac, 0xfff, 0xfff, 0x39b, 0xfff, 0x377, 0xfff, 
955         0x512, 0x495, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
956         0xfff, 0xfff, 0xfff, 0xfff, 0x357, 0x4ea, 0xfff, 0xfff, 
957         0xfff, 0xfff, 0x198, 0xfff, 0xfff, 0xfff, 0x434, 0x04a, 
958         0xfff, 0xfff, 0xfff, 0xfff, 0x062, 0xfff, 0x1d6, 0x1c8, 
959         0xfff, 0x1f3, 0x281, 0xfff, 0x462, 0xfff, 0xfff, 0xfff, 
960         0x4b0, 0xfff, 0x207, 0xfff, 0xfff, 0xfff, 0xfff, 0x3dd, 
961         0xfff, 0xfff, 0x55d, 0xfff, 0x552, 0x494, 0x1af, 0xfff, 
962         0xfff, 0xfff, 0xfff, 0xfff, 0x227, 0xfff, 0xfff, 0x069, 
963         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x43e, 
964         0x0b5, 0xfff, 0x524, 0x2d2, 0xfff, 0xfff, 0xfff, 0x28f, 
965         0xfff, 0x01b, 0x50e, 0xfff, 0xfff, 0x1bb, 0xfff, 0xfff, 
966         0x41d, 0xfff, 0x32e, 0x48e, 0xfff, 0x1f7, 0x224, 0xfff, 
967         0xfff, 0xfff, 0xfff, 0xfff, 0x394, 0xfff, 0xfff, 0xfff, 
968         0xfff, 0x52c, 0xfff, 0xfff, 0xfff, 0x392, 0xfff, 0x1e7, 
969         0xfff, 0xfff, 0x3f9, 0x3a7, 0xfff, 0x51f, 0xfff, 0x0bb, 
970         0x118, 0x3ca, 0xfff, 0x1dd, 0xfff, 0x48b, 0xfff, 0xfff, 
971         0xfff, 0xfff, 0x50f, 0xfff, 0x0d6, 0xfff, 0x1fa, 0xfff, 
972         0x11e, 0xfff, 0xfff, 0xfff, 0xfff, 0x4d7, 0xfff, 0x078, 
973         0x008, 0xfff, 0x25d, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
974         0x032, 0x33c, 0xfff, 0x4d9, 0x160, 0xfff, 0xfff, 0x300, 
975         0x0b1, 0xfff, 0x322, 0xfff, 0x4ec, 0xfff, 0xfff, 0x200, 
976         0x00c, 0x369, 0x473, 0xfff, 0xfff, 0x32c, 0xfff, 0xfff, 
977         0xfff, 0xfff, 0xfff, 0xfff, 0x53e, 0x3d4, 0x417, 0xfff, 
978         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
979         0x34b, 0x001, 0x39a, 0x02c, 0xfff, 0xfff, 0x2ce, 0x00f, 
980         0xfff, 0x0ba, 0xfff, 0xfff, 0xfff, 0xfff, 0x060, 0xfff, 
981         0x406, 0xfff, 0xfff, 0xfff, 0x4ee, 0x4ac, 0xfff, 0x43f, 
982         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x29b, 0xfff, 0xfff, 
983         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x216, 
984         0x190, 0xfff, 0x396, 0x464, 0xfff, 0xfff, 0x323, 0xfff, 
985         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2e9, 0xfff, 0x26d, 
986         0x2cd, 0x040, 0xfff, 0xfff, 0xfff, 0xfff, 0x38b, 0x3c0, 
987         0xfff, 0xfff, 0xfff, 0x1f2, 0xfff, 0x0ea, 0xfff, 0xfff, 
988         0x472, 0xfff, 0x1fb, 0xfff, 0xfff, 0x0af, 0x27f, 0xfff, 
989         0xfff, 0xfff, 0x479, 0x023, 0xfff, 0x0d8, 0x3b3, 0xfff, 
990         0xfff, 0xfff, 0x121, 0xfff, 0xfff, 0x3bf, 0xfff, 0xfff, 
991         0x16b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
992         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
993         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
994         0x45a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
995         0xfff, 0x0be, 0xfff, 0xfff, 0xfff, 0x111, 0xfff, 0x220, 
996         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
997         0xfff, 0xfff, 0x09b, 0x218, 0xfff, 0x022, 0x202, 0xfff, 
998         0x4c8, 0xfff, 0x0ed, 0xfff, 0xfff, 0x182, 0xfff, 0xfff, 
999         0xfff, 0x17f, 0x213, 0xfff, 0x321, 0x36a, 0xfff, 0x086, 
1000         0xfff, 0xfff, 0xfff, 0x43b, 0x088, 0xfff, 0xfff, 0xfff, 
1001         0xfff, 0x26c, 0xfff, 0x2f8, 0x3b4, 0xfff, 0xfff, 0xfff, 
1002         0x132, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x333, 0x444, 
1003         0x0c1, 0x4d8, 0x46d, 0x264, 0xfff, 0xfff, 0xfff, 0xfff, 
1004         0x426, 0xfff, 0xfff, 0xfff, 0xfff, 0x2fe, 0xfff, 0xfff, 
1005         0xfff, 0xfff, 0x011, 0xfff, 0x05f, 0xfff, 0xfff, 0xfff, 
1006         0xfff, 0x10c, 0x101, 0xfff, 0xfff, 0xfff, 0xfff, 0x110, 
1007         0xfff, 0x044, 0x304, 0x361, 0x404, 0xfff, 0x51b, 0x099, 
1008         0xfff, 0x440, 0xfff, 0xfff, 0xfff, 0x222, 0xfff, 0xfff, 
1009         0xfff, 0xfff, 0x1b5, 0xfff, 0x136, 0x430, 0xfff, 0x1da, 
1010         0xfff, 0xfff, 0xfff, 0x043, 0xfff, 0x17c, 0xfff, 0xfff, 
1011         0xfff, 0x01c, 0xfff, 0xfff, 0xfff, 0x425, 0x236, 0xfff, 
1012         0x317, 0xfff, 0xfff, 0x437, 0x3fc, 0xfff, 0x1f1, 0xfff, 
1013         0x324, 0xfff, 0xfff, 0x0ca, 0x306, 0xfff, 0x548, 0xfff, 
1014         0x46e, 0xfff, 0xfff, 0xfff, 0x4b8, 0x1c2, 0x286, 0xfff, 
1015         0xfff, 0x087, 0x18a, 0x19f, 0xfff, 0xfff, 0xfff, 0xfff, 
1016         0x18c, 0xfff, 0x215, 0xfff, 0xfff, 0xfff, 0xfff, 0x283, 
1017         0xfff, 0xfff, 0xfff, 0x126, 0xfff, 0xfff, 0x370, 0xfff, 
1018         0x53f, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x31c, 0xfff, 
1019         0x4d1, 0xfff, 0xfff, 0xfff, 0x021, 0xfff, 0x157, 0xfff, 
1020         0xfff, 0x028, 0x16e, 0xfff, 0x421, 0xfff, 0x1c6, 0xfff, 
1021         0xfff, 0x511, 0xfff, 0xfff, 0x39c, 0x46f, 0x1b2, 0xfff, 
1022         0xfff, 0x316, 0xfff, 0xfff, 0x009, 0xfff, 0xfff, 0x195, 
1023         0xfff, 0x240, 0x546, 0xfff, 0xfff, 0x520, 0xfff, 0xfff, 
1024         0xfff, 0xfff, 0xfff, 0xfff, 0x454, 0xfff, 0xfff, 0xfff, 
1025         0x3f3, 0xfff, 0xfff, 0x187, 0xfff, 0x4a9, 0xfff, 0xfff, 
1026         0xfff, 0xfff, 0xfff, 0xfff, 0x51c, 0x453, 0x1e6, 0xfff, 
1027         0xfff, 0xfff, 0x1b0, 0xfff, 0x477, 0xfff, 0xfff, 0xfff, 
1028         0x4fe, 0xfff, 0x32f, 0xfff, 0xfff, 0x15e, 0x1d4, 0xfff, 
1029         0x0e5, 0xfff, 0xfff, 0xfff, 0x242, 0x14b, 0x046, 0xfff, 
1030         0x3f6, 0x3bb, 0x3e4, 0xfff, 0xfff, 0x2e3, 0xfff, 0x245, 
1031         0xfff, 0x149, 0xfff, 0xfff, 0xfff, 0x2db, 0xfff, 0xfff, 
1032         0x181, 0xfff, 0x089, 0x2c5, 0xfff, 0x1f5, 0xfff, 0x2d6, 
1033         0x507, 0xfff, 0x42d, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
1034         0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
1035         0x080, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 
1036         0xfff, 0xfff, 0xfff, 0xfff, 0x3c3, 0x320, 0xfff, 0x1e1, 
1037         0xfff, 0x0f5, 0x13b, 0xfff, 0xfff, 0xfff, 0x003, 0x4da, 
1038         0xfff, 0xfff, 0xfff, 0x42c, 0xfff, 0xfff, 0x0cb, 0xfff, 
1039         0x536, 0x2c3, 0xfff, 0xfff, 0xfff, 0xfff, 0x199, 0xfff, 
1040         0xfff, 0x0c0, 0xfff, 0x01e, 0x497, 0xfff, 0xfff, 0x3e5, 
1041         0xfff, 0xfff, 0xfff, 0x0cf, 0xfff, 0x2bd, 0xfff, 0x223, 
1042         0xfff, 0x3ff, 0xfff, 0x058, 0x174, 0x3ef, 0xfff, 0x002
1043 };
1044
1045 static unsigned short err_pos(unsigned short din)
1046 {
1047         BUG_ON(din > 4096);
1048         return err_pos_lut[din];
1049 }
1050 static int chk_no_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1051 {
1052         if ((chk_syndrome_list[0] | chk_syndrome_list[1] |
1053              chk_syndrome_list[2] | chk_syndrome_list[3] |
1054              chk_syndrome_list[4] | chk_syndrome_list[5] |
1055              chk_syndrome_list[6] | chk_syndrome_list[7]) != 0x0) {
1056                 return -EINVAL;
1057         } else {
1058                 err_info[0] = 0x0;
1059                 return 0;
1060         }
1061 }
1062 static int chk_1_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1063 {
1064         unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
1065         tmp0 = gf4096_mul(chk_syndrome_list[1], gf4096_inv(chk_syndrome_list[0]));
1066         tmp1 = gf4096_mul(chk_syndrome_list[2], gf4096_inv(chk_syndrome_list[1]));
1067         tmp2 = gf4096_mul(chk_syndrome_list[3], gf4096_inv(chk_syndrome_list[2]));
1068         tmp3 = gf4096_mul(chk_syndrome_list[4], gf4096_inv(chk_syndrome_list[3]));
1069         tmp4 = gf4096_mul(chk_syndrome_list[5], gf4096_inv(chk_syndrome_list[4]));
1070         tmp5 = gf4096_mul(chk_syndrome_list[6], gf4096_inv(chk_syndrome_list[5]));
1071         tmp6 = gf4096_mul(chk_syndrome_list[7], gf4096_inv(chk_syndrome_list[6]));
1072         if ((tmp0 == tmp1) & (tmp1 == tmp2) & (tmp2 == tmp3) & (tmp3 == tmp4) & (tmp4 == tmp5) & (tmp5 == tmp6)) {
1073                 err_info[0] = 0x1;      // encode 1-symbol error as 0x1
1074                 err_info[1] = err_pos(tmp0);
1075                 err_info[1] = (unsigned short)(0x55e - err_info[1]);
1076                 err_info[5] = chk_syndrome_list[0];
1077                 return 0;
1078         } else
1079                 return -EINVAL;
1080 }
1081 static int chk_2_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1082 {
1083         unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
1084         unsigned short coefs[4];
1085         unsigned short err_pats[4];
1086         int found_num_root = 0;
1087         unsigned short bit2_root0, bit2_root1;
1088         unsigned short bit2_root0_inv, bit2_root1_inv;
1089         unsigned short err_loc_eqn, test_root;
1090         unsigned short bit2_loc0, bit2_loc1;
1091         unsigned short bit2_pat0, bit2_pat1;
1092
1093         find_2x2_soln(chk_syndrome_list[1],
1094                       chk_syndrome_list[0],
1095                       chk_syndrome_list[2], chk_syndrome_list[1], chk_syndrome_list[2], chk_syndrome_list[3], coefs);
1096         for (test_root = 0x1; test_root < 0xfff; test_root++) {
1097                 err_loc_eqn =
1098                     gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) ^ gf4096_mul(coefs[0], test_root) ^ 0x1;
1099                 if (err_loc_eqn == 0x0) {
1100                         if (found_num_root == 0) {
1101                                 bit2_root0 = test_root;
1102                                 found_num_root = 1;
1103                         } else if (found_num_root == 1) {
1104                                 bit2_root1 = test_root;
1105                                 found_num_root = 2;
1106                                 break;
1107                         }
1108                 }
1109         }
1110         if (found_num_root != 2)
1111                 return -EINVAL;
1112         else {
1113                 bit2_root0_inv = gf4096_inv(bit2_root0);
1114                 bit2_root1_inv = gf4096_inv(bit2_root1);
1115                 find_2bit_err_pats(chk_syndrome_list[0],
1116                                    chk_syndrome_list[1], bit2_root0_inv, bit2_root1_inv, err_pats);
1117                 bit2_pat0 = err_pats[0];
1118                 bit2_pat1 = err_pats[1];
1119                 //for(x+1)
1120                 tmp0 = gf4096_mul(gf4096_mul(bit2_root0_inv, bit2_root0_inv), gf4096_mul(bit2_root0_inv, bit2_root0_inv));      //rinv0^4
1121                 tmp1 = gf4096_mul(bit2_root0_inv, tmp0);        //rinv0^5
1122                 tmp2 = gf4096_mul(bit2_root0_inv, tmp1);        //rinv0^6
1123                 tmp3 = gf4096_mul(bit2_root0_inv, tmp2);        //rinv0^7
1124                 tmp4 = gf4096_mul(gf4096_mul(bit2_root1_inv, bit2_root1_inv), gf4096_mul(bit2_root1_inv, bit2_root1_inv));      //rinv1^4
1125                 tmp5 = gf4096_mul(bit2_root1_inv, tmp4);        //rinv1^5
1126                 tmp6 = gf4096_mul(bit2_root1_inv, tmp5);        //rinv1^6
1127                 tmp7 = gf4096_mul(bit2_root1_inv, tmp6);        //rinv1^7
1128                 //check if only 2-bit error
1129                 if ((chk_syndrome_list[4] ==
1130                      (gf4096_mul(bit2_pat0, tmp0) ^
1131                       gf4096_mul(bit2_pat1,
1132                                  tmp4))) & (chk_syndrome_list[5] ==
1133                                             (gf4096_mul(bit2_pat0, tmp1) ^
1134                                              gf4096_mul(bit2_pat1,
1135                                                         tmp5))) &
1136                     (chk_syndrome_list[6] ==
1137                      (gf4096_mul(bit2_pat0, tmp2) ^
1138                       gf4096_mul(bit2_pat1,
1139                                  tmp6))) & (chk_syndrome_list[7] ==
1140                                             (gf4096_mul(bit2_pat0, tmp3) ^ gf4096_mul(bit2_pat1, tmp7)))) {
1141                         if ((err_pos(bit2_root0_inv) == 0xfff) | (err_pos(bit2_root1_inv) == 0xfff)) {
1142                                 return -EINVAL;
1143                         } else {
1144                                 bit2_loc0 = 0x55e - err_pos(bit2_root0_inv);
1145                                 bit2_loc1 = 0x55e - err_pos(bit2_root1_inv);
1146                                 err_info[0] = 0x2;      // encode 2-symbol error as 0x2
1147                                 err_info[1] = bit2_loc0;
1148                                 err_info[2] = bit2_loc1;
1149                                 err_info[5] = bit2_pat0;
1150                                 err_info[6] = bit2_pat1;
1151                                 return 0;
1152                         }
1153                 } else
1154                         return -EINVAL;
1155         }
1156 }
1157 static int chk_3_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1158 {
1159         unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
1160         unsigned short coefs[4];
1161         unsigned short err_pats[4];
1162         int found_num_root = 0;
1163         unsigned short bit3_root0, bit3_root1, bit3_root2;
1164         unsigned short bit3_root0_inv, bit3_root1_inv, bit3_root2_inv;
1165         unsigned short err_loc_eqn, test_root;
1166
1167         find_3bit_err_coefs(chk_syndrome_list[0], chk_syndrome_list[1],
1168                             chk_syndrome_list[2], chk_syndrome_list[3],
1169                             chk_syndrome_list[4], chk_syndrome_list[5], coefs);
1170
1171         for (test_root = 0x1; test_root < 0xfff; test_root++) {
1172                 err_loc_eqn = gf4096_mul(coefs[2],
1173                                          gf4096_mul(gf4096_mul(test_root, test_root),
1174                                                     test_root)) ^ gf4096_mul(coefs[1], gf4096_mul(test_root, test_root))
1175                         ^ gf4096_mul(coefs[0], test_root) ^ 0x1;
1176
1177                 if (err_loc_eqn == 0x0) {
1178                         if (found_num_root == 0) {
1179                                 bit3_root0 = test_root;
1180                                 found_num_root = 1;
1181                         } else if (found_num_root == 1) {
1182                                 bit3_root1 = test_root;
1183                                 found_num_root = 2;
1184                         } else if (found_num_root == 2) {
1185                                 bit3_root2 = test_root;
1186                                 found_num_root = 3;
1187                                 break;
1188                         }
1189                 }
1190         }
1191         if (found_num_root != 3)
1192                 return -EINVAL;
1193         else {
1194                 bit3_root0_inv = gf4096_inv(bit3_root0);
1195                 bit3_root1_inv = gf4096_inv(bit3_root1);
1196                 bit3_root2_inv = gf4096_inv(bit3_root2);
1197
1198                 find_3bit_err_pats(chk_syndrome_list[0], chk_syndrome_list[1],
1199                                    chk_syndrome_list[2], bit3_root0_inv,
1200                                    bit3_root1_inv, bit3_root2_inv, err_pats);
1201
1202                 //check if only 3-bit error
1203                 tmp0 = gf4096_mul(bit3_root0_inv, bit3_root0_inv);
1204                 tmp0 = gf4096_mul(tmp0, tmp0);
1205                 tmp0 = gf4096_mul(tmp0, bit3_root0_inv);
1206                 tmp0 = gf4096_mul(tmp0, bit3_root0_inv);        //rinv0^6
1207                 tmp1 = gf4096_mul(tmp0, bit3_root0_inv);        //rinv0^7
1208                 tmp2 = gf4096_mul(bit3_root1_inv, bit3_root1_inv);
1209                 tmp2 = gf4096_mul(tmp2, tmp2);
1210                 tmp2 = gf4096_mul(tmp2, bit3_root1_inv);
1211                 tmp2 = gf4096_mul(tmp2, bit3_root1_inv);        //rinv1^6
1212                 tmp3 = gf4096_mul(tmp2, bit3_root1_inv);        //rinv1^7
1213                 tmp4 = gf4096_mul(bit3_root2_inv, bit3_root2_inv);
1214                 tmp4 = gf4096_mul(tmp4, tmp4);
1215                 tmp4 = gf4096_mul(tmp4, bit3_root2_inv);
1216                 tmp4 = gf4096_mul(tmp4, bit3_root2_inv);        //rinv2^6
1217                 tmp5 = gf4096_mul(tmp4, bit3_root2_inv);        //rinv2^7
1218
1219                 //check if only 3 errors
1220                 if ((chk_syndrome_list[6] == (gf4096_mul(err_pats[0], tmp0) ^
1221                                               gf4096_mul(err_pats[1], tmp2) ^
1222                                               gf4096_mul(err_pats[2], tmp4))) &
1223                     (chk_syndrome_list[7] == (gf4096_mul(err_pats[0], tmp1) ^
1224                                               gf4096_mul(err_pats[1], tmp3) ^ gf4096_mul(err_pats[2], tmp5)))) {
1225                         if ((err_pos(bit3_root0_inv) == 0xfff) |
1226                             (err_pos(bit3_root1_inv) == 0xfff) | (err_pos(bit3_root2_inv) == 0xfff)) {
1227                                 return -EINVAL;
1228                         } else {
1229                                 err_info[0] = 0x3;
1230                                 err_info[1] = (0x55e - err_pos(bit3_root0_inv));
1231                                 err_info[2] = (0x55e - err_pos(bit3_root1_inv));
1232                                 err_info[3] = (0x55e - err_pos(bit3_root2_inv));
1233                                 err_info[5] = err_pats[0];
1234                                 err_info[6] = err_pats[1];
1235                                 err_info[7] = err_pats[2];
1236                                 return 0;
1237                         }
1238                 } else
1239                         return -EINVAL;
1240         }
1241 }
1242 static int chk_4_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info)
1243 {
1244         unsigned short coefs[4];
1245         unsigned short err_pats[4];
1246         int found_num_root = 0;
1247         unsigned short bit4_root0, bit4_root1, bit4_root2, bit4_root3;
1248         unsigned short bit4_root0_inv, bit4_root1_inv, bit4_root2_inv, bit4_root3_inv;
1249         unsigned short err_loc_eqn, test_root;
1250
1251         find_4bit_err_coefs(chk_syndrome_list[0],
1252                             chk_syndrome_list[1],
1253                             chk_syndrome_list[2],
1254                             chk_syndrome_list[3],
1255                             chk_syndrome_list[4],
1256                             chk_syndrome_list[5], chk_syndrome_list[6], chk_syndrome_list[7], coefs);
1257
1258         for (test_root = 0x1; test_root < 0xfff; test_root++) {
1259                 err_loc_eqn =
1260                     gf4096_mul(coefs[3],
1261                                gf4096_mul(gf4096_mul
1262                                           (gf4096_mul(test_root, test_root),
1263                                            test_root),
1264                                           test_root)) ^ gf4096_mul(coefs[2],
1265                                                                    gf4096_mul
1266                                                                    (gf4096_mul(test_root, test_root), test_root))
1267                     ^ gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) ^ gf4096_mul(coefs[0], test_root)
1268                     ^ 0x1;
1269                 if (err_loc_eqn == 0x0) {
1270                         if (found_num_root == 0) {
1271                                 bit4_root0 = test_root;
1272                                 found_num_root = 1;
1273                         } else if (found_num_root == 1) {
1274                                 bit4_root1 = test_root;
1275                                 found_num_root = 2;
1276                         } else if (found_num_root == 2) {
1277                                 bit4_root2 = test_root;
1278                                 found_num_root = 3;
1279                         } else {
1280                                 found_num_root = 4;
1281                                 bit4_root3 = test_root;
1282                                 break;
1283                         }
1284                 }
1285         }
1286         if (found_num_root != 4) {
1287                 return -EINVAL;
1288         } else {
1289                 bit4_root0_inv = gf4096_inv(bit4_root0);
1290                 bit4_root1_inv = gf4096_inv(bit4_root1);
1291                 bit4_root2_inv = gf4096_inv(bit4_root2);
1292                 bit4_root3_inv = gf4096_inv(bit4_root3);
1293                 find_4bit_err_pats(chk_syndrome_list[0],
1294                                    chk_syndrome_list[1],
1295                                    chk_syndrome_list[2],
1296                                    chk_syndrome_list[3],
1297                                    bit4_root0_inv, bit4_root1_inv, bit4_root2_inv, bit4_root3_inv, err_pats);
1298                 err_info[0] = 0x4;
1299                 err_info[1] = (0x55e - err_pos(bit4_root0_inv));
1300                 err_info[2] = (0x55e - err_pos(bit4_root1_inv));
1301                 err_info[3] = (0x55e - err_pos(bit4_root2_inv));
1302                 err_info[4] = (0x55e - err_pos(bit4_root3_inv));
1303                 err_info[5] = err_pats[0];
1304                 err_info[6] = err_pats[1];
1305                 err_info[7] = err_pats[2];
1306                 err_info[8] = err_pats[3];
1307                 return 0;
1308         }
1309 }
1310
1311 void correct_12bit_symbol(unsigned char *buf, unsigned short sym,
1312                           unsigned short val)
1313 {
1314         if (unlikely(sym > 1366)) {
1315                 printk(KERN_ERR "Error: symbol %d out of range; cannot correct\n", sym);
1316         } else if (sym == 0) {
1317                 buf[0] ^= val;
1318         } else if (sym & 1) {
1319                 buf[1+(3*(sym-1))/2] ^= (val >> 4);
1320                 buf[2+(3*(sym-1))/2] ^= ((val & 0xf) << 4);
1321         } else {
1322                 buf[2+(3*(sym-2))/2] ^= (val >> 8);
1323                 buf[3+(3*(sym-2))/2] ^= (val & 0xff);
1324         }
1325
1326                 
1327 }
1328
1329 int cafe_correct_ecc(unsigned char *buf,
1330                      unsigned short *chk_syndrome_list)
1331 {
1332         unsigned short err_info[9];
1333         int i;
1334
1335         if (chk_no_err_only(chk_syndrome_list, err_info) &&
1336             chk_1_err_only(chk_syndrome_list, err_info) &&
1337             chk_2_err_only(chk_syndrome_list, err_info) &&
1338             chk_3_err_only(chk_syndrome_list, err_info) &&
1339             chk_4_err_only(chk_syndrome_list, err_info)) {
1340                 return -EIO;
1341         }
1342
1343         for (i=0; i < err_info[0]; i++)
1344                 correct_12bit_symbol(buf, err_info[1+i], err_info[5+i]);
1345
1346         return err_info[0];
1347 }
1348