Annotation of ntddk/src/scsi/qic117/reedsolo.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1993 - Colorado Memory Systems,  Inc.
        !             4: All Rights Reserved
        !             5: 
        !             6: Module Name:
        !             7: 
        !             8:     reedsolo.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     These routines perform the Reed-Solomon Error correction
        !            13:     required for QIC-40 rev D. Spec.
        !            14: 
        !            15: Revision History:
        !            16: 
        !            17: 
        !            18: 
        !            19: 
        !            20: --*/
        !            21: 
        !            22: //
        !            23: // Includes
        !            24: //
        !            25: 
        !            26: #include <ntddk.h>
        !            27: #include <ntddtape.h>
        !            28: #include "common.h"
        !            29: #include "q117.h"
        !            30: #include "protos.h"
        !            31: 
        !            32: //
        !            33: // Protos for entry points
        !            34: //
        !            35: 
        !            36: 
        !            37: UCHAR
        !            38: q117RdsMultiplyTuples (
        !            39:     IN UCHAR tup1,
        !            40:     IN UCHAR tup2
        !            41:     );
        !            42: 
        !            43: UCHAR
        !            44: q117RdsDivideTuples (
        !            45:     IN UCHAR tup1,
        !            46:     IN UCHAR tup2
        !            47:     );
        !            48: 
        !            49: UCHAR
        !            50: q117RdsExpTuple (
        !            51:     IN UCHAR tup1,
        !            52:     IN UCHAR xpnt
        !            53:     );
        !            54: 
        !            55: VOID
        !            56: q117RdsGetSyndromes (
        !            57:     IN OUT UCHAR *Array,        // pointer to 32K data area (segment)
        !            58:     IN UCHAR Count,             // number of good sectors in segment (4-32)
        !            59:     IN UCHAR *ps1,
        !            60:     IN UCHAR *ps2,
        !            61:     IN UCHAR *ps3
        !            62:     );
        !            63: 
        !            64: BOOLEAN
        !            65: q117RdsCorrectFailure (
        !            66:     IN OUT UCHAR *Array,         // pointer to 32K data area (segment)
        !            67:     IN UCHAR Count,              // number of good sectors in segment (4-32)
        !            68:     IN UCHAR s1,
        !            69:     IN UCHAR s2,
        !            70:     IN UCHAR s3
        !            71:     );
        !            72: 
        !            73: BOOLEAN
        !            74: q117RdsCorrectOneError (
        !            75:     IN OUT UCHAR *Array,             // pointer to 32K data area (segment)
        !            76:     IN UCHAR Count,                  // number of good sectors in segment (4-32)
        !            77:     IN UCHAR ErrorLocation,
        !            78:     IN UCHAR s1,
        !            79:     IN UCHAR s2,
        !            80:     IN UCHAR s3
        !            81:     );
        !            82: 
        !            83: BOOLEAN
        !            84: q117RdsCorrectTwoErrors (
        !            85:     IN OUT UCHAR *Array,             // pointer to 32K data area (segment)
        !            86:     IN UCHAR Count,                  // number of good sectors in segment (4-32)
        !            87:     IN UCHAR ErrorLocation1,
        !            88:     IN UCHAR ErrorLocation2,
        !            89:     IN UCHAR s1,
        !            90:     IN UCHAR s2,
        !            91:     IN UCHAR s3
        !            92:     );
        !            93: 
        !            94: BOOLEAN
        !            95: q117RdsCorrectThreeErrors (
        !            96:     IN OUT UCHAR *Array,             // pointer to 32K data area (segment)
        !            97:     IN UCHAR Count,                  // number of good sectors in segment (4-32)
        !            98:     IN UCHAR ErrorLocation1,
        !            99:     IN UCHAR ErrorLocation2,
        !           100:     IN UCHAR ErrorLocation3,
        !           101:     IN UCHAR s1,
        !           102:     IN UCHAR s2,
        !           103:     UCHAR s3
        !           104:     );
        !           105: 
        !           106: BOOLEAN
        !           107: q117RdsCorrectOneErrorAndOneFailure (
        !           108:     IN OUT UCHAR *Array,              // pointer to 32K data area (segment)
        !           109:     IN UCHAR Count,                   // number of good sectors in segment (4-32)
        !           110:     IN UCHAR ErrorLocation1,
        !           111:     IN UCHAR s1,
        !           112:     IN UCHAR s2,
        !           113:     IN UCHAR s3
        !           114:     );
        !           115: 
        !           116: 
        !           117: UCHAR  rds_exptup[255*2+2];
        !           118: UCHAR  rds_tupexp[256];
        !           119: UCHAR  rds_xC0[256];
        !           120: 
        !           121: #define PASS 0
        !           122: #define FAIL 1
        !           123: 
        !           124: #define ADD_TUPLES(a, b) ((UCHAR) ( (a) ^ (b) ))
        !           125: 
        !           126: 
        !           127: VOID
        !           128: q117RdsInitReed (
        !           129:     VOID
        !           130:     )
        !           131: 
        !           132: /*++
        !           133: 
        !           134: Routine Description:
        !           135: 
        !           136: 
        !           137: Arguments:
        !           138: 
        !           139:     Context - Current context of driver
        !           140: 
        !           141: Return Value:
        !           142: 
        !           143:     NONE
        !           144: 
        !           145: --*/
        !           146: 
        !           147: {
        !           148:     ULONG i;
        !           149:     ULONG tuple = 1, alpha_8 = 0x87;
        !           150: 
        !           151:     for (i = 0; i <= 254; ++i)  {
        !           152:         rds_exptup[i] = (UCHAR)tuple;
        !           153:         rds_tupexp[tuple] = (UCHAR)i;
        !           154:         if (tuple & 0x80) {
        !           155:             tuple = ((tuple << 1) ^ alpha_8) & 0xff;
        !           156:         } else {
        !           157:             tuple <<= 1;
        !           158:         }
        !           159:     }
        !           160:     for (i=0;i<255;++i) {
        !           161:         rds_exptup[i+255] = rds_exptup[i];
        !           162:         if (i<2) {
        !           163:             rds_exptup[i+255+255] = rds_exptup[i];
        !           164:         }
        !           165:     }
        !           166:     for (i = 0; i<=255; ++i) {
        !           167:         rds_xC0[i] = q117RdsMultiplyTuples((UCHAR)i,0xc0);
        !           168:     }
        !           169: }
        !           170: 
        !           171: UCHAR
        !           172: q117RdsMultiplyTuples (
        !           173:     IN UCHAR tup1,
        !           174:     IN UCHAR tup2
        !           175:     )
        !           176: 
        !           177: /*++
        !           178: 
        !           179: Routine Description:
        !           180: 
        !           181:     8-tuples to be multiplied.
        !           182: 
        !           183: Arguments:
        !           184: 
        !           185: 
        !           186: Return Value:
        !           187: 
        !           188:     Result of multiply
        !           189: 
        !           190: --*/
        !           191: 
        !           192: {
        !           193: 
        !           194:     if ( (tup1 == 0) || (tup2 == 0) ) {
        !           195: 
        !           196:         return(0);
        !           197: 
        !           198:     }
        !           199: 
        !           200:     return ( rds_exptup[rds_tupexp[tup1] + rds_tupexp[tup2]] );
        !           201: }
        !           202: 
        !           203: UCHAR
        !           204: q117RdsDivideTuples (
        !           205:     IN UCHAR tup1,
        !           206:     IN UCHAR tup2
        !           207:     )
        !           208: 
        !           209: /*++
        !           210: 
        !           211: Routine Description:
        !           212: 
        !           213:     8-tuples to be devided
        !           214: 
        !           215: Arguments:
        !           216: 
        !           217: 
        !           218: Return Value:
        !           219: 
        !           220:     Result of divide
        !           221: 
        !           222: --*/
        !           223: 
        !           224: {
        !           225:     if (tup2 == 0) {
        !           226:         return(0);
        !           227:     }
        !           228:     if (tup1 == 0) {
        !           229:         return(0);
        !           230:     }
        !           231: 
        !           232:     return (UCHAR)((ULONG)rds_exptup[rds_tupexp[tup1] + 255 - rds_tupexp[tup2]]);
        !           233: }
        !           234: 
        !           235: UCHAR
        !           236: q117RdsExpTuple (
        !           237:     IN UCHAR tup1,
        !           238:     IN UCHAR xpnt
        !           239:     )
        !           240: 
        !           241: /*++
        !           242: 
        !           243: Routine Description:
        !           244: 
        !           245:     Exponent routine.
        !           246: 
        !           247: Arguments:
        !           248: 
        !           249: 
        !           250: Return Value:
        !           251: 
        !           252:     Result of tup1^xpnt
        !           253: 
        !           254: --*/
        !           255: 
        !           256: {
        !           257:     if (tup1 == 0)
        !           258:         return(0);
        !           259: 
        !           260:     return (UCHAR)((ULONG)rds_exptup[(rds_tupexp[tup1] * xpnt ) % 255]);
        !           261: }
        !           262: 
        !           263: VOID
        !           264: q117RdsMakeCRC (
        !           265:     IN OUT UCHAR *Array,      // pointer to 32K data area (segment)
        !           266:     IN UCHAR Count            // number of sectors (1K blocks)(1-32)
        !           267:     )
        !           268: 
        !           269: /*++
        !           270: 
        !           271: Routine Description:
        !           272: 
        !           273:     Add Reed Solomon codes to buffer
        !           274: 
        !           275: Arguments:
        !           276: 
        !           277: 
        !           278: Return Value:
        !           279: 
        !           280: 
        !           281: --*/
        !           282: 
        !           283: {
        !           284:     ULONG num;
        !           285:     UCHAR i,j,k,p0,p1,p2;
        !           286: 
        !           287: 
        !           288:     for ( num = 0;num < BYTES_PER_SECTOR;++num ) {
        !           289:         p0 = p1 = p2 = 0;
        !           290: 
        !           291:         for ( i = 0; i < (UCHAR)(Count-3); ++i ) {
        !           292: 
        !           293:             j = rds_xC0[k = (p2 ^ Array[i * BYTES_PER_SECTOR + num])];
        !           294:             p2 = j ^ p1;
        !           295:             p1 = j ^ p0;
        !           296:             p0 = k;
        !           297: 
        !           298:         }
        !           299: 
        !           300:         Array[i * BYTES_PER_SECTOR + num] = p2;
        !           301:         i++;
        !           302:         Array[i * BYTES_PER_SECTOR + num] = p1;
        !           303:         i++;
        !           304:         Array[i * BYTES_PER_SECTOR + num] = p0;
        !           305:         i++;
        !           306:     }
        !           307: }
        !           308: 
        !           309: BOOLEAN
        !           310: q117RdsReadCheck (
        !           311:     IN UCHAR *Array,         // pointer to 32K data area (segment)
        !           312:     IN UCHAR Count           // number of sectors (1K blocks)(1-32)
        !           313:     )
        !           314: 
        !           315: /*++
        !           316: 
        !           317: Routine Description:
        !           318: 
        !           319:     perform read check on buffer (fast check for CRC failures)
        !           320: 
        !           321: Arguments:
        !           322: 
        !           323: 
        !           324: Return Value:
        !           325: 
        !           326:     1 - Success
        !           327: 
        !           328:     0 - Failure
        !           329: 
        !           330: --*/
        !           331: 
        !           332: 
        !           333: {
        !           334:     LONG num;
        !           335:     UCHAR i,sum;
        !           336: 
        !           337:     for ( num = 0; num < BYTES_PER_SECTOR; ++num ) {
        !           338: 
        !           339:         sum = 0;
        !           340:         for ( i = 0; i < Count; ++i ) {
        !           341: 
        !           342:             sum ^= Array[i * BYTES_PER_SECTOR + num];
        !           343: 
        !           344:         }
        !           345:         if ( sum != 0 ) {
        !           346: 
        !           347:             return FAIL;
        !           348: 
        !           349:         }
        !           350:     }
        !           351: 
        !           352:     return PASS;
        !           353: }
        !           354: 
        !           355: BOOLEAN
        !           356: q117RdsCorrect(
        !           357:     IN OUT UCHAR *Array,    // pointer to 32K data area (segment)
        !           358:     IN UCHAR Count,         // number of good sectors in segment (4-32)
        !           359:     IN UCHAR CRCErrors,     // number of crc errors
        !           360:     IN UCHAR e1,
        !           361:     IN UCHAR e2,
        !           362:     IN UCHAR e3             // sectors where errors occurred
        !           363:     )
        !           364: 
        !           365: /*++
        !           366: 
        !           367: Routine Description:
        !           368: 
        !           369:     perform error Reed-Solomon error correction on segment
        !           370: 
        !           371: Arguments:
        !           372: 
        !           373: 
        !           374: Return Value:
        !           375: 
        !           376:     1 - Success
        !           377: 
        !           378:     0 - Failure
        !           379: 
        !           380: --*/
        !           381: 
        !           382: {
        !           383:     USHORT num;
        !           384:     BOOLEAN ret;
        !           385:     UCHAR s1,s2,s3;
        !           386: 
        !           387:     ret = PASS;
        !           388:     Count--;
        !           389:     e1 = Count-e1;
        !           390:     e2 = Count-e2;
        !           391:     e3 = Count-e3;
        !           392: 
        !           393:     for ( num = 0; num < BYTES_PER_SECTOR; ++num ) {
        !           394:         q117RdsGetSyndromes(&Array[num],Count,&s1,&s2,&s3);
        !           395:         if ( s1 || s2 || s3 ) {
        !           396: 
        !           397:             switch( CRCErrors ) {
        !           398: 
        !           399:                 case 0:
        !           400:                     ret = q117RdsCorrectFailure(&Array[num],Count,s1,s2,s3);
        !           401:                     break;
        !           402: 
        !           403:                 case 1:
        !           404:                     ret = q117RdsCorrectOneError(&Array[num],Count,e1,s1,s2,s3);
        !           405:                     break;
        !           406: 
        !           407:                 case 2:
        !           408:                    ret = q117RdsCorrectTwoErrors(&Array[num],Count,e1,e2,s1,s2,s3);
        !           409:                     break;
        !           410: 
        !           411:                 case 3:
        !           412:                     ret = q117RdsCorrectThreeErrors(&Array[num],Count,e1,e2,e3,s1,s2,s3);
        !           413:                     break;
        !           414: 
        !           415:                 default:
        !           416:                     ret = FAIL;
        !           417:                     break;
        !           418:             }
        !           419:         }
        !           420:         if (ret)
        !           421:             return ret;
        !           422:     }
        !           423:     return ret;
        !           424: }
        !           425: 
        !           426: 
        !           427: //
        !           428: // Due to bug in CL386 version 0.00.45,  turn off optimization
        !           429: //
        !           430: #if i386
        !           431: #pragma optimize("",off)
        !           432: #endif
        !           433: 
        !           434: 
        !           435: VOID
        !           436: q117RdsGetSyndromes (
        !           437:     IN OUT UCHAR *Array,       // pointer to 32K data area (segment)
        !           438:     IN UCHAR Count,            // number of good sectors in segment (4-32)
        !           439:     IN UCHAR *ps1,
        !           440:     IN UCHAR *ps2,
        !           441:     IN UCHAR *ps3
        !           442:     )
        !           443: 
        !           444: /*++
        !           445: 
        !           446: Routine Description:
        !           447: 
        !           448:     8-tuples to be multiplied.
        !           449: 
        !           450: Arguments:
        !           451: 
        !           452: 
        !           453: Return Value:
        !           454: 
        !           455: 
        !           456: --*/
        !           457: 
        !           458: {
        !           459:     UCHAR q,r,s,s1,s2,s3,cx,al,ah;
        !           460: 
        !           461:     q = r = s = 0;
        !           462: 
        !           463:     for ( cx = 0; cx <= Count; ++cx ) {
        !           464: 
        !           465:         al = rds_xC0[ah = q];
        !           466:         q = r ^ al;
        !           467:         r = s ^ al;
        !           468:         s = ah ^ Array[cx * BYTES_PER_SECTOR];
        !           469: 
        !           470:     }
        !           471: 
        !           472:     s1 = q117RdsMultiplyTuples(q,0xa2) ^ q117RdsMultiplyTuples(r,0xc3) ^ s;
        !           473:     s2 = q ^ r ^ s;
        !           474:     s3 = q117RdsMultiplyTuples(q,0x4) ^ q117RdsMultiplyTuples(r,2) ^ s;
        !           475:     *ps1 = s1;
        !           476:     *ps2 = s2;
        !           477:     *ps3 = s3;
        !           478: }
        !           479: #if i386
        !           480: #pragma optimize("",on)
        !           481: #endif
        !           482: 
        !           483: 
        !           484: BOOLEAN
        !           485: q117RdsCorrectFailure (
        !           486:     IN OUT UCHAR *Array,     // pointer to 32K data area (segment)
        !           487:     IN UCHAR Count,          // number of good sectors in segment (4-32)
        !           488:     IN UCHAR s1,
        !           489:     IN UCHAR s2,
        !           490:     IN UCHAR s3
        !           491:     )
        !           492: 
        !           493: /*++
        !           494: 
        !           495: Routine Description:
        !           496: 
        !           497:     Correct one failure
        !           498: 
        !           499: Arguments:
        !           500: 
        !           501: 
        !           502: Return Value:
        !           503: 
        !           504:     1 - Success
        !           505: 
        !           506:     0 - Failure
        !           507: 
        !           508: --*/
        !           509: 
        !           510: {
        !           511:     UCHAR errorloc,c1,y1,x1,ck;
        !           512: 
        !           513:     //
        !           514:     // check for divide by zero
        !           515:     //
        !           516:     if (s1 == 0) {
        !           517:         return FAIL;
        !           518:     }
        !           519:     errorloc = rds_tupexp[q117RdsDivideTuples(s2,s1)];
        !           520:     if (errorloc > Count) {
        !           521:         return FAIL;
        !           522:     }
        !           523:     y1 = s2;
        !           524:     x1 = rds_exptup[errorloc];
        !           525:     c1 = ADD_TUPLES(s2,Array[(Count-errorloc) * BYTES_PER_SECTOR]);
        !           526:     ck = q117RdsMultiplyTuples(y1,x1);
        !           527:     if (ck != s3) {
        !           528:         return FAIL;
        !           529:     } else {
        !           530:         Array[(Count-errorloc) * BYTES_PER_SECTOR] = c1;
        !           531:     }
        !           532:     return PASS;
        !           533: }
        !           534: 
        !           535: BOOLEAN
        !           536: q117RdsCorrectOneError (
        !           537:     IN OUT UCHAR *Array,      // pointer to 32K data area (segment)
        !           538:     IN UCHAR Count,           // number of good sectors in segment (4-32)
        !           539:     IN UCHAR ErrorLocation,
        !           540:     IN UCHAR s1,
        !           541:     IN UCHAR s2,
        !           542:     IN UCHAR s3
        !           543:     )
        !           544: 
        !           545: /*++
        !           546: 
        !           547: Routine Description:
        !           548: 
        !           549:     Correct one error.
        !           550: 
        !           551: Arguments:
        !           552: 
        !           553: 
        !           554: Return Value:
        !           555: 
        !           556:     1 - Success
        !           557: 
        !           558:     0 - Failure
        !           559: 
        !           560: --*/
        !           561: 
        !           562: {
        !           563:     UCHAR x1,y1,c1,ck;
        !           564: 
        !           565:     x1 = rds_exptup[ErrorLocation];
        !           566:     y1 = s2;
        !           567:     c1 = ADD_TUPLES(s2,Array[(Count-ErrorLocation) * BYTES_PER_SECTOR]);
        !           568:     ck = q117RdsMultiplyTuples(y1,x1);
        !           569: 
        !           570:     if ( ck != s3 ) {
        !           571: 
        !           572:         return q117RdsCorrectOneErrorAndOneFailure(Array,Count,ErrorLocation,s1,s2,s3);
        !           573: 
        !           574:     } else {
        !           575: 
        !           576:         Array[(Count-ErrorLocation) * BYTES_PER_SECTOR] = c1;
        !           577: 
        !           578:     }
        !           579:     return PASS;
        !           580: }
        !           581: 
        !           582: BOOLEAN
        !           583: q117RdsCorrectTwoErrors (
        !           584:     IN OUT UCHAR *Array,       // pointer to 32K data area (segment)
        !           585:     IN UCHAR Count,            // number of good sectors in segment (4-32)
        !           586:     IN UCHAR ErrorLocation1,
        !           587:     IN UCHAR ErrorLocation2,
        !           588:     IN UCHAR s1,
        !           589:     IN UCHAR s2,
        !           590:     IN UCHAR s3
        !           591:     )
        !           592: 
        !           593: /*++
        !           594: 
        !           595: Routine Description:
        !           596: 
        !           597:     Correct two errors.
        !           598: 
        !           599: Arguments:
        !           600: 
        !           601: 
        !           602: Return Value:
        !           603: 
        !           604:     1 - Success
        !           605: 
        !           606:     0 - Failure
        !           607: 
        !           608: --*/
        !           609: 
        !           610: {
        !           611:     UCHAR y1,y2,x1,x2,c1,c2,ck;
        !           612: 
        !           613:     x1 = rds_exptup[ErrorLocation1];
        !           614:     x2 = rds_exptup[ErrorLocation2];
        !           615: 
        !           616:     y2 = q117RdsDivideTuples(
        !           617:             ADD_TUPLES(
        !           618:                 q117RdsMultiplyTuples(s2, x1), s3 ), ADD_TUPLES(x1,x2)
        !           619:             );
        !           620: 
        !           621:     y1 = ADD_TUPLES(y2,s2);
        !           622: 
        !           623:     c1 = ADD_TUPLES( y1, Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] );
        !           624:     c2 = ADD_TUPLES( y2, Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR] );
        !           625: 
        !           626:     ck =x1 = q117RdsDivideTuples(
        !           627:                 ADD_TUPLES(
        !           628:                     q117RdsMultiplyTuples(y1,x2),
        !           629:                     q117RdsMultiplyTuples(y2,x1)
        !           630:                 ), q117RdsMultiplyTuples(x1,x2));
        !           631: 
        !           632:     if ( ck != s1 ) {
        !           633: 
        !           634:         return FAIL;
        !           635: 
        !           636:     } else {
        !           637: 
        !           638:         Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] = c1;
        !           639:         Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR] = c2;
        !           640: 
        !           641:     }
        !           642: 
        !           643:     return PASS;
        !           644: }
        !           645: 
        !           646: BOOLEAN
        !           647: q117RdsCorrectThreeErrors (
        !           648:     IN OUT UCHAR *Array,       // pointer to 32K data area (segment)
        !           649:     IN UCHAR Count,            // number of good sectors in segment (4-32)
        !           650:     IN UCHAR ErrorLocation1,
        !           651:     IN UCHAR ErrorLocation2,
        !           652:     IN UCHAR ErrorLocation3,
        !           653:     IN UCHAR s1,
        !           654:     IN UCHAR s2,
        !           655:     UCHAR s3
        !           656:     )
        !           657: 
        !           658: /*++
        !           659: 
        !           660: Routine Description:
        !           661: 
        !           662:     Correct three errors.
        !           663: 
        !           664: Arguments:
        !           665: 
        !           666: 
        !           667: Return Value:
        !           668: 
        !           669:     1 - Success
        !           670: 
        !           671:     0 - Failure
        !           672: 
        !           673: --*/
        !           674: 
        !           675: {
        !           676:     UCHAR y1,y2,y3,z1,z2,z3,x1,x2,x3,c1,c2,c3,q1,q2,q3,q4;
        !           677: 
        !           678:     x1 = rds_exptup[ErrorLocation1];
        !           679:     x2 = rds_exptup[ErrorLocation2];
        !           680:     x3 = rds_exptup[ErrorLocation3];
        !           681:     z1 = q117RdsDivideTuples(1,x1);
        !           682:     z2 = q117RdsDivideTuples(1,x2);
        !           683:     z3 = q117RdsDivideTuples(1,x3);
        !           684:     q1 = q117RdsDivideTuples(
        !           685:             ADD_TUPLES(q117RdsMultiplyTuples(x1,s2),s3),
        !           686:             ADD_TUPLES(x1,x2)
        !           687:             );
        !           688:     q2 = q117RdsDivideTuples(
        !           689:             ADD_TUPLES(q117RdsMultiplyTuples(z1,s2),s1),
        !           690:             ADD_TUPLES(z1,z2)
        !           691:             );
        !           692:     q3 = q117RdsDivideTuples(ADD_TUPLES(x1,x3),ADD_TUPLES(x1,x2));
        !           693:     q4 = q117RdsDivideTuples(ADD_TUPLES(z1,z3),ADD_TUPLES(z1,z2));
        !           694:     y3 = q117RdsDivideTuples(ADD_TUPLES(q1,q2),ADD_TUPLES(q3,q4));
        !           695:     y2 = ADD_TUPLES(q2,q117RdsMultiplyTuples(q4,y3));
        !           696:     y1 = ADD_TUPLES(ADD_TUPLES(y3,y2),s2);
        !           697:     c1 = ADD_TUPLES(y1,Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR]);
        !           698:     c2 = ADD_TUPLES(y2,Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR]);
        !           699:     c3 = ADD_TUPLES(y3,Array[(Count-ErrorLocation3) * BYTES_PER_SECTOR]);
        !           700: 
        !           701:     Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] = c1;
        !           702:     Array[(Count-ErrorLocation2) * BYTES_PER_SECTOR] = c2;
        !           703:     Array[(Count-ErrorLocation3) * BYTES_PER_SECTOR] = c3;
        !           704: 
        !           705:     return PASS;
        !           706: }
        !           707: 
        !           708: BOOLEAN
        !           709: q117RdsCorrectOneErrorAndOneFailure (
        !           710:     IN OUT UCHAR *Array,        // pointer to 32K data area (segment)
        !           711:     IN UCHAR Count,             // number of good sectors in segment (4-32)
        !           712:     IN UCHAR ErrorLocation1,
        !           713:     IN UCHAR s1,
        !           714:     IN UCHAR s2,
        !           715:     IN UCHAR s3
        !           716:     )
        !           717: 
        !           718: /*++
        !           719: 
        !           720: Routine Description:
        !           721: 
        !           722:     Correct one error and one failure.
        !           723: 
        !           724: Arguments:
        !           725: 
        !           726: 
        !           727: Return Value:
        !           728: 
        !           729:     1 - Success
        !           730: 
        !           731:     0 - Failure
        !           732: 
        !           733: --*/
        !           734: 
        !           735: {
        !           736:     UCHAR y1,y2,x1,x2,c1,c2;
        !           737:     UCHAR errorLoc2;
        !           738: 
        !           739:     x1 = rds_exptup[ErrorLocation1];
        !           740: 
        !           741:     y1 = q117RdsDivideTuples(
        !           742:             q117RdsMultiplyTuples(
        !           743:                 ADD_TUPLES(
        !           744:                     q117RdsMultiplyTuples(s1,s3),
        !           745:                     q117RdsExpTuple(s2,2)
        !           746:                 ),x1),
        !           747:             ADD_TUPLES(s3,
        !           748:                 q117RdsMultiplyTuples(s1,q117RdsExpTuple(x1,2)))
        !           749:             );
        !           750: 
        !           751:     y2 = ADD_TUPLES(y1,s2);
        !           752: 
        !           753:     x2 = q117RdsDivideTuples(
        !           754:             q117RdsMultiplyTuples(y2,x1),
        !           755:             ADD_TUPLES(y1,q117RdsMultiplyTuples(s1,x1))
        !           756:             );
        !           757: 
        !           758:     errorLoc2 = rds_tupexp[x2];
        !           759: 
        !           760:     if ( errorLoc2 > Count ) {
        !           761: 
        !           762:         return FAIL;
        !           763: 
        !           764:     }
        !           765: 
        !           766:     c1 = ADD_TUPLES(y1,Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR]);
        !           767:     c2 = ADD_TUPLES(y2,Array[(Count-errorLoc2) * BYTES_PER_SECTOR]);
        !           768: 
        !           769:     Array[(Count-ErrorLocation1) * BYTES_PER_SECTOR] = c1;
        !           770:     Array[(Count-errorLoc2) * BYTES_PER_SECTOR] = c2;
        !           771: 
        !           772:     return PASS;
        !           773: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.