|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 - Colorado Memory Systems, Inc. ! 4: All Rights Reserved ! 5: ! 6: Module Name: ! 7: ! 8: erase.c ! 9: ! 10: Abstract: ! 11: ! 12: Does a read pass over the entire tape to create the bad block map and ! 13: writes the bad block map to the tape and zeros the tape directory. ! 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: q117VerifyFormat( ! 35: IN OUT PQ117_CONTEXT Context ! 36: ) ! 37: ! 38: /*++ ! 39: ! 40: Routine Description: ! 41: ! 42: ! 43: ! 44: ! 45: Arguments: ! 46: ! 47: Context - ! 48: ! 49: Return Value: ! 50: ! 51: ! 52: NoErr, UnusTape, any Driver error, <LinkBack>, RdncUnsc. ! 53: ! 54: ! 55: --*/ ! 56: ! 57: { ! 58: STATUS status; ! 59: ! 60: Context->CurrentTape.CurBadListIndex = 0; ! 61: ! 62: status = q117FillTapeBlocks( ! 63: DVerify, ! 64: 0, ! 65: Context->CurrentTape.LastSegment, ! 66: NULL, ! 67: 0, ! 68: 0, ! 69: NULL, ! 70: Context); ! 71: ! 72: Context->CurrentTape.CurBadListIndex = 0; ! 73: ! 74: return status; ! 75: } ! 76: ! 77: ! 78: STATUS ! 79: q117EraseQ ( ! 80: IN OUT PQ117_CONTEXT Context ! 81: ) ! 82: ! 83: /*++ ! 84: ! 85: Routine Description: ! 86: ! 87: Writes the bad sector map already in memory (put there either by a ! 88: call to Init() or Erase()) to the tape and stomps on each entry ! 89: in the tape directory. ! 90: ! 91: Arguments: ! 92: ! 93: Context - ! 94: ! 95: Return Value: ! 96: ! 97: Possible return values: NoErr, FMemErr, UnusTape, any Driver ! 98: error, <LinkBack>, RdncUnsc. ! 99: ! 100: --*/ ! 101: ! 102: { ! 103: STATUS ret; // Return value from other routines called. ! 104: LONG i; // generic loop index ! 105: PVOLUME_TABLE_ENTRY scrbuf; ! 106: PSEGMENT_BUFFER bufferInfo; ! 107: PIO_REQUEST ioreq; ! 108: ! 109: if (!q117QueueEmpty(Context)) { ! 110: ! 111: return(FCodeErr); ! 112: ! 113: } ! 114: ! 115: q117ClearVolume(Context); ! 116: ! 117: scrbuf = (PVOLUME_TABLE_ENTRY)q117GetFreeBuffer(&bufferInfo,Context); ! 118: ! 119: if (ret = q117IssIOReq( ! 120: scrbuf, ! 121: DRead, ! 122: (LONG)Context->CurrentTape.VolumeSegment * BLOCKS_PER_SEGMENT, ! 123: bufferInfo, ! 124: Context)) { ! 125: ! 126: return(ret); ! 127: ! 128: } ! 129: ! 130: ioreq = q117Dequeue(WaitForItem,Context); ! 131: ret = ioreq->Status; ! 132: ! 133: if (ret == BadBlk || ret == NoErr) { ! 134: ! 135: // ! 136: // correct data segment with Reed-Solomon and Heroic retries ! 137: // ! 138: ret = q117ReconstructSegment(ioreq,Context); ! 139: ! 140: } ! 141: ! 142: if (ret) { ! 143: ! 144: return ret; ! 145: ! 146: } ! 147: ! 148: // ! 149: // stomp on the signatures only ! 150: // ! 151: ! 152: for (i = 0; ! 153: i < ( ( DATA_BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR ) / ! 154: sizeof(VOLUME_TABLE_ENTRY)); ! 155: i++) { ! 156: ! 157: RtlZeroMemory(&scrbuf[i].Signature, sizeof(scrbuf->Signature)); ! 158: ! 159: } ! 160: ! 161: // ! 162: // now write it out again! ! 163: // ! 164: ! 165: if (ret = q117IssIOReq( ! 166: scrbuf, ! 167: DWrite, ! 168: (LONG)Context->CurrentTape.VolumeSegment * BLOCKS_PER_SEGMENT, ! 169: bufferInfo, ! 170: Context)) { ! 171: ! 172: return(ret); ! 173: ! 174: } ! 175: ! 176: ret = q117Dequeue(WaitForItem,Context)->Status; ! 177: ! 178: q117ClearVolume(Context); ! 179: ! 180: q117SetTpSt(Context); ! 181: ! 182: return(ret); ! 183: } ! 184: ! 185: STATUS ! 186: q117EraseS ( ! 187: IN OUT PQ117_CONTEXT Context ! 188: ) ! 189: ! 190: /*++ ! 191: ! 192: Routine Description: ! 193: ! 194: Init() must be called before calling this routine. Reads the tape ! 195: directory to find the ending block of the last backup on the tape ! 196: and writes 0's to every sector from the end of the tape directory ! 197: up to and including the ending block of the last backup, and then 0's ! 198: the tape directory and rewrites the bad sector map by calling ! 199: EraseQ(). ! 200: ! 201: Arguments: ! 202: ! 203: Context - ! 204: ! 205: Return Value: ! 206: ! 207: ! 208: ! 209: --*/ ! 210: ! 211: { ! 212: STATUS ret; // Return value from other routines called. ! 213: PVOID scrbuf; ! 214: PSEGMENT_BUFFER bufferInfo; ! 215: ! 216: scrbuf = q117GetFreeBuffer(&bufferInfo, Context); ! 217: ! 218: RtlZeroMemory(scrbuf, BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR); ! 219: ! 220: ret = q117FillTapeBlocks( ! 221: DWrite, ! 222: Context->CurrentTape.VolumeSegment, ! 223: Context->CurrentTape.LastSegment, ! 224: scrbuf, ! 225: 0, ! 226: 0, ! 227: bufferInfo, ! 228: Context); ! 229: ! 230: Context->CurrentOperation.EndOfUsedTape = ! 231: Context->CurrentTape.LastUsedSegment = ! 232: Context->CurrentTape.VolumeSegment; ! 233: ! 234: q117ClearVolume(Context); ! 235: ! 236: q117SetTpSt(Context); ! 237: ! 238: return(ret); ! 239: } ! 240: ! 241: VOID ! 242: q117ClearVolume ( ! 243: IN OUT PQ117_CONTEXT Context ! 244: ) ! 245: ! 246: /*++ ! 247: ! 248: Routine Description: ! 249: ! 250: Clear state information for any active volume. ! 251: ! 252: Arguments: ! 253: ! 254: Context - ! 255: ! 256: Return Value: ! 257: ! 258: --*/ ! 259: { ! 260: #ifndef NO_MARKS ! 261: RtlZeroMemory(&Context->MarkArray,sizeof(Context->MarkArray)); ! 262: Context->CurrentMark = Context->MarkArray.TotalMarks; ! 263: Context->MarkArray.MarkEntry[Context->CurrentMark].Offset = 0xffffffff; ! 264: #endif ! 265: ! 266: Context->CurrentOperation.Position = TAPE_REWIND; ! 267: ! 268: // ! 269: // Destroy the active volume ! 270: // ! 271: ! 272: RtlZeroMemory(&Context->ActiveVolume,sizeof(Context->ActiveVolume)); ! 273: Context->ActiveVolumeNumber = 0; ! 274: ! 275: // ! 276: // Set tape to all available ! 277: // ! 278: Context->CurrentOperation.EndOfUsedTape = ! 279: Context->CurrentTape.LastUsedSegment = ! 280: Context->CurrentTape.VolumeSegment; ! 281: ! 282: } ! 283: ! 284: ! 285: ! 286: ! 287: ! 288: ! 289: ! 290:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.