1 
2 /*  dvdisaster: Additional error correction for optical media.
3  *  Copyright (C) 2004-2015 Carsten Gnoerlich.
4  *
5  *  Email: carsten@dvdisaster.org  -or-  cgnoerlich@fsfe.org
6  *  Project homepage: http://www.dvdisaster.org
7  *
8  *  This file is part of dvdisaster.
9  *
10  *  dvdisaster is free software: you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation, either version 3 of the License, or
13  *  (at your option) any later version.
14  *
15  *  dvdisaster is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with dvdisaster. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include "dvdisaster.h"
25 
26 /*
27  * Debugging function
28  */
29 
DumpSector(RawBuffer * rb,char * path)30 void DumpSector(RawBuffer *rb, char *path)
31 {  FILE *file;
32    char *filename;
33    int i;
34 
35    if(rb->samplesRead <= 0)
36      return;
37 
38    filename = g_strdup_printf("%s%lld.h", path, (long long)rb->lba);
39 
40    file = portable_fopen(filename, "w");
41 
42    fprintf(file,
43 	   "#define SAMPLES_READ %d\n"
44 	   "#define SAMPLE_LENGTH %d\n"
45 	   "#define LBA %lld\n"
46 	   "unsigned char cd_frame[][%d] = {\n",
47 	   rb->samplesRead, rb->sampleSize,
48 	   (long long)rb->lba, rb->sampleSize);
49 
50    for(i=0; i<rb->samplesRead; i++)
51    {  int j;
52 
53       fprintf(file, "{\n");
54       for(j=0; j<rb->sampleSize; j++)
55       {  fprintf(file, "%3d, ",rb->rawBuf[i][j]);
56 	 if(j%16 == 15) fprintf(file, "\n");
57       }
58       fprintf(file, "},\n");
59    }
60 
61    fprintf(file, "};\n");
62 
63    fclose(file);
64 
65    PrintCLI(_("Sector %lld dumped to %s\n"), rb->lba, filename);
66 
67    g_free(filename);
68 }
69 
70 /***
71  *** Create our local working context
72  ***/
73 
CreateRawBuffer(int sample_length)74 RawBuffer *CreateRawBuffer(int sample_length)
75 {  RawBuffer *rb;
76    int i,j;
77 
78    rb = g_malloc0(sizeof(RawBuffer));
79    rb->samplesMax = MAX(1, Closure->maxReadAttempts);
80    rb->sampleSize = sample_length;
81 
82    rb->gt = CreateGaloisTables(0x11d);
83    rb->rt = CreateReedSolomonTables(rb->gt, 0, 1, 10);
84 
85    rb->dataOffset = 16;  /* default for mode1 data sectors */
86 
87    rb->workBuf   = CreateAlignedBuffer(sample_length*MAX_CLUSTER_SECTORS);
88    rb->zeroSector= g_malloc0(sample_length);
89    rb->rawBuf    = g_malloc(Closure->maxReadAttempts * sizeof(unsigned char*));
90    rb->recovered = g_malloc(sample_length);
91    rb->byteState = g_malloc(sample_length);
92    rb->byteCount = g_malloc(sample_length);
93    rb->reference = g_malloc(sample_length);
94 
95    for(i=0; i<Closure->maxReadAttempts; i++)
96    {  rb->rawBuf[i] = g_malloc(sample_length);
97    }
98 
99    for(i=0; i<N_P_VECTORS; i++)
100    {  rb->pParity1[i] = g_malloc(Closure->maxReadAttempts);
101       rb->pParity2[i] = g_malloc(Closure->maxReadAttempts);
102    }
103 
104    for(i=0; i<N_Q_VECTORS; i++)
105    {  rb->qParity1[i] = g_malloc(Closure->maxReadAttempts);
106       rb->qParity2[i] = g_malloc(Closure->maxReadAttempts);
107    }
108 
109    rb->pLoad = g_malloc0(Closure->maxReadAttempts * sizeof(int));
110    rb->qLoad = g_malloc0(Closure->maxReadAttempts * sizeof(int));
111 
112    for(i=0; i<N_P_VECTORS; i++)
113       rb->pList[i]  = g_malloc(Closure->maxReadAttempts * sizeof(char*));
114 
115    for(i=0; i<N_P_VECTORS; i++)
116      for(j=0; j<Closure->maxReadAttempts; j++)
117        rb->pList[i][j] = g_malloc(P_VECTOR_SIZE);
118 
119    for(i=0; i<N_Q_VECTORS; i++)
120       rb->qList[i]  = g_malloc(Closure->maxReadAttempts * sizeof(char*));
121 
122    for(i=0; i<N_Q_VECTORS; i++)
123      for(j=0; j<Closure->maxReadAttempts; j++)
124        rb->qList[i][j] = g_malloc(Q_VECTOR_SIZE);
125 
126    memset(rb->pn, 0, sizeof(rb->pn));
127    memset(rb->qn, 0, sizeof(rb->qn));
128 
129    return rb;
130 }
131 
ReallocRawBuffer(RawBuffer * rb,int new_samples_max)132 void ReallocRawBuffer(RawBuffer *rb, int new_samples_max)
133 {  int i,j;
134 
135    if(new_samples_max <= rb->samplesMax)
136       return;
137 
138    rb->rawBuf = g_realloc(rb->rawBuf, new_samples_max * sizeof(unsigned char*));
139 
140    for(i=rb->samplesMax; i<new_samples_max; i++)
141    {  rb->rawBuf[i] = g_malloc(rb->sampleSize);
142    }
143 
144    for(i=0; i<N_P_VECTORS; i++)
145    {  rb->pParity1[i] = g_realloc(rb->pParity1[i], new_samples_max);
146       rb->pParity2[i] = g_realloc(rb->pParity2[i], new_samples_max);
147    }
148 
149    for(i=0; i<N_Q_VECTORS; i++)
150    {  rb->qParity1[i] = g_realloc(rb->qParity1[i], new_samples_max);
151       rb->qParity2[i] = g_realloc(rb->qParity2[i], new_samples_max);
152    }
153 
154    rb->pLoad = g_realloc(rb->pLoad, new_samples_max * sizeof(int));
155    rb->qLoad = g_realloc(rb->qLoad, new_samples_max * sizeof(int));
156 
157    for(i=0; i<N_P_VECTORS; i++)
158       rb->pList[i]  = g_realloc(rb->pList[i],  new_samples_max * sizeof(char*));
159 
160    for(i=0; i<N_P_VECTORS; i++)
161      for(j=rb->samplesMax; j<new_samples_max; j++)
162        rb->pList[i][j] = g_malloc(P_VECTOR_SIZE);
163 
164    for(i=0; i<N_Q_VECTORS; i++)
165       rb->qList[i]  = g_realloc(rb->qList[i],  new_samples_max * sizeof(char*));
166 
167    for(i=0; i<N_Q_VECTORS; i++)
168      for(j=rb->samplesMax; j<new_samples_max; j++)
169        rb->qList[i][j] = g_malloc(Q_VECTOR_SIZE);
170 
171    rb->samplesMax = new_samples_max;
172 
173    rb->bestP1 = rb->bestP2 = N_P_VECTORS;
174    rb->bestQ1 = rb->bestQ2 = N_Q_VECTORS;
175 }
176 
ResetRawBuffer(RawBuffer * rb)177 void ResetRawBuffer(RawBuffer *rb)
178 {  int i;
179 
180    rb->samplesRead = 0;
181 
182    for(i=0; i<N_P_VECTORS; i++)
183      rb->pParityN[i][0] = rb->pParityN[i][1] = 0;
184 
185    for(i=0; i<N_Q_VECTORS; i++)
186      rb->qParityN[i][0] = rb->qParityN[i][1] = 0;
187 
188    rb->bestFrame = 0;
189    rb->bestP1 = rb->bestP2 = N_P_VECTORS;
190    rb->bestQ1 = rb->bestQ2 = N_Q_VECTORS;
191 }
192 
FreeRawBuffer(RawBuffer * rb)193 void FreeRawBuffer(RawBuffer *rb)
194 {  int i,j;
195 
196    FreeGaloisTables(rb->gt);
197    FreeReedSolomonTables(rb->rt);
198 
199    for(i=0; i<rb->samplesMax; i++)
200      g_free(rb->rawBuf[i]);
201 
202    for(i=0; i<N_P_VECTORS; i++)
203    {  g_free(rb->pParity1[i]);
204       g_free(rb->pParity2[i]);
205    }
206 
207    for(i=0; i<N_Q_VECTORS; i++)
208    {  g_free(rb->qParity1[i]);
209       g_free(rb->qParity2[i]);
210    }
211 
212    g_free(rb->pLoad);
213    g_free(rb->qLoad);
214 
215    for(i=0; i<N_P_VECTORS; i++)
216    {  for(j=0; j<rb->samplesMax; j++)
217 	 g_free(rb->pList[i][j]);
218 
219       g_free(rb->pList[i]);
220    }
221 
222    for(i=0; i<N_Q_VECTORS; i++)
223    {  for(j=0; j<rb->samplesMax; j++)
224 	 g_free(rb->qList[i][j]);
225 
226       g_free(rb->qList[i]);
227    }
228 
229    FreeAlignedBuffer(rb->workBuf);
230    g_free(rb->zeroSector);
231    g_free(rb->rawBuf);
232    g_free(rb->recovered);
233    g_free(rb->byteState);
234    g_free(rb->byteCount);
235    g_free(rb->reference);
236    g_free(rb);
237 }
238 
239 /***
240  *** CD MSF address calculations
241  ***/
242 
243 /* Convert LBA sector number into MSF format */
244 
lba_to_msf(int lba,unsigned char * minute,unsigned char * second,unsigned char * frame)245 static void lba_to_msf(int lba, unsigned char *minute, unsigned char *second, unsigned char
246 *frame)
247 {
248   *frame = lba % 75;
249   lba /= 75;
250   lba += 2;             /* address + 150 frames */
251   *second = lba % 60;
252   *minute = lba / 60;
253 }
254 
MSFtoLBA(unsigned char minute_bcd,unsigned char second_bcd,unsigned char frame_bcd)255 int MSFtoLBA(unsigned char minute_bcd, unsigned char second_bcd, unsigned char frame_bcd)
256 {  int minute = (minute_bcd & 0x0f) + 10*((minute_bcd >> 4) & 0x0f);
257    int second = (second_bcd & 0x0f) + 10*((second_bcd >> 4) & 0x0f);
258    int frame = (frame_bcd & 0x0f) + 10*((frame_bcd >> 4) & 0x0f);
259 
260    return (int)frame + 75 * (second - 2 + 60 * minute);
261 }
262 
263 /* Convert byte into BCD notation */
264 
int_to_bcd(int value)265 static int int_to_bcd(int value)
266 {
267   return ((value / 10) << 4) | (value % 10);
268 }
269 
270 /*
271  * Validate the MSF field contents.
272  * Returns TRUE if the given lba matches the MSF field.
273  * When sloppy==TRUE; only the frm fields must match.
274  * This is because drives often return a sector which is a few numbers
275  * off due to problems finding the sync header. These must be kept from
276  * going into the sample set. However, differences in the min/sec fields
277  * are probably just read errors in the respective bytes as the drive
278  * will probably not have derailed over such a large distance.
279  */
280 
CheckMSF(unsigned char * frame,int lba,int sloppy)281 int CheckMSF(unsigned char *frame, int lba, int sloppy)
282 {  unsigned char min,sec,frm;
283 
284    lba_to_msf(lba, &min, &sec, &frm);
285    min = int_to_bcd(min);
286    sec = int_to_bcd(sec);
287    frm = int_to_bcd(frm);
288 
289    if(sloppy && frame[14] == frm)
290       return TRUE;
291 
292    if(   frame[12] != min
293       || frame[13] != sec
294       || frame[14] != frm)
295      return FALSE;
296 
297    return TRUE;
298 }
299 
300 /*
301  * Initialize Sync, MSF and data mode bytes
302  */
303 
304 static unsigned char sync_pattern[12] =
305 { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0 };
306 
InitializeCDFrame(unsigned char * cd_frame,int sector,int xa_mode,int reinitialize)307 void InitializeCDFrame(unsigned char *cd_frame, int sector,
308 		       int xa_mode, int reinitialize)
309 {  unsigned char minute, second, frame;
310 
311    if(!reinitialize)
312       memset(cd_frame, 0, MAX_RAW_TRANSFER_SIZE);  /* defensive programming */
313 
314    /* 12 sync bytes 0x00, 0xff, 0xff, ..., 0xff, 0xff, 0x00 */
315 
316    memcpy(cd_frame, sync_pattern, 12);
317 
318    /* MSF of sector address, BCD encoded */
319 
320    lba_to_msf(sector, &minute, &second, &frame);
321    cd_frame[12] = int_to_bcd(minute);
322    cd_frame[13] = int_to_bcd(second);
323    cd_frame[14] = int_to_bcd(frame);
324 
325    /* Data mode */
326 
327    cd_frame[15] = 0x01;
328 
329    if(!xa_mode)
330       memset(&(cd_frame[2068]), 0, 8); /* data tracks have always 8 zero bytes here */
331 }
332 
333 /*
334  * Returns TRUE is at least 75% of the frame sync bytes match the sync pattern.
335  */
336 
check_for_sync_pattern(unsigned char * new_frame)337 static int check_for_sync_pattern(unsigned char *new_frame)
338 {  int matches = 0;
339    int i;
340 
341    for(i=0; i<12; i++)
342      if(new_frame[i] == sync_pattern[i])
343        matches++;
344 
345    return matches >= 8;
346 }
347 
348 /***
349  *** CD level CRC calculation
350  ***/
351 
352 /*
353  * Test raw sector against its 32bit CRC.
354  * Returns TRUE if frame is good.
355  */
356 
CheckEDC(unsigned char * cd_frame,int xa_mode)357 int CheckEDC(unsigned char *cd_frame, int xa_mode)
358 { unsigned int expected_crc, real_crc;
359 
360    /* XA: Get CRC from byte position 2072 */
361 
362    if(xa_mode)
363    {  expected_crc =  cd_frame[2072] << 24
364                     | cd_frame[2073] << 16
365                     | cd_frame[2074] <<  8
366                     | cd_frame[2075];
367    }
368    else /* Get CRC from byte position 2064 */
369    {  expected_crc =  cd_frame[0x810] << 24
370                     | cd_frame[0x811] << 16
371                     | cd_frame[0x812] <<  8
372                     | cd_frame[0x813];
373    }
374 
375 #ifdef HAVE_LITTLE_ENDIAN
376    expected_crc = SwapBytes32(expected_crc);  /* CRC on disc is big endian */
377 #endif
378 
379    if(xa_mode) real_crc = EDCCrc32(cd_frame+16, 2056);
380    else        real_crc = EDCCrc32(cd_frame, 2064);
381 
382    return expected_crc == real_crc;
383 }
384 
385 /***
386  *** A very simple L-EC error correction.
387  ***
388  * Perform just one pass over the Q and P vectors to see if everything
389  * is okay respectively correct minor errors. This is pretty much the
390  * same stuff the drive is supposed to do in the final L-EC stage.
391  */
392 
simple_lec(RawBuffer * rb,unsigned char * frame,char * msg)393 static int simple_lec(RawBuffer *rb, unsigned char *frame, char *msg)
394 {  unsigned char byte_state[rb->sampleSize];
395    unsigned char p_vector[P_VECTOR_SIZE];
396    unsigned char q_vector[Q_VECTOR_SIZE];
397    unsigned char p_state[P_VECTOR_SIZE];
398    int erasures[Q_VECTOR_SIZE], erasure_count;
399    int ignore[2];
400    int p_failures, q_failures;
401    int p_corrected, q_corrected;
402    int p,q;
403 
404    /* Setup */
405 
406    memset(byte_state, 0, rb->sampleSize);
407 
408    p_failures = q_failures = 0;
409    p_corrected = q_corrected = 0;
410 
411    /* Perform Q-Parity error correction */
412 
413    for(q=0; q<N_Q_VECTORS; q++)
414    {  int err;
415 
416       /* We have no erasure information for Q vectors */
417 
418      GetQVector(frame, q_vector, q);
419      err = DecodePQ(rb->rt, q_vector, Q_PADDING, ignore, 0);
420 
421      /* See what we've got */
422 
423      if(err < 0)  /* Uncorrectable. Mark bytes are erasure. */
424      {  q_failures++;
425         FillQVector(byte_state, 1, q);
426      }
427      else         /* Correctable */
428      {  if(err == 1 || err == 2) /* Store back corrected vector */
429 	{  SetQVector(frame, q_vector, q);
430 	   q_corrected++;
431 	}
432      }
433    }
434 
435    /* Perform P-Parity error correction */
436 
437    for(p=0; p<N_P_VECTORS; p++)
438    {  int err,i;
439 
440       /* Try error correction without erasure information */
441 
442       GetPVector(frame, p_vector, p);
443       err = DecodePQ(rb->rt, p_vector, P_PADDING, ignore, 0);
444 
445       /* If unsuccessful, try again using erasures.
446 	 Erasure information is uncertain, so try this last. */
447 
448       if(err < 0 || err > 2)
449       {  GetPVector(byte_state, p_state, p);
450 	 erasure_count = 0;
451 
452 	 for(i=0; i<P_VECTOR_SIZE; i++)
453 	   if(p_state[i])
454 	     erasures[erasure_count++] = i;
455 
456 	 if(erasure_count > 0 && erasure_count <= 2)
457 	 {  GetPVector(frame, p_vector, p);
458 	    err = DecodePQ(rb->rt, p_vector, P_PADDING, erasures, erasure_count);
459 	 }
460       }
461 
462       /* See what we've got */
463 
464       if(err < 0)  /* Uncorrectable. */
465       {  p_failures++;
466       }
467       else         /* Correctable. */
468       {  if(err == 1 || err == 2) /* Store back corrected vector */
469 	 {  SetPVector(frame, p_vector, p);
470 	    p_corrected++;
471 	 }
472       }
473    }
474 
475    /* Sum up */
476 
477    if(q_failures || p_failures || q_corrected || p_corrected)
478    {
479      PrintCLIorLabel(Closure->status,
480 		     "Sector %lld  L-EC P/Q results: %d/%d failures, %d/%d corrected (%s).\n",
481 		     rb->lba, p_failures, q_failures, p_corrected, q_corrected, msg);
482      return 1;
483    }
484 
485    return 0;
486 }
487 
488 /***
489  *** Validate CD raw sector
490  ***/
491 
ValidateRawSector(RawBuffer * rb,unsigned char * frame,char * msg)492 int ValidateRawSector(RawBuffer *rb, unsigned char *frame, char *msg)
493 {  int lec_did_sth = FALSE;
494    unsigned char saved_msf[4];
495 
496    /* See if the buffer was returned unchanged. */
497 
498    if(CheckForMissingSector(frame, rb->lba, NULL, 0) != SECTOR_PRESENT)
499    {  RememberSense(3, 255, 0);  /* No data returned */
500       return FALSE;
501    }
502 
503    /* A fully zeroed out buffer is suspicious since at least the
504       sync byte sequence and address fields should not be zero.
505       This is usually a sign that the atapi/scsi driver is broken;
506       e.g. that it does not pass through data when the drive
507       signalled an error. */
508 
509    if(!memcmp(frame, rb->zeroSector, rb->sampleSize))
510    {  RememberSense(3, 255, 5); /* zero sector */
511       return FALSE;
512    }
513 
514    /* Some operating systems are even worse - random data is returned.
515       If the sync sequence is missing, reject the sector. */
516 
517    if(!check_for_sync_pattern(frame))
518    {  RememberSense(3, 255, 8); /* random data */
519       return FALSE;
520    }
521 
522    /* Adapt for XA mode */
523 
524    if(rb->xaMode)
525    {  memcpy(saved_msf, frame+12, 4);
526       memset(frame+12, 0, 4);
527    }
528 
529   /* Do simple L-EC.
530      It seems that drives stop their internal L-EC as soon as the
531      EDC is okay, so we may see uncorrected errors in the parity bytes.
532      Since we are also interested in the user data only and doing the
533      L-EC is expensive, we skip our L-EC as well when the EDC is fine. */
534 
535   if(!CheckEDC(frame, rb->xaMode))
536      lec_did_sth = simple_lec(rb, frame, msg);
537 
538 
539   if(rb->xaMode)
540     memcpy(frame+12, saved_msf, 4);
541 
542   /* Test internal sector checksum again */
543 
544   if(!CheckEDC(frame, rb->xaMode))
545   {  RememberSense(3, 255, 1);  /* EDC failure in RAW sector */
546        return FALSE;
547   }
548 
549   /* Test internal sector address */
550 
551   if(!CheckMSF(frame, rb->lba, STRICT_MSF_CHECK))
552   {  RememberSense(3, 255, 2);  /* Wrong MSF in RAW sector */
553      return FALSE;
554   }
555 
556   /* Tell user that L-EC succeeded */
557 
558   if(lec_did_sth)
559     PrintCLIorLabel(Closure->status,
560 		    "Sector %lld: Recovered in raw reader by L-EC.\n",
561 		    rb->lba);
562 
563    return TRUE;
564 }
565 
566 /***
567  *** Try to recover a raw CD frame sample.
568  ***/
569 
570 /*
571  * Customized RS decoding.
572  *
573  * Erasure information is uncertain,
574  * so we try to correct with erasure information as well as without.
575  *
576  * Returns the number of corrected errors or 3 if correction failed.
577  */
578 
p_decode(RawBuffer * rb,unsigned char * vector,unsigned char * state)579 static int p_decode(RawBuffer *rb, unsigned char *vector, unsigned char *state)
580 { int erasures[P_VECTOR_SIZE];
581   int ignore[2];
582   unsigned char working_vector[P_VECTOR_SIZE];
583   int err, erasure_count;
584 
585   /* Try error correction without erasure information */
586 
587   memcpy(working_vector, vector, P_VECTOR_SIZE);
588   err = DecodePQ(rb->rt, working_vector, P_PADDING, ignore, 0);
589 
590   /* If unsuccessful, try again using erasures. */
591 
592   if(err < 0 || err > 2)
593   {  int i;
594 
595      erasure_count = 0;
596 
597      for(i=0; i<P_VECTOR_SIZE; i++)
598        if(!(state[i]&2))
599 	 erasures[erasure_count++] = i;
600 
601      if(erasure_count > 0 && erasure_count <= 2)
602      {  memcpy(working_vector, vector, P_VECTOR_SIZE);
603         err = DecodePQ(rb->rt, working_vector, P_PADDING, erasures, erasure_count);
604      }
605   }
606 
607   if(err == 1 || err == 2)
608     memcpy(vector, working_vector, P_VECTOR_SIZE);
609 
610   return err < 0 ? 3 : err;
611 }
612 
q_decode(RawBuffer * rb,unsigned char * vector,unsigned char * state)613 static int q_decode(RawBuffer *rb, unsigned char *vector, unsigned char *state)
614 { int erasures[Q_VECTOR_SIZE];
615   int ignore[2];
616   unsigned char working_vector[Q_VECTOR_SIZE];
617   int err, erasure_count;
618 
619   /* Try error correction without erasure information */
620 
621   memcpy(working_vector, vector, Q_VECTOR_SIZE);
622   err = DecodePQ(rb->rt, working_vector, Q_PADDING, ignore, 0);
623 
624   /* If unsuccessful, try again using erasures. */
625 
626   if(err < 0 || err > 2)
627   {  int i;
628 
629      erasure_count = 0;
630 
631      for(i=0; i<Q_VECTOR_SIZE-2; i++)
632        if(!(state[i]&2))
633 	 erasures[erasure_count++] = i;
634 
635      if(erasure_count > 0 && erasure_count <= 2)
636      {  memcpy(working_vector, vector, Q_VECTOR_SIZE);
637         err = DecodePQ(rb->rt, working_vector, Q_PADDING, erasures, erasure_count);
638      }
639   }
640 
641   if(err == 1 || err == 2)
642     memcpy(vector, working_vector, Q_VECTOR_SIZE);
643 
644   return err < 0 ? 3 : err;
645 }
646 
647 /*
648  * Try to correct remaining bytes in rb->recovered.
649  * Iterates over P and Q vectors until no further improvements are made.
650  */
651 
652 //#define DEBUG_ITERATIVE
653 
IterativeLEC(RawBuffer * rb)654 int IterativeLEC(RawBuffer *rb)
655 {  unsigned char p_vector[P_VECTOR_SIZE];
656    unsigned char q_vector[Q_VECTOR_SIZE];
657    int p_failures, q_failures;
658    int p_corrected, q_corrected;
659    int p,q;
660    int last_p_failures = N_P_VECTORS;
661    int last_q_failures = N_Q_VECTORS;
662    int iteration=1;
663 
664    for(; ;) /* iterate over P- and Q-Parity until failures converge */
665    {
666       p_failures = q_failures = 0;
667       p_corrected = q_corrected = 0;
668 
669       /* Perform Q-Parity error correction */
670 
671       for(q=0; q<N_Q_VECTORS; q++)
672       {  int err;
673 
674 	 /* Try error correction */
675 
676 	 GetQVector(rb->recovered, q_vector, q);
677 	 err = q_decode(rb, q_vector, rb->byteState);
678 
679 	 /* See what we've got */
680 
681 	 if(err > 2)  /* Uncorrectable. Mark bytes as erasure. */
682 	 {  q_failures++;
683 	    AndQVector(rb->byteState, ~1, q);
684 	 }
685 	 else  /* Correctable. Mark bytes as good; store back results. */
686 	 {  if(err == 1 || err == 2) /* Store back corrected vector */
687 	    {  SetQVector(rb->recovered, q_vector, q);
688 	       q_corrected++;
689 	    }
690 	    OrQVector(rb->byteState, 1, q);
691 	 }
692       }
693 
694       /* Perform P-Parity error correction */
695 
696       for(p=0; p<N_P_VECTORS; p++)
697       {  int err;
698 
699 	 /* Try error correction */
700 
701 	 GetPVector(rb->recovered, p_vector, p);
702 	 err = p_decode(rb, p_vector, rb->byteState);
703 
704 	 /* See what we've got */
705 
706 	 if(err > 2)  /* Uncorrectable. */
707 	 {  p_failures++;
708 	    AndPVector(rb->byteState, ~2, p);
709 	 }
710 	 else  /* Correctable. Mark bytes as good; store back results. */
711 	 {  if(err == 1 || err == 2) /* Store back corrected vector */
712 	    {  SetPVector(rb->recovered, p_vector, p);
713 	       p_corrected++;
714 	    }
715 	    OrPVector(rb->byteState, 2, p);
716 	 }
717       }
718 
719       /* See if there was an improvement */
720 
721 #ifdef DEBUG_ITERATIVE
722       printf("L-EC: iteration %d\n", iteration);
723       printf("      Q-failures/corrected: %2d/%2d\n", q_failures, q_corrected);
724       printf("      P-failures/corrected: %2d/%2d\n", p_failures, p_corrected);
725 #endif
726 
727       if(CheckEDC(rb->recovered, rb->xaMode) || p_failures + q_failures == 0)
728 	break;
729 
730       if(   last_p_failures > p_failures
731 	 || last_q_failures > q_failures)
732       {  last_p_failures = p_failures;
733 	 last_q_failures = q_failures;
734 	 iteration++;
735       }
736       else break;
737    }
738 
739    return (p_failures + q_failures == 0);
740 }
741 
742 /***
743  *** Some frame statistics are updated iteratively,
744  *** e.g. whenever a new frame is accumulated.
745  */
746 
UpdateFrameStats(RawBuffer * rb)747 void UpdateFrameStats(RawBuffer *rb)
748 {  unsigned char *new_sample = rb->rawBuf[rb->samplesRead-1];
749    unsigned char vector[Q_VECTOR_SIZE];
750    int p_corr = 0;
751    int p_err  = 0;
752    int q_corr = 0;
753    int q_err  = 0;
754    int err,eras[2];
755    int p,q;
756 
757    /* MAYBE TODO: Try trivial corrections first, e.g.
758       correct P/Q with single failure until they damage
759       some other vector */
760 
761    /* MAYBE TODO: add single byte failures are to the double
762       failure count since we want to pick the vector
763       with the least number of defective vectors. */
764 
765    for(p=0; p<N_P_VECTORS; p++)
766    {  GetPVector(new_sample, vector, p);
767       err = DecodePQ(rb->rt, vector, P_PADDING, eras, 0);
768       switch(err)
769       {  case 0:
770 	    break;
771 	 case 1:
772 	    p_corr++;
773 	    //	    p_err++;
774 	    break;
775 	 default:
776 	    p_err++;
777 	    break;
778       }
779    }
780 
781    for(q=0; q<N_Q_VECTORS; q++)
782    {  GetQVector(new_sample, vector, q);
783       err = DecodePQ(rb->rt, vector, Q_PADDING, eras, 0);
784       switch(err)
785       {  case 0:
786 	    break;
787 	 case 1:
788 	    q_corr++;
789 	    //	    q_err++;
790 	    break;
791 	 default:
792 	    q_err++;
793 	    break;
794       }
795    }
796 
797    if(p_err > rb->bestP2)
798       return;
799 
800    if(p_err == rb->bestP2)
801    {  if(p_corr > rb->bestP1)
802 	 return;
803 
804       if(p_corr == rb->bestP1)
805       {  if(q_err > rb->bestQ2)
806 	    return;
807 
808 	 if(q_err == rb->bestQ2 && q_corr >= rb->bestQ1)
809 	    return;
810       }
811    }
812 
813    rb->bestFrame = rb->samplesRead - 1;
814    rb->bestP1 = p_corr;
815    rb->bestP2 = p_err;
816    rb->bestQ1 = q_corr;
817    rb->bestQ2 = q_err;
818 }
819 
820 /***
821  *** The grand wrapper:
822  ***
823  * Try several strategies to analyse and recover
824  * a collection of RAW frame samples.
825  */
826 
TryCDFrameRecovery(RawBuffer * rb,unsigned char * outbuf)827 int TryCDFrameRecovery(RawBuffer *rb, unsigned char *outbuf)
828 {  unsigned char *new_frame = rb->workBuf->buf;
829 
830    /*** Reject unplausible sectors */
831 
832    /* See if the buffer was returned unchanged. */
833 
834    if(CheckForMissingSector(new_frame, rb->lba, NULL, 0) != SECTOR_PRESENT)
835    {  RememberSense(3, 255, 0);  /* No data returned */
836       return -1;
837    }
838 
839    /* A fully zeroed out buffer is suspicious since at least the
840       sync byte sequence and address fields should not be zero.
841       This is usually a sign that the atapi/scsi driver is broken;
842       e.g. that it does not pass through data when the drive
843       signalled an error. */
844 
845    if(!memcmp(new_frame, rb->zeroSector, rb->sampleSize))
846    {  RememberSense(3, 255, 5); /* zero sector */
847       return -1;
848    }
849 
850    /* Some operating systems are even worse - random data is returned.
851       If the sync sequence is missing, reject the sector. */
852 
853    if(!check_for_sync_pattern(new_frame))
854    {  RememberSense(3,255, 8); /* random data */
855       return -1;
856    }
857 
858    /* Compare lba against MSF field. Some drives return sectors
859       from wrong places in RAW mode. */
860 
861    if(!CheckMSF(new_frame, rb->lba, SLOPPY_MSF_CHECK))
862    {  RememberSense(3, 255, 2); /* Wrong MSF in raw sector */
863       return -1;
864    }
865 
866    /* Okay, accept sector as a valid sample for recovery. */
867 
868    if(rb->xaMode)
869      memset(new_frame+12, 0, 4);
870 
871    memcpy(rb->rawBuf[rb->samplesRead], new_frame, rb->sampleSize);
872    rb->samplesRead++;
873 
874    UpdateFrameStats(rb);
875 
876    /*** Cheap shots: See if we can recover the sector itself
877 	(without using the more complex heuristics and other
878 	sectors).
879         Note that we ignore the return value of IterativeLEC().
880         If e.g. some parity bytes remain uncorrected we don't care
881         as long as the EDC tells us that the user data part is okay. */
882 
883    memcpy(rb->recovered, new_frame, rb->sampleSize);
884    memset(rb->byteState, 0, rb->sampleSize);
885 
886    /* If the data section is unaffected by the error,
887       do not investigate further. */
888 
889    if(CheckEDC(rb->recovered, rb->xaMode)
890       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
891    {
892        PrintCLIorLabel(Closure->status,
893 		       "Sector %lld: Good. Data section passes EDC test.\n",
894 		       rb->lba);
895        memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
896        return 0;
897    }
898 
899    /* Sometimes we have only errors in the sync pattern and the P/Q vectors,
900       but the data section will pass the EDC test. Try it. */
901 
902    if(memcmp(rb->recovered, sync_pattern, 12))
903    {  memcpy(rb->recovered, sync_pattern, 12);
904 
905       if(CheckEDC(rb->recovered, rb->xaMode)
906 	 && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
907       {
908 	 PrintCLIorLabel(Closure->status,
909 			 "Sector %lld: Recovered in raw reader after correcting sync pattern.\n",
910 			 rb->lba);
911 
912 	 memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
913 	 return 0;
914       }
915    }
916 
917 
918    /* Try the simple iterative L-EC */
919 
920    IterativeLEC(rb);
921 
922    if(CheckEDC(rb->recovered, rb->xaMode)
923       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
924    {
925        PrintCLIorLabel(Closure->status,
926 		       "Sector %lld: Recovered in raw reader by iterative L-EC.\n",
927 		       rb->lba);
928 
929        memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
930        return 0;
931    }
932 
933    /*** More sophisticated heuristics */
934 
935    /* Incremental update of our data */
936 
937    UpdateByteCounts(rb);
938    CalculatePQLoad(rb);
939    UpdatePQParityList(rb, new_frame);
940 
941    /* The actual heuristics */
942 
943 #if 0
944    SmartLEC(rb);
945 
946    if(CheckEDC(rb->recovered, rb->xaMode)
947       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
948    {  PrintCLIorLabel(Closure->status,
949 		      "Sector %lld: Recovered in raw reader by smart L-EC.\n",
950 		      rb->lba);
951       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
952       return 0;
953    }
954 #endif
955 
956    SearchPlausibleSector(rb, 0);
957 
958    if(CheckEDC(rb->recovered, rb->xaMode)
959       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
960    {  PrintCLIorLabel(Closure->status,
961 		      "Sector %lld: Recovered in raw reader by plausible sector search (0).\n",
962 		      rb->lba);
963       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
964       return 0;
965    }
966 
967    BruteForceSearchPlausibleSector(rb);
968 
969    if(CheckEDC(rb->recovered, rb->xaMode)
970       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
971    {  PrintCLIorLabel(Closure->status,
972 		      "Sector %lld: Recovered in raw reader by brute force plausible sector search (0).\n",
973 		      rb->lba);
974       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
975       return 0;
976    }
977 
978    AckHeuristic(rb);
979 
980    if(CheckEDC(rb->recovered, rb->xaMode)
981       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
982    {  PrintCLIorLabel(Closure->status,
983 		      "Sector %lld: Recovered in raw reader by mutual ack heuristic (0).\n",
984 		      rb->lba);
985       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
986       return 0;
987    }
988 
989    HeuristicLEC(rb->recovered, rb, outbuf);
990 
991    if(CheckEDC(rb->recovered, rb->xaMode)
992       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
993    {  PrintCLIorLabel(Closure->status,
994 		      "Sector %lld: Recovered in raw reader by heuristic L-EC (0).\n",
995 		      rb->lba);
996       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
997       return 0;
998    }
999 
1000    SearchPlausibleSector(rb, 1);
1001 
1002    if(CheckEDC(rb->recovered, rb->xaMode)
1003       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
1004    {  PrintCLIorLabel(Closure->status,
1005 		      "Sector %lld: Recovered in raw reader by plausible sector search (1).\n",
1006 		      rb->lba);
1007       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
1008       return 0;
1009    }
1010 
1011    BruteForceSearchPlausibleSector(rb);
1012 
1013    if(CheckEDC(rb->recovered, rb->xaMode)
1014       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
1015    {  PrintCLIorLabel(Closure->status,
1016 		      "Sector %lld: Recovered in raw reader by brute force plausible sector search (1).\n",
1017 		      rb->lba);
1018       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
1019       return 0;
1020    }
1021 
1022    AckHeuristic(rb);
1023 
1024    if(CheckEDC(rb->recovered, rb->xaMode)
1025       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
1026    {  PrintCLIorLabel(Closure->status,
1027 		      "Sector %lld: Recovered in raw reader by mutual ack heuristic (1).\n",
1028 		      rb->lba);
1029       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
1030       return 0;
1031    }
1032 
1033    HeuristicLEC(rb->recovered, rb, outbuf);
1034 
1035    if(CheckEDC(rb->recovered, rb->xaMode)
1036       && CheckMSF(rb->recovered, rb->lba, STRICT_MSF_CHECK))
1037    {  PrintCLIorLabel(Closure->status,
1038 		      "Sector %lld: Recovered in raw reader by heuristic L-EC (1).\n",
1039 		      rb->lba);
1040       memcpy(outbuf, rb->recovered+rb->dataOffset, 2048);
1041       return 0;
1042    }
1043 
1044    /*** Recovery failed */
1045 
1046    RememberSense(3, 255, 6);  /* Sector accumulated for analysis */
1047    rb->recommendedAttempts = Closure->maxReadAttempts;
1048    return -1;
1049 }
1050