|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1989 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: scsi.h ! 8: ! 9: Abstract: ! 10: ! 11: These are the structures and defines that are used in the ! 12: SCSI port and class drivers. ! 13: ! 14: Authors: ! 15: ! 16: John Freeman (johnfr) 28-Mar-90 ! 17: Andre Vachon (andrev) 06-Jun-90 ! 18: Mike Glass (mglass) ! 19: Jeff Havens (jhavens) ! 20: ! 21: Revision History: ! 22: ! 23: --*/ ! 24: #ifndef _NTSCSI_ ! 25: #define _NTSCSI_ ! 26: ! 27: #include "srb.h" ! 28: ! 29: // ! 30: // Define SCSI maximum configuration parameters. ! 31: // ! 32: ! 33: #define SCSI_MAXIMUM_TARGETS 8 ! 34: #define SCSI_MAXIMUM_LOGICAL_UNITS 8 ! 35: #define SCSI_MAXIMUM_TARGETS_PER_BUS 32 ! 36: ! 37: #define MAXIMUM_CDB_SIZE 12 ! 38: ! 39: // ! 40: // Command Descriptor Block. Passed by SCSI controller chip over the SCSI bus ! 41: // ! 42: ! 43: typedef union _CDB { ! 44: ! 45: // ! 46: // Generic 6-Byte CDB ! 47: // ! 48: ! 49: struct _CDB6GENERIC { ! 50: UCHAR OperationCode; ! 51: UCHAR Immediate : 1; ! 52: UCHAR CommandUniqueBits : 4; ! 53: UCHAR LogicalUnitNumber : 3; ! 54: UCHAR CommandUniqueBytes[3]; ! 55: UCHAR Link : 1; ! 56: UCHAR Flag : 1; ! 57: UCHAR Reserved : 4; ! 58: UCHAR VendorUnique : 2; ! 59: } CDB6GENERIC, *PCDB6GENERIC; ! 60: ! 61: // ! 62: // Standard 6-byte CDB ! 63: // ! 64: ! 65: struct _CDB6READWRITE { ! 66: UCHAR OperationCode; ! 67: UCHAR LogicalBlockMsb1 : 5; ! 68: UCHAR LogicalUnitNumber : 3; ! 69: UCHAR LogicalBlockMsb0; ! 70: UCHAR LogicalBlockLsb; ! 71: UCHAR TransferBlocks; ! 72: UCHAR Control; ! 73: } CDB6READWRITE, *PCDB6READWRITE; ! 74: ! 75: ! 76: // ! 77: // SCSI Inquiry CDB ! 78: // ! 79: ! 80: struct _CDB6INQUIRY { ! 81: UCHAR OperationCode; ! 82: UCHAR Reserved1 : 5; ! 83: UCHAR LogicalUnitNumber : 3; ! 84: UCHAR PageCode; ! 85: UCHAR IReserved; ! 86: UCHAR AllocationLength; ! 87: UCHAR Control; ! 88: } CDB6INQUIRY, *PCDB6INQUIRY; ! 89: ! 90: // ! 91: // SCSI Format CDB ! 92: // ! 93: ! 94: struct _CDB6FORMAT { ! 95: UCHAR OperationCode; ! 96: UCHAR FormatControl : 5; ! 97: UCHAR LogicalUnitNumber : 3; ! 98: UCHAR FReserved1; ! 99: UCHAR InterleaveMsb; ! 100: UCHAR InterleaveLsb; ! 101: UCHAR FReserved2; ! 102: } CDB6FORMAT, *PCDB6FORMAT; ! 103: ! 104: // ! 105: // Standard 10-byte CDB ! 106: ! 107: struct _CDB10 { ! 108: UCHAR OperationCode; ! 109: UCHAR RelativeAddress : 1; ! 110: UCHAR Reserved1 : 2; ! 111: UCHAR ForceUnitAccess : 1; ! 112: UCHAR DisablePageOut : 1; ! 113: UCHAR LogicalUnitNumber : 3; ! 114: UCHAR LogicalBlockByte0; ! 115: UCHAR LogicalBlockByte1; ! 116: UCHAR LogicalBlockByte2; ! 117: UCHAR LogicalBlockByte3; ! 118: UCHAR Reserved2; ! 119: UCHAR TransferBlocksMsb; ! 120: UCHAR TransferBlocksLsb; ! 121: UCHAR Control; ! 122: } CDB10, *PCDB10; ! 123: ! 124: // ! 125: // CD Rom Audio CDBs ! 126: // ! 127: ! 128: struct _PAUSE_RESUME { ! 129: UCHAR OperationCode; ! 130: UCHAR Reserved1 : 5; ! 131: UCHAR LogicalUnitNumber : 3; ! 132: UCHAR Reserved2[6]; ! 133: UCHAR Action; ! 134: UCHAR Control; ! 135: } PAUSE_RESUME, *PPAUSE_RESUME; ! 136: ! 137: // ! 138: // Read Table of Contents ! 139: // ! 140: ! 141: struct _READ_TOC { ! 142: UCHAR OperationCode; ! 143: UCHAR Reserved0 : 1; ! 144: UCHAR Msf : 1; ! 145: UCHAR Reserved1 : 3; ! 146: UCHAR LogicalUnitNumber : 3; ! 147: UCHAR Reserved2[4]; ! 148: UCHAR StartingTrack; ! 149: UCHAR AllocationLength[2]; ! 150: UCHAR Control : 6; ! 151: UCHAR Format : 2; ! 152: } READ_TOC, *PREAD_TOC; ! 153: ! 154: struct _PLAY_AUDIO_MSF { ! 155: UCHAR OperationCode; ! 156: UCHAR Reserved1 : 5; ! 157: UCHAR LogicalUnitNumber : 3; ! 158: UCHAR Reserved2; ! 159: UCHAR StartingM; ! 160: UCHAR StartingS; ! 161: UCHAR StartingF; ! 162: UCHAR EndingM; ! 163: UCHAR EndingS; ! 164: UCHAR EndingF; ! 165: UCHAR Control; ! 166: } PLAY_AUDIO_MSF, *PPLAY_AUDIO_MSF; ! 167: ! 168: // ! 169: // Read SubChannel Data ! 170: // ! 171: ! 172: struct _SUBCHANNEL { ! 173: UCHAR OperationCode; ! 174: UCHAR Reserved0 : 1; ! 175: UCHAR Msf : 1; ! 176: UCHAR Reserved1 : 3; ! 177: UCHAR LogicalUnitNumber : 3; ! 178: UCHAR Reserved2 : 6; ! 179: UCHAR SubQ : 1; ! 180: UCHAR Reserved3 : 1; ! 181: UCHAR Format; ! 182: UCHAR Reserved4[2]; ! 183: UCHAR TrackNumber; ! 184: UCHAR AllocationLength[2]; ! 185: UCHAR Control; ! 186: } SUBCHANNEL, *PSUBCHANNEL; ! 187: ! 188: // ! 189: // Mode sense ! 190: // ! 191: ! 192: struct _MODE_SENSE { ! 193: UCHAR OperationCode; ! 194: UCHAR Reserved1 : 3; ! 195: UCHAR Dbd : 1; ! 196: UCHAR Reserved2 : 1; ! 197: UCHAR LogicalUnitNumber : 3; ! 198: UCHAR PageCode : 6; ! 199: UCHAR Pc : 2; ! 200: UCHAR Reserved3; ! 201: UCHAR AllocationLength; ! 202: UCHAR Control; ! 203: } MODE_SENSE, *PMODE_SENSE; ! 204: ! 205: // ! 206: // Mode select ! 207: // ! 208: ! 209: struct _MODE_SELECT { ! 210: UCHAR OperationCode; ! 211: UCHAR SPBit : 1; ! 212: UCHAR Reserved1 : 3; ! 213: UCHAR PFBit : 1; ! 214: UCHAR LogicalUnitNumber : 3; ! 215: UCHAR Reserved2[2]; ! 216: UCHAR ParameterListLength; ! 217: UCHAR Control; ! 218: } MODE_SELECT, *PMODE_SELECT; ! 219: ! 220: struct _LOCATE { ! 221: UCHAR OperationCode; ! 222: UCHAR Immediate : 1; ! 223: UCHAR CPBit : 1; ! 224: UCHAR BTBit : 1; ! 225: UCHAR Reserved1 : 2; ! 226: UCHAR LogicalUnitNumber : 3; ! 227: UCHAR Reserved3; ! 228: UCHAR LogicalBlockAddress[4]; ! 229: UCHAR Reserved4; ! 230: UCHAR Partition; ! 231: UCHAR Control; ! 232: } LOCATE, *PLOCATE; ! 233: ! 234: struct _LOGSENSE { ! 235: UCHAR OperationCode; ! 236: UCHAR SPBit : 1; ! 237: UCHAR PPCBit : 1; ! 238: UCHAR Reserved1 : 3; ! 239: UCHAR LogicalUnitNumber : 3; ! 240: UCHAR PageCode : 6; ! 241: UCHAR PCBit : 2; ! 242: UCHAR Reserved2; ! 243: UCHAR Reserved3; ! 244: UCHAR ParameterPointer[2]; // [0]=MSB, [1]=LSB ! 245: UCHAR AllocationLength[2]; // [0]=MSB, [1]=LSB ! 246: UCHAR Control; ! 247: } LOGSENSE, *PLOGSENSE; ! 248: ! 249: struct _PRINT { ! 250: UCHAR OperationCode; ! 251: UCHAR Reserved : 5; ! 252: UCHAR LogicalUnitNumber : 3; ! 253: UCHAR TransferLength[3]; ! 254: UCHAR Control; ! 255: } PRINT, *PPRINT; ! 256: ! 257: struct _SEEK { ! 258: UCHAR OperationCode; ! 259: UCHAR Reserved1 : 5; ! 260: UCHAR LogicalUnitNumber : 3; ! 261: UCHAR LogicalBlockAddress[4]; ! 262: UCHAR Reserved2[3]; ! 263: UCHAR Control; ! 264: } SEEK, *PSEEK; ! 265: ! 266: struct _ERASE { ! 267: UCHAR OperationCode; ! 268: UCHAR Long : 1; ! 269: UCHAR Immediate : 1; ! 270: UCHAR Reserved1 : 3; ! 271: UCHAR LogicalUnitNumber : 3; ! 272: UCHAR Reserved2[3]; ! 273: UCHAR Control; ! 274: } ERASE, *PERASE; ! 275: ! 276: struct _START_STOP { ! 277: UCHAR OperationCode; ! 278: UCHAR Immediate: 1; ! 279: UCHAR Reserved1 : 4; ! 280: UCHAR LogicalUnitNumber : 3; ! 281: UCHAR Reserved2[2]; ! 282: UCHAR Start : 1; ! 283: UCHAR LoadEject : 1; ! 284: UCHAR Reserved3 : 6; ! 285: UCHAR Control; ! 286: } START_STOP, *PSTART_STOP; ! 287: ! 288: struct _MEDIA_REMOVAL { ! 289: UCHAR OperationCode; ! 290: UCHAR Reserved1 : 5; ! 291: UCHAR LogicalUnitNumber : 3; ! 292: UCHAR Reserved2[2]; ! 293: UCHAR Prevent; ! 294: UCHAR Control; ! 295: } MEDIA_REMOVAL, *PMEDIA_REMOVAL; ! 296: ! 297: // ! 298: // Tape CDBs ! 299: // ! 300: ! 301: struct _SEEK_BLOCK { ! 302: UCHAR OperationCode; ! 303: UCHAR Immediate : 1; ! 304: UCHAR Reserved1 : 7; ! 305: UCHAR BlockAddress[3]; ! 306: UCHAR Link : 1; ! 307: UCHAR Flag : 1; ! 308: UCHAR Reserved2 : 4; ! 309: UCHAR VendorUnique : 2; ! 310: } SEEK_BLOCK, *PSEEK_BLOCK; ! 311: ! 312: struct _REQUEST_BLOCK_ADDRESS { ! 313: UCHAR OperationCode; ! 314: UCHAR Reserved1[3]; ! 315: UCHAR AllocationLength; ! 316: UCHAR Link : 1; ! 317: UCHAR Flag : 1; ! 318: UCHAR Reserved2 : 4; ! 319: UCHAR VendorUnique : 2; ! 320: } REQUEST_BLOCK_ADDRESS, *PREQUEST_BLOCK_ADDRESS; ! 321: ! 322: struct _PARTITION { ! 323: UCHAR OperationCode; ! 324: UCHAR Immediate : 1; ! 325: UCHAR Sel: 1; ! 326: UCHAR PartitionSelect : 6; ! 327: UCHAR Reserved1[3]; ! 328: UCHAR Control; ! 329: } PARTITION, *PPARTITION; ! 330: ! 331: struct _WRITE_TAPE_MARKS { ! 332: UCHAR OperationCode; ! 333: UCHAR Immediate : 1; ! 334: UCHAR WriteSetMarks: 1; ! 335: UCHAR Reserved : 3; ! 336: UCHAR LogicalUnitNumber : 3; ! 337: UCHAR TransferLength[3]; ! 338: UCHAR Control; ! 339: } WRITE_TAPE_MARKS, *PWRITE_TAPE_MARKS; ! 340: ! 341: struct _SPACE_TAPE_MARKS { ! 342: UCHAR OperationCode; ! 343: UCHAR Code : 3; ! 344: UCHAR Reserved : 2; ! 345: UCHAR LogicalUnitNumber : 3; ! 346: UCHAR NumMarksMSB ; ! 347: UCHAR NumMarks; ! 348: UCHAR NumMarksLSB; ! 349: union { ! 350: UCHAR value; ! 351: struct { ! 352: UCHAR Link : 1; ! 353: UCHAR Flag : 1; ! 354: UCHAR Reserved : 4; ! 355: UCHAR VendorUnique : 2; ! 356: } Fields; ! 357: } Byte6; ! 358: } SPACE_TAPE_MARKS, *PSPACE_TAPE_MARKS; ! 359: ! 360: // ! 361: // Read tape position ! 362: // ! 363: ! 364: struct _READ_POSITION { ! 365: UCHAR Operation; ! 366: UCHAR BlockType:1; ! 367: UCHAR Reserved1:4; ! 368: UCHAR Lun:3; ! 369: UCHAR Reserved2[7]; ! 370: UCHAR Control; ! 371: } READ_POSITION, *PREAD_POSITION; ! 372: ! 373: // ! 374: // ReadWrite for Tape ! 375: // ! 376: ! 377: struct _CDB6READWRITETAPE { ! 378: UCHAR OperationCode; ! 379: UCHAR VendorSpecific : 5; ! 380: UCHAR Reserved : 3; ! 381: UCHAR TransferLenMSB; ! 382: UCHAR TransferLen; ! 383: UCHAR TransferLenLSB; ! 384: UCHAR Link : 1; ! 385: UCHAR Flag : 1; ! 386: UCHAR Reserved1 : 4; ! 387: UCHAR VendorUnique : 2; ! 388: } CDB6READWRITETAPE, *PCDB6READWRITETAPE; ! 389: ! 390: } CDB, *PCDB; ! 391: ! 392: // ! 393: // Command Descriptor Block constants. ! 394: // ! 395: ! 396: #define CDB6GENERIC_LENGTH 6 ! 397: #define CDB10GENERIC_LENGTH 10 ! 398: ! 399: #define SETBITON 1 ! 400: #define SETBITOFF 0 ! 401: // ! 402: // Mode Sense/Select page constants. ! 403: // ! 404: ! 405: #define MODE_PAGE_ERROR_RECOVERY 0x01 ! 406: #define MODE_PAGE_DISCONNECT 0x02 ! 407: #define MODE_PAGE_FORMAT_DEVICE 0x03 ! 408: #define MODE_PAGE_RIGID_GEOMETRY 0x04 ! 409: #define MODE_PAGE_FLEXIBILE 0x05 ! 410: #define MODE_PAGE_VERIFY_ERROR 0x07 ! 411: #define MODE_PAGE_CACHING 0x08 ! 412: #define MODE_PAGE_PERIPHERAL 0x09 ! 413: #define MODE_PAGE_CONTROL 0x0A ! 414: #define MODE_PAGE_MEDIUM_TYPES 0x0B ! 415: #define MODE_PAGE_NOTCH_PARTITION 0x0C ! 416: #define MODE_SENSE_RETURN_ALL 0x3f ! 417: #define MODE_SENSE_CURRENT_VALUES 0x00 ! 418: #define MODE_SENSE_CHANGEABLE_VALUES 0x40 ! 419: #define MODE_SENSE_DEFAULT_VAULES 0x80 ! 420: #define MODE_SENSE_SAVED_VALUES 0xc0 ! 421: #define MODE_PAGE_DEVICE_CONFIG 0x10 ! 422: #define MODE_PAGE_MEDIUM_PARTITION 0x11 ! 423: #define MODE_PAGE_DATA_COMPRESS 0x0f ! 424: ! 425: // ! 426: // SCSI CDB operation codes ! 427: // ! 428: ! 429: #define SCSIOP_TEST_UNIT_READY 0x00 ! 430: #define SCSIOP_REZERO_UNIT 0x01 ! 431: #define SCSIOP_REWIND 0x01 ! 432: #define SCSIOP_REQUEST_BLOCK_ADDR 0x02 ! 433: #define SCSIOP_REQUEST_SENSE 0x03 ! 434: #define SCSIOP_FORMAT_UNIT 0x04 ! 435: #define SCSIOP_READ_BLOCK_LIMITS 0x05 ! 436: #define SCSIOP_REASSIGN_BLOCKS 0x07 ! 437: #define SCSIOP_READ6 0x08 ! 438: #define SCSIOP_RECEIVE 0x08 ! 439: #define SCSIOP_WRITE6 0x0A ! 440: #define SCSIOP_PRINT 0x0A ! 441: #define SCSIOP_SEND 0x0A ! 442: #define SCSIOP_SEEK6 0x0B ! 443: #define SCSIOP_TRACK_SELECT 0x0B ! 444: #define SCSIOP_SLEW_PRINT 0x0B ! 445: #define SCSIOP_SEEK_BLOCK 0x0C ! 446: #define SCSIOP_PARTITION 0x0D ! 447: #define SCSIOP_READ_REVERSE 0x0F ! 448: #define SCSIOP_WRITE_FILEMARKS 0x10 ! 449: #define SCSIOP_FLUSH_BUFFER 0x10 ! 450: #define SCSIOP_SPACE 0x11 ! 451: #define SCSIOP_INQUIRY 0x12 ! 452: #define SCSIOP_VERIFY6 0x13 ! 453: #define SCSIOP_RECOVER_BUF_DATA 0x14 ! 454: #define SCSIOP_MODE_SELECT 0x15 ! 455: #define SCSIOP_RESERVE_UNIT 0x16 ! 456: #define SCSIOP_RELEASE_UNIT 0x17 ! 457: #define SCSIOP_COPY 0x18 ! 458: #define SCSIOP_ERASE 0x19 ! 459: #define SCSIOP_MODE_SENSE 0x1A ! 460: #define SCSIOP_START_STOP_UNIT 0x1B ! 461: #define SCSIOP_STOP_PRINT 0x1B ! 462: #define SCSIOP_LOAD_UNLOAD 0x1B ! 463: #define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C ! 464: #define SCSIOP_SEND_DIAGNOSTIC 0x1D ! 465: #define SCSIOP_MEDIUM_REMOVAL 0x1E ! 466: #define SCSIOP_READ_CAPACITY 0x25 ! 467: #define SCSIOP_READ 0x28 ! 468: #define SCSIOP_WRITE 0x2A ! 469: #define SCSIOP_SEEK 0x2B ! 470: #define SCSIOP_LOCATE 0x2B ! 471: #define SCSIOP_WRITE_VERIFY 0x2E ! 472: #define SCSIOP_VERIFY 0x2F ! 473: #define SCSIOP_SEARCH_DATA_HIGH 0x30 ! 474: #define SCSIOP_SEARCH_DATA_EQUAL 0x31 ! 475: #define SCSIOP_SEARCH_DATA_LOW 0x32 ! 476: #define SCSIOP_SET_LIMITS 0x33 ! 477: #define SCSIOP_READ_POSITION 0x34 ! 478: #define SCSIOP_SYNCHRONIZE_CACHE 0x35 ! 479: #define SCSIOP_COMPARE 0x39 ! 480: #define SCSIOP_COPY_COMPARE 0x3A ! 481: #define SCSIOP_WRITE_DATA_BUFF 0x3B ! 482: #define SCSIOP_READ_DATA_BUFF 0x3C ! 483: #define SCSIOP_CHANGE_DEFINITION 0x40 ! 484: #define SCSIOP_READ_SUB_CHANNEL 0x42 ! 485: #define SCSIOP_READ_TOC 0x43 ! 486: #define SCSIOP_READ_HEADER 0x44 ! 487: #define SCSIOP_PLAY_AUDIO 0x45 ! 488: #define SCSIOP_PLAY_AUDIO_MSF 0x47 ! 489: #define SCSIOP_PLAY_TRACK_INDEX 0x48 ! 490: #define SCSIOP_PLAY_TRACK_RELATIVE 0x49 ! 491: #define SCSIOP_PAUSE_RESUME 0x4B ! 492: #define SCSIOP_LOG_SELECT 0x4C ! 493: #define SCSIOP_LOG_SENSE 0x4D ! 494: ! 495: // ! 496: // If the IMMED bit is 1, status is returned as soon ! 497: // as the operation is initiated. If the IMMED bit ! 498: // is 0, status is not returned until the operation ! 499: // is completed. ! 500: // ! 501: ! 502: #define CDB_RETURN_ON_COMPLETION 0 ! 503: #define CDB_RETURN_IMMEDIATE 1 ! 504: ! 505: // ! 506: // CDB Force media access used in extended read and write commands. ! 507: // ! 508: ! 509: #define CDB_FORCE_MEDIA_ACCESS 0x08 ! 510: ! 511: // ! 512: // Denon CD ROM operation codes ! 513: // ! 514: ! 515: #define SCSIOP_DENON_EJECT_DISC 0xE6 ! 516: #define SCSIOP_DENON_STOP_AUDIO 0xE7 ! 517: #define SCSIOP_DENON_PLAY_AUDIO 0xE8 ! 518: #define SCSIOP_DENON_READ_TOC 0xE9 ! 519: #define SCSIOP_DENON_READ_SUBCODE 0xEB ! 520: ! 521: // ! 522: // SCSI Bus Messages ! 523: // ! 524: ! 525: #define SCSIMESS_ABORT 0x06 ! 526: #define SCSIMESS_ABORT_WITH_TAG 0x0D ! 527: #define SCSIMESS_BUS_DEVICE_RESET 0X0C ! 528: #define SCSIMESS_CLEAR_QUEUE 0X0E ! 529: #define SCSIMESS_COMMAND_COMPLETE 0X00 ! 530: #define SCSIMESS_DISCONNECT 0X04 ! 531: #define SCSIMESS_EXTENDED_MESSAGE 0X01 ! 532: #define SCSIMESS_IDENTIFY 0X80 ! 533: #define SCSIMESS_IDENTIFY_WITH_DISCON 0XC0 ! 534: #define SCSIMESS_IGNORE_WIDE_RESIDUE 0X23 ! 535: #define SCSIMESS_INITIATE_RECOVERY 0X0F ! 536: #define SCSIMESS_INIT_DETECTED_ERROR 0X05 ! 537: #define SCSIMESS_LINK_CMD_COMP 0X0A ! 538: #define SCSIMESS_LINK_CMD_COMP_W_FLAG 0X0B ! 539: #define SCSIMESS_MESS_PARITY_ERROR 0X09 ! 540: #define SCSIMESS_MESSAGE_REJECT 0X07 ! 541: #define SCSIMESS_NO_OPERATION 0X08 ! 542: #define SCSIMESS_HEAD_OF_QUEUE_TAG 0X21 ! 543: #define SCSIMESS_ORDERED_QUEUE_TAG 0X22 ! 544: #define SCSIMESS_SIMPLE_QUEUE_TAG 0X20 ! 545: #define SCSIMESS_RELEASE_RECOVERY 0X10 ! 546: #define SCSIMESS_RESTORE_POINTERS 0X03 ! 547: #define SCSIMESS_SAVE_DATA_POINTER 0X02 ! 548: #define SCSIMESS_TERMINATE_IO_PROCESS 0X11 ! 549: ! 550: // ! 551: // SCSI Extended Message operation codes ! 552: // ! 553: ! 554: #define SCSIMESS_MODIFY_DATA_POINTER 0X00 ! 555: #define SCSIMESS_SYNCHRONOUS_DATA_REQ 0X01 ! 556: #define SCSIMESS_WIDE_DATA_REQUEST 0X03 ! 557: ! 558: // ! 559: // SCSI Extended Message Lengths ! 560: // ! 561: ! 562: #define SCSIMESS_MODIFY_DATA_LENGTH 5 ! 563: #define SCSIMESS_SYNCH_DATA_LENGTH 3 ! 564: #define SCSIMESS_WIDE_DATA_LENGTH 2 ! 565: ! 566: // ! 567: // SCSI extended message structure ! 568: // ! 569: ! 570: #pragma pack (1) ! 571: typedef struct _SCSI_EXTENDED_MESSAGE { ! 572: UCHAR InitialMessageCode; ! 573: UCHAR MessageLength; ! 574: UCHAR MessageType; ! 575: union _EXTENDED_ARGUMENTS { ! 576: ! 577: struct { ! 578: UCHAR Modifier[4]; ! 579: } Modify; ! 580: ! 581: struct { ! 582: UCHAR TransferPeriod; ! 583: UCHAR ReqAckOffset; ! 584: } Synchronous; ! 585: ! 586: struct{ ! 587: UCHAR Width; ! 588: } Wide; ! 589: }ExtendedArguments; ! 590: }SCSI_EXTENDED_MESSAGE, *PSCSI_EXTENDED_MESSAGE; ! 591: #pragma pack () ! 592: ! 593: // ! 594: // SCSI bus status codes. ! 595: // ! 596: ! 597: #define SCSISTAT_GOOD 0x00 ! 598: #define SCSISTAT_CHECK_CONDITION 0x02 ! 599: #define SCSISTAT_CONDITION_MET 0x04 ! 600: #define SCSISTAT_BUSY 0x08 ! 601: #define SCSISTAT_INTERMEDIATE 0x10 ! 602: #define SCSISTAT_INTERMEDIATE_COND_MET 0x14 ! 603: #define SCSISTAT_RESERVATION_CONFLICT 0x18 ! 604: #define SCSISTAT_COMMAND_TERMINATED 0x22 ! 605: #define SCSISTAT_QUEUE_FULL 0x28 ! 606: ! 607: // ! 608: // Enable Vital Product Data Flag (EVPD) ! 609: // used with INQUIRY command. ! 610: // ! 611: ! 612: #define CDB_INQUIRY_EVPD 0x01 ! 613: ! 614: // ! 615: // Defines for format CDB ! 616: // ! 617: ! 618: #define LUN0_FORMAT_SAVING_DEFECT_LIST 0 ! 619: #define USE_DEFAULTMSB 0 ! 620: #define USE_DEFAULTLSB 0 ! 621: ! 622: #define START_UNIT_CODE 0x01 ! 623: #define STOP_UNIT_CODE 0x00 ! 624: ! 625: // ! 626: // Inquiry buffer structure. This is the data returned from the target ! 627: // after it receives an inquiry. ! 628: // ! 629: // This structure may be extended by the number of bytes specified ! 630: // in the field AdditionalLength. The defined size constant only ! 631: // includes fields through ProductRevisionLevel. ! 632: // ! 633: // The NT SCSI drivers are only interested in the first 36 bytes of data. ! 634: // ! 635: ! 636: #define INQUIRYDATABUFFERSIZE 36 ! 637: ! 638: typedef struct _INQUIRYDATA { ! 639: UCHAR DeviceType : 5; ! 640: UCHAR DeviceTypeQualifier : 3; ! 641: UCHAR DeviceTypeModifier : 7; ! 642: UCHAR RemovableMedia : 1; ! 643: UCHAR Versions; ! 644: UCHAR ResponseDataFormat; ! 645: UCHAR AdditionalLength; ! 646: UCHAR Reserved[2]; ! 647: UCHAR SoftReset : 1; ! 648: UCHAR CommandQueue : 1; ! 649: UCHAR Reserved2 : 1; ! 650: UCHAR LinkedCommands : 1; ! 651: UCHAR Synchronous : 1; ! 652: UCHAR Wide16Bit : 1; ! 653: UCHAR Wide32Bit : 1; ! 654: UCHAR RelativeAddressing : 1; ! 655: UCHAR VendorId[8]; ! 656: UCHAR ProductId[16]; ! 657: UCHAR ProductRevisionLevel[4]; ! 658: UCHAR VendorSpecific[20]; ! 659: UCHAR Reserved3[40]; ! 660: } INQUIRYDATA, *PINQUIRYDATA; ! 661: ! 662: // ! 663: // Inquiry defines. Used to interpret data returned from target as result ! 664: // of inquiry command. ! 665: // ! 666: // DeviceType field ! 667: // ! 668: ! 669: #define DIRECT_ACCESS_DEVICE 0x00 // disks ! 670: #define SEQUENTIAL_ACCESS_DEVICE 0x01 // tapes ! 671: #define PRINTER_DEVICE 0x02 // printers ! 672: #define PROCESSOR_DEVICE 0x03 // scanners, printers, etc ! 673: #define WRITE_ONCE_READ_MULTIPLE_DEVICE 0x04 // worms ! 674: #define READ_ONLY_DIRECT_ACCESS_DEVICE 0x05 // cdroms ! 675: #define SCANNER_DEVICE 0x06 // scanners ! 676: #define OPTICAL_DEVICE 0x07 // optical disks ! 677: #define MEDIUM_CHANGER 0x08 // jukebox ! 678: #define COMMUNICATION_DEVICE 0x09 // network ! 679: #define LOGICAL_UNIT_NOT_PRESENT_DEVICE 0x7F ! 680: #define DEVICE_QUALIFIER_NOT_SUPPORTED 0x03 ! 681: ! 682: // ! 683: // DeviceTypeQualifier field ! 684: // ! 685: ! 686: #define DEVICE_CONNECTED 0x00 ! 687: ! 688: // ! 689: // Sense Data Format ! 690: // ! 691: ! 692: typedef struct _SENSE_DATA { ! 693: UCHAR ErrorCode:7; ! 694: UCHAR Valid:1; ! 695: UCHAR SegmentNumber; ! 696: UCHAR SenseKey:4; ! 697: UCHAR Reserved:1; ! 698: UCHAR IncorrectLength:1; ! 699: UCHAR EndOfMedia:1; ! 700: UCHAR FileMark:1; ! 701: UCHAR Information[4]; ! 702: UCHAR AdditionalSenseLength; ! 703: UCHAR CommandSpecificInformation[4]; ! 704: UCHAR AdditionalSenseCode; ! 705: UCHAR AdditionalSenseCodeQualifier; ! 706: UCHAR FieldReplaceableUnitCode; ! 707: UCHAR SenseKeySpecific[3]; ! 708: } SENSE_DATA, *PSENSE_DATA; ! 709: ! 710: // ! 711: // Default request sense buffer size ! 712: // ! 713: ! 714: #define SENSE_BUFFER_SIZE 18 ! 715: ! 716: // ! 717: // Sense codes ! 718: // ! 719: ! 720: #define SCSI_SENSE_NO_SENSE 0x00 ! 721: #define SCSI_SENSE_RECOVERED_ERROR 0x01 ! 722: #define SCSI_SENSE_NOT_READY 0x02 ! 723: #define SCSI_SENSE_MEDIUM_ERROR 0x03 ! 724: #define SCSI_SENSE_HARDWARE_ERROR 0x04 ! 725: #define SCSI_SENSE_ILLEGAL_REQUEST 0x05 ! 726: #define SCSI_SENSE_UNIT_ATTENTION 0x06 ! 727: #define SCSI_SENSE_DATA_PROTECT 0x07 ! 728: #define SCSI_SENSE_BLANK_CHECK 0x08 ! 729: #define SCSI_SENSE_UNIQUE 0x09 ! 730: #define SCSI_SENSE_COPY_ABORTED 0x0A ! 731: #define SCSI_SENSE_ABORTED_COMMAND 0x0B ! 732: #define SCSI_SENSE_EQUAL 0x0C ! 733: #define SCSI_SENSE_VOL_OVERFLOW 0x0D ! 734: #define SCSI_SENSE_MISCOMPARE 0x0E ! 735: #define SCSI_SENSE_RESERVED 0x0F ! 736: ! 737: // ! 738: // Additional tape bit ! 739: // ! 740: ! 741: #define SCSI_ILLEGAL_LENGTH 0x20 ! 742: #define SCSI_EOM 0x40 ! 743: #define SCSI_FILE_MARK 0x80 ! 744: ! 745: // ! 746: // Additional Sense codes ! 747: // ! 748: ! 749: #define SCSI_ADSENSE_NO_SENSE 0x00 ! 750: #define SCSI_ADSENSE_LUN_NOT_READY 0x04 ! 751: #define SCSI_ADSENSE_ILLEGAL_COMMAND 0x20 ! 752: #define SCSI_ADSENSE_ILLEGAL_BLOCK 0x21 ! 753: #define SCSI_ADSENSE_INVALID_LUN 0x25 ! 754: #define SCSI_ADSENSE_MUSIC_AREA 0xA0 ! 755: #define SCSI_ADSENSE_DATA_AREA 0xA1 ! 756: #define SCSI_ADSENSE_VOLUME_OVERFLOW 0xA7 ! 757: ! 758: #define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE 0x3a ! 759: #define SCSI_ADWRITE_PROTECT 0x27 ! 760: #define SCSI_ADSENSE_MEDIUM_CHANGED 0x28 ! 761: #define SCSI_ADSENSE_BUS_RESET 0x29 ! 762: #define SCSI_ADSENSE_TRACK_ERROR 0x14 ! 763: #define SCSI_ADSENSE_SEEK_ERROR 0x15 ! 764: #define SCSI_ADSENSE_REC_DATA_NOECC 0x17 ! 765: #define SCSI_ADSENSE_REC_DATA_ECC 0x18 ! 766: ! 767: // ! 768: // Additional sense code qualifier ! 769: // ! 770: ! 771: #define SCSI_SENSEQ_FORMAT_IN_PROGRESS 0x04 ! 772: #define SCSI_SENSEQ_INIT_COMMAND_REQUIRED 0x02 ! 773: #define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED 0x03 ! 774: #define SCSI_SENSEQ_BECOMING_READY 0x01 ! 775: #define SCSI_SENSEQ_FILEMARK_DETECTED 0x01 ! 776: #define SCSI_SENSEQ_SETMARK_DETECTED 0x03 ! 777: #define SCSI_SENSEQ_END_OF_MEDIA_DETECTED 0x02 ! 778: #define SCSI_SENSEQ_BEGINNING_OF_MEDIA_DETECTED 0x04 ! 779: ! 780: // ! 781: // SCSI IO Device Control Codes ! 782: // ! 783: ! 784: #define FILE_DEVICE_SCSI 0x0000001b ! 785: ! 786: #define IOCTL_SCSI_EXECUTE_IN ((FILE_DEVICE_SCSI << 16) + 0x0011) ! 787: #define IOCTL_SCSI_EXECUTE_OUT ((FILE_DEVICE_SCSI << 16) + 0x0012) ! 788: #define IOCTL_SCSI_EXECUTE_NONE ((FILE_DEVICE_SCSI << 16) + 0x0013) ! 789: ! 790: // ! 791: // Read Capacity Data - returned in Big Endian format ! 792: // ! 793: ! 794: typedef struct _READ_CAPACITY_DATA { ! 795: ULONG LogicalBlockAddress; ! 796: ULONG BytesPerBlock; ! 797: } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA; ! 798: ! 799: ! 800: // ! 801: // Read Block Limits Data - returned in Big Endian format ! 802: // This structure returns the maximum and minimum block ! 803: // size for a TAPE device. ! 804: // ! 805: ! 806: typedef struct _READ_BLOCK_LIMITS { ! 807: UCHAR Reserved; ! 808: UCHAR BlockMaximumSize[3]; ! 809: UCHAR BlockMinimumSize[2]; ! 810: } READ_BLOCK_LIMITS_DATA, *PREAD_BLOCK_LIMITS_DATA; ! 811: ! 812: // ! 813: // Mode data structures. ! 814: // ! 815: ! 816: // ! 817: // Define Mode parameter header. ! 818: // ! 819: ! 820: typedef struct _MODE_PARAMETER_HEADER { ! 821: UCHAR ModeDataLength; ! 822: UCHAR MediumType; ! 823: UCHAR DeviceSpecificParameter; ! 824: UCHAR BlockDescriptorLength; ! 825: }MODE_PARAMETER_HEADER, *PMODE_PARAMETER_HEADER; ! 826: ! 827: #define MODE_FD_SINGLE_SIDE 0x01 ! 828: #define MODE_FD_DOUBLE_SIDE 0x02 ! 829: #define MODE_FD_MAXIMUM_TYPE 0x1E ! 830: #define MODE_DSP_FUA_SUPPORTED 0x10 ! 831: #define MODE_DSP_WRITE_PROTECT 0x80 ! 832: ! 833: // ! 834: // Define the mode parameter block. ! 835: // ! 836: ! 837: typedef struct _MODE_PARAMETER_BLOCK { ! 838: UCHAR DensityCode; ! 839: UCHAR NumberOfBlocks[3]; ! 840: UCHAR Reserved; ! 841: UCHAR BlockLength[3]; ! 842: }MODE_PARAMETER_BLOCK, *PMODE_PARAMETER_BLOCK; ! 843: ! 844: // ! 845: // Define Disconnect-Reconnect page. ! 846: // ! 847: ! 848: typedef struct _MODE_DISCONNECT_PAGE { ! 849: UCHAR PageCode : 6; ! 850: UCHAR Reserved : 1; ! 851: UCHAR PageSavable : 1; ! 852: UCHAR PageLength; ! 853: UCHAR BufferFullRatio; ! 854: UCHAR BufferEmptyRatio; ! 855: UCHAR BusInactivityLimit[2]; ! 856: UCHAR BusDisconnectTime[2]; ! 857: UCHAR BusConnectTime[2]; ! 858: UCHAR MaximumBurstSize[2]; ! 859: UCHAR DataTransferDisconnect : 2; ! 860: UCHAR Reserved2[3]; ! 861: }MODE_DISCONNECT_PAGE, *PMODE_DISCONNECT_PAGE; ! 862: ! 863: // ! 864: // Define mode caching page. ! 865: // ! 866: ! 867: typedef struct _MODE_CACHING_PAGE { ! 868: UCHAR PageCode : 6; ! 869: UCHAR Reserved : 1; ! 870: UCHAR PageSavable : 1; ! 871: UCHAR PageLength; ! 872: UCHAR ReadDisableCache : 1; ! 873: UCHAR MultiplicationFactor : 1; ! 874: UCHAR WriteCacheEnable : 1; ! 875: UCHAR Reserved2 : 5; ! 876: UCHAR WriteRetensionPriority : 4; ! 877: UCHAR ReadRetensionPriority : 4; ! 878: UCHAR DisablePrefetchTransfer[2]; ! 879: UCHAR MinimumPrefectch[2]; ! 880: UCHAR MaximumPrefectch[2]; ! 881: UCHAR MaximumPrefectchCeil[2]; ! 882: }MODE_CACHING_PAGE, *PMODE_CACHING_PAGE; ! 883: ! 884: // ! 885: // Define mode flexible disk page. ! 886: // ! 887: ! 888: typedef struct _MODE_FLEXIBLE_DISK_PAGE { ! 889: UCHAR PageCode : 6; ! 890: UCHAR Reserved : 1; ! 891: UCHAR PageSavable : 1; ! 892: UCHAR PageLength; ! 893: UCHAR TransferRate[2]; ! 894: UCHAR NumberOfHeads; ! 895: UCHAR SectorsPerTrack; ! 896: UCHAR BytesPerSector[2]; ! 897: UCHAR NumberOfCylinders[2]; ! 898: UCHAR StartWritePrecom[2]; ! 899: UCHAR StartReducedCurrent[2]; ! 900: UCHAR StepRate[2]; ! 901: UCHAR StepPluseWidth; ! 902: UCHAR HeadSettleDelay[2]; ! 903: UCHAR MotorOnDelay; ! 904: UCHAR MotorOffDelay; ! 905: UCHAR Reserved2 : 5; ! 906: UCHAR MotorOnAsserted : 1; ! 907: UCHAR StartSectorNumber : 1; ! 908: UCHAR TrueReadySignal : 1; ! 909: UCHAR StepPlusePerCyclynder : 4; ! 910: UCHAR Reserved3 : 4; ! 911: UCHAR WriteCompenstation; ! 912: UCHAR HeadLoadDelay; ! 913: UCHAR HeadUnloadDelay; ! 914: UCHAR Pin2Usage : 4; ! 915: UCHAR Pin34Usage : 4; ! 916: UCHAR Pin1Usage : 4; ! 917: UCHAR Pin4Usage : 4; ! 918: UCHAR MediumRotationRate[2]; ! 919: UCHAR Reserved4[2]; ! 920: }MODE_FLEXIBLE_DISK_PAGE, *PMODE_FLEXIBLE_DISK_PAGE; ! 921: ! 922: // ! 923: // Define mode format page. ! 924: // ! 925: ! 926: typedef struct _MODE_FORMAT_PAGE { ! 927: UCHAR PageCode : 6; ! 928: UCHAR Reserved : 1; ! 929: UCHAR PageSavable : 1; ! 930: UCHAR PageLength; ! 931: UCHAR TracksPerZone[2]; ! 932: UCHAR AlternetSectorsPerZone[2]; ! 933: UCHAR AlternetTracksPerZone[2]; ! 934: UCHAR SectorsPerTrack[2]; ! 935: UCHAR BytesPerPhysicalSector[2]; ! 936: UCHAR Interleave[2]; ! 937: UCHAR TrackSkewFactor[2]; ! 938: UCHAR CylinderSkewFactor[2]; ! 939: UCHAR Reserved2 : 4; ! 940: UCHAR SurfaceFirst : 1; ! 941: UCHAR RemovableMedia : 1; ! 942: UCHAR HardSectorFormating : 1; ! 943: UCHAR SoftSectorFormating : 1; ! 944: UCHAR Reserved3[2]; ! 945: }MODE_FORMAT_PAGE, *PMODE_FORMAT_PAGE; ! 946: ! 947: // ! 948: // Define rigid disk driver geometry page. ! 949: // ! 950: ! 951: typedef struct _MODE_RIGID_GEOMETRY_PAGE { ! 952: UCHAR PageCode : 6; ! 953: UCHAR Reserved : 1; ! 954: UCHAR PageSavable : 1; ! 955: UCHAR PageLength; ! 956: UCHAR NumberOfCylinders[2]; ! 957: UCHAR NumberOfHeads; ! 958: UCHAR StartWritePrecom[2]; ! 959: UCHAR StartReducedCurrent[2]; ! 960: UCHAR DriveStepRate[2]; ! 961: UCHAR LandZoneCyclinder[2]; ! 962: UCHAR RotationalPositionLock : 2; ! 963: UCHAR Reserved2 : 6; ! 964: UCHAR RotationOffset; ! 965: UCHAR Reserved3; ! 966: UCHAR RoataionRate[2]; ! 967: UCHAR Reserved4[2]; ! 968: }MODE_RIGID_GEOMETRY_PAGE, *PMODE_RIGID_GEOMETRY_PAGE; ! 969: ! 970: // ! 971: // Define read write recovery page ! 972: // ! 973: ! 974: typedef struct _MODE_READ_WRITE_RECOVERY_PAGE { ! 975: ! 976: UCHAR PageCode : 6; ! 977: UCHAR Reserved1 : 1; ! 978: UCHAR PSBit : 1; ! 979: UCHAR PageLength; ! 980: UCHAR DCRBit : 1; ! 981: UCHAR DTEBit : 1; ! 982: UCHAR PERBit : 1; ! 983: UCHAR EERBit : 1; ! 984: UCHAR Reserved2 : 1; ! 985: UCHAR TBBit : 1; ! 986: UCHAR Reserved3 : 2; ! 987: UCHAR ReadRetryCount; ! 988: UCHAR Reserved4[4]; ! 989: UCHAR WriteRetryCount; ! 990: UCHAR Reserved5[3]; ! 991: ! 992: } MODE_READ_WRITE_RECOVERY_PAGE, *PMODE_READ_WRITE_RECOVERY_PAGE; ! 993: ! 994: // ! 995: // Mode parameter list block descriptor - ! 996: // set the block length for reading/writing ! 997: // ! 998: // ! 999: ! 1000: #define MODE_BLOCK_DESC_LENGTH 8 ! 1001: ! 1002: typedef struct _MODE_PARM_READ_WRITE { ! 1003: ! 1004: MODE_PARAMETER_HEADER ParameterListHeader; // List Header Format ! 1005: MODE_PARAMETER_BLOCK ParameterListBlock; // List Block Descriptor ! 1006: ! 1007: } MODE_PARM_READ_WRITE_DATA, *PMODE_PARM_READ_WRITE_DATA; ! 1008: ! 1009: // ! 1010: // CDROM audio control (0x0E) ! 1011: // ! 1012: ! 1013: #define CDB_AUDIO_PAUSE 0 ! 1014: #define CDB_AUDIO_RESUME 1 ! 1015: ! 1016: #define CDB_DEVICE_START 0x11 ! 1017: #define CDB_DEVICE_STOP 0x10 ! 1018: ! 1019: #define CDB_EJECT_MEDIA 0x10 ! 1020: #define CDB_LOAD_MEDIA 0x01 ! 1021: ! 1022: #define CDB_SUBCHANNEL_HEADER 0x00 ! 1023: #define CDB_SUBCHANNEL_BLOCK 0x01 ! 1024: ! 1025: #define CDROM_AUDIO_CONTROL_PAGE 0x0E ! 1026: #define MODE_SELECT_IMMEDIATE 0x04 ! 1027: #define MODE_SELECT_PFBIT 0x10 ! 1028: ! 1029: #define CDB_USE_MSF 0x01 ! 1030: ! 1031: typedef struct _PORT_OUTPUT { ! 1032: UCHAR ChannelSelection; ! 1033: UCHAR Volume; ! 1034: } PORT_OUTPUT, *PPORT_OUTPUT; ! 1035: ! 1036: typedef struct _AUDIO_OUTPUT { ! 1037: UCHAR CodePage; ! 1038: UCHAR ParameterLength; ! 1039: UCHAR Immediate; ! 1040: UCHAR Reserved[2]; ! 1041: UCHAR LbaFormat; ! 1042: UCHAR LogicalBlocksPerSecond[2]; ! 1043: PORT_OUTPUT PortOutput[4]; ! 1044: } AUDIO_OUTPUT, *PAUDIO_OUTPUT; ! 1045: ! 1046: // ! 1047: // Multisession CDROM ! 1048: // ! 1049: ! 1050: #define GET_LAST_SESSION 0x01 ! 1051: #define GET_SESSION_DATA 0x02; ! 1052: ! 1053: // ! 1054: // Tape definitions ! 1055: // ! 1056: ! 1057: typedef struct _TAPE_POSITION_DATA { ! 1058: UCHAR Reserved1:2; ! 1059: UCHAR BlockPositionUnsupported:1; ! 1060: UCHAR Reserved2:3; ! 1061: UCHAR EndOfPartition:1; ! 1062: UCHAR BeginningOfPartition:1; ! 1063: UCHAR PartitionNumber; ! 1064: USHORT Reserved3; ! 1065: UCHAR FirstBlock[4]; ! 1066: UCHAR LastBlock[4]; ! 1067: UCHAR Reserved4; ! 1068: UCHAR NumberOfBlocks[3]; ! 1069: UCHAR NumberOfBytes[4]; ! 1070: } TAPE_POSITION_DATA, *PTAPE_POSITION_DATA; ! 1071: ! 1072: // ! 1073: // Byte reversing macro for converting ! 1074: // between big- and little-endian formats ! 1075: // ! 1076: ! 1077: #define REVERSE_BYTES(Destination, Source) { \ ! 1078: (Destination)->Byte3 = (Source)->Byte0; \ ! 1079: (Destination)->Byte2 = (Source)->Byte1; \ ! 1080: (Destination)->Byte1 = (Source)->Byte2; \ ! 1081: (Destination)->Byte0 = (Source)->Byte3; \ ! 1082: } ! 1083: ! 1084: // ! 1085: // This structure is used to convert little endian ! 1086: // ULONGs to SCSI CDB 4 byte big endians values. ! 1087: // ! 1088: ! 1089: typedef struct _FOUR_BYTE { ! 1090: UCHAR Byte0; ! 1091: UCHAR Byte1; ! 1092: UCHAR Byte2; ! 1093: UCHAR Byte3; ! 1094: } FOUR_BYTE, *PFOUR_BYTE; ! 1095: ! 1096: // ! 1097: // This macro has the effect of Bit = log2(Data) ! 1098: // ! 1099: ! 1100: #define WHICH_BIT(Data, Bit) { \ ! 1101: for (Bit = 0; Bit < 32; Bit++) { \ ! 1102: if ((Data >> Bit) == 1) { \ ! 1103: break; \ ! 1104: } \ ! 1105: } \ ! 1106: } ! 1107: ! 1108: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.