|
|
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.