|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.