hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/lib/reed_solomon/decode_rs.c
....@@ -22,6 +22,7 @@
2222 uint16_t *index_of = rs->index_of;
2323 uint16_t u, q, tmp, num1, num2, den, discr_r, syn_error;
2424 int count = 0;
25
+ int num_corrected;
2526 uint16_t msk = (uint16_t) rs->nn;
2627
2728 /*
....@@ -39,7 +40,7 @@
3940
4041 /* Check length parameter for validity */
4142 pad = nn - nroots - len;
42
- BUG_ON(pad < 0 || pad >= nn);
43
+ BUG_ON(pad < 0 || pad >= nn - nroots);
4344
4445 /* Does the caller provide the syndrome ? */
4546 if (s != NULL) {
....@@ -98,8 +99,7 @@
9899 /* if syndrome is zero, data[] is a codeword and there are no
99100 * errors to correct. So return data[] unmodified
100101 */
101
- count = 0;
102
- goto finish;
102
+ return 0;
103103 }
104104
105105 decode:
....@@ -185,6 +185,15 @@
185185 if (lambda[i] != nn)
186186 deg_lambda = i;
187187 }
188
+
189
+ if (deg_lambda == 0) {
190
+ /*
191
+ * deg(lambda) is zero even though the syndrome is non-zero
192
+ * => uncorrectable error detected
193
+ */
194
+ return -EBADMSG;
195
+ }
196
+
188197 /* Find roots of error+erasure locator polynomial by Chien search */
189198 memcpy(&reg[1], &lambda[1], nroots * sizeof(reg[0]));
190199 count = 0; /* Number of roots of lambda(x) */
....@@ -198,6 +207,12 @@
198207 }
199208 if (q != 0)
200209 continue; /* Not a root */
210
+
211
+ if (k < pad) {
212
+ /* Impossible error location. Uncorrectable error. */
213
+ return -EBADMSG;
214
+ }
215
+
201216 /* store root (index-form) and error location number */
202217 root[count] = i;
203218 loc[count] = k;
....@@ -212,8 +227,7 @@
212227 * deg(lambda) unequal to number of roots => uncorrectable
213228 * error detected
214229 */
215
- count = -EBADMSG;
216
- goto finish;
230
+ return -EBADMSG;
217231 }
218232 /*
219233 * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
....@@ -233,7 +247,9 @@
233247 /*
234248 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
235249 * inv(X(l))**(fcr-1) and den = lambda_pr(inv(X(l))) all in poly-form
250
+ * Note: we reuse the buffer for b to store the correction pattern
236251 */
252
+ num_corrected = 0;
237253 for (j = count - 1; j >= 0; j--) {
238254 num1 = 0;
239255 for (i = deg_omega; i >= 0; i--) {
....@@ -241,6 +257,13 @@
241257 num1 ^= alpha_to[rs_modnn(rs, omega[i] +
242258 i * root[j])];
243259 }
260
+
261
+ if (num1 == 0) {
262
+ /* Nothing to correct at this position */
263
+ b[j] = 0;
264
+ continue;
265
+ }
266
+
244267 num2 = alpha_to[rs_modnn(rs, root[j] * (fcr - 1) + nn)];
245268 den = 0;
246269
....@@ -252,30 +275,52 @@
252275 i * root[j])];
253276 }
254277 }
255
- /* Apply error to data */
256
- if (num1 != 0 && loc[j] >= pad) {
257
- uint16_t cor = alpha_to[rs_modnn(rs,index_of[num1] +
258
- index_of[num2] +
259
- nn - index_of[den])];
260
- /* Store the error correction pattern, if a
261
- * correction buffer is available */
262
- if (corr) {
263
- corr[j] = cor;
264
- } else {
265
- /* If a data buffer is given and the
266
- * error is inside the message,
267
- * correct it */
268
- if (data && (loc[j] < (nn - nroots)))
269
- data[loc[j] - pad] ^= cor;
278
+
279
+ b[j] = alpha_to[rs_modnn(rs, index_of[num1] +
280
+ index_of[num2] +
281
+ nn - index_of[den])];
282
+ num_corrected++;
283
+ }
284
+
285
+ /*
286
+ * We compute the syndrome of the 'error' and check that it matches
287
+ * the syndrome of the received word
288
+ */
289
+ for (i = 0; i < nroots; i++) {
290
+ tmp = 0;
291
+ for (j = 0; j < count; j++) {
292
+ if (b[j] == 0)
293
+ continue;
294
+
295
+ k = (fcr + i) * prim * (nn-loc[j]-1);
296
+ tmp ^= alpha_to[rs_modnn(rs, index_of[b[j]] + k)];
297
+ }
298
+
299
+ if (tmp != alpha_to[s[i]])
300
+ return -EBADMSG;
301
+ }
302
+
303
+ /*
304
+ * Store the error correction pattern, if a
305
+ * correction buffer is available
306
+ */
307
+ if (corr && eras_pos) {
308
+ j = 0;
309
+ for (i = 0; i < count; i++) {
310
+ if (b[i]) {
311
+ corr[j] = b[i];
312
+ eras_pos[j++] = loc[i] - pad;
270313 }
314
+ }
315
+ } else if (data && par) {
316
+ /* Apply error to data and parity */
317
+ for (i = 0; i < count; i++) {
318
+ if (loc[i] < (nn - nroots))
319
+ data[loc[i] - pad] ^= b[i];
320
+ else
321
+ par[loc[i] - pad - len] ^= b[i];
271322 }
272323 }
273324
274
-finish:
275
- if (eras_pos != NULL) {
276
- for (i = 0; i < count; i++)
277
- eras_pos[i] = loc[i] - pad;
278
- }
279
- return count;
280
-
325
+ return num_corrected;
281326 }