Annotation of ntddk/src/comm/oldpar/par.h, revision 1.1

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 PARTIMEOUT            ((ULONG)0x00000008)
        !            25: #define PARSTART              ((ULONG)0x00000010)
        !            26: #define PARISR                ((ULONG)0x00000020)
        !            27: #define PARDPC                ((ULONG)0x00000040)
        !            28: #define PARCRIT               ((ULONG)0x00000080)
        !            29: #define PARBUSYPATH           ((ULONG)0x00000100)
        !            30: #define PARIRPCOMPLETE        ((ULONG)0x00000200)
        !            31: #define PARDISPATCH           ((ULONG)0x00000400)
        !            32: #define PARISRACTION          ((ULONG)0x00000800)
        !            33: #define PARPOLLREPORT         ((ULONG)0x00001000)
        !            34: #define PARERRORS             ((ULONG)0x40000000)
        !            35: #define PARBUGCHECK           ((ULONG)0x80000000)
        !            36: extern ULONG ParDebugLevel;
        !            37: #define ParDump(LEVEL,STRING) \
        !            38:         do { \
        !            39:             ULONG _level = (LEVEL); \
        !            40:             if (ParDebugLevel & _level) { \
        !            41:                 DbgPrint STRING; \
        !            42:             } \
        !            43:             if (_level == PARBUGCHECK) { \
        !            44:                 ASSERT(FALSE); \
        !            45:             } \
        !            46:         } while (0)
        !            47: #else
        !            48: #define ParDump(LEVEL,STRING) do {NOTHING;} while (0)
        !            49: #endif
        !            50: 
        !            51: //
        !            52: // This define gives the default Object directory
        !            53: // that we should use to insert the symbolic links
        !            54: // between the NT device name and namespace used by
        !            55: // that object directory.
        !            56: #define DEFAULT_DIRECTORY L"DosDevices"
        !            57: 
        !            58: //
        !            59: // For the above directory, the serial port will
        !            60: // use the following name as the suffix of the serial
        !            61: // ports for that directory.  It will also append
        !            62: // a number onto the end of the name.  That number
        !            63: // will start at 1.
        !            64: #define DEFAULT_PARALLEL_NAME L"LPT"
        !            65: //
        !            66: //
        !            67: // This define gives the default NT name for
        !            68: // for serial ports detected by the firmware.
        !            69: // This name will be appended to Device prefix
        !            70: // with a number following it.  The number is
        !            71: // incremented each time encounter a serial
        !            72: // port detected by the firmware.  Note that
        !            73: // on a system with multiple busses, this means
        !            74: // that the first port on a bus is not necessarily
        !            75: // \Device\Parallel0.
        !            76: //
        !            77: #define DEFAULT_NT_SUFFIX L"Parallel"
        !            78: 
        !            79: 
        !            80: //
        !            81: // Defines the number of interrupts it takes for us to decide that
        !            82: // we have an interrupt storm on machine
        !            83: //
        !            84: #define PARALLEL_STORM_WATCH 500
        !            85: 
        !            86: #define PARALLEL_DATA_OFFSET 0
        !            87: #define PARALLEL_STATUS_OFFSET 1
        !            88: #define PARALLEL_CONTROL_OFFSET 2
        !            89: #define PARALLEL_REGISTER_SPAN 3
        !            90: 
        !            91: typedef struct _CONFIG_DATA {
        !            92:     //
        !            93:     // This list entry is used to link all of the "valid"
        !            94:     // configuration entries together.
        !            95:     //
        !            96:     LIST_ENTRY ConfigList;
        !            97: 
        !            98:     //
        !            99:     // The nt object directory into which to place the symbolic
        !           100:     // link to this port.
        !           101:     //
        !           102:     UNICODE_STRING ObjectDirectory;
        !           103: 
        !           104:     //
        !           105:     // The suffix to be used in the nt device name space for this
        !           106:     // port.
        !           107:     //
        !           108:     UNICODE_STRING NtNameForPort;
        !           109: 
        !           110:     //
        !           111:     // The name to be symbolic linked to the nt name.
        !           112:     //
        !           113:     UNICODE_STRING SymbolicLinkName;
        !           114: 
        !           115:     //
        !           116:     // The base address of the registry set for this device.
        !           117:     //
        !           118:     PHYSICAL_ADDRESS Controller;
        !           119: 
        !           120:     //
        !           121:     // The number of contiguous bytes take up by the register
        !           122:     // set for the device.
        !           123:     //
        !           124:     ULONG SpanOfController;
        !           125: 
        !           126:     //
        !           127:     // The bus number (with respect to the bus type) of the bus
        !           128:     // that this device occupies.
        !           129:     //
        !           130:     ULONG BusNumber;
        !           131: 
        !           132:     //
        !           133:     // Denotes whether this devices physical addresses live in io space
        !           134:     // or memory space.
        !           135:     //
        !           136:     ULONG AddressSpace;
        !           137: 
        !           138:     //
        !           139:     // Denotes whether this device is latched or level sensitive.
        !           140:     //
        !           141:     KINTERRUPT_MODE InterruptMode;
        !           142: 
        !           143:     //
        !           144:     // The kind of bus that this device lives on (e.g. Isa, Eisa, MCA, etc)
        !           145:     //
        !           146:     INTERFACE_TYPE InterfaceType;
        !           147: 
        !           148:     //
        !           149:     // The originalirql is what is optained from the firmware data.  The level
        !           150:     // is also obtained from the firmware data.  When we get a configuration
        !           151:     // record based on the services portion of the registry we will always set
        !           152:     // the vector equal to the irql unless overridden by user input.
        !           153:     //
        !           154:     ULONG OriginalVector;
        !           155:     ULONG OriginalIrql;
        !           156: 
        !           157:     //
        !           158:     // Denotes whether the device should be disabled after it has been
        !           159:     // initialized.
        !           160:     //
        !           161:     ULONG DisablePort;
        !           162: 
        !           163:     } CONFIG_DATA,*PCONFIG_DATA;
        !           164: 
        !           165: typedef enum _PAR_COMMAND {
        !           166:     ParWrite,
        !           167:     ParSetInformation,
        !           168:     ParQueryInformation
        !           169:     } PAR_COMMAND, *PPAR_COMMAND;
        !           170: 
        !           171: typedef struct _PAR_DEVICE_EXTENSION {
        !           172: 
        !           173:     //
        !           174:     // For reporting resource usage, we keep around the physical
        !           175:     // address we got from the registry.
        !           176:     //
        !           177:     PHYSICAL_ADDRESS OriginalController;
        !           178: 
        !           179:     //
        !           180:     // We keep a pointer around to our device name for dumps
        !           181:     // and for creating "external" symbolic links to this
        !           182:     // device.
        !           183:     //
        !           184:     UNICODE_STRING DeviceName;
        !           185: 
        !           186:     //
        !           187:     // This points to the object directory that we will place
        !           188:     // a symbolic link to our device name.
        !           189:     //
        !           190:     UNICODE_STRING ObjectDirectory;
        !           191: 
        !           192:     //
        !           193:     // This points to the device name for this device
        !           194:     // sans device prefix.
        !           195:     //
        !           196:     UNICODE_STRING NtNameForPort;
        !           197: 
        !           198:     //
        !           199:     // This points to the symbolic link name that will be
        !           200:     // linked to the actual nt device name.
        !           201:     //
        !           202:     UNICODE_STRING SymbolicLinkName;
        !           203: 
        !           204:     //
        !           205:     // Points to the device object that contains
        !           206:     // this device extension.
        !           207:     //
        !           208:     PDEVICE_OBJECT DeviceObject;
        !           209: 
        !           210:     //
        !           211:     // For value -1  when the interval timer maintained by the IO system
        !           212:     // fires, it implies that the timer routine is to do nothing.
        !           213:     //
        !           214:     // For value 0, then the timer routine should timeout the particular
        !           215:     // operation.
        !           216:     //
        !           217:     // For values > 0 then the timer should do nothing other then synchronize
        !           218:     // with the isr and decrement this value by 1.
        !           219:     //
        !           220:     LONG TimerCount;
        !           221: 
        !           222:     //
        !           223:     // This holds the current value to initialize TimerCount
        !           224:     // to when an operation starts.
        !           225:     //
        !           226:     ULONG TimerStart;
        !           227: 
        !           228:     //
        !           229:     // Unexpected interrupts are counted here.  It is cleared
        !           230:     // every second by the timer management routine.  On
        !           231:     // a device that is being interrupt driven, if the unexpected
        !           232:     // interrupt count exceeds a threshold, the interrupts will
        !           233:     // be disabled on the device and the device will go to polled
        !           234:     // mode.
        !           235:     //
        !           236:     ULONG UnexpectedCount;
        !           237: 
        !           238:     //
        !           239:     // The base address for the set of device registers
        !           240:     // of the port.
        !           241:     //
        !           242:     PUCHAR Controller;
        !           243: 
        !           244:     //
        !           245:     // Points to the interrupt object used by this device.
        !           246:     //
        !           247:     PKINTERRUPT Interrupt;
        !           248: 
        !           249:     //
        !           250:     // This value holds the span (in units of bytes) of the register
        !           251:     // set controlling this port.  This is constant over the life
        !           252:     // of the port.
        !           253:     //
        !           254:     ULONG SpanOfController;
        !           255: 
        !           256:     //
        !           257:     // Set at intialization to indicate that on the current
        !           258:     // architecture we need to unmap the base register address
        !           259:     // when we unload the driver.
        !           260:     //
        !           261:     BOOLEAN UnMapRegisters;
        !           262: 
        !           263:     //
        !           264:     // These two variables denote the "staging" of initializing the
        !           265:     // device.  Some devices won't respond with an interrupt when
        !           266:     // initializing.  When we start initializing, we set the Initializing
        !           267:     // variable to TRUE and the Initialized flag to FALES.
        !           268:     //
        !           269:     // Whenever we go an access the hardware we check the initializing flag.
        !           270:     // If it is true, then we check the "status" of the device, and if the
        !           271:     // everything is ok, set initializing to FALSE and Initialized to TRUE.
        !           272:     // If the "status" of the device is not "good", then we process it as an
        !           273:     // error, and return the error indication to the caller.
        !           274:     //
        !           275:     BOOLEAN Initialized;
        !           276:     BOOLEAN Initializing;
        !           277: 
        !           278:     //
        !           279:     // This denotes the number of characters left in the current write.
        !           280:     //
        !           281:     ULONG CountBuffer;
        !           282: 
        !           283:     BOOLEAN AutoFeed;
        !           284:     BOOLEAN CompletingIoControl;
        !           285: 
        !           286:     //
        !           287:     // Records whether we actually created the symbolic link name
        !           288:     // at driver load time.  If we didn't create it, we won't try
        !           289:     // to distroy it when we unload.
        !           290:     //
        !           291:     BOOLEAN CreatedSymbolicLink;
        !           292: 
        !           293:     //
        !           294:     // This field will denote that the driver is using a timer instead of
        !           295:     // interrupts to "schedule" work out to the device.
        !           296:     //
        !           297:     BOOLEAN UsingATimer;
        !           298: 
        !           299:     PAR_COMMAND Command;
        !           300: 
        !           301:     //
        !           302:     // Says whether this device can share interrupts with devices
        !           303:     // other than parallel devices.
        !           304:     //
        !           305:     BOOLEAN InterruptShareable;
        !           306: 
        !           307:     //
        !           308:     // Denotes to the timer routine whether it should log an error
        !           309:     // because we were blasted by to many interrupts.
        !           310:     //
        !           311:     BOOLEAN StormKnocksOutInterrupts;
        !           312: 
        !           313:     //
        !           314:     // We keep the following values around so that we can connect
        !           315:     // to the interrupt and report resources after the configuration
        !           316:     // record is gone.
        !           317:     //
        !           318:     //
        !           319:     // The following two values are obtained from HalGetInterruptVector
        !           320:     //
        !           321:     ULONG Vector;
        !           322:     KIRQL Irql;
        !           323: 
        !           324:     //
        !           325:     // The following two values are what is obtained (or deduced) from either
        !           326:     // the firmware created portion of the registry, or the user data.
        !           327:     //
        !           328:     ULONG OriginalVector;
        !           329:     ULONG OriginalIrql;
        !           330: 
        !           331:     //
        !           332:     // This is either what is deduced from the particular bus this port is
        !           333:     // on, or overridden by what the user placed in the registry.
        !           334:     //
        !           335:     KINTERRUPT_MODE InterruptMode;
        !           336: 
        !           337:     //
        !           338:     // Give back by HalGetInterruptVector.  This says what processors this
        !           339:     // device can interrupt to.
        !           340:     //
        !           341:     KAFFINITY ProcessorAffinity;
        !           342: 
        !           343:     //
        !           344:     // The next three are supplied by the firmware or overridden by the user.
        !           345:     //
        !           346:     ULONG AddressSpace;
        !           347:     ULONG BusNumber;
        !           348:     INTERFACE_TYPE InterfaceType;
        !           349: 
        !           350:     //
        !           351:     // All irps go through the start io routine.  Whenver
        !           352:     // we start out a new irp we increment this value.  This
        !           353:     // is how we can have a unique irp value to give if we
        !           354:     // need to log an error during the processing of a particular
        !           355:     // irp.
        !           356:     //
        !           357:     ULONG IrpSequence;
        !           358: 
        !           359:     //
        !           360:     // This spinlock is used to synchronize access to the hardware
        !           361:     // when the port is being driver off of a timer, rather than
        !           362:     // when using interrupts.
        !           363:     //
        !           364:     KSPIN_LOCK PollingLock;
        !           365: 
        !           366:     //
        !           367:     // We use a timer so that we can try to do a bunch of
        !           368:     // operations, then give the rest of the system time
        !           369:     // to run
        !           370:     //
        !           371:     KTIMER PollingTimer;
        !           372: 
        !           373:     //
        !           374:     // This dpc is queued when the polling timer expires, and it is
        !           375:     // also queued after we start a write operations.
        !           376:     //
        !           377:     KDPC PollingDpc;
        !           378: 
        !           379:     //
        !           380:     // This is the length of time the timer will spend in the
        !           381:     // timer queue.
        !           382:     //
        !           383:     LARGE_INTEGER PollingDelayAmount;
        !           384: 
        !           385:     //
        !           386:     // This timer is used for polling the busy bit.
        !           387:     //
        !           388:     KTIMER BusyTimer;
        !           389: 
        !           390:     //
        !           391:     // This dpc is queued from the isr to start the above timer.
        !           392:     //
        !           393:     KDPC StartBusyTimerDpc;
        !           394: 
        !           395:     //
        !           396:     // This is the dpc queued when the above timer fires.
        !           397:     //
        !           398:     KDPC BusyTimerDpc;
        !           399: 
        !           400:     //
        !           401:     // This holds the delta time fed to above timer.
        !           402:     //
        !           403:     LARGE_INTEGER BusyDelayAmount;
        !           404: 
        !           405:     //
        !           406:     // We keep this boolean around to tell use that we've started off
        !           407:     // the busy "path of execution".  If this variable is true when
        !           408:     // the isr would start off the busy path, it won't start it.  If
        !           409:     // it is false, we set it to true and start the path.  It is not
        !           410:     // set back to false until just before the path calls back the
        !           411:     // isr.
        !           412:     //
        !           413:     BOOLEAN BusyPath;
        !           414: } PAR_DEVICE_EXTENSION, *PPAR_DEVICE_EXTENSION;
        !           415: 
        !           416: //
        !           417: // Bit Definitions in the status register.
        !           418: //
        !           419: 
        !           420: #define PAR_STATUS_NOT_ERROR   0x08  //not error on device
        !           421: #define PAR_STATUS_SLCT        0x10  //device is selected (on-line)
        !           422: #define PAR_STATUS_PE          0x20  //paper empty
        !           423: #define PAR_STATUS_NOT_ACK     0x40  //not acknowledge (data transfer was not ok)
        !           424: #define PAR_STATUS_NOT_BUSY    0x80  //operation in progress
        !           425: 
        !           426: //
        !           427: //  Bit Definitions in the control register.
        !           428: //
        !           429: 
        !           430: #define PAR_CONTROL_STROBE      0x01 //to read or write data
        !           431: #define PAR_CONTROL_AUTOFD      0x02 //to autofeed continuous form paper
        !           432: #define PAR_CONTROL_NOT_INIT    0x04 //begin an initialization routine
        !           433: #define PAR_CONTROL_SLIN        0x08 //to select the device
        !           434: #define PAR_CONTROL_IRQ_ENB     0x10 //to enable interrupts
        !           435: #define PAR_CONTROL_DIR         0x20 //direction = read
        !           436: #define PAR_CONTROL_WR_CONTROL  0xc0 //the 2 highest bits of the control
        !           437:                                      // register must be 1
        !           438: 
        !           439: //VOID StoreData(
        !           440: //      IN PUCHAR RegisterBase,
        !           441: //      IN UCHAR DataByte
        !           442: //      )
        !           443: //Data must be on line before Strobe = 1;
        !           444: // Strobe = 1, DIR = 0
        !           445: //Strobe = 0
        !           446: //
        !           447: // We change the port direction to output (and make sure stobe is low).
        !           448: //
        !           449: // Note that the data must be available at the port for at least
        !           450: // .5 microseconds before and after you strobe, and that the strobe
        !           451: // must be active for at least 500 nano seconds.  We are going
        !           452: // to end up stalling for twice as much time as we need to, but, there
        !           453: // isn't much we can do about that.
        !           454: //
        !           455: // We put the data into the port and wait for 1 micro.
        !           456: // We strobe the line for at least 1 micro
        !           457: // We lower the strobe and again delay for 1 micro
        !           458: // We then revert to the original port direction.
        !           459: //
        !           460: // Thanks to Olivetti for advice.
        !           461: //
        !           462: 
        !           463: #define StoreData(RegisterBase,DataByte)                            \
        !           464: {                                                                   \
        !           465:     PUCHAR _Address = RegisterBase;                                 \
        !           466:     UCHAR _Control;                                                 \
        !           467:     _Control = GetControl(_Address);                                \
        !           468:     ASSERT(!(_Control & PAR_CONTROL_STROBE));                       \
        !           469:     StoreControl(                                                   \
        !           470:         _Address,                                                   \
        !           471:         (UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \
        !           472:         );                                                          \
        !           473:     WRITE_PORT_UCHAR(                                               \
        !           474:         _Address+PARALLEL_DATA_OFFSET,                              \
        !           475:         (UCHAR)DataByte                                             \
        !           476:         );                                                          \
        !           477:     KeStallExecutionProcessor((ULONG)1);                            \
        !           478:     StoreControl(                                                   \
        !           479:         _Address,                                                   \
        !           480:         (UCHAR)((_Control | PAR_CONTROL_STROBE) & ~PAR_CONTROL_DIR) \
        !           481:         );                                                          \
        !           482:     KeStallExecutionProcessor((ULONG)1);                            \
        !           483:     StoreControl(                                                   \
        !           484:         _Address,                                                   \
        !           485:         (UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \
        !           486:         );                                                          \
        !           487:     KeStallExecutionProcessor((ULONG)1);                            \
        !           488:     StoreControl(                                                   \
        !           489:         _Address,                                                   \
        !           490:         (UCHAR)_Control                                             \
        !           491:         );                                                          \
        !           492: }
        !           493: 
        !           494: //UCHAR
        !           495: //GetControl(
        !           496: //  IN PUCHAR RegisterBase
        !           497: //  )
        !           498: #define GetControl(RegisterBase) \
        !           499:     (READ_PORT_UCHAR((RegisterBase)+PARALLEL_CONTROL_OFFSET))
        !           500: 
        !           501: 
        !           502: //VOID
        !           503: //StoreControl(
        !           504: //  IN PUCHAR RegisterBase,
        !           505: //  IN UCHAR ControlByte
        !           506: //  )
        !           507: #define StoreControl(RegisterBase,ControlByte)  \
        !           508: {                                               \
        !           509:     WRITE_PORT_UCHAR(                           \
        !           510:         (RegisterBase)+PARALLEL_CONTROL_OFFSET, \
        !           511:         (UCHAR)ControlByte                      \
        !           512:         );                                      \
        !           513: }
        !           514: 
        !           515: 
        !           516: //UCHAR
        !           517: //GetStatus(
        !           518: //  IN PUCHAR RegisterBase
        !           519: //  )
        !           520: 
        !           521: #define GetStatus(RegisterBase) \
        !           522:     (READ_PORT_UCHAR((RegisterBase)+PARALLEL_STATUS_OFFSET))
        !           523: 
        !           524: typedef enum _PAR_ERROR_TYPE {
        !           525:     PoweredOff,
        !           526:     NotConnected,
        !           527:     Offline,
        !           528:     PaperEmpty,
        !           529:     PowerFailure,
        !           530:     DataError,
        !           531:     Busy
        !           532: } PAR_ERROR_TYPE, *PPAR_ERROR_TYPE;
        !           533: 
        !           534: BOOLEAN
        !           535: ParInitializeDevice(
        !           536:     IN PVOID Context
        !           537:     );
        !           538: 
        !           539: NTSTATUS
        !           540: ParDispatch(
        !           541:     IN PDEVICE_OBJECT DeviceObject,
        !           542:     IN PIRP Irp
        !           543:     );
        !           544: 
        !           545: NTSTATUS
        !           546: ParSetInformationFile(
        !           547:     IN PDEVICE_OBJECT DeviceObject,
        !           548:     IN PIRP Irp
        !           549:     );
        !           550: 
        !           551: NTSTATUS
        !           552: ParQueryInformationFile(
        !           553:     IN PDEVICE_OBJECT DeviceObject,
        !           554:     IN PIRP Irp
        !           555:     );
        !           556: 
        !           557: VOID
        !           558: ParDpcRoutine(
        !           559:     IN PKDPC Dpc,
        !           560:     IN PDEVICE_OBJECT DeviceObject,
        !           561:     IN PIRP Irp,
        !           562:     IN PVOID Context
        !           563:     );
        !           564: 
        !           565: VOID
        !           566: ParTimerRoutine(
        !           567:     PDEVICE_OBJECT DeviceObject,
        !           568:     IN PVOID Context
        !           569:     );
        !           570: 
        !           571: BOOLEAN
        !           572: ParManageTimeOut(
        !           573:     IN PVOID Context
        !           574:     );
        !           575: 
        !           576: BOOLEAN
        !           577: ParInterruptServiceRoutine(
        !           578:     IN PKINTERRUPT InterruptObject,
        !           579:     IN PVOID Context
        !           580:     );
        !           581: 
        !           582: BOOLEAN
        !           583: ParInitiateIo(
        !           584:     IN PDEVICE_OBJECT DeviceObject
        !           585:     );
        !           586: 
        !           587: VOID
        !           588: ParStartIo(
        !           589:     IN PDEVICE_OBJECT DeviceObject,
        !           590:     IN PIRP Irp
        !           591:     );
        !           592: 
        !           593: VOID
        !           594: ParUnload(
        !           595:     IN PDRIVER_OBJECT DriverObject
        !           596:     );
        !           597: 
        !           598: VOID
        !           599: ParCancelRequest(
        !           600:     IN PDEVICE_OBJECT DeviceObject,
        !           601:     IN PIRP Irp
        !           602:     );
        !           603: 
        !           604: BOOLEAN
        !           605: ParSynchronizeExecution(
        !           606:     IN PPAR_DEVICE_EXTENSION Extension,
        !           607:     IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
        !           608:     IN PVOID SynchronizeContext
        !           609:     );
        !           610: 
        !           611: VOID
        !           612: ParPollingDpcRoutine(
        !           613:     IN PKDPC Dpc,
        !           614:     IN PVOID DeferredContext,
        !           615:     IN PVOID SystemContext1,
        !           616:     IN PVOID SystemContext2
        !           617:     );
        !           618: 
        !           619: BOOLEAN
        !           620: ParPolling(
        !           621:     IN PVOID Context
        !           622:     );
        !           623: 
        !           624: VOID
        !           625: ParLogError(
        !           626:     IN PDRIVER_OBJECT DriverObject,
        !           627:     IN PDEVICE_OBJECT DeviceObject OPTIONAL,
        !           628:     IN PHYSICAL_ADDRESS P1,
        !           629:     IN PHYSICAL_ADDRESS P2,
        !           630:     IN ULONG SequenceNumber,
        !           631:     IN UCHAR MajorFunctionCode,
        !           632:     IN UCHAR RetryCount,
        !           633:     IN ULONG UniqueErrorValue,
        !           634:     IN NTSTATUS FinalStatus,
        !           635:     IN NTSTATUS SpecificIOStatus
        !           636:     );
        !           637: 
        !           638: VOID
        !           639: ParStartBusyTimer(
        !           640:     IN PKDPC Dpc,
        !           641:     IN PVOID DeferredContext,
        !           642:     IN PVOID SystemContext1,
        !           643:     IN PVOID SystemContext2
        !           644:     );
        !           645: 
        !           646: VOID
        !           647: ParBusyTimer(
        !           648:     IN PKDPC Dpc,
        !           649:     IN PVOID DeferredContext,
        !           650:     IN PVOID SystemContext1,
        !           651:     IN PVOID SystemContext2
        !           652:     );
        !           653: 
        !           654: BOOLEAN
        !           655: ParBusyCallIsr(
        !           656:     IN PVOID Context
        !           657:     );
        !           658: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.