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