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