|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 - Colorado Memory Systems, Inc. ! 4: All Rights Reserved ! 5: ! 6: Module Name: ! 7: ! 8: endback.c ! 9: ! 10: Abstract: ! 11: ! 12: High level end write operations. Flushes buffers and zero-fills ! 13: to the end of a segment. ! 14: ! 15: Revision History: ! 16: ! 17: ! 18: ! 19: ! 20: --*/ ! 21: ! 22: // ! 23: // include files ! 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: STATUS ! 34: q117EndBack( ! 35: IN OUT PQ117_CONTEXT Context ! 36: ) ! 37: ! 38: /*++ ! 39: ! 40: Routine Description: ! 41: ! 42: This routine finishes writing all information to the tape for pending ! 43: update. ! 44: ! 45: Uses global variable CurrentOperation.SegmentBytesRemaining, the number of bytes left in last ! 46: segment on the tape. ! 47: ! 48: Arguments: ! 49: ! 50: Context - ! 51: ! 52: Return Value: ! 53: ! 54: Possible return values: NoErr, any Driver error, ! 55: <EndOfVol>, <LinkRC>, RdncUnscError ! 56: ! 57: --*/ ! 58: ! 59: { ! 60: USHORT end_fill,remainder; ! 61: STATUS ret; // Return value from other routines called. ! 62: PIO_REQUEST ioreq; ! 63: ! 64: // ! 65: // clear the end of the last segment buffer ! 66: // ! 67: ! 68: if (Context->CurrentOperation.SegmentBytesRemaining) { ! 69: ! 70: // ! 71: // clear the rest of the data ! 72: // ! 73: ! 74: RtlZeroMemory(Context->CurrentOperation.SegmentPointer,Context->CurrentOperation.SegmentBytesRemaining); ! 75: end_fill = Context->CurrentOperation.SegmentBytesRemaining; ! 76: ! 77: } else { ! 78: ! 79: end_fill = 0; ! 80: ! 81: } ! 82: ! 83: // ! 84: // Set fill bytes (so bad sector re-mapping knows how much of this segment ! 85: // is zeros) ! 86: // ! 87: ! 88: Context->CurrentOperation.BytesZeroFilled = end_fill; ! 89: ! 90: // ! 91: // write out last block ! 92: // ! 93: ! 94: if (!(ret = q117IssIOReq( ! 95: (PVOID)NULL, ! 96: DWrite, ! 97: (LONG)Context->CurrentOperation.CurrentSegment * BLOCKS_PER_SEGMENT, ! 98: NULL, ! 99: Context))) { ! 100: ! 101: ++Context->CurrentOperation.CurrentSegment; ! 102: ! 103: // ! 104: // wait for all blocks to be written ! 105: // ! 106: ! 107: while (!ret && !q117QueueEmpty(Context)) { ! 108: ! 109: ioreq = q117Dequeue(WaitForItem, Context); ! 110: ! 111: if (ioreq->Status && ioreq->Status != BadBlk) { ! 112: ! 113: ret = ioreq->Status; ! 114: ! 115: } else { ! 116: ! 117: if (ioreq->Status == BadBlk) { ! 118: ! 119: if (!(ret = q117MapBadBlock( ! 120: ioreq, ! 121: &Context->CurrentOperation.SegmentPointer, ! 122: &Context->CurrentOperation.SegmentBytesRemaining, ! 123: &Context->CurrentOperation.CurrentSegment, ! 124: &remainder, ! 125: Context))) { ! 126: ! 127: if (remainder) { ! 128: ! 129: if (Context->CurrentOperation.SegmentBytesRemaining) { ! 130: ! 131: // ! 132: // clear the rest of the data ! 133: // ! 134: ! 135: RtlZeroMemory(Context->CurrentOperation.SegmentPointer,Context->CurrentOperation.SegmentBytesRemaining); ! 136: Context->CurrentOperation.BytesZeroFilled = Context->CurrentOperation.SegmentBytesRemaining; ! 137: } ! 138: ! 139: // ! 140: // write out overflow data ! 141: // ! 142: ! 143: if (!(ret=q117IssIOReq( ! 144: (PVOID)NULL, ! 145: DWrite, ! 146: (LONG)Context->CurrentOperation.CurrentSegment * ! 147: BLOCKS_PER_SEGMENT, ! 148: NULL, ! 149: Context))) { ! 150: ! 151: ++Context->CurrentOperation.CurrentSegment; ! 152: } ! 153: } ! 154: } ! 155: } ! 156: } ! 157: } ! 158: } ! 159: return(ret); ! 160: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.