Annotation of ntddk/src/scsi/qic117/rcnsttrk.c, revision 1.1.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:     rcnsttrk.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     This is the tape class driver.
                     13: 
                     14: Revision History:
                     15: 
                     16: 
                     17: 
                     18: 
                     19: --*/
                     20: 
                     21: //
                     22: // Includes
                     23: //
                     24: 
                     25: #include <ntddk.h>
                     26: #include <ntddtape.h>
                     27: #include "common.h"
                     28: #include "q117.h"
                     29: #include "protos.h"
                     30: 
                     31: 
                     32: STATUS
                     33: q117ReconstructSegment(
                     34:     IN PIO_REQUEST IoReq,
                     35:     IN PQ117_CONTEXT Context
                     36:     )
                     37: 
                     38: /*++
                     39: 
                     40: Routine Description:
                     41: 
                     42:     Reconstructs a segment of data by performing error correction
                     43:     and heroic retries.
                     44: 
                     45: Arguments:
                     46: 
                     47: Return Value:
                     48: 
                     49:     Any driver error
                     50:     RdncUnsc - If error correction failed
                     51:     NoErr - If correction complete
                     52: 
                     53: --*/
                     54: 
                     55: {
                     56:     IO_REQUEST req;
                     57:     ULONG badbits,mapbits;
                     58:     STATUS ret;
                     59: 
                     60:     mapbits = q117ReadBadSectorList(Context, (SEGMENT)(IoReq->Block/BLOCKS_PER_SEGMENT));
                     61:     badbits = IoReq->BadList;
                     62: 
                     63:     if ( ret = q117DoCorrect(IoReq->Data,mapbits,badbits) ) {
                     64: 
                     65:         CheckedDump(QIC117DBGP,("Track Reconstruction required\n"));
                     66:         CheckedDump(QIC117DBGP,("map: %08x bad:%08x\n",mapbits,badbits));
                     67: 
                     68:         //
                     69:         // if error correction failed then we must re-read the data
                     70:         //   because it has been corrupted by the Reed-Solomon routines
                     71:         //
                     72: 
                     73:         req.Data = IoReq->Data;
                     74:         req.Block = IoReq->Block;
                     75:         req.BadList = mapbits;
                     76:         req.Command = DRetry;
                     77:         req.Number = BLOCKS_PER_SEGMENT;
                     78: 
                     79:         ret = q117DoIO((PIO_REQUEST)&req, IoReq->BufferInfo,Context);
                     80: 
                     81:         if (ret) {
                     82: 
                     83:             return (ret);
                     84: 
                     85:         }
                     86: 
                     87:         if (req.Status != BadBlk && req.Status) {
                     88: 
                     89:             return(req.Status);
                     90: 
                     91:         }
                     92: 
                     93:         badbits = req.BadList;
                     94: 
                     95:         ret = q117DoCorrect(IoReq->Data, mapbits, badbits);
                     96:     }
                     97:     return(ret);
                     98: }
                     99: 
                    100: STATUS
                    101: q117DoCorrect(
                    102:     IN PVOID DataBuffer,
                    103:     IN ULONG BadSectorMap,
                    104:     IN ULONG SectorsInError
                    105:     )
                    106: 
                    107: /*++
                    108: 
                    109: Routine Description:
                    110: 
                    111:     does the error correction for a segment (using Reed-Solomon
                    112:     module)
                    113: 
                    114: Arguments:
                    115: 
                    116: Return Value:
                    117: 
                    118:     RdncUnsc - If error correction failed
                    119:     NoErr - If correction complete
                    120: 
                    121: --*/
                    122: 
                    123: {
                    124:     LONG i,j;
                    125:     UCHAR offset,num_map,num_bad;
                    126:     UCHAR s[ECC_BLOCKS_PER_SEGMENT];
                    127:     ULONG bit_i;
                    128: 
                    129:     //
                    130:     // Turn off bits for any correspondingly mapped out sectors.
                    131:     //
                    132:     SectorsInError &= ~BadSectorMap;
                    133: 
                    134:     num_map = q117CountBits(NULL, 0, BadSectorMap);
                    135:     num_bad = q117CountBits(NULL, 0, SectorsInError);
                    136: 
                    137:     if (num_bad > ECC_BLOCKS_PER_SEGMENT) {
                    138: 
                    139:         CheckedDump(QIC117DBGP,("DoCorrect: Too many bad sectors\n"));
                    140: 
                    141:         return(RdncUnsc);
                    142: 
                    143:     }
                    144: 
                    145:     if (num_bad == 0) {
                    146: 
                    147:         if (q117RdsReadCheck(DataBuffer,(UCHAR)(BLOCKS_PER_SEGMENT-num_map)) == NoErr) {
                    148: 
                    149:             return(NoErr);
                    150: 
                    151:         }
                    152: 
                    153:         CheckedDump(QIC117DBGP,("CRC failure detected\n"));
                    154: 
                    155: 
                    156:     }
                    157: 
                    158:     j = offset = 0;
                    159:     bit_i = 1;
                    160: 
                    161:     //
                    162:     // get offset into buffer (note: offset excludes bad sectors)
                    163:     //
                    164:     for (i = 0; i < BLOCKS_PER_SEGMENT; ++i) {
                    165: 
                    166:         if (!(BadSectorMap & bit_i)) {
                    167: 
                    168:             if (SectorsInError & bit_i) {
                    169: 
                    170:                 s[j++] = offset;
                    171: 
                    172:             }
                    173: 
                    174:             ++offset;
                    175: 
                    176:         }
                    177: 
                    178:         //
                    179:         // shift bit left one (same as mult by two or add to self)
                    180:         //
                    181:         bit_i += bit_i;
                    182:     }
                    183: 
                    184:     CheckedDump(QIC117INFO,("Correct( s0: %x s1: %x s2: %x) ... ",s[0],s[1],s[2]));
                    185: 
                    186:     if ( q117RdsCorrect(DataBuffer,(UCHAR)(BLOCKS_PER_SEGMENT-num_map),
                    187:             num_bad,s[0],s[1],s[2]) == NoErr ) {
                    188: 
                    189:         CheckedDump(QIC117INFO,("OK"));
                    190: 
                    191:         return(NoErr);
                    192: 
                    193:     } else {
                    194: 
                    195:         CheckedDump(QIC117INFO,("failed"));
                    196: 
                    197:         return(RdncUnsc);
                    198: 
                    199:     }
                    200: }
                    201: 
                    202: UCHAR
                    203: q117CountBits(
                    204:     IN PQ117_CONTEXT Context,
                    205:     IN SEGMENT Segment,
                    206:     ULONG Map
                    207:     )
                    208: 
                    209: /*++
                    210: 
                    211: Routine Description:
                    212: 
                    213:     Counts the number of bad sectors for the segment set in "Segment" argument
                    214: 
                    215: Arguments:
                    216: 
                    217: 
                    218: Return Value:
                    219: 
                    220:     Number of bits set
                    221: 
                    222: --*/
                    223: 
                    224: {
                    225:     USHORT i;
                    226:     UCHAR numBits;
                    227:     ULONG tmp;
                    228:     ULONG allBits;
                    229: 
                    230: 
                    231:     numBits = 0;
                    232: 
                    233:     if (Context == NULL) {
                    234: 
                    235:         allBits = Map;
                    236: 
                    237:     } else {
                    238: 
                    239:        allBits = q117ReadBadSectorList(Context, Segment);
                    240: 
                    241:     }
                    242: 
                    243:     //
                    244:     // Optimization (no bits set)
                    245:     //
                    246: 
                    247:     if (allBits != 0) {
                    248: 
                    249:         tmp = 1;
                    250: 
                    251:         //
                    252:         // Loop through checking all the bits
                    253:         //
                    254:         for (i = 0; i < BLOCKS_PER_SEGMENT; ++i) {
                    255: 
                    256:             if ( allBits & tmp ) {
                    257:                 ++numBits;
                    258:             }
                    259: 
                    260: 
                    261:             //
                    262:             // shift left one (tmp *= 2 optimized)
                    263:             //
                    264:             tmp += tmp;
                    265: 
                    266:         }
                    267: 
                    268:     }
                    269: 
                    270:     return numBits;
                    271: }
                    272: 
                    273: ULONG q117ReadBadSectorList (
                    274:     IN PQ117_CONTEXT Context,
                    275:     IN SEGMENT Segment
                    276:     )
                    277: 
                    278: /*++
                    279: 
                    280: Routine Description:
                    281: 
                    282: 
                    283: Arguments:
                    284: 
                    285:     Context - Context of the driver
                    286: 
                    287:     Segment -
                    288: 
                    289: 
                    290: Return Value:
                    291: 
                    292: 
                    293: 
                    294: --*/
                    295: 
                    296: {
                    297:     ULONG  listEntry=0l;
                    298:     USHORT  listIndex = 0;
                    299:     ULONG  startSector;
                    300:     ULONG  endSector;
                    301:     ULONG  badSectorMap = 0l;
                    302:     ULONG  mapFlag;
                    303: 
                    304:     if (Context->CurrentTape.TapeFormatCode == QIC_FORMAT) {
                    305: 
                    306:         badSectorMap = Context->CurrentTape.BadMapPtr->BadSectors[Segment];
                    307: 
                    308:     } else {
                    309: 
                    310:         listIndex = Context->CurrentTape.CurBadListIndex;
                    311: 
                    312:         listEntry = 
                    313:             q117BadListEntryToSector(
                    314:                 Context->CurrentTape.BadMapPtr->BadList[listIndex].ListEntry
                    315:             );
                    316: 
                    317:         //
                    318:         // if there is no bad sector list.
                    319:         // 
                    320:         if ((listIndex == 0) && (listEntry == 0l)) {
                    321: 
                    322:             badSectorMap = 0l;
                    323: 
                    324:         } else {
                    325: 
                    326:             //
                    327:             // get the start and end sectors for the segment we are looking
                    328:             // for.
                    329:             //
                    330:             startSector = (Segment * BLOCKS_PER_SEGMENT) + 1;
                    331:             endSector = (startSector + BLOCKS_PER_SEGMENT) - 1;
                    332: 
                    333: 
                    334:             //
                    335:             // position to the start of this list
                    336:             //
                    337: 
                    338:             //
                    339:             // if we are ahead of the entry we are looking for
                    340:             // scoot back.
                    341:             //
                    342:             while (listEntry > startSector && listIndex > 0) {
                    343: 
                    344:                 --listIndex;
                    345: 
                    346:                 listEntry = 
                    347:                     q117BadListEntryToSector(
                    348:                         Context->CurrentTape.BadMapPtr->BadList[listIndex].ListEntry
                    349:                     );
                    350: 
                    351:             }
                    352: 
                    353:             //
                    354:             // Now look forward for sectors within the range.
                    355:             //
                    356:             while (listEntry &&
                    357:                     (listEntry <= endSector) &&
                    358:                     (listIndex < MAX_BAD_LIST)) {
                    359: 
                    360:                 if (listEntry >= startSector && listEntry <= endSector) {
                    361: 
                    362:                     mapFlag = 1l << (listEntry - startSector);
                    363:                     badSectorMap |= mapFlag;
                    364: 
                    365:                 }
                    366: 
                    367:                 listEntry = q117BadListEntryToSector(Context->CurrentTape.BadMapPtr->BadList[listIndex++].ListEntry);
                    368: 
                    369:             }
                    370: 
                    371:             //
                    372:             // If we walked off the end of the list (listEntry = 0),
                    373:             // put us back on.
                    374:             //
                    375:             if (listEntry == 0) {
                    376:                 listIndex--;
                    377:             }
                    378: 
                    379:             Context->CurrentTape.CurBadListIndex = listIndex;
                    380:         }
                    381:     }
                    382: 
                    383:     return (badSectorMap);
                    384: }
                    385: 
                    386: USHORT
                    387: q117GoodDataBytes(
                    388:     IN SEGMENT Segment,
                    389:     IN PQ117_CONTEXT Context
                    390:     )
                    391: 
                    392: /*++
                    393: 
                    394: Routine Description:
                    395: 
                    396:     Calculates the number of bytes (excluding bad sectors and
                    397:     error correction sectors) within a givin segment.
                    398: 
                    399: Arguments:
                    400: 
                    401:     Segment - segment to look up in Context->CurrentTape.BadSectorMap
                    402: 
                    403: Return Value:
                    404: 
                    405:     Number of bytes.
                    406: 
                    407: --*/
                    408: 
                    409: {
                    410:     int val;
                    411: 
                    412:     val = BLOCKS_PER_SEGMENT - ECC_BLOCKS_PER_SEGMENT -
                    413:         q117CountBits(Context, Segment, 0l);
                    414: 
                    415:     //
                    416:     // Value could be negitave
                    417:     //
                    418:     if ( val <= 0 ) {
                    419: 
                    420:         return(0);
                    421: 
                    422:     }
                    423: 
                    424:     return val * BYTES_PER_SECTOR;
                    425: }

unix.superglobalmegacorp.com

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