r8169: more alignment for the 0x8168
[sfrench/cifs-2.6.git] / drivers / char / ftape / lowlevel / ftape-ecc.c
1 /*
2  *
3  *      Copyright (c) 1993 Ning and David Mosberger.
4  
5  This is based on code originally written by Bas Laarhoven (bas@vimec.nl)
6  and David L. Brown, Jr., and incorporates improvements suggested by
7  Kai Harrekilde-Petersen.
8
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13  
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  General Public License for more details.
18  
19  You should have received a copy of the GNU General Public License
20  along with this program; see the file COPYING.  If not, write to
21  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
22  USA.
23
24  *
25  * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-ecc.c,v $
26  * $Revision: 1.3 $
27  * $Date: 1997/10/05 19:18:10 $
28  *
29  *      This file contains the Reed-Solomon error correction code 
30  *      for the QIC-40/80 floppy-tape driver for Linux.
31  */
32
33 #include <linux/ftape.h>
34
35 #include "../lowlevel/ftape-tracing.h"
36 #include "../lowlevel/ftape-ecc.h"
37
38 /* Machines that are big-endian should define macro BIG_ENDIAN.
39  * Unfortunately, there doesn't appear to be a standard include file
40  * that works for all OSs.
41  */
42
43 #if defined(__sparc__) || defined(__hppa)
44 #define BIG_ENDIAN
45 #endif                          /* __sparc__ || __hppa */
46
47 #if defined(__mips__)
48 #error Find a smart way to determine the Endianness of the MIPS CPU
49 #endif
50
51 /* Notice: to minimize the potential for confusion, we use r to
52  *         denote the independent variable of the polynomials in the
53  *         Galois Field GF(2^8).  We reserve x for polynomials that
54  *         that have coefficients in GF(2^8).
55  *         
56  * The Galois Field in which coefficient arithmetic is performed are
57  * the polynomials over Z_2 (i.e., 0 and 1) modulo the irreducible
58  * polynomial f(r), where f(r)=r^8 + r^7 + r^2 + r + 1.  A polynomial
59  * is represented as a byte with the MSB as the coefficient of r^7 and
60  * the LSB as the coefficient of r^0.  For example, the binary
61  * representation of f(x) is 0x187 (of course, this doesn't fit into 8
62  * bits).  In this field, the polynomial r is a primitive element.
63  * That is, r^i with i in 0,...,255 enumerates all elements in the
64  * field.
65  *
66  * The generator polynomial for the QIC-80 ECC is
67  *
68  *      g(x) = x^3 + r^105*x^2 + r^105*x + 1
69  *
70  * which can be factored into:
71  *
72  *      g(x) = (x-r^-1)(x-r^0)(x-r^1)
73  *
74  * the byte representation of the coefficients are:
75  *
76  *      r^105 = 0xc0
77  *      r^-1  = 0xc3
78  *      r^0   = 0x01
79  *      r^1   = 0x02
80  *
81  * Notice that r^-1 = r^254 as exponent arithmetic is performed
82  * modulo 2^8-1 = 255.
83  *
84  * For more information on Galois Fields and Reed-Solomon codes, refer
85  * to any good book.  I found _An Introduction to Error Correcting
86  * Codes with Applications_ by S. A. Vanstone and P. C. van Oorschot
87  * to be a good introduction into the former.  _CODING THEORY: The
88  * Essentials_ I found very useful for its concise description of
89  * Reed-Solomon encoding/decoding.
90  *
91  */
92
93 typedef __u8 Matrix[3][3];
94
95 /*
96  * gfpow[] is defined such that gfpow[i] returns r^i if
97  * i is in the range [0..255].
98  */
99 static const __u8 gfpow[] =
100 {
101         0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
102         0x87, 0x89, 0x95, 0xad, 0xdd, 0x3d, 0x7a, 0xf4,
103         0x6f, 0xde, 0x3b, 0x76, 0xec, 0x5f, 0xbe, 0xfb,
104         0x71, 0xe2, 0x43, 0x86, 0x8b, 0x91, 0xa5, 0xcd,
105         0x1d, 0x3a, 0x74, 0xe8, 0x57, 0xae, 0xdb, 0x31,
106         0x62, 0xc4, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0x67,
107         0xce, 0x1b, 0x36, 0x6c, 0xd8, 0x37, 0x6e, 0xdc,
108         0x3f, 0x7e, 0xfc, 0x7f, 0xfe, 0x7b, 0xf6, 0x6b,
109         0xd6, 0x2b, 0x56, 0xac, 0xdf, 0x39, 0x72, 0xe4,
110         0x4f, 0x9e, 0xbb, 0xf1, 0x65, 0xca, 0x13, 0x26,
111         0x4c, 0x98, 0xb7, 0xe9, 0x55, 0xaa, 0xd3, 0x21,
112         0x42, 0x84, 0x8f, 0x99, 0xb5, 0xed, 0x5d, 0xba,
113         0xf3, 0x61, 0xc2, 0x03, 0x06, 0x0c, 0x18, 0x30,
114         0x60, 0xc0, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0,
115         0x47, 0x8e, 0x9b, 0xb1, 0xe5, 0x4d, 0x9a, 0xb3,
116         0xe1, 0x45, 0x8a, 0x93, 0xa1, 0xc5, 0x0d, 0x1a,
117         0x34, 0x68, 0xd0, 0x27, 0x4e, 0x9c, 0xbf, 0xf9,
118         0x75, 0xea, 0x53, 0xa6, 0xcb, 0x11, 0x22, 0x44,
119         0x88, 0x97, 0xa9, 0xd5, 0x2d, 0x5a, 0xb4, 0xef,
120         0x59, 0xb2, 0xe3, 0x41, 0x82, 0x83, 0x81, 0x85,
121         0x8d, 0x9d, 0xbd, 0xfd, 0x7d, 0xfa, 0x73, 0xe6,
122         0x4b, 0x96, 0xab, 0xd1, 0x25, 0x4a, 0x94, 0xaf,
123         0xd9, 0x35, 0x6a, 0xd4, 0x2f, 0x5e, 0xbc, 0xff,
124         0x79, 0xf2, 0x63, 0xc6, 0x0b, 0x16, 0x2c, 0x58,
125         0xb0, 0xe7, 0x49, 0x92, 0xa3, 0xc1, 0x05, 0x0a,
126         0x14, 0x28, 0x50, 0xa0, 0xc7, 0x09, 0x12, 0x24,
127         0x48, 0x90, 0xa7, 0xc9, 0x15, 0x2a, 0x54, 0xa8,
128         0xd7, 0x29, 0x52, 0xa4, 0xcf, 0x19, 0x32, 0x64,
129         0xc8, 0x17, 0x2e, 0x5c, 0xb8, 0xf7, 0x69, 0xd2,
130         0x23, 0x46, 0x8c, 0x9f, 0xb9, 0xf5, 0x6d, 0xda,
131         0x33, 0x66, 0xcc, 0x1f, 0x3e, 0x7c, 0xf8, 0x77,
132         0xee, 0x5b, 0xb6, 0xeb, 0x51, 0xa2, 0xc3, 0x01
133 };
134
135 /*
136  * This is a log table.  That is, gflog[r^i] returns i (modulo f(r)).
137  * gflog[0] is undefined and the first element is therefore not valid.
138  */
139 static const __u8 gflog[256] =
140 {
141         0xff, 0x00, 0x01, 0x63, 0x02, 0xc6, 0x64, 0x6a,
142         0x03, 0xcd, 0xc7, 0xbc, 0x65, 0x7e, 0x6b, 0x2a,
143         0x04, 0x8d, 0xce, 0x4e, 0xc8, 0xd4, 0xbd, 0xe1,
144         0x66, 0xdd, 0x7f, 0x31, 0x6c, 0x20, 0x2b, 0xf3,
145         0x05, 0x57, 0x8e, 0xe8, 0xcf, 0xac, 0x4f, 0x83,
146         0xc9, 0xd9, 0xd5, 0x41, 0xbe, 0x94, 0xe2, 0xb4,
147         0x67, 0x27, 0xde, 0xf0, 0x80, 0xb1, 0x32, 0x35,
148         0x6d, 0x45, 0x21, 0x12, 0x2c, 0x0d, 0xf4, 0x38,
149         0x06, 0x9b, 0x58, 0x1a, 0x8f, 0x79, 0xe9, 0x70,
150         0xd0, 0xc2, 0xad, 0xa8, 0x50, 0x75, 0x84, 0x48,
151         0xca, 0xfc, 0xda, 0x8a, 0xd6, 0x54, 0x42, 0x24,
152         0xbf, 0x98, 0x95, 0xf9, 0xe3, 0x5e, 0xb5, 0x15,
153         0x68, 0x61, 0x28, 0xba, 0xdf, 0x4c, 0xf1, 0x2f,
154         0x81, 0xe6, 0xb2, 0x3f, 0x33, 0xee, 0x36, 0x10,
155         0x6e, 0x18, 0x46, 0xa6, 0x22, 0x88, 0x13, 0xf7,
156         0x2d, 0xb8, 0x0e, 0x3d, 0xf5, 0xa4, 0x39, 0x3b,
157         0x07, 0x9e, 0x9c, 0x9d, 0x59, 0x9f, 0x1b, 0x08,
158         0x90, 0x09, 0x7a, 0x1c, 0xea, 0xa0, 0x71, 0x5a,
159         0xd1, 0x1d, 0xc3, 0x7b, 0xae, 0x0a, 0xa9, 0x91,
160         0x51, 0x5b, 0x76, 0x72, 0x85, 0xa1, 0x49, 0xeb,
161         0xcb, 0x7c, 0xfd, 0xc4, 0xdb, 0x1e, 0x8b, 0xd2,
162         0xd7, 0x92, 0x55, 0xaa, 0x43, 0x0b, 0x25, 0xaf,
163         0xc0, 0x73, 0x99, 0x77, 0x96, 0x5c, 0xfa, 0x52,
164         0xe4, 0xec, 0x5f, 0x4a, 0xb6, 0xa2, 0x16, 0x86,
165         0x69, 0xc5, 0x62, 0xfe, 0x29, 0x7d, 0xbb, 0xcc,
166         0xe0, 0xd3, 0x4d, 0x8c, 0xf2, 0x1f, 0x30, 0xdc,
167         0x82, 0xab, 0xe7, 0x56, 0xb3, 0x93, 0x40, 0xd8,
168         0x34, 0xb0, 0xef, 0x26, 0x37, 0x0c, 0x11, 0x44,
169         0x6f, 0x78, 0x19, 0x9a, 0x47, 0x74, 0xa7, 0xc1,
170         0x23, 0x53, 0x89, 0xfb, 0x14, 0x5d, 0xf8, 0x97,
171         0x2e, 0x4b, 0xb9, 0x60, 0x0f, 0xed, 0x3e, 0xe5,
172         0xf6, 0x87, 0xa5, 0x17, 0x3a, 0xa3, 0x3c, 0xb7
173 };
174
175 /* This is a multiplication table for the factor 0xc0 (i.e., r^105 (mod f(r)).
176  * gfmul_c0[f] returns r^105 * f(r) (modulo f(r)).
177  */
178 static const __u8 gfmul_c0[256] =
179 {
180         0x00, 0xc0, 0x07, 0xc7, 0x0e, 0xce, 0x09, 0xc9,
181         0x1c, 0xdc, 0x1b, 0xdb, 0x12, 0xd2, 0x15, 0xd5,
182         0x38, 0xf8, 0x3f, 0xff, 0x36, 0xf6, 0x31, 0xf1,
183         0x24, 0xe4, 0x23, 0xe3, 0x2a, 0xea, 0x2d, 0xed,
184         0x70, 0xb0, 0x77, 0xb7, 0x7e, 0xbe, 0x79, 0xb9,
185         0x6c, 0xac, 0x6b, 0xab, 0x62, 0xa2, 0x65, 0xa5,
186         0x48, 0x88, 0x4f, 0x8f, 0x46, 0x86, 0x41, 0x81,
187         0x54, 0x94, 0x53, 0x93, 0x5a, 0x9a, 0x5d, 0x9d,
188         0xe0, 0x20, 0xe7, 0x27, 0xee, 0x2e, 0xe9, 0x29,
189         0xfc, 0x3c, 0xfb, 0x3b, 0xf2, 0x32, 0xf5, 0x35,
190         0xd8, 0x18, 0xdf, 0x1f, 0xd6, 0x16, 0xd1, 0x11,
191         0xc4, 0x04, 0xc3, 0x03, 0xca, 0x0a, 0xcd, 0x0d,
192         0x90, 0x50, 0x97, 0x57, 0x9e, 0x5e, 0x99, 0x59,
193         0x8c, 0x4c, 0x8b, 0x4b, 0x82, 0x42, 0x85, 0x45,
194         0xa8, 0x68, 0xaf, 0x6f, 0xa6, 0x66, 0xa1, 0x61,
195         0xb4, 0x74, 0xb3, 0x73, 0xba, 0x7a, 0xbd, 0x7d,
196         0x47, 0x87, 0x40, 0x80, 0x49, 0x89, 0x4e, 0x8e,
197         0x5b, 0x9b, 0x5c, 0x9c, 0x55, 0x95, 0x52, 0x92,
198         0x7f, 0xbf, 0x78, 0xb8, 0x71, 0xb1, 0x76, 0xb6,
199         0x63, 0xa3, 0x64, 0xa4, 0x6d, 0xad, 0x6a, 0xaa,
200         0x37, 0xf7, 0x30, 0xf0, 0x39, 0xf9, 0x3e, 0xfe,
201         0x2b, 0xeb, 0x2c, 0xec, 0x25, 0xe5, 0x22, 0xe2,
202         0x0f, 0xcf, 0x08, 0xc8, 0x01, 0xc1, 0x06, 0xc6,
203         0x13, 0xd3, 0x14, 0xd4, 0x1d, 0xdd, 0x1a, 0xda,
204         0xa7, 0x67, 0xa0, 0x60, 0xa9, 0x69, 0xae, 0x6e,
205         0xbb, 0x7b, 0xbc, 0x7c, 0xb5, 0x75, 0xb2, 0x72,
206         0x9f, 0x5f, 0x98, 0x58, 0x91, 0x51, 0x96, 0x56,
207         0x83, 0x43, 0x84, 0x44, 0x8d, 0x4d, 0x8a, 0x4a,
208         0xd7, 0x17, 0xd0, 0x10, 0xd9, 0x19, 0xde, 0x1e,
209         0xcb, 0x0b, 0xcc, 0x0c, 0xc5, 0x05, 0xc2, 0x02,
210         0xef, 0x2f, 0xe8, 0x28, 0xe1, 0x21, 0xe6, 0x26,
211         0xf3, 0x33, 0xf4, 0x34, 0xfd, 0x3d, 0xfa, 0x3a
212 };
213
214
215 /* Returns V modulo 255 provided V is in the range -255,-254,...,509.
216  */
217 static inline __u8 mod255(int v)
218 {
219         if (v > 0) {
220                 if (v < 255) {
221                         return v;
222                 } else {
223                         return v - 255;
224                 }
225         } else {
226                 return v + 255;
227         }
228 }
229
230
231 /* Add two numbers in the field.  Addition in this field is equivalent
232  * to a bit-wise exclusive OR operation---subtraction is therefore
233  * identical to addition.
234  */
235 static inline __u8 gfadd(__u8 a, __u8 b)
236 {
237         return a ^ b;
238 }
239
240
241 /* Add two vectors of numbers in the field.  Each byte in A and B gets
242  * added individually.
243  */
244 static inline unsigned long gfadd_long(unsigned long a, unsigned long b)
245 {
246         return a ^ b;
247 }
248
249
250 /* Multiply two numbers in the field:
251  */
252 static inline __u8 gfmul(__u8 a, __u8 b)
253 {
254         if (a && b) {
255                 return gfpow[mod255(gflog[a] + gflog[b])];
256         } else {
257                 return 0;
258         }
259 }
260
261
262 /* Just like gfmul, except we have already looked up the log of the
263  * second number.
264  */
265 static inline __u8 gfmul_exp(__u8 a, int b)
266 {
267         if (a) {
268                 return gfpow[mod255(gflog[a] + b)];
269         } else {
270                 return 0;
271         }
272 }
273
274
275 /* Just like gfmul_exp, except that A is a vector of numbers.  That
276  * is, each byte in A gets multiplied by gfpow[mod255(B)].
277  */
278 static inline unsigned long gfmul_exp_long(unsigned long a, int b)
279 {
280         __u8 t;
281
282         if (sizeof(long) == 4) {
283                 return (
284                 ((t = (__u32)a >> 24 & 0xff) ?
285                  (((__u32) gfpow[mod255(gflog[t] + b)]) << 24) : 0) |
286                 ((t = (__u32)a >> 16 & 0xff) ?
287                  (((__u32) gfpow[mod255(gflog[t] + b)]) << 16) : 0) |
288                 ((t = (__u32)a >> 8 & 0xff) ?
289                  (((__u32) gfpow[mod255(gflog[t] + b)]) << 8) : 0) |
290                 ((t = (__u32)a >> 0 & 0xff) ?
291                  (((__u32) gfpow[mod255(gflog[t] + b)]) << 0) : 0));
292         } else if (sizeof(long) == 8) {
293                 return (
294                 ((t = (__u64)a >> 56 & 0xff) ?
295                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 56) : 0) |
296                 ((t = (__u64)a >> 48 & 0xff) ?
297                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 48) : 0) |
298                 ((t = (__u64)a >> 40 & 0xff) ?
299                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 40) : 0) |
300                 ((t = (__u64)a >> 32 & 0xff) ?
301                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 32) : 0) |
302                 ((t = (__u64)a >> 24 & 0xff) ?
303                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 24) : 0) |
304                 ((t = (__u64)a >> 16 & 0xff) ?
305                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 16) : 0) |
306                 ((t = (__u64)a >> 8 & 0xff) ?
307                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 8) : 0) |
308                 ((t = (__u64)a >> 0 & 0xff) ?
309                  (((__u64) gfpow[mod255(gflog[t] + b)]) << 0) : 0));
310         } else {
311                 TRACE_FUN(ft_t_any);
312                 TRACE_ABORT(-1, ft_t_err, "Error: size of long is %d bytes",
313                             (int)sizeof(long));
314         }
315 }
316
317
318 /* Divide two numbers in the field.  Returns a/b (modulo f(x)).
319  */
320 static inline __u8 gfdiv(__u8 a, __u8 b)
321 {
322         if (!b) {
323                 TRACE_FUN(ft_t_any);
324                 TRACE_ABORT(0xff, ft_t_bug, "Error: division by zero");
325         } else if (a == 0) {
326                 return 0;
327         } else {
328                 return gfpow[mod255(gflog[a] - gflog[b])];
329         }
330 }
331
332
333 /* The following functions return the inverse of the matrix of the
334  * linear system that needs to be solved to determine the error
335  * magnitudes.  The first deals with matrices of rank 3, while the
336  * second deals with matrices of rank 2.  The error indices are passed
337  * in arguments L0,..,L2 (0=first sector, 31=last sector).  The error
338  * indices must be sorted in ascending order, i.e., L0<L1<L2.
339  *
340  * The linear system that needs to be solved for the error magnitudes
341  * is A * b = s, where s is the known vector of syndromes, b is the
342  * vector of error magnitudes and A in the ORDER=3 case:
343  *
344  *    A_3 = {{1/r^L[0], 1/r^L[1], 1/r^L[2]},
345  *          {        1,        1,        1},
346  *          { r^L[0], r^L[1], r^L[2]}} 
347  */
348 static inline int gfinv3(__u8 l0,
349                          __u8 l1, 
350                          __u8 l2, 
351                          Matrix Ainv)
352 {
353         __u8 det;
354         __u8 t20, t10, t21, t12, t01, t02;
355         int log_det;
356
357         /* compute some intermediate results: */
358         t20 = gfpow[l2 - l0];           /* t20 = r^l2/r^l0 */
359         t10 = gfpow[l1 - l0];           /* t10 = r^l1/r^l0 */
360         t21 = gfpow[l2 - l1];           /* t21 = r^l2/r^l1 */
361         t12 = gfpow[l1 - l2 + 255];     /* t12 = r^l1/r^l2 */
362         t01 = gfpow[l0 - l1 + 255];     /* t01 = r^l0/r^l1 */
363         t02 = gfpow[l0 - l2 + 255];     /* t02 = r^l0/r^l2 */
364         /* Calculate the determinant of matrix A_3^-1 (sometimes
365          * called the Vandermonde determinant):
366          */
367         det = gfadd(t20, gfadd(t10, gfadd(t21, gfadd(t12, gfadd(t01, t02)))));
368         if (!det) {
369                 TRACE_FUN(ft_t_any);
370                 TRACE_ABORT(0, ft_t_err,
371                            "Inversion failed (3 CRC errors, >0 CRC failures)");
372         }
373         log_det = 255 - gflog[det];
374
375         /* Now, calculate all of the coefficients:
376          */
377         Ainv[0][0]= gfmul_exp(gfadd(gfpow[l1], gfpow[l2]), log_det);
378         Ainv[0][1]= gfmul_exp(gfadd(t21, t12), log_det);
379         Ainv[0][2]= gfmul_exp(gfadd(gfpow[255 - l1], gfpow[255 - l2]),log_det);
380
381         Ainv[1][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l2]), log_det);
382         Ainv[1][1]= gfmul_exp(gfadd(t20, t02), log_det);
383         Ainv[1][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l2]),log_det);
384
385         Ainv[2][0]= gfmul_exp(gfadd(gfpow[l0], gfpow[l1]), log_det);
386         Ainv[2][1]= gfmul_exp(gfadd(t10, t01), log_det);
387         Ainv[2][2]= gfmul_exp(gfadd(gfpow[255 - l0], gfpow[255 - l1]),log_det);
388
389         return 1;
390 }
391
392
393 static inline int gfinv2(__u8 l0, __u8 l1, Matrix Ainv)
394 {
395         __u8 det;
396         __u8 t1, t2;
397         int log_det;
398
399         t1 = gfpow[255 - l0];
400         t2 = gfpow[255 - l1];
401         det = gfadd(t1, t2);
402         if (!det) {
403                 TRACE_FUN(ft_t_any);
404                 TRACE_ABORT(0, ft_t_err,
405                            "Inversion failed (2 CRC errors, >0 CRC failures)");
406         }
407         log_det = 255 - gflog[det];
408
409         /* Now, calculate all of the coefficients:
410          */
411         Ainv[0][0] = Ainv[1][0] = gfpow[log_det];
412
413         Ainv[0][1] = gfmul_exp(t2, log_det);
414         Ainv[1][1] = gfmul_exp(t1, log_det);
415
416         return 1;
417 }
418
419
420 /* Multiply matrix A by vector S and return result in vector B.  M is
421  * assumed to be of order NxN, S and B of order Nx1.
422  */
423 static inline void gfmat_mul(int n, Matrix A, 
424                              __u8 *s, __u8 *b)
425 {
426         int i, j;
427         __u8 dot_prod;
428
429         for (i = 0; i < n; ++i) {
430                 dot_prod = 0;
431                 for (j = 0; j < n; ++j) {
432                         dot_prod = gfadd(dot_prod, gfmul(A[i][j], s[j]));
433                 }
434                 b[i] = dot_prod;
435         }
436 }
437 \f
438
439
440 /* The Reed Solomon ECC codes are computed over the N-th byte of each
441  * block, where N=SECTOR_SIZE.  There are up to 29 blocks of data, and
442  * 3 blocks of ECC.  The blocks are stored contiguously in memory.  A
443  * segment, consequently, is assumed to have at least 4 blocks: one or
444  * more data blocks plus three ECC blocks.
445  *
446  * Notice: In QIC-80 speak, a CRC error is a sector with an incorrect
447  *         CRC.  A CRC failure is a sector with incorrect data, but
448  *         a valid CRC.  In the error control literature, the former
449  *         is usually called "erasure", the latter "error."
450  */
451 /* Compute the parity bytes for C columns of data, where C is the
452  * number of bytes that fit into a long integer.  We use a linear
453  * feed-back register to do this.  The parity bytes P[0], P[STRIDE],
454  * P[2*STRIDE] are computed such that:
455  *
456  *              x^k * p(x) + m(x) = 0 (modulo g(x))
457  *
458  * where k = NBLOCKS,
459  *       p(x) = P[0] + P[STRIDE]*x + P[2*STRIDE]*x^2, and
460  *       m(x) = sum_{i=0}^k m_i*x^i.
461  *       m_i = DATA[i*SECTOR_SIZE]
462  */
463 static inline void set_parity(unsigned long *data,
464                               int nblocks, 
465                               unsigned long *p, 
466                               int stride)
467 {
468         unsigned long p0, p1, p2, t1, t2, *end;
469
470         end = data + nblocks * (FT_SECTOR_SIZE / sizeof(long));
471         p0 = p1 = p2 = 0;
472         while (data < end) {
473                 /* The new parity bytes p0_i, p1_i, p2_i are computed
474                  * from the old values p0_{i-1}, p1_{i-1}, p2_{i-1}
475                  * recursively as:
476                  *
477                  *        p0_i = p1_{i-1} + r^105 * (m_{i-1} - p0_{i-1})
478                  *        p1_i = p2_{i-1} + r^105 * (m_{i-1} - p0_{i-1})
479                  *        p2_i =                    (m_{i-1} - p0_{i-1})
480                  *
481                  * With the initial condition: p0_0 = p1_0 = p2_0 = 0.
482                  */
483                 t1 = gfadd_long(*data, p0);
484                 /*
485                  * Multiply each byte in t1 by 0xc0:
486                  */
487                 if (sizeof(long) == 4) {
488                         t2= (((__u32) gfmul_c0[(__u32)t1 >> 24 & 0xff]) << 24 |
489                              ((__u32) gfmul_c0[(__u32)t1 >> 16 & 0xff]) << 16 |
490                              ((__u32) gfmul_c0[(__u32)t1 >>  8 & 0xff]) <<  8 |
491                              ((__u32) gfmul_c0[(__u32)t1 >>  0 & 0xff]) <<  0);
492                 } else if (sizeof(long) == 8) {
493                         t2= (((__u64) gfmul_c0[(__u64)t1 >> 56 & 0xff]) << 56 |
494                              ((__u64) gfmul_c0[(__u64)t1 >> 48 & 0xff]) << 48 |
495                              ((__u64) gfmul_c0[(__u64)t1 >> 40 & 0xff]) << 40 |
496                              ((__u64) gfmul_c0[(__u64)t1 >> 32 & 0xff]) << 32 |
497                              ((__u64) gfmul_c0[(__u64)t1 >> 24 & 0xff]) << 24 |
498                              ((__u64) gfmul_c0[(__u64)t1 >> 16 & 0xff]) << 16 |
499                              ((__u64) gfmul_c0[(__u64)t1 >>  8 & 0xff]) <<  8 |
500                              ((__u64) gfmul_c0[(__u64)t1 >>  0 & 0xff]) <<  0);
501                 } else {
502                         TRACE_FUN(ft_t_any);
503                         TRACE(ft_t_err, "Error: long is of size %d",
504                               (int) sizeof(long));
505                         TRACE_EXIT;
506                 }
507                 p0 = gfadd_long(t2, p1);
508                 p1 = gfadd_long(t2, p2);
509                 p2 = t1;
510                 data += FT_SECTOR_SIZE / sizeof(long);
511         }
512         *p = p0;
513         p += stride;
514         *p = p1;
515         p += stride;
516         *p = p2;
517         return;
518 }
519
520
521 /* Compute the 3 syndrome values.  DATA should point to the first byte
522  * of the column for which the syndromes are desired.  The syndromes
523  * are computed over the first NBLOCKS of rows.  The three bytes will
524  * be placed in S[0], S[1], and S[2].
525  *
526  * S[i] is the value of the "message" polynomial m(x) evaluated at the
527  * i-th root of the generator polynomial g(x).
528  *
529  * As g(x)=(x-r^-1)(x-1)(x-r^1) we evaluate the message polynomial at
530  * x=r^-1 to get S[0], at x=r^0=1 to get S[1], and at x=r to get S[2].
531  * This could be done directly and efficiently via the Horner scheme.
532  * However, it would require multiplication tables for the factors
533  * r^-1 (0xc3) and r (0x02).  The following scheme does not require
534  * any multiplication tables beyond what's needed for set_parity()
535  * anyway and is slightly faster if there are no errors and slightly
536  * slower if there are errors.  The latter is hopefully the infrequent
537  * case.
538  *
539  * To understand the alternative algorithm, notice that set_parity(m,
540  * k, p) computes parity bytes such that:
541  *
542  *      x^k * p(x) = m(x) (modulo g(x)).
543  *
544  * That is, to evaluate m(r^m), where r^m is a root of g(x), we can
545  * simply evaluate (r^m)^k*p(r^m).  Also, notice that p is 0 if and
546  * only if s is zero.  That is, if all parity bytes are 0, we know
547  * there is no error in the data and consequently there is no need to
548  * compute s(x) at all!  In all other cases, we compute s(x) from p(x)
549  * by evaluating (r^m)^k*p(r^m) for m=-1, m=0, and m=1.  The p(x)
550  * polynomial is evaluated via the Horner scheme.
551  */
552 static int compute_syndromes(unsigned long *data, int nblocks, unsigned long *s)
553 {
554         unsigned long p[3];
555
556         set_parity(data, nblocks, p, 1);
557         if (p[0] | p[1] | p[2]) {
558                 /* Some of the checked columns do not have a zero
559                  * syndrome.  For simplicity, we compute the syndromes
560                  * for all columns that we have computed the
561                  * remainders for.
562                  */
563                 s[0] = gfmul_exp_long(
564                         gfadd_long(p[0], 
565                                    gfmul_exp_long(
566                                            gfadd_long(p[1], 
567                                                       gfmul_exp_long(p[2], -1)),
568                                            -1)), 
569                         -nblocks);
570                 s[1] = gfadd_long(gfadd_long(p[2], p[1]), p[0]);
571                 s[2] = gfmul_exp_long(
572                         gfadd_long(p[0], 
573                                    gfmul_exp_long(
574                                            gfadd_long(p[1],
575                                                       gfmul_exp_long(p[2], 1)),
576                                            1)),
577                         nblocks);
578                 return 0;
579         } else {
580                 return 1;
581         }
582 }
583
584
585 /* Correct the block in the column pointed to by DATA.  There are NBAD
586  * CRC errors and their indices are in BAD_LOC[0], up to
587  * BAD_LOC[NBAD-1].  If NBAD>1, Ainv holds the inverse of the matrix
588  * of the linear system that needs to be solved to determine the error
589  * magnitudes.  S[0], S[1], and S[2] are the syndrome values.  If row
590  * j gets corrected, then bit j will be set in CORRECTION_MAP.
591  */
592 static inline int correct_block(__u8 *data, int nblocks,
593                                 int nbad, int *bad_loc, Matrix Ainv,
594                                 __u8 *s,
595                                 SectorMap * correction_map)
596 {
597         int ncorrected = 0;
598         int i;
599         __u8 t1, t2;
600         __u8 c0, c1, c2;        /* check bytes */
601         __u8 error_mag[3], log_error_mag;
602         __u8 *dp, l, e;
603         TRACE_FUN(ft_t_any);
604
605         switch (nbad) {
606         case 0:
607                 /* might have a CRC failure: */
608                 if (s[0] == 0) {
609                         /* more than one error */
610                         TRACE_ABORT(-1, ft_t_err,
611                                  "ECC failed (0 CRC errors, >1 CRC failures)");
612                 }
613                 t1 = gfdiv(s[1], s[0]);
614                 if ((bad_loc[nbad++] = gflog[t1]) >= nblocks) {
615                         TRACE(ft_t_err,
616                               "ECC failed (0 CRC errors, >1 CRC failures)");
617                         TRACE_ABORT(-1, ft_t_err,
618                                   "attempt to correct data at %d", bad_loc[0]);
619                 }
620                 error_mag[0] = s[1];
621                 break;
622         case 1:
623                 t1 = gfadd(gfmul_exp(s[1], bad_loc[0]), s[2]);
624                 t2 = gfadd(gfmul_exp(s[0], bad_loc[0]), s[1]);
625                 if (t1 == 0 && t2 == 0) {
626                         /* one erasure, no error: */
627                         Ainv[0][0] = gfpow[bad_loc[0]];
628                 } else if (t1 == 0 || t2 == 0) {
629                         /* one erasure and more than one error: */
630                         TRACE_ABORT(-1, ft_t_err,
631                                     "ECC failed (1 erasure, >1 error)");
632                 } else {
633                         /* one erasure, one error: */
634                         if ((bad_loc[nbad++] = gflog[gfdiv(t1, t2)]) 
635                             >= nblocks) {
636                                 TRACE(ft_t_err, "ECC failed "
637                                       "(1 CRC errors, >1 CRC failures)");
638                                 TRACE_ABORT(-1, ft_t_err,
639                                             "attempt to correct data at %d",
640                                             bad_loc[1]);
641                         }
642                         if (!gfinv2(bad_loc[0], bad_loc[1], Ainv)) {
643                                 /* inversion failed---must have more
644                                  *  than one error 
645                                  */
646                                 TRACE_EXIT -1;
647                         }
648                 }
649                 /* FALL THROUGH TO ERROR MAGNITUDE COMPUTATION:
650                  */
651         case 2:
652         case 3:
653                 /* compute error magnitudes: */
654                 gfmat_mul(nbad, Ainv, s, error_mag);
655                 break;
656
657         default:
658                 TRACE_ABORT(-1, ft_t_err,
659                             "Internal Error: number of CRC errors > 3");
660         }
661
662         /* Perform correction by adding ERROR_MAG[i] to the byte at
663          * offset BAD_LOC[i].  Also add the value of the computed
664          * error polynomial to the syndrome values.  If the correction
665          * was successful, the resulting check bytes should be zero
666          * (i.e., the corrected data is a valid code word).
667          */
668         c0 = s[0];
669         c1 = s[1];
670         c2 = s[2];
671         for (i = 0; i < nbad; ++i) {
672                 e = error_mag[i];
673                 if (e) {
674                         /* correct the byte at offset L by magnitude E: */
675                         l = bad_loc[i];
676                         dp = &data[l * FT_SECTOR_SIZE];
677                         *dp = gfadd(*dp, e);
678                         *correction_map |= 1 << l;
679                         ++ncorrected;
680
681                         log_error_mag = gflog[e];
682                         c0 = gfadd(c0, gfpow[mod255(log_error_mag - l)]);
683                         c1 = gfadd(c1, e);
684                         c2 = gfadd(c2, gfpow[mod255(log_error_mag + l)]);
685                 }
686         }
687         if (c0 || c1 || c2) {
688                 TRACE_ABORT(-1, ft_t_err,
689                             "ECC self-check failed, too many errors");
690         }
691         TRACE_EXIT ncorrected;
692 }
693
694
695 #if defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID)
696
697 /* Perform a sanity check on the computed parity bytes:
698  */
699 static int sanity_check(unsigned long *data, int nblocks)
700 {
701         TRACE_FUN(ft_t_any);
702         unsigned long s[3];
703
704         if (!compute_syndromes(data, nblocks, s)) {
705                 TRACE_ABORT(0, ft_bug,
706                             "Internal Error: syndrome self-check failed");
707         }
708         TRACE_EXIT 1;
709 }
710
711 #endif /* defined(ECC_SANITY_CHECK) || defined(ECC_PARANOID) */
712
713 /* Compute the parity for an entire segment of data.
714  */
715 int ftape_ecc_set_segment_parity(struct memory_segment *mseg)
716 {
717         int i;
718         __u8 *parity_bytes;
719
720         parity_bytes = &mseg->data[(mseg->blocks - 3) * FT_SECTOR_SIZE];
721         for (i = 0; i < FT_SECTOR_SIZE; i += sizeof(long)) {
722                 set_parity((unsigned long *) &mseg->data[i], mseg->blocks - 3,
723                            (unsigned long *) &parity_bytes[i],
724                            FT_SECTOR_SIZE / sizeof(long));
725 #ifdef ECC_PARANOID
726                 if (!sanity_check((unsigned long *) &mseg->data[i],
727                                    mseg->blocks)) {
728                         return -1;
729                 }
730 #endif                          /* ECC_PARANOID */
731         }
732         return 0;
733 }
734
735
736 /* Checks and corrects (if possible) the segment MSEG.  Returns one of
737  * ECC_OK, ECC_CORRECTED, and ECC_FAILED.
738  */
739 int ftape_ecc_correct_data(struct memory_segment *mseg)
740 {
741         int col, i, result;
742         int ncorrected = 0;
743         int nerasures = 0;      /* # of erasures (CRC errors) */
744         int erasure_loc[3];     /* erasure locations */
745         unsigned long ss[3];
746         __u8 s[3];
747         Matrix Ainv;
748         TRACE_FUN(ft_t_flow);
749
750         mseg->corrected = 0;
751
752         /* find first column that has non-zero syndromes: */
753         for (col = 0; col < FT_SECTOR_SIZE; col += sizeof(long)) {
754                 if (!compute_syndromes((unsigned long *) &mseg->data[col],
755                                        mseg->blocks, ss)) {
756                         /* something is wrong---have to fix things */
757                         break;
758                 }
759         }
760         if (col >= FT_SECTOR_SIZE) {
761                 /* all syndromes are ok, therefore nothing to correct */
762                 TRACE_EXIT ECC_OK;
763         }
764         /* count the number of CRC errors if there were any: */
765         if (mseg->read_bad) {
766                 for (i = 0; i < mseg->blocks; i++) {
767                         if (BAD_CHECK(mseg->read_bad, i)) {
768                                 if (nerasures >= 3) {
769                                         /* this is too much for ECC */
770                                         TRACE_ABORT(ECC_FAILED, ft_t_err,
771                                                 "ECC failed (>3 CRC errors)");
772                                 }       /* if */
773                                 erasure_loc[nerasures++] = i;
774                         }
775                 }
776         }
777         /*
778          * If there are at least 2 CRC errors, determine inverse of matrix
779          * of linear system to be solved:
780          */
781         switch (nerasures) {
782         case 2:
783                 if (!gfinv2(erasure_loc[0], erasure_loc[1], Ainv)) {
784                         TRACE_EXIT ECC_FAILED;
785                 }
786                 break;
787         case 3:
788                 if (!gfinv3(erasure_loc[0], erasure_loc[1],
789                             erasure_loc[2], Ainv)) {
790                         TRACE_EXIT ECC_FAILED;
791                 }
792                 break;
793         default:
794                 /* this is not an error condition... */
795                 break;
796         }
797
798         do {
799                 for (i = 0; i < sizeof(long); ++i) {
800                         s[0] = ss[0];
801                         s[1] = ss[1];
802                         s[2] = ss[2];
803                         if (s[0] | s[1] | s[2]) {
804 #ifdef BIG_ENDIAN
805                                 result = correct_block(
806                                         &mseg->data[col + sizeof(long) - 1 - i],
807                                         mseg->blocks,
808                                         nerasures,
809                                         erasure_loc,
810                                         Ainv,
811                                         s,
812                                         &mseg->corrected);
813 #else
814                                 result = correct_block(&mseg->data[col + i],
815                                                        mseg->blocks,
816                                                        nerasures,
817                                                        erasure_loc,
818                                                        Ainv,
819                                                        s,
820                                                        &mseg->corrected);
821 #endif
822                                 if (result < 0) {
823                                         TRACE_EXIT ECC_FAILED;
824                                 }
825                                 ncorrected += result;
826                         }
827                         ss[0] >>= 8;
828                         ss[1] >>= 8;
829                         ss[2] >>= 8;
830                 }
831
832 #ifdef ECC_SANITY_CHECK
833                 if (!sanity_check((unsigned long *) &mseg->data[col],
834                                   mseg->blocks)) {
835                         TRACE_EXIT ECC_FAILED;
836                 }
837 #endif                          /* ECC_SANITY_CHECK */
838
839                 /* find next column with non-zero syndromes: */
840                 while ((col += sizeof(long)) < FT_SECTOR_SIZE) {
841                         if (!compute_syndromes((unsigned long *)
842                                     &mseg->data[col], mseg->blocks, ss)) {
843                                 /* something is wrong---have to fix things */
844                                 break;
845                         }
846                 }
847         } while (col < FT_SECTOR_SIZE);
848         if (ncorrected && nerasures == 0) {
849                 TRACE(ft_t_warn, "block contained error not caught by CRC");
850         }
851         TRACE((ncorrected > 0) ? ft_t_noise : ft_t_any, "number of corrections: %d", ncorrected);
852         TRACE_EXIT ncorrected ? ECC_CORRECTED : ECC_OK;
853 }