|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990, 1991 Microsoft Corporation ! 4: ! 5: Module Name : ! 6: ! 7: par.h ! 8: ! 9: Abstract: ! 10: ! 11: Type definitions and data for the parallel port driver ! 12: ! 13: Author: ! 14: ! 15: ! 16: Revision History: ! 17: --*/ ! 18: ! 19: ! 20: #if DBG ! 21: #define PARCONFIG ((ULONG)0x00000001) ! 22: #define PARUNLOAD ((ULONG)0x00000002) ! 23: #define PARINITDEV ((ULONG)0x00000004) ! 24: #define PARIRPPATH ((ULONG)0x00000008) ! 25: #define PARSTARTER ((ULONG)0x00000010) ! 26: #define PARPUSHER ((ULONG)0x00000020) ! 27: #define PARERRORS ((ULONG)0x00000040) ! 28: #define PARTHREAD ((ULONG)0x00000080) ! 29: ! 30: extern ULONG ParDebugLevel; ! 31: #define ParDump(LEVEL,STRING) \ ! 32: do { \ ! 33: ULONG _level = (LEVEL); \ ! 34: if (ParDebugLevel & _level) { \ ! 35: DbgPrint STRING; \ ! 36: } \ ! 37: } while (0) ! 38: #else ! 39: #define ParDump(LEVEL,STRING) do {NOTHING;} while (0) ! 40: #endif ! 41: ! 42: // ! 43: // This define gives the default Object directory ! 44: // that we should use to insert the symbolic links ! 45: // between the NT device name and namespace used by ! 46: // that object directory. ! 47: #define DEFAULT_DIRECTORY L"DosDevices" ! 48: ! 49: // ! 50: // For the above directory, the serial port will ! 51: // use the following name as the suffix of the serial ! 52: // ports for that directory. It will also append ! 53: // a number onto the end of the name. That number ! 54: // will start at 1. ! 55: #define DEFAULT_PARALLEL_NAME L"LPT" ! 56: // ! 57: // ! 58: // This define gives the default NT name for ! 59: // for serial ports detected by the firmware. ! 60: // This name will be appended to Device prefix ! 61: // with a number following it. The number is ! 62: // incremented each time encounter a serial ! 63: // port detected by the firmware. Note that ! 64: // on a system with multiple busses, this means ! 65: // that the first port on a bus is not necessarily ! 66: // \Device\Parallel0. ! 67: // ! 68: #define DEFAULT_NT_SUFFIX L"Parallel" ! 69: ! 70: ! 71: // ! 72: // Defines the number of interrupts it takes for us to decide that ! 73: // we have an interrupt storm on machine ! 74: // ! 75: #define PARALLEL_STORM_WATCH 500 ! 76: ! 77: #define PARALLEL_DATA_OFFSET 0 ! 78: #define PARALLEL_STATUS_OFFSET 1 ! 79: #define PARALLEL_CONTROL_OFFSET 2 ! 80: #define PARALLEL_REGISTER_SPAN 3 ! 81: ! 82: typedef struct _CONFIG_DATA { ! 83: // ! 84: // This list entry is used to link all of the "valid" ! 85: // configuration entries together. ! 86: // ! 87: LIST_ENTRY ConfigList; ! 88: ! 89: // ! 90: // The nt object directory into which to place the symbolic ! 91: // link to this port. ! 92: // ! 93: UNICODE_STRING ObjectDirectory; ! 94: ! 95: // ! 96: // The suffix to be used in the nt device name space for this ! 97: // port. ! 98: // ! 99: UNICODE_STRING NtNameForPort; ! 100: ! 101: // ! 102: // The name to be symbolic linked to the nt name. ! 103: // ! 104: UNICODE_STRING SymbolicLinkName; ! 105: ! 106: // ! 107: // The base address of the registry set for this device. ! 108: // ! 109: PHYSICAL_ADDRESS Controller; ! 110: ! 111: // ! 112: // The number of contiguous bytes take up by the register ! 113: // set for the device. ! 114: // ! 115: ULONG SpanOfController; ! 116: ! 117: // ! 118: // The bus number (with respect to the bus type) of the bus ! 119: // that this device occupies. ! 120: // ! 121: ULONG BusNumber; ! 122: ! 123: // ! 124: // Denotes whether this devices physical addresses live in io space ! 125: // or memory space. ! 126: // ! 127: ULONG AddressSpace; ! 128: ! 129: // ! 130: // Denotes whether this device is latched or level sensitive. ! 131: // ! 132: KINTERRUPT_MODE InterruptMode; ! 133: ! 134: // ! 135: // The kind of bus that this device lives on (e.g. Isa, Eisa, MCA, etc) ! 136: // ! 137: INTERFACE_TYPE InterfaceType; ! 138: ! 139: // ! 140: // The originalirql is what is optained from the firmware data. The level ! 141: // is also obtained from the firmware data. When we get a configuration ! 142: // record based on the services portion of the registry we will always set ! 143: // the vector equal to the irql unless overridden by user input. ! 144: // ! 145: ULONG OriginalVector; ! 146: ULONG OriginalIrql; ! 147: ! 148: // ! 149: // Denotes whether the device should be disabled after it has been ! 150: // initialized. ! 151: // ! 152: ULONG DisablePort; ! 153: ! 154: } CONFIG_DATA,*PCONFIG_DATA; ! 155: ! 156: typedef struct _PAR_DEVICE_EXTENSION { ! 157: ! 158: // ! 159: // Queue of irps waiting to be processes. ! 160: // ! 161: LIST_ENTRY WorkQueue; ! 162: ! 163: // ! 164: // For reporting resource usage, we keep around the physical ! 165: // address we got from the registry. ! 166: // ! 167: PHYSICAL_ADDRESS OriginalController; ! 168: ! 169: // ! 170: // Pointer to the current irp that the thread is working on. ! 171: // ! 172: PIRP CurrentOpIrp; ! 173: ! 174: // ! 175: // We keep a pointer around to our device name for dumps ! 176: // and for creating "external" symbolic links to this ! 177: // device. ! 178: // ! 179: UNICODE_STRING DeviceName; ! 180: ! 181: // ! 182: // This points to the object directory that we will place ! 183: // a symbolic link to our device name. ! 184: // ! 185: UNICODE_STRING ObjectDirectory; ! 186: ! 187: // ! 188: // This points to the device name for this device ! 189: // sans device prefix. ! 190: // ! 191: UNICODE_STRING NtNameForPort; ! 192: ! 193: // ! 194: // This points to the symbolic link name that will be ! 195: // linked to the actual nt device name. ! 196: // ! 197: UNICODE_STRING SymbolicLinkName; ! 198: ! 199: // ! 200: // Points to the device object that contains ! 201: // this device extension. ! 202: // ! 203: PDEVICE_OBJECT DeviceObject; ! 204: ! 205: // ! 206: // This holds the current value to initialie a countdown ! 207: // to when an operation starts. ! 208: // ! 209: ULONG TimerStart; ! 210: ! 211: // ! 212: // The base address for the set of device registers ! 213: // of the port. ! 214: // ! 215: PUCHAR Controller; ! 216: ! 217: // ! 218: // This value holds the span (in units of bytes) of the register ! 219: // set controlling this port. This is constant over the life ! 220: // of the port. ! 221: // ! 222: ULONG SpanOfController; ! 223: ! 224: // ! 225: // Set at intialization to indicate that on the current ! 226: // architecture we need to unmap the base register address ! 227: // when we unload the driver. ! 228: // ! 229: BOOLEAN UnMapRegisters; ! 230: ! 231: // ! 232: // Set to false whenever we think that the device needs to be ! 233: // initilized. ! 234: // ! 235: BOOLEAN Initialized; ! 236: ! 237: BOOLEAN AutoFeed; ! 238: ! 239: BOOLEAN TimeToTerminateThread; ! 240: ! 241: // ! 242: // Records whether we actually created the symbolic link name ! 243: // at driver load time. If we didn't create it, we won't try ! 244: // to distroy it when we unload. ! 245: // ! 246: BOOLEAN CreatedSymbolicLink; ! 247: ! 248: // ! 249: // Says whether this device can share interrupts with devices ! 250: // other than parallel devices. ! 251: // ! 252: BOOLEAN InterruptShareable; ! 253: ! 254: // ! 255: // We keep the following values around so that we can connect ! 256: // to the interrupt and report resources after the configuration ! 257: // record is gone. ! 258: // ! 259: // ! 260: // The following two values are obtained from HalGetInterruptVector ! 261: // ! 262: ULONG Vector; ! 263: KIRQL Irql; ! 264: ! 265: // ! 266: // The following two values are what is obtained (or deduced) from either ! 267: // the firmware created portion of the registry, or the user data. ! 268: // ! 269: ULONG OriginalVector; ! 270: ULONG OriginalIrql; ! 271: ! 272: // ! 273: // This is either what is deduced from the particular bus this port is ! 274: // on, or overridden by what the user placed in the registry. ! 275: // ! 276: KINTERRUPT_MODE InterruptMode; ! 277: ! 278: // ! 279: // Give back by HalGetInterruptVector. This says what processors this ! 280: // device can interrupt to. ! 281: // ! 282: KAFFINITY ProcessorAffinity; ! 283: ! 284: // ! 285: // The next three are supplied by the firmware or overridden by the user. ! 286: // ! 287: ULONG AddressSpace; ! 288: ULONG BusNumber; ! 289: INTERFACE_TYPE InterfaceType; ! 290: ! 291: // ! 292: // Handle of the thread doing all the real work. ! 293: // ! 294: PVOID ThreadObjectPointer; ! 295: ! 296: KSEMAPHORE RequestSemaphore; ! 297: ! 298: // ! 299: // One second expressed in system time units. ! 300: // ! 301: LARGE_INTEGER AbsoluteOneSecond; ! 302: ! 303: // ! 304: // One delta second expressed in system time units. ! 305: // ! 306: LARGE_INTEGER OneSecond; ! 307: } PAR_DEVICE_EXTENSION, *PPAR_DEVICE_EXTENSION; ! 308: ! 309: // ! 310: // Bit Definitions in the status register. ! 311: // ! 312: ! 313: #define PAR_STATUS_NOT_ERROR 0x08 //not error on device ! 314: #define PAR_STATUS_SLCT 0x10 //device is selected (on-line) ! 315: #define PAR_STATUS_PE 0x20 //paper empty ! 316: #define PAR_STATUS_NOT_ACK 0x40 //not acknowledge (data transfer was not ok) ! 317: #define PAR_STATUS_NOT_BUSY 0x80 //operation in progress ! 318: ! 319: // ! 320: // Bit Definitions in the control register. ! 321: // ! 322: ! 323: #define PAR_CONTROL_STROBE 0x01 //to read or write data ! 324: #define PAR_CONTROL_AUTOFD 0x02 //to autofeed continuous form paper ! 325: #define PAR_CONTROL_NOT_INIT 0x04 //begin an initialization routine ! 326: #define PAR_CONTROL_SLIN 0x08 //to select the device ! 327: #define PAR_CONTROL_IRQ_ENB 0x10 //to enable interrupts ! 328: #define PAR_CONTROL_DIR 0x20 //direction = read ! 329: #define PAR_CONTROL_WR_CONTROL 0xc0 //the 2 highest bits of the control ! 330: // register must be 1 ! 331: ! 332: //VOID StoreData( ! 333: // IN PUCHAR RegisterBase, ! 334: // IN UCHAR DataByte ! 335: // ) ! 336: //Data must be on line before Strobe = 1; ! 337: // Strobe = 1, DIR = 0 ! 338: //Strobe = 0 ! 339: // ! 340: // We change the port direction to output (and make sure stobe is low). ! 341: // ! 342: // Note that the data must be available at the port for at least ! 343: // .5 microseconds before and after you strobe, and that the strobe ! 344: // must be active for at least 500 nano seconds. We are going ! 345: // to end up stalling for twice as much time as we need to, but, there ! 346: // isn't much we can do about that. ! 347: // ! 348: // We put the data into the port and wait for 1 micro. ! 349: // We strobe the line for at least 1 micro ! 350: // We lower the strobe and again delay for 1 micro ! 351: // We then revert to the original port direction. ! 352: // ! 353: // Thanks to Olivetti for advice. ! 354: // ! 355: ! 356: #define StoreData(RegisterBase,DataByte) \ ! 357: { \ ! 358: PUCHAR _Address = RegisterBase; \ ! 359: UCHAR _Control; \ ! 360: _Control = GetControl(_Address); \ ! 361: ASSERT(!(_Control & PAR_CONTROL_STROBE)); \ ! 362: StoreControl( \ ! 363: _Address, \ ! 364: (UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \ ! 365: ); \ ! 366: WRITE_PORT_UCHAR( \ ! 367: _Address+PARALLEL_DATA_OFFSET, \ ! 368: (UCHAR)DataByte \ ! 369: ); \ ! 370: KeStallExecutionProcessor((ULONG)1); \ ! 371: StoreControl( \ ! 372: _Address, \ ! 373: (UCHAR)((_Control | PAR_CONTROL_STROBE) & ~PAR_CONTROL_DIR) \ ! 374: ); \ ! 375: KeStallExecutionProcessor((ULONG)1); \ ! 376: StoreControl( \ ! 377: _Address, \ ! 378: (UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \ ! 379: ); \ ! 380: KeStallExecutionProcessor((ULONG)1); \ ! 381: StoreControl( \ ! 382: _Address, \ ! 383: (UCHAR)_Control \ ! 384: ); \ ! 385: } ! 386: ! 387: //UCHAR ! 388: //GetControl( ! 389: // IN PUCHAR RegisterBase ! 390: // ) ! 391: #define GetControl(RegisterBase) \ ! 392: (READ_PORT_UCHAR((RegisterBase)+PARALLEL_CONTROL_OFFSET)) ! 393: ! 394: ! 395: //VOID ! 396: //StoreControl( ! 397: // IN PUCHAR RegisterBase, ! 398: // IN UCHAR ControlByte ! 399: // ) ! 400: #define StoreControl(RegisterBase,ControlByte) \ ! 401: { \ ! 402: WRITE_PORT_UCHAR( \ ! 403: (RegisterBase)+PARALLEL_CONTROL_OFFSET, \ ! 404: (UCHAR)ControlByte \ ! 405: ); \ ! 406: } ! 407: ! 408: ! 409: //UCHAR ! 410: //GetStatus( ! 411: // IN PUCHAR RegisterBase ! 412: // ) ! 413: ! 414: #define GetStatus(RegisterBase) \ ! 415: (READ_PORT_UCHAR((RegisterBase)+PARALLEL_STATUS_OFFSET)) ! 416: ! 417: UCHAR ! 418: ParInitializeDevice( ! 419: IN PPAR_DEVICE_EXTENSION Extension ! 420: ); ! 421: ! 422: NTSTATUS ! 423: ParCreateOpen( ! 424: IN PDEVICE_OBJECT DeviceObject, ! 425: IN PIRP Irp ! 426: ); ! 427: ! 428: NTSTATUS ! 429: ParClose( ! 430: IN PDEVICE_OBJECT DeviceObject, ! 431: IN PIRP Irp ! 432: ); ! 433: ! 434: NTSTATUS ! 435: ParCleanup( ! 436: IN PDEVICE_OBJECT DeviceObject, ! 437: IN PIRP Irp ! 438: ); ! 439: ! 440: NTSTATUS ! 441: ParDispatch( ! 442: IN PDEVICE_OBJECT DeviceObject, ! 443: IN PIRP Irp ! 444: ); ! 445: ! 446: NTSTATUS ! 447: ParSetInformationFile( ! 448: IN PDEVICE_OBJECT DeviceObject, ! 449: IN PIRP Irp ! 450: ); ! 451: ! 452: NTSTATUS ! 453: ParQueryInformationFile( ! 454: IN PDEVICE_OBJECT DeviceObject, ! 455: IN PIRP Irp ! 456: ); ! 457: ! 458: VOID ! 459: ParStartIo( ! 460: IN PPAR_DEVICE_EXTENSION DeviceObject ! 461: ); ! 462: ! 463: VOID ! 464: ParUnload( ! 465: IN PDRIVER_OBJECT DriverObject ! 466: ); ! 467: ! 468: VOID ! 469: ParCancelRequest( ! 470: IN PDEVICE_OBJECT DeviceObject, ! 471: IN PIRP Irp ! 472: ); ! 473: ! 474: VOID ! 475: ParLogError( ! 476: IN PDRIVER_OBJECT DriverObject, ! 477: IN PDEVICE_OBJECT DeviceObject OPTIONAL, ! 478: IN PHYSICAL_ADDRESS P1, ! 479: IN PHYSICAL_ADDRESS P2, ! 480: IN ULONG SequenceNumber, ! 481: IN UCHAR MajorFunctionCode, ! 482: IN UCHAR RetryCount, ! 483: IN ULONG UniqueErrorValue, ! 484: IN NTSTATUS FinalStatus, ! 485: IN NTSTATUS SpecificIOStatus ! 486: );
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.