|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
4: All Rights Reserved
5:
6: Module Name:
7:
8: q117.h
9:
10: Abstract:
11:
12: Data structures used only by q117 driver. Contains QIC-40 structures
13: and Context for q117.
14:
15: Revision History:
16:
17: --*/
18:
19: //
20: // For NTBACKUP to work, an early warning is required to allow the
21: // application to perform tape linking. To achive this, a 5 segment
22: // region at the end of the tape is RESERVED to genterate early warning
23: // status. This value is used in q117WriteTape for this purpose.
24: //
25: #define SEGMENTS_OF_EARLY_WARNING 5
26:
27:
28: #define FORMAT_BYTE 0x6b
29:
30: #define MAX_BAD_BLOCKS ((1024*27)/sizeof(ULONG))
31: #define LIST_ENTRY_SIZE 3
32: #define MAX_BAD_LIST (((1024*27)/LIST_ENTRY_SIZE) - 1)
33:
34: #define MAX_TITLE_SIZE 44 // max volume title entry size in far memory array
35: #define MAX_PASSWORD_SIZE 8 // max volume password size
36:
37: #define MAX_QIC40_FILENAME 13
38: #define MAX_HEADER_SIZE 256 // maximum QIC-40 header size
39: #define DATA_HEADER_SIG_SIZE 4 // data header signature size
40:
41: #define ECC_BLOCKS_PER_SEGMENT 3 // number of correction sectors ber block
42: #define BLOCKS_PER_SEGMENT 32 // Number of sectors per block on the tape.
43: // number of data sectors per block
44:
45: #define DATA_BLOCKS_PER_SEGMENT (BLOCKS_PER_SEGMENT - ECC_BLOCKS_PER_SEGMENT)
46:
47: #define BYTES_PER_SECTOR 1024
48: #define BYTES_PER_SEGMENT (BYTES_PER_SECTOR*BLOCKS_PER_SEGMENT)
49:
50: #define TapeHeaderSig 0xaa55aa55l
51: #define VolumeTableSig (((ULONG)'L'<<24) + ((ULONG)'B'<<16) + ('T'<<8) + 'V')
52: #define FileHeaderSig 0x33cc33ccl
53:
54: #define QIC40_VENDOR_UNIQUE_SIZE 106
55:
56:
57: #define VENDOR_TYPE_NONE 0
58: #define VENDOR_TYPE_CMS 1
59:
60: #define MOUNTAIN_SEMISPECED_SPACE 9
61:
62: #define VU_SIGNATURE_SIZE 4
63: #define VU_TAPE_NAME_SIZE 11
64:
65: #define VU_SEGS_PER_TRACK 68
66: #define VU_SEGS_PER_TRACK_XL 102
67: #define VU_80SEGS_PER_TRACK 100
68: #define VU_80SEGS_PER_TRACK_XL 150
69:
70: #define VU_MAX_FLOPPY_TRACK 169
71: #define VU_MAX_FLOPPY_TRACK_XL 254
72: #define VU_80MAX_FLOPPY_TRACK 149
73: #define VU_80MAX_FLOPPY_TRACK_XL 149
74:
75: #define VU_TRACKS_PER_CART 20
76: #define VU_80TRACKS_PER_CART 28
77:
78: #define VU_MAX_FLOPPY_SIDE 1
79: #define VU_80MAX_FLOPPY_SIDE 4
80: #define VU_80MAX_FLOPPY_SIDE_XL 6
81:
82: #define VU_MAX_FLOPPY_SECT 128
83:
84: #define NEW_SPEC_TAPE_NAME_SIZE 44
85:
86: #define FILE_VENDOR_SPECIFIC 0
87: #define FILE_UNIX_SPECIFIC 1
88: #define FILE_DATA_BAD 2
89:
90: #define OP_MS_DOS 0
91: #define OP_UNIX 1
92: #define OP_UNIX_PUBLIC 2
93: #define OP_OS_2 3
94: #define OP_WINDOWS_NT 4
95:
96: // Valid values for compression code
97: #define COMP_STAC 0x01
98: #define COMP_VEND 0x3f
99:
100: //
101: // The following section specifies QIC-40 data structures.
102: // These structures are aligned on byte boundaries.
103: //
104: #pragma pack(1)
105:
106: struct _FAIL_DATE {
107: UWORD Year:7; // year +1970 (1970-2097)
108: UWORD Month:4; // month (1-12)
109: UWORD Day:5; // day (1-31)
110: };
111:
112: struct _CMS_VENDOR_UNIQUE {
113: UBYTE type; // 0 = none; 1 = CMS
114: CHAR signature[VU_SIGNATURE_SIZE]; // "CMS" , ASCIIZ string
115: ULONG creation_time; // QIC40/QIC113 date/time format
116: CHAR tape_name[VU_TAPE_NAME_SIZE]; // space padded name
117: CHAR checksum; // checksum of UBYTEs 0 - 19 of this struct
118: };
119:
120: struct _CMS_NEW_TAPE_NAME {
121: CHAR reserved[MOUNTAIN_SEMISPECED_SPACE]; // leave room for Mountain stuff
122: CHAR tape_name[NEW_SPEC_TAPE_NAME_SIZE]; // space padded name
123: ULONG creation_time; // QIC40/QIC113 date/time format
124: };
125:
126: struct _CMS_CORRECT_TAPE_NAME {
127: UWORD unused2;
128: UWORD TrackSeg; // Tape segments per tape track
129: UBYTE CartTracks; // Tape tracks per cartridge
130: UBYTE MaxFlopSide; // Maximum floppy sides
131: UBYTE MaxFlopTrack; // Maximum floppy tracks
132: UBYTE MaxFlopSect; // Maximum floppy sectors
133: CHAR tape_name[NEW_SPEC_TAPE_NAME_SIZE]; // space padded name
134: ULONG creation_time; // QIC40/QIC113 date/time format
135: };
136:
137: typedef union _QIC40_VENDOR_UNIQUE {
138: struct _CMS_VENDOR_UNIQUE cms;
139: CHAR vu[QIC40_VENDOR_UNIQUE_SIZE];
140: struct _CMS_NEW_TAPE_NAME new_name;
141: struct _CMS_CORRECT_TAPE_NAME correct_name;
142: } QIC40_VENDOR_UNIQUE, *PQIC40_VENDOR_UNIQUE;
143:
144: typedef struct S_BadList {
145: UBYTE ListEntry[LIST_ENTRY_SIZE];
146: } BAD_LIST, *BAD_LIST_PTR;
147:
148: typedef union U_BadMap {
149: ULONG BadSectors[MAX_BAD_BLOCKS];
150: BAD_LIST BadList[MAX_BAD_LIST];
151: } BAD_MAP, *BAD_MAP_PTR;
152:
153:
154:
155:
156: // Tape Header (sectors 0-1) and BadSector Array (2-13)
157: typedef struct _TAPE_HEADER {
158: ULONG Signature; // set to 0xaa55aa55l
159: UBYTE FormatCode; // set to 0x01
160: UBYTE unused1;
161: SEGMENT HeaderSegment; // segment number of header
162: SEGMENT DupHeaderSegment; // segment number of duplicate header
163: SEGMENT FirstSegment; // segment number of Data area
164: SEGMENT LastSegment; // segment number of End of Data area
165: ULONG CurrentFormat; // time of most recent format
166: ULONG CurrentUpdate; // time of most recent write to cartridge
167: union _QIC40_VENDOR_UNIQUE VendorUnique; // Vendor unique stuff
168: UBYTE ReformatError; // 0xff if any of remaining data is lost
169: UBYTE unused3;
170: ULONG SegmentsUsed; // incremented every time a segment is used
171: UBYTE unused4[4];
172: ULONG InitialFormat; // time of initial format
173: UWORD FormatCount; // number of times tape has been formatted
174: UWORD FailedSectors; // the number entries in failed sector log
175: CHAR ManufacturerName[44]; // name of manufacturer that pre-formatted
176: CHAR LotCode[44]; // pre-format lot code
177: UBYTE unused5[22];
178: struct S_Failed {
179: SEGMENT Segment; // number of segment that failed
180: struct _FAIL_DATE DateFailed; // date of failure
181: } Failed[(1024+768)/4]; // fill out remaining UBYTEs of sector + next
182: BAD_MAP BadMap;
183: } TAPE_HEADER, *PTAPE_HEADER;
184:
185: //
186: // CMS Vendor specific area
187: //
188: typedef struct _CMS_VOLUME_VENDOR {
189: CHAR Signature[4]; // set to "CMS" (null terminated) if it is our backup
190: UWORD FirmwareRevision; // firmware version
191: UWORD SoftwareRevision; // software version
192: CHAR RightsFiles; // if 0xff = novell rights information present
193: UWORD NumFiles; // number of files in volume
194: CHAR OpSysType; // flavor of operating system at creation
195: } CMS_VOLUME_VENDOR, PCMS_VOLUME_VENDOR;
196:
197: //
198: // QIC-40 Volume table structure
199: //
200: typedef struct _VOLUME_TABLE_ENTRY {
201: ULONG Signature; // this entry will be "VTBL" if volume exists
202: SEGMENT StartSegment; // starting segment of volume for this cart
203: SEGMENT EndingSegment; // ending segment of volume for this cart
204: CHAR Description[MAX_TITLE_SIZE]; // user description of volume
205: ULONG CreationTime; // time of creation of the volume
206: UWORD VendorSpecific:1; // set if remainder of volume entry is vend spec
207: UWORD MultiCartridge:1; // set if volume spans another tape
208: UWORD NotVerified:1; // set if volume not verified yet
209: UWORD NoNewName:1; // set if new file names (redirection) disallowed
210: UWORD StacCompress:1;
211: UWORD reserved:3;
212: UWORD SequenceNumber:8; // multi-cartridge sequence number
213: union {
214: CMS_VOLUME_VENDOR cms_QIC40;
215: UBYTE reserved[26]; // vendor extension data
216: } Vendor;
217: CHAR Password[MAX_PASSWORD_SIZE];// password for volume
218: ULONG DirectorySize; // number of UBYTEs reserved for directory
219: ULONG DataSize; // size of data area (includes other cartridges)
220: UWORD OpSysVersion; // operating system version
221: CHAR VolumeLabel[16]; // volume label of source drive
222: UBYTE LogicalDevice; // who knows
223: UBYTE PhysicalDevice; // who knows
224: UWORD CompressCode:6; // type of compression, 3Fh = vendor specific
225: UWORD CompressAlwaysZero:1; // must be 0
226: UWORD CompressSwitch:1; // compression use flag
227: UWORD reserved1:8;
228: UBYTE reserved2[6];
229: } VOLUME_TABLE_ENTRY, *PVOLUME_TABLE_ENTRY;
230:
231: #pragma pack()
232:
233:
234: //
235: // The following structure is the context for the q117 driver. It contains
236: // all current "state" information for the tape drive.
237: //
238: typedef struct _Q117_CONTEXT {
239:
240: BOOLEAN DriverOpened; // Set if driver is opened
241:
242: VOLUME_TABLE_ENTRY ActiveVolume; // volume currently being saved to (nt volume)
243: USHORT ActiveVolumeNumber; // The sequence number of the current struct VolDir.
244:
245: //TAPE_STATUS TapeStatus;
246:
247: // PVOID DeviceExtension; // Used by the tape thread
248:
249: PDEVICE_OBJECT q117iDeviceObject;
250: PQ117_ADAPTER_INFO AdapterInfo; // Filled in at init time with DMA channel
251:
252: //
253: // Error tracking
254: //
255:
256: ULONG ErrorSequence;
257: UCHAR MajorFunction;
258:
259: //
260: // Queue management globals
261: //
262:
263: SEGMENT_BUFFER SegmentBuffer[UNIX_MAXBFS]; // Array of segment buffers
264:
265: ULONG SegmentBuffersAvailable;
266:
267: ULONG QueueTailIndex; // Index in the IORequest array that indexes the tail.
268:
269: ULONG QueueHeadIndex; // This is the head of the Filer IORequest ring-tail array.
270:
271: PIO_REQUEST IoRequest; // pointer to array of IORequests
272:
273: //
274: // current buffer information
275: //
276:
277: struct {
278:
279: enum {
280: NoOperation,
281: BackupInProgress,
282: RestoreInProgress
283: } Type;
284:
285: //
286: // Information associated with currently active segment
287: //
288: PVOID SegmentPointer;
289: USHORT SegmentBytesRemaining;
290: SEGMENT LastSegmentRead;
291: SEGMENT CurrentSegment; // in backup (active segment) in restore (read-ahead segment)
292: USHORT BytesZeroFilled; // Bytes at end of backup that were zeroed (not part of backup)
293: STATUS SegmentStatus;
294: SEGMENT EndOfUsedTape;
295: SEGMENT LastSegment; // Last segment of volume
296: ULONG BytesOnTape;
297: BOOLEAN UpdateBadMap; // if true then update bad sector map
298: ULONG BytesRead;
299: ULONG Position; // type of last IOCTL_TAPE_SET_POSITION
300:
301: } CurrentOperation;
302:
303: //
304: // current tape information
305: //
306:
307: struct {
308: enum {
309: TapeInfoLoaded,
310: NeedInfoLoaded
311: } State;
312:
313: SEGMENT LastUsedSegment;
314: SEGMENT VolumeSegment;
315: ULONG BadSectors;
316: SEGMENT LastSegment; // Last formatted segment.
317: USHORT MaximumVolumes; // Maximum volumes entries available
318: PTAPE_HEADER TapeHeader; // Header from tape
319: struct _TAPE_GET_MEDIA_PARAMETERS *MediaInfo;
320: BAD_MAP_PTR BadMapPtr;
321: ULONG BadSectorMapSize;
322: USHORT CurBadListIndex;
323: USHORT TapeFormatCode;
324:
325: } CurrentTape;
326:
327:
328:
329: // if this global is set then the tape directory has been loaded
330: PIO_REQUEST tapedir;
331:
332: char drive_type; // QIC40 or QIC80
333:
334: //
335: // The following pointers are allocated when open is called and
336: // freed at close time.
337: //
338:
339: #ifndef NO_MARKS
340: #define MAX_MARKS 255
341: ULONG CurrentMark;
342: struct _MARKENTRIES {
343: ULONG TotalMarks;
344: struct _MARKLIST {
345: ULONG Type;
346: ULONG Offset;
347: } MarkEntry[MAX_MARKS];
348: } MarkArray;
349: #endif
350:
351: } Q117_CONTEXT, *PQ117_CONTEXT;
352:
353:
354: typedef enum _DEQUEUE_TYPE {
355: FlushItem,
356: WaitForItem
357: } DEQUEUE_TYPE;
358:
359: //
360: // Common need: convert block into segment
361: //
362: #define BLOCK_TO_SEGMENT(block) ((SEGMENT)((block) / BLOCKS_PER_SEGMENT))
363: #define SEGMENT_TO_BLOCK(segment) ((BLOCK)(segment) * BLOCKS_PER_SEGMENT)
364:
365:
366: //
367: // This define is the block size used by position commands
368: // Note: It is 512 to be compatible with the Maynstream backup
369: // that does not do a getmedia parameters
370: //
371: #define BLOCK_SIZE BYTES_PER_SECTOR
372:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.