AIOWDM Driver

Overview

AIOWDM is a driver for three things: AIOWDM works with WDM-compatible versions of Windows, including Windows 98, Windows ME, Windows NT/2000, and Windows NT/XP. Under older versions of Windows (Windows 3.1, Windows 95, and Windows NT 4.x or less), these roles are currently filled by our IRQGen, IRQCOS, and WDGIRQ drivers, respectively.



Interface Documentation

All functions are exported in three forms: underscored with the cdecl calling convention (the easiest for C++), undecorated with the stdcall calling convention (easiest for Visual BASIC), and undecorated with the cdecl calling convention (easiest for most other languages). Import declarations are given for Object Pascal / Delphi, C++ Builder / Visual C++, and Visual BASIC.

Visual BASIC doesn't have true pointers, and thus pointer-using functions are declared in Visual BASIC to always have a non-null pointer.


GetNumCards()

function GetNumCards: Integer; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) signed long GetNumCards(void);

Private Declare Function GetNumCards Lib "AIOWDM" Alias "VBGetNumCards" () As Long

This function returns the number of cards in the system using AIOWDM. The cards are numbered from zero to one less than the number returned by GetNumCards(); these card numbers are specified for the CardNum parameters of most other AIOWDM.dll functions. If an invalid card number is specified to another function, the function will fail.


QueryCardInfo()

function QueryCardInfo(CardNum: Integer; pDeviceID: PLongWord; pBase: PLongWord; pNameSize: pLongWord; pName: PChar): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long QueryCardInfo(long CardNum, unsigned long *pDeviceID, unsigned long *pBase, unsigned long *pNameSize, unsigned char *pName);

Private Declare Function QueryCardInfo Lib "AIOWDM" Alias "VBQueryCardInfo" (ByVal CardNum As Long, ByRef pDeviceID As Long, ByRef pBase As Long, ByRef pNameSize as Long, ByVal pName As String) As Long

This function retrieves information about the card indicated by CardNum. It returns nonzero if it succeeds, or zero if it fails (which probably means CardNum was bad). The information retrieved is:

Parameters are as follows:

WaitForIRQ()

function WaitForIRQ(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long WaitForIRQ(long CardNum);

Private Declare Function WaitForIRQ Lib "AIOWDM" Alias "VBWaitForIRQ" (ByVal CardNum As Long) As Long

This function deadlocks the calling thread until an IRQ occurs or the request is aborted. It's intended for multi-threaded IRQ handling, where the calling application spawns a separate thread to service IRQs quickly.

It returns nonzero if it returned because an IRQ occurred, or zero if it returned because the wait was aborted or there was an error. If the wait was aborted, GetLastError() will return ERROR_OPERATION_ABORTED, and if someone is already waiting for an IRQ on that card, it will return ERROR_INVALID_FUNCTION. (Other errors will return other error codes.)


AbortRequest()

function AbortRequest(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long AbortRequest(long CardNum);

Private Declare Function AbortRequest Lib "AIOWDM" Alias "VBAbortRequest" (ByVal CardNum As Long) As Long

This function cancels an IRQ request begun by WaitForIRQ() or COSWaitForIRQ(), or the one begun internally by WDGHandleIRQ(). It returns zero if it fails or nonzero if it succeeds, though the return value is generally not useful since if it fails there was no pending IRQ request on that card to abort.

Make sure you call AbortRequest() or CloseCard() before closing the requesting thread or application; if you don't, the thread will never complete, and the driver will retain the request even though the thread or application has been unloaded from memory. If an IRQ then occurs, or the request is aborted, the wait will resume execution in the nonexistent thread, which will cause a Blue Screen Of Death.

If this does happen, perhaps due to the application crashing, do not then call AbortRequest(). Instead, use Device Manager to disable all devices using AIOWDM, then re-enable them. This will clear the faulty request without causing a Blue Screen Of Death, and allow you to resume working.


CloseCard()

function CloseCard(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long CloseCard(long CardNum);

Private Declare Function CloseCard Lib "AIOWDM" Alias "VBCloseCard" (ByVal CardNum As Long) As Long

This function aborts any pending IRQ requests and closes the handle for the card. While it's necessary to abort all pending requests before closing the application, it isn't necessary to close the handles, as this is done automatically when AIOWDM.dll is unloaded. (When the .DLL is unloaded during an application close, IRQ-requesting threads have been closed already, and thus it's already too late to abort the pending requests - doing so would simply crash the computer.)

It returns zero if it fails or nonzero if it succeeds, though the return value is generally not useful since if it fails there was no open handle to close.


COSWaitForIRQ()

function COSWaitForIRQ(CardNum: Integer; PPIs: LongWord; pData: Pointer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long COSWaitForIRQ(long CardNum, unsigned long PPIs, void *pData);

Private Declare Function COSWaitForIRQ Lib "AIOWDM" Alias "VBCOSWaitForIRQ" (ByVal CardNum As Long, ByVal PPIs As Long, ByRef pData As Byte) As Long

This function is similar to WaitForIRQ(), but it also reads data from the card's PPIs immediately after the IRQ. It's designed specifically for the PCI-DIO-24S, PCI-DIO-48S, IOD24S, and IOD48S, and can be dangerous with another card (as some cards take action based on incoming reads), so check the DeviceID of your card through QueryCardInfo() first. Parameters are as follows:

For Visual BASIC, pData should be the first byte in an array of at least 3 bytes per PPI. For example, if Data was declared with "Dim Data(5) As Byte", you might make the call "COSWaitForIRQ(CardNum, 2, Data(0))".


WDGInit()

function WDGInit(CardNum: Integer): LongWord; cdecl;

extern __declspec(dllimport) unsigned long WDGInit(long CardNum);

Private Declare Function WDGInit Lib "AIOWDM" Alias "VBWDGInit" (ByVal CardNum As Long) As Long

This function prepares a watchdog card driver for further WDG...() function calls, like WDGPet() and WDGHandleIRQ(). It's designed specifically for the PCI-WDG-CSM, and can be dangerous with another card, so check the DeviceID of your card through QueryCardInfo() first. If you call one of these functions on a card whose driver hasn't been prepared, it will fail. It returns nonzero if it succeeds, or zero if it fails.


WDGHandleIRQ()

function WDGHandleIRQ(CardNum: Integer; Action: LongWord): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long WDGHandleIRQ(long CardNum, unsigned long Action);

Private Declare Function WDGHandleIRQ Lib "AIOWDM" Alias "VBWDGHandleIRQ" (ByVal CardNum As Long, Action As Long) As Long

This function sets up an IRQ handler to handle the next watchdog IRQ from the card specified. (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) It returns nonzero if it succeeds, or zero if it fails. Action determines how the IRQ will be handled, as follows:

0 = Ignore.
This will allow the watchdog circuit to trip when the timer times out, performing a "hard" reset (if connected to the computer's reset line or power supply). A "hard" reset doesn't give Windows the opportunity to save important data, but is as certain a reset as possible. Note that this is what will happen if WDGHandleIRQ() is never called.

1 = Disable.
The watchdog timer will be disabled when the card generates an IRQ. This is not generally useful by itself except in testing.

2 = "Soft" Shutdown And Restart.
When the card generates an IRQ the driver will set the watchdog timer to a 90sec timeout, then begin a system shutdown. This "soft" shutdown allows Windows and other programs to save important data, but possibly allows them to cancel it. When the watchdog timer times out, however, the reset circuit will trip, performing a "hard" restart. If the "soft" shutdown completed successfully, the computer will be reset at that time.

3 = Disable And "Soft" Restart.
When the card generates an IRQ the driver will disable the watchdog timer, then begin a system restart. This is similar to 2, but doesn't allow the watchdog timer to actually time out except in case of failures so dire the IRQ doesn't get handled.

4 = "Mostly Soft" Shutdown And Restart.
When the card generates an IRQ the driver will set the watchdog timer to a 90sec timeout, then begin a system shutdown. This "mostly soft" shutdown allows Windows and other programs to save important data within a limited timeframe, and doesn't allow the shutdown to be cancelled. When the watchdog timer actually times out, the reset circuit will trip, performing a "hard" restart. If the "mostly soft" shutdown completed successfully, the computer will be reset at that time.

5 = Disable And "Mostly Soft" Restart.
When the card generates an IRQ the driver will disable the watchdog timer, then begin a system restart. This is similar to 4, but doesn't allow the watchdog timer to actually time out except in case of failures so dire the IRQ doesn't get handled.
Actions greater than 5 are not supported, and will cause this function to fail.


WDGSetTimeout()

function WDGSetTimeout(CardNum: Integer; Milliseconds: Double; MHzClockRate: Double): Double; cdecl;

extern __declspec(dllimport) double WDGSetTimeout(long CardNum, double Milliseconds, double MHzClockRate);

Private Declare Function WDGSetTimeout Lib "AIOWDM" Alias "VBWDGSetTimeout" (ByVal CardNum As Long, ByVal Milliseconds As Double, ByVal MHzClockRate As Double) As Double

This function stops the watchdog's timer, sets the timer's timeout duration, and prepares it for a WDGStart(). (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) If it fails, it returns zero. If it succeeds, it returns the actual timeout achieved, which will be as close to Milliseconds as allowed by the counter's resolution. Parameters are as follows:


WDGSetResetDuration()

function WDGSetResetDuration(CardNum: Integer; Milliseconds: Double; MHzClockRate: Double): Double; cdecl;

extern __declspec(dllimport) double WDGSetResetDuration(long CardNum, double Milliseconds, double MHzClockRate);

Private Declare Function WDGSetResetDuration Lib "AIOWDM" Alias "VBWDGSetResetDuration" (ByVal CardNum As Long, ByVal Milliseconds As Double, ByVal MHzClockRate As Double) As Double

This function sets the duration of the watchdog circuit's reset for the PCI-WDG-CSM, or enables or disables the buzzer for the WDG-CSM (ISA card). (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) Setting Milliseconds to 0.0 will disable the WDG-CSM's buzzer, or prevent the PCI-WDG-CSM from triggering the reset circuit even if it times out. Setting Milliseconds to a value greater than 0.0 but less than or equal to 1.0 will enable the WDG-CSM's buzzer, or set an infinite reset duration for the PCI-WDG-CSM. Setting Milliseconds to a value greater than 1.0 will enable the WDG-CSM's buzzer, or set the PCI-WDG-CSM's reset duration as close to the value passed as possible. If it sets the reset duration to a finite value, it returns that value, otherwise (if it fails or merely controls the buzzer) it returns zero.


WDGPet()

function WDGPet(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long WDGPet(long CardNum);

Private Declare Function WDGPet Lib "AIOWDM" Alias "VBWDGPet" (ByVal CardNum As Long) As Long

This function "pets" a watchdog card, resetting its timers to prevent it from timing out. (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) It returns nonzero if it succeeds, or zero if it fails.


WDGReadTemp()

function WDGReadTemp(CardNum: Integer): Double; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) double WDGReadTemp(long CardNum);

Private Declare Function WDGReadTemp Lib "AIOWDM" Alias "VBWDGReadTemp" (ByVal CardNum As Long) As Double

This function returns the temperature sensor from a watchdog card, in degrees Farenheit. (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) A watchdog card without a temperature sensor will report a temperature of 194.0 degrees F. An actual temperature will never be less than 7.0 degrees F (and even that should never be seen in practice, of course). If this function fails, it returns 0.0 degrees F.


WDGReadStatus()

function WDGReadStatus(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long WDGReadStatus(long CardNum);

Private Declare Function WDGReadStatus Lib "AIOWDM" Alias "VBWDGReadStatus" (ByVal CardNum As Long) As Long

This function reads a watchdog card's status byte at Base + 4. (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) Note that this action incidentally enables watchdog IRQs, but that IRQs will be ignored unless WDGHandleIRQ() has been called for that card. It returns the value of the status byte (which will be FF hex or less) if it succeeds, or a value greater than FF hex if it fails. The format of this byte is described in the card's manual.


WDGStart()

function WDGStart(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long WDGStart(long CardNum);

Private Declare Function WDGStart Lib "AIOWDM" Alias "VBWDGStart" (ByVal CardNum As Long) As Long

This function starts watchdog timing. (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) Note that the watchdog timer should be configured (as by WDGSetTimeout()) to start properly. It returns nonzero if it succeeds, or zero if it fails.


WDGStop()

function WDGStop(CardNum: Integer): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long WDGStop(long CardNum);

Private Declare Function WDGStop Lib "AIOWDM" Alias "VBWDGStop" (ByVal CardNum As Long) As Long

This function stops watchdog timing. (This card's driver must already be prepared for watchdog operation by the WDGInit() function.) It returns nonzero if it succeeds, or zero if it fails.


EmergencyReboot()

function EmergencyReboot(): LongWord; cdecl; external 'AIOWDM.dll';

extern __declspec(dllimport) unsigned long EmergencyReboot(void);

Private Declare Function EmergencyReboot Lib "AIOWDM" Alias "VBEmergencyReboot" () As Long

This function begins a "mostly soft" restart, which allows Windows and other programs to save important data within a limited timeframe, but doesn't allow the restart to be cancelled. It returns nonzero if it succeeds, or zero if it fails(which probably means the calling process isn't allowed to restart the system).