|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 - Colorado Memory Systems, Inc. ! 4: All Rights Reserved ! 5: ! 6: Module Name: ! 7: ! 8: update.c ! 9: ! 10: Abstract: ! 11: ! 12: Performs the various tape updating functions. ! 13: ! 14: Revision History: ! 15: ! 16: ! 17: ! 18: ! 19: --*/ ! 20: ! 21: // ! 22: // include files ! 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: q117UpdateHeader( ! 34: IN PTAPE_HEADER Header, ! 35: IN PQ117_CONTEXT Context ! 36: ) ! 37: ! 38: /*++ ! 39: ! 40: Routine Description: ! 41: ! 42: This routine updates the tape header. ! 43: ! 44: Arguments: ! 45: ! 46: Header - ! 47: ! 48: Context - ! 49: ! 50: Return Value: ! 51: ! 52: ! 53: ! 54: --*/ ! 55: ! 56: { ! 57: STATUS ret; ! 58: PVOID scrbuf; ! 59: PSEGMENT_BUFFER bufferInfo; ! 60: ! 61: // ! 62: // put saved logical part of header into transfer buffer ! 63: // ! 64: scrbuf = q117GetFreeBuffer(&bufferInfo,Context); ! 65: RtlMoveMemory(scrbuf, Header, sizeof(TAPE_HEADER)); ! 66: ! 67: // ! 68: // write out the TapeHeader structure ! 69: // ! 70: ret = q117FillTapeBlocks( ! 71: DWriteBad, ! 72: (SEGMENT)0, ! 73: Header->DupHeaderSegment, ! 74: scrbuf, ! 75: Header->HeaderSegment, ! 76: Header->DupHeaderSegment, ! 77: bufferInfo, ! 78: Context); ! 79: return(ret); ! 80: } ! 81: ! 82: STATUS ! 83: q117Update( ! 84: IN OUT PQ117_CONTEXT Context ! 85: ) ! 86: ! 87: /*++ ! 88: ! 89: Routine Description: ! 90: ! 91: This routine updates tape directory with cur_vol. ! 92: ! 93: Arguments: ! 94: ! 95: Link - ! 96: ! 97: Context - ! 98: ! 99: Return Value: ! 100: ! 101: ! 102: ! 103: --*/ ! 104: { ! 105: STATUS ret; // Return value from other routines called. ! 106: ! 107: Context->ActiveVolume.DataSize = Context->CurrentOperation.BytesOnTape; ! 108: ! 109: // ! 110: // update volume table entry (to be written to tape directory) ! 111: // ! 112: Context->ActiveVolume.EndingSegment = (USHORT)Context->CurrentOperation.CurrentSegment-1; ! 113: ! 114: ! 115: if (Context->CurrentOperation.UpdateBadMap) { ! 116: if (ret = q117DoUpdateBad(Context)) ! 117: return(ret); ! 118: } ! 119: ! 120: // ! 121: // update volume directory ! 122: // ! 123: // thevoldir->endblock was set to 0 at StartBack(). ! 124: // ! 125: ret=q117AppVolTD(&Context->ActiveVolume,Context); ! 126: if (ret==NoErr) { ! 127: Context->CurrentOperation.EndOfUsedTape = Context->ActiveVolume.EndingSegment; ! 128: #ifndef NO_MARKS ! 129: ret = q117DoUpdateMarks(Context); ! 130: #endif ! 131: } else { ! 132: Context->CurrentOperation.EndOfUsedTape=0; ! 133: } ! 134: ! 135: // ! 136: // Set the tape status. ! 137: // ! 138: q117SetTpSt(Context); ! 139: return(ret); ! 140: } ! 141: ! 142: ! 143: STATUS ! 144: q117DoUpdateBad( ! 145: IN OUT PQ117_CONTEXT Context ! 146: ) ! 147: ! 148: /*++ ! 149: ! 150: Routine Description: ! 151: ! 152: ! 153: ! 154: Arguments: ! 155: ! 156: Context - ! 157: ! 158: Return Value: ! 159: ! 160: ! 161: ! 162: --*/ ! 163: { ! 164: STATUS ret; ! 165: PVOID scrbuf; ! 166: PSEGMENT_BUFFER bufferInfo; ! 167: PTAPE_HEADER hdr; ! 168: ! 169: // ! 170: //rdr - Beta fix ! 171: // ! 172: ! 173: // return(BadTape); ! 174: ! 175: CheckedDump(QIC117INFO,( "Q117i: Starting DoUpdateBad\n")); ! 176: ! 177: ! 178: // ! 179: // read the header segment in ! 180: // ! 181: //if (ret = q117ReadHeaderSegment(&hdr,Context)) { ! 182: // ! 183: // return(ret); ! 184: // ! 185: //} ! 186: hdr = Context->CurrentTape.TapeHeader; ! 187: ! 188: // ! 189: // put in the new bad sector map ! 190: // ! 191: ! 192: //RtlMoveMemory(&(hdr->BadMap), ! 193: // Context->CurrentTape.BadMapPtr, ! 194: // sizeof(BAD_MAP)); ! 195: ! 196: scrbuf = q117GetFreeBuffer(&bufferInfo,Context); ! 197: ! 198: // ! 199: // put saved logical part of header into transfer buffer ! 200: // ! 201: ! 202: RtlMoveMemory(scrbuf, hdr, sizeof(TAPE_HEADER)); ! 203: ! 204: // ! 205: // write out the TapeHeader structure ! 206: // ! 207: ! 208: if ( ret = q117FillTapeBlocks( ! 209: DWriteBad, ! 210: (SEGMENT)0, ! 211: hdr->DupHeaderSegment, ! 212: scrbuf, ! 213: hdr->HeaderSegment, ! 214: hdr->DupHeaderSegment, ! 215: bufferInfo, ! 216: Context) ) { ! 217: ! 218: return(UpdErr); ! 219: ! 220: } ! 221: ! 222: // ! 223: // tape directory potentialy corrupted by FillTapeBlocks(), so just ! 224: // re-read it ! 225: // ! 226: Context->tapedir = (PIO_REQUEST)NULL; ! 227: ! 228: CheckedDump(QIC117INFO,( "Q117i: Ending DoUpdateBad (Success)\n")); ! 229: return(NoErr); ! 230: } ! 231: ! 232: #ifndef NO_MARKS ! 233: ! 234: STATUS ! 235: q117DoUpdateMarks( ! 236: IN OUT PQ117_CONTEXT Context ! 237: ) ! 238: ! 239: /*++ ! 240: ! 241: Routine Description: ! 242: ! 243: ! 244: ! 245: Arguments: ! 246: ! 247: Context - ! 248: ! 249: Return Value: ! 250: ! 251: ! 252: ! 253: --*/ ! 254: { ! 255: STATUS ret; ! 256: PSEGMENT_BUFFER bufferInfo; ! 257: PVOID scrbuf; ! 258: PIO_REQUEST ioreq; ! 259: ! 260: ! 261: scrbuf = q117GetFreeBuffer(&bufferInfo,Context); ! 262: ! 263: // ! 264: // Fill in the mark list ! 265: // ! 266: RtlZeroMemory(scrbuf, ! 267: q117GoodDataBytes( ! 268: (SEGMENT)Context->ActiveVolume.DirectorySize, Context ) ! 269: ); ! 270: ! 271: RtlMoveMemory(scrbuf, &Context->MarkArray, sizeof(Context->MarkArray)); ! 272: ! 273: ret=q117IssIOReq(scrbuf,DWrite, ! 274: Context->ActiveVolume.DirectorySize * BLOCKS_PER_SEGMENT,bufferInfo,Context); ! 275: ! 276: if (!ret) { ! 277: // ! 278: // Wait for data to be written ! 279: // ! 280: ioreq=q117Dequeue(WaitForItem,Context); ! 281: ! 282: ret = ioreq->Status; ! 283: ! 284: } ! 285: ! 286: return(ret); ! 287: } ! 288: ! 289: STATUS ! 290: q117GetMarks( ! 291: IN OUT PQ117_CONTEXT Context ! 292: ) ! 293: ! 294: /*++ ! 295: ! 296: Routine Description: ! 297: ! 298: ! 299: ! 300: Arguments: ! 301: ! 302: Context - ! 303: ! 304: Return Value: ! 305: ! 306: ! 307: ! 308: --*/ ! 309: { ! 310: STATUS ret; ! 311: PSEGMENT_BUFFER bufferInfo; ! 312: PVOID scrbuf; ! 313: PIO_REQUEST ioreq; ! 314: ! 315: ! 316: scrbuf = q117GetFreeBuffer(&bufferInfo,Context); ! 317: ! 318: // ! 319: // Read this data block into memory ! 320: // ! 321: ret=q117IssIOReq(scrbuf,DRead, ! 322: Context->ActiveVolume.DirectorySize * BLOCKS_PER_SEGMENT,bufferInfo,Context); ! 323: ! 324: if (!ret) { ! 325: // Wait for data to be read ! 326: ioreq=q117Dequeue(WaitForItem,Context); ! 327: ! 328: if (ioreq->Status != BadBlk && ioreq->Status) { ! 329: ! 330: ret = ioreq->Status; ! 331: ! 332: } else { ! 333: ! 334: /* correct data segment with Reed-Solomon and Heroic retries */ ! 335: ret = q117ReconstructSegment(ioreq,Context); ! 336: } ! 337: ! 338: if (!ret) { ! 339: RtlMoveMemory(&Context->MarkArray, scrbuf, sizeof(Context->MarkArray)); ! 340: } ! 341: ! 342: } ! 343: ! 344: return(ret); ! 345: } ! 346: #endif ! 347: ! 348: STATUS ! 349: q117FillTapeBlocks( ! 350: IN OUT DRIVER_COMMAND Command, ! 351: IN SEGMENT CurrentSegment, ! 352: IN SEGMENT EndSegment, ! 353: IN OUT PVOID Buffer, ! 354: IN SEGMENT FirstGood, ! 355: IN SEGMENT SecondGood, ! 356: IN PSEGMENT_BUFFER BufferInfo, ! 357: IN PQ117_CONTEXT Context ! 358: ) ! 359: ! 360: /*++ ! 361: ! 362: Routine Description: ! 363: ! 364: ! 365: ! 366: Arguments: ! 367: ! 368: Command - ! 369: ! 370: CurrentSegment - ! 371: ! 372: EndSegment - ! 373: ! 374: Buffer - ! 375: ! 376: FirstGood - ! 377: ! 378: SecondGood - ! 379: ! 380: BufferInfo - ! 381: ! 382: Context - ! 383: ! 384: Return Value: ! 385: ! 386: ! 387: ! 388: --*/ ! 389: { ! 390: STATUS ret; ! 391: CHAR iocmd; ! 392: PIO_REQUEST ioreq; ! 393: ULONG cur_seg = 0; // The current segment being processed ! 394: BAD_LIST badList[BLOCKS_PER_SEGMENT]; ! 395: ULONG listEntry; ! 396: USHORT listIndex; ! 397: ! 398: // ! 399: // set queue into single buffer mode ! 400: // ! 401: q117QueueSingle(Context); ! 402: ! 403: // ! 404: // get pointer to free buffer ! 405: // ! 406: if (Buffer == NULL) { ! 407: Buffer = q117GetFreeBuffer(&BufferInfo,Context); ! 408: } ! 409: ! 410: do { ! 411: while(!q117QueueFull(Context) && CurrentSegment <= EndSegment) { ! 412: if (Command == DWriteBad && (CurrentSegment == FirstGood || CurrentSegment == SecondGood)) { ! 413: iocmd = DWrite; ! 414: } else { ! 415: iocmd = Command; ! 416: } ! 417: ! 418: // ! 419: // We need to skip segments with no data area (less than 4 ! 420: // good segments) ! 421: // ! 422: while (q117GoodDataBytes(CurrentSegment,Context) <= 0) { ! 423: ++CurrentSegment; ! 424: } ! 425: if (ret=q117IssIOReq(Buffer,iocmd,(LONG)CurrentSegment * BLOCKS_PER_SEGMENT,BufferInfo,Context)) { ! 426: ! 427: return(ret); ! 428: } ! 429: ++CurrentSegment; ! 430: } ! 431: ! 432: ioreq = q117Dequeue(WaitForItem,Context); ! 433: ! 434: if ((ioreq->Status!=NoErr) && ! 435: (ioreq->Status!=BadBlk) && ! 436: (ioreq->Status!=BadMark)) { ! 437: ! 438: // ! 439: // Any Driver error except BadBlk. ! 440: // ! 441: return(ioreq->Status); ! 442: } ! 443: if (Command == DVerify) { ! 444: ! 445: if (Context->CurrentTape.TapeFormatCode == QIC_FORMAT) { ! 446: ! 447: Context->CurrentTape.BadMapPtr->BadSectors[(ioreq->Block)/BLOCKS_PER_SEGMENT] = ! 448: ioreq->BadList|ioreq->RetryList; ! 449: ! 450: } else { ! 451: ! 452: if ((ioreq->BadList|ioreq->RetryList) != 0l) { ! 453: ! 454: q117BadMapToBadList( ! 455: (SEGMENT)((ioreq->Block)/BLOCKS_PER_SEGMENT), ! 456: (ioreq->BadList | ioreq->RetryList), ! 457: badList); ! 458: ! 459: listIndex = 0; ! 460: ! 461: do { ! 462: ! 463: RtlMoveMemory( ! 464: Context->CurrentTape.BadMapPtr->BadList[Context->CurrentTape.CurBadListIndex++].ListEntry, ! 465: badList[listIndex++].ListEntry, ! 466: (ULONG)LIST_ENTRY_SIZE); ! 467: ! 468: listEntry = q117BadListEntryToSector(badList[listIndex].ListEntry); ! 469: ! 470: } while (listEntry && ! 471: (listIndex < BLOCKS_PER_SEGMENT)); ! 472: ! 473: } ! 474: ! 475: } ! 476: ! 477: } ! 478: ! 479: // ! 480: // Till nothing left in the queue. ! 481: // ! 482: } while (!q117QueueEmpty(Context) || CurrentSegment <= EndSegment); ! 483: ! 484: q117QueueNormal(Context); ! 485: return(NoErr); ! 486: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.