`Hardware White Paper
`
`
`
`Draft ACPI Driver Interface Design Notes and
`Reference
`
`This paper documents the Microsoft-provided interface offered by the ACPI Driver to other kernel-mode
`drivers.
`Important: This document is an early draft revision, distributed primarily for review comment. Changes may
`be made to any part of the document, especially at the detailed level.
`Version 0.91
`November 11, 1998
`
`Contents
`Introduction ..............................................................................................................................................................2
`Two Ways of Using the ACPI Driver Interface ..................................................................................................2
`Constraints on Using the ACPI Driver Interface ................................................................................................2
`Example Using a Hypothetical Hot Key Driver .......................................................................................................3
`Example Driver Setup and Event Handling Using a Dedicated GPE Bit ...........................................................3
`Example Driver Setup and Event Handling Using Event Notification ...............................................................4
`Using the ACPI Interface IOCTLs ...........................................................................................................................5
`Using the IOCTLs that Run AML Control Methods ..........................................................................................8
`Using the IOCTLs that Acquire and Release the Global Lock ...........................................................................9
`Using Direct Function Calls ...................................................................................................................................11
`Using the Device Notification Direct Interfaces and Callback .........................................................................12
`Using the General Purpose Event Direct Interfaces and Callback ....................................................................15
`Reference ...............................................................................................................................................................17
`ACPI Driver Interface Structure Reference ......................................................................................................17
`ACPI Driver Function and Callback Reference ................................................................................................20
`
`This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS DOCUMENT.
`Microsoft Corporation may have patents or pending patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this
`document. The furnishing of this document does not give you any license to the patents, trademarks, copyrights, or other intellectual property rights except as expressly
`provided in any written license agreement from Microsoft Corporation.
`Microsoft does not make any representation or warranty regarding specifications in this document or any product or item developed based on these specifications.
`Microsoft disclaims all express and implied warranties, including but not limited to the implied warranties or merchantability, fitness for a particular purpose and
`freedom from infringement. Without limiting the generality of the foregoing, Microsoft does not make any warranty of any kind that any item developed based on these
`specifications, or any portion of a specification, will not infringe any copyright, patent, trade secret or other intellectual property right of any person or entity in any
`country. It is your responsibility to seek licenses for such intellectual property rights where appropriate. Microsoft shall not be liable for any damages arising out of or in
`connection with the use of these specifications, including liability for lost profit, business interruption, or any other damages whatsoever. Some states do not allow the
`exclusion or limitation of liability or consequential or incidental damages; the above limitation may not apply to you.
`Microsoft, Visual Basic, Win32, Windows, and Windows NT are trademarks or registered trademarks of Microsoft Corporation in the United States and/or other
`countries. Other product and company names mentioned herein may be the trademarks of their respective owners.
`© 1998 Microsoft Corporation. All rights reserved.
`
`
`
`
`
`
`
`AMD EX1005
`U.S. Patent No. 6,895,519
`
`0001
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 2
`
`Introduction
`This paper documents the interface offered by the ACPI Driver to other kernel-mode drivers. Only drivers that
`support IRP_MJ_PNP requests and IRP_MJ_POWER requests can use the ACPI driver interface.
`In general, this interface enables drivers to use the ACPI framework (control methods, ACPI Name Space,
`event handling, and the Global Lock mechanism). In particular, the interface offered by the ACPI Driver
`enables drivers to:
`• Run control methods found in the device driver’s device object in the ACPI name space.
`• Acquire and release the Global Lock; this enables a driver to synchronize with the system firmware.
`• Register for notification of proprietary device events.
`• Handle events associated with a general-purpose event (GPE) bit.
`
`
`
`Two Ways of Using the ACPI Driver Interface
`A driver uses the ACPI Driver interface in two different, but not mutually exclusive, ways. Both ways, listed
`below, are documented in this paper.
`Initiate an IRP with a major function code of IRP_MJ_DEVICE_CONTROL that contains one of the
`•
`IOCTL codes documented in this paper.
`• Use direct function calls.
`
`The IOCTLs, constants, and so on that are described in this paper are defined in acpiioct.h, which can be found
`in the Windows 98 DDK.
`
`Constraints on Using the ACPI Driver Interface
`There are some constraints on what a driver can do with the ACPI Driver interface. These constraints are
`shown in the following summary table.
`
`Using the Interface to…
`Run a control method.
`
`Type of Call
`Initiate an
`IRP_MJ_DEVICE_CONTROL
`
`Acquire and release the
`global lock.
`Register for notification of
`device events.
`
`Initiate an
`IRP_MJ_DEVICE_CONTROL
`Direct function call
`
`Handle events associated
`with a GPE bit.
`
`Direct function call
`
`Constraint
`The control method must be contained in
`the AML Device object that represents the
`device controlled by the calling driver.
`This constraint is discussed in the text
`following this table.
`
`
`Driver can register for notification only on
`the AML Device object that represents the
`device the calling driver controls. Further,
`it can handle only device notification
`codes of 80h or higher.
`Must use a dedicated GPE bit; cannot
`share a GPE bit with the operating system
`or the ACPI driver. Note that if a
`dedicated GPE bit is not available, a
`driver can instead register for notification
`of device events (as shown in the example
`Hot key driver scenarios below).
`
`Notice that a driver can use IOCTLs to run only certain AML control methods in the ACPI name space. The
`control method must be under the AML Device object in the name space that corresponds to the device the
`driver controls. For example, in the hypothetical name space below, the driver associated with the HKEY
`
`
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0002
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 3
`
`// Extended I/O Bus
`
`// Hot key Device Object
`// Unique Device ID that enables the ACPI Driver
`// to enumerate the Hot key device
`// Returns a bitmap that contains the data that
`// identifies which hot key was pressed
`// Returns the index of the GPE bit the Hot key
`// device is associated with
`// PS2 Mouse Device
`// Hardware Device ID
`// Status of the PS2 Mouse device
`// Current Resource
`// Value-added control method
`
`device can run the control method \_SB.EIO.HKEY.INFO but cannot run the control method
`\_SB.EIO.PS2M.VAL0.
`\_SB
`
`.
`
`.
`
`.
`
`EIO
`
`
`.
`
`
`.
`
`
`.
`
`
`
`
`HKEY
`
`
`
`
`_HID
`
`
`
`
`
`
`
`
`
`
`INFO
`
`
`
`
`
`
`
`
`
`_HKGP
`
`
`
`
`
`
`
`
`PS2M
`
`
`
`
`
`_HID
`
`
`
`
`_STA
`
`
`
`
`_CRS
`
`
`
`
`VAL0
`
`
`.
`
`.
`
`.
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`Example Using a Hypothetical Hot Key Driver
`This section introduces a hypothetical device driver called MyDriver that uses the ACPI Driver interface.
`MyDriver controls a hot key device that can recognize the keystrokes or keystroke combinations (used
`particularly on a laptop) that enable the user to use the keyboard to:
`• Switch between the local LCD and an external CRT.
`Increase or decrease audio volume.
`•
`Notice that this example does not show hot keys used for requesting Power Off or Suspend because, on ACPI
`platforms, these requests are handled by standard ACPI mechanisms (which are defined in the ACPI
`Specification).
`Important: This example assumes the following:
`• On both Windows 98 and Windows NT 5.0, all hot keys must be entirely handled through proprietary
`drivers and applications.
`• For a hot key that switches between the local LCD and an external CTR to work requires exporting a new
`function from the miniport driver that is called when such events happen. This feature is not currently
`implemented.
`The ACPI Driver interface can be used in two different ways to accomplish MyDriver’s goals:
`If a dedicated GPE bit is available, MyDriver can use the GpeConnectVector direct function call to
`•
`associate the driver with the GPE bit, then the driver can handle events associated with that bit.
`• As an alternative, MyDriver can use the RegisterForDeviceNotifications function call to register a
`callback routine with the ACPI driver; this callback routine is invoked when AML code executes an AML
`Notify operation on the Hot key device.
`Each of these two techniques requires a somewhat different ACPI name space, as is shown below.
`Example Driver Setup and Event Handling Using a Dedicated GPE Bit
`An example ACPI name space that describes a hot key device that uses a dedicated GPE bit is shown below.
`The two phases of this process are described in this section:
`• During driver setup, MyDriver is loaded and executes the code that registers it as the handler of events on
`the GPE bit to which the hot key device is connected. This phase processes all the initialization code.
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`
`
`
`
`
`
`
`
`0003
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 4
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`• Event handling is initiated when the user presses a hot key on the keyboard.
`This example is based on the following example ACPI name space:
`
`\_SB
`
`.
`
`.
`
`.
`
`EIO
`
`
`.
`
`
`.
`
`
`.
`
`
`
`HKEY
`
`
`
`_HID
`
`
`
`
`
`
`
`
`INFO
`
`
`
`
`
`
`
`
`HKGP
`
`
`
`
`
`
`.
`
`.
`
`.
`Driver Setup
`The steps in driver setup are:
`1. The unique ID in the _HID object causes the ACPI Driver, in its role as an enumerator, to load MyDriver.
`(For information about the _HID control method, see section 6.1.3 of the ACPI Specification.)
`When MyDriver is started, it initiates an IRP_MJ_DEVICE_CONTROL IRP with the IOCTL code of
`IOCTL_ACPI_EVAL_METHOD that runs the HKGP control method. (For more information about the
`control method evaluation IOCTLs, see “Using the ACPI Interface IOCTLs.”) Running the HKGP control
`method returns the index of the GPE bit to which the Hot Key device is connected.
`2. To get pointers to the direct call functions offered by the ACPI driver, MyDriver calls Query_Interface.
`This returns a pointer to the GpeConnectVector function. ACPI’s GUID must be used: IRP_MJ_PNP,
`IRP_MN_QUERY_INTERFACE
`3. MyDriver calls GpeConnectVector, using the bit index returned by evaluating the HKGP method as an
`argument. When this call returns, MyDriver’s callback routine is registered with the ACPI Driver to
`handle all events on that particular GPE bit.
`Event Handling
`The steps in the event handling are:
`
`1. The callback routine initiates an IRP_MJ_DEVICE_CONTROL request, with the IOCTL code The
`AsyncEval version must be used here.]This runs the INFO control method in the ACPI name space under
`the HKEY Device object. The INFO control method returns a bitmap that contains the information that
`identifies the hot key that was pressed.
`2. The callback routine interprets the bitmap and, based on that information, does one of the following:
`• Switches between the local LCD and external CRT.
`Increases or decreases audio volume.
`•
`
`// Extended I/O Bus
`
`// Hot key Device Object
`// Unique Device ID that enables the ACPI Driver
`// to enumerate the Hot Key device
`// Returns a bitmap that contains the data that
`// identifies which hot key was pressed
`// Returns the index of the GPE bit the hot key
`// device is associated with
`
`
`
`
`
`
`
`
`
`Example Driver Setup and Event Handling Using Event Notification
`An example ACPI name space that describes a Hot key device that uses event notification is shown below. The
`two phases of this process are described in this section:
`• During driver setup, MyDriver is loaded and executes the code that registers the HKEY device for a
`device notification.
`• Event handling is initiated when the user presses a hot key on the keyboard.
`This example is based on the following example ACPI name space:
`
`
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0004
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 5
`
`// Control method run to handle event on
`// bit 0x06 of the GPE register. This control
`// method contains the following ASL statement:
`// Notify (HKEY, x’80’)
`
`// Extended I/O Bus
`
`// Hot Key Device Object
`// Unique Device ID that enables the ACPI Driver
`// to enumerate the Hot Key device
`// Returns a bitmap that contains the data that
`// identifies which hot key was pressed
`
`
`\_GPE
`
`_L06
`
`
`
`
`
`
`
`
`
`
`.
`
`.
`
`.
`
`\_SB
`
`.
`
`.
`
`.
`
`EIO
`
`
`.
`
`
`.
`
`
`.
`
`
`
`HKEY
`
`
`
`_HID
`
`
`
`
`
`
`
`
`INFO
`
`
`
`
`
`
`.
`
`.
`
`.
`Driver Setup
`The steps in driver setup are:
`1. The unique ID in the _HID object causes the ACPI Driver, in its role as an enumerator, to load MyDriver.
`(For information about the _HID control method, see section 6.1.3 of the ACPI Specification.)
`2. To get pointers to the direct call functions offered by the ACPI driver, MyDriver calls Query_Interface.
`This returns a pointer to the RegisterForDeviceNotifications function.
`3. MyDriver calls RegisterForDeviceNotifications, passing in a pointer to PDO of the HKEY device and a
`pointer to the entry-point of the MyDriver’s notification call back routine. When this call returns,
`MyDriver’s notification call back routine has been registered with the ACPI Driver to handle device
`notifications for the HKEY device.
`Event Handling
`The steps in event handling are:
`1. When an event happens at GPE bit 6, the ACPI Driver runs the _L06 control method, which results in the
`HKEY driver’s registered device notification callback being called with a Notify value of X’80’. This
`routine can be called at DPC.
` The AsyncEval version must be used since callback can run at DPC.
`2.
`3. The callback routine interprets the bitmap and, based on that information, does one of the following:
`• Switches between the local LCD and external CRT.
`Increases or decreases audio volume.
`•
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`
`Using the ACPI Interface IOCTLs
`A kernel-mode driver sends an IOCTL to the ACPI driver by initiating an IRP_MJ_DEVICE_CONTROL
`request. The IOCTL codes recognized by the ACPI driver are listed in the following table.
`Notice that for the IOCTL_ACPI_EVAL_METHOD and IOCTL_ACPI_ASYNC_EVAL_METHOD IRPs,
`which are used to run a control method, that control method must be under the AML Device object in the
`ACPI name space that represents the device the calling driver controls. For more information about these two
`IOCTLs, see the topic “Using IOCTLs That Run Control Methods.”
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0005
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 6
`
`IOCTL Code
`IOCTL_ACPI_ASYNC_EVAL_METHOD
`
`IOCTL_ACPI_EVAL_METHOD
`
`IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK
`
`IOCTL_ACPI_RELEASE_GLOBAL_LOCK
`
`Description
`This IOCTL may be evaluated at DISPATCH
`level. Use this IOCTL to run any type of AML
`control method, including those that take many
`arguments and/or return many values. The
`Completion Routine must be set in order to
`receive the return data.
`This IOCTL may only be used from BELOW
`DISPATCH level. Use this IOCTL to run any
`type of AML control method, including those
`that take many arguments and/or return many
`values. It is not necessary to set the Completion
`Routine in order to receive the return data.
`When this IRP completes, the driver that
`initiated the IRP owns the Global Lock. Use
`this IOCTL to synchronize access with system
`firmware. For information about the Global
`Lock, see section 5.6.2.1 of the ACPI
`Specification. For more information, see “Using
`the IOCTLs That Acquire and Release the
`Global Lock.”
`Use this IOCTL to release ownership of the
`Global Lock. For more information, see “Using
`the IOCTLs That Acquire and Release the
`Global Lock.”
`
`The following excerpt of sample code shows how a driver can send an IOCTL to the ACPI driver. Notice the
`use of the KeInitializeEvent and KeWaitForSingleObject function calls to wait for the IRP to complete. (For
`information about these two functions, see the NT DDK documentation on the MSDN Professional Level
`CDs.)
`
`
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0006
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 7
`
`NTSTATUS
`SendDownStreamIrp(
` IN PDEVICE_OBJECT Pdo,
` IN ULONG Ioctl,
` IN PVOID InputBuffer,
` IN ULONG InputSize,
` IN PVOID OutputBuffer,
` IN ULONG OutputSize
`)
`/*
`Routine Description:
` General-purpose function called to send a request to the Pdo.
` The Ioctl argument accepts the control method being passed down
` by the calling function.This subroutine is only valid for the IOCTLS other than ASYNC EVAL.
`It is not certain whether ACQUIRE_LOCK or REMOVE_LOCK is used here.
`Arguments:
` Pdo - the request is sent to this device object
` Ioctl - the request - specified by the calling function
` InputBuffer - incoming request
` InputSize - size of the incoming request
` OutputBuffer - the answer
` OutputSize - size of the answer buffer
`Return Value:
` NT Status of the operation
`*/
`{
` IO_STATUS_BLOCK ioBlock;
` KEVENT MyIoctlEvent;
` NTSTATUS Status;
` PIRP Irp;
`
` // Initialize an event to wait on
` KeInitializeEvent(&MyIoctlEvent, SynchronizationEvent, FALSE);
`
` // Build the request
` Irp = IoBuildDeviceIoControlRequest(
` Ioctl,
` Pdo,
` InputBuffer,
` InputSize,
` OutputBuffer,
` OutputSize,
` FALSE,
` &MyIoctlEvent,
` &ioBlock);
`
` if (!Irp) {
` return STATUS_INSUFFICIENT_RESOURCES;
` }
`
` // Pass request to Pdo, always wait for completion routine
` Status = IoCallDriver(Pdo, Irp);
`
` if (Status == STATUS_PENDING) {
` // Wait for the IRP to be completed, then grab the real status code
` KeWaitForSingleObject(
` &MyIoctlEvent,
` Executive,
` KernelMode,
` FALSE,
` NULL);
`
` Status = ioBlock.Status;
` }
`
` // Sanity check the data
` if (OutputBuffer != NULL) {
` if ( ( (PACPI_EVAL_OUTPUT_BUFFER) OutputBuffer->Signature !=
` ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
` ( (PACPI_EVAL_OUTPUT_BUFFER) OutputBuffer->Count == 0) {
` Status = STATUS_ACPI_INVALID_DATA;
` }
` // Done
` return Status;
`}
`
`
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0007
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 8
`
`The following excerpt of driver code shows IOCTL_ACPI_EVAL_METHOD being called out. This sample
`code gets a device status via the _STA method and calls the SendDownStreamIrp function shown earlier in
`this section. For a discussion of the ACPI driver data structures used in the code below, see “ACPI Driver
`Interface Structure Interface” in the Reference section of this document. The ACPI data structures and
`constants called out here are defined in Acpiioct.h, which is located in the Windows 98 DDK.
`NTSTATUS
`GetStaData(
` IN PDEVICE_OBJECT Pdo,
` OUT PULONG ReturnStatus
` )
`/*++
`
`Routine Description:
` Called to get a device status via the _STA method. Generic, works for
` any device with the _STA method (assuming caller has a Pdo).
`
`Arguments:
` Pdo - For the device.
` ReturnStatus - Pointer to where the status data is placed.
`
`Return Value:
` NT Status of the operation
`
`--*/
`{
` ACPI_EVAL_INPUT_BUFFER inputBuffer;
` ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
` NTSTATUS status;
` PACPI_METHOD_ARGUMENT argument;
`
` .
` .
` .
`
` ASSERT( ReturnStatus != NULL );
` *ReturnStatus = 0x0;
`
` // Fill in the input data
` inputBuffer.MethodNameAsUlong = MYDRIVER_STA_METHOD;
` inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
`
` // Send the request along
` status = SendDownStreamIrp(
` Pdo,
` IOCTL_ACPI_EVAL_METHOD,
` &inputBuffer,
` sizeof(ACPI_EVAL_INPUT_BUFFER),
` &outputBuffer,
` sizeof(ACPI_EVAL_OUTPUT_BUFFER)
` );
` if (!NT_SUCCESS(status)) {
` return status;
` }
`
` // Grab the argument
` argument = outputBuffer.Argument;
` status = GetDwordElement( argument, ReturnStatus );Get Dword Element ( ) code needed here.
` return status;
`}
`
`
`
`Using the IOCTLs that Run AML Control Methods
`Device drivers use one of two different IOCTLs to run an AML control method. The main difference between
`the two IOCTLs is the level at which they can run. IOCTL_ACPI_EVAL_METHOD can only be called at
`BELOW DPC level. IOCTL_ACPI_ASYNC_EVAL_METHOD can be called at DISPATCH level, but
`there is higher overhead associated with this IOCTL. Both of these IOCTLS can take a varied number of
`arguments and return a varied number of results. Only IOCTL_ACPI_EVAL_METHOD is documented here
`because of the similarity of the two IOCTLs.
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0008
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 9
`
`When IOCTL_ACPI_EVAL_METHOD is sent to the ACPI device object through a call to IoCallDriver, a
`pointer to IO_STACK_LOCATION is obtained and then a method is called to handle the IOCTL
`synchronously. The argument list is parsed and the request in an IRP is converted into the structures required
`by the AML Interpreter.
`The following structure types define the possible argument lists:
`ACPI_EVAL_INPUT_BUFFER_SIGNATURE
`ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE
`ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_SIGNATURE
`ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE
`
`Using the IOCTLs that Acquire and Release the Global Lock
`A kernel-mode driver can use IOCTLs to acquire and release the Global Lock when it needs to synchronize
`access to hardware for the driver and system firmware. For more information about the Global Lock, see
`section 5.2.6.1 of the ACPI Specification.
`To acquire and release the Global Lock:
`Immediately before doing something that needs to be synchronized, initiate an IRP with the IOCTL code
`1.
`IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK.
`2. When that IRP completes, the initiating driver owns the Global Lock.
`3. As soon as possible, release the Global Lock by initiating an IRP with the IOCTL code
`IOCTL_ACPI_RELEASE_GLOBAL_LOCK.
`IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK enables a device driver to synchronize with the ACPI driver
`and system firmware by acquiring the ACPI Global Lock. The caller passes a buffer to receive an
`ACPI_GLOBAL_LOCK structure. This structure holds private data that the ACPI driver uses to track
`requests for the global lock.
`IOCTL_ACPI_RELEASE_GLOBAL_LOCK releases the ACPI Global Lock after a driver acquires it with
`IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK. The ACPI_GLOBAL_LOCK structure passed to this
`IOCTL must be the same structure returned earlier from IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK.
`An example of code that acquires the global lock is shown below.
`
`
`
`
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0009
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 10
`
`// Pdo corresponding to this fdo
`
`
`
`
`
`
`
`
`
`
`// MyDevice Data port
`// MyDevice Status port
`// MyDevice Command port
`
`typedef struct {
`DeviceObject;
`
`PDEVICE_OBJECT
`NextFdo;
`
`PDEVICE_OBJECT
`
`
`Pdo;
`
`
`
`PDEVICE_OBJECT
`LowerDeviceObject;
`
`PDEVICE_OBJECT
`
`// Static device information
`
`PUCHAR
`
`
`DataPort;
`
`
`
`PUCHAR
`
`
`StatusPort;
`
`
`
`PUCHAR
`
`
`CommandPort;
`
`
`
`.
`
`
`.
`
`
`.
`
`// Global Lock
`
`ACPI_GLOBAL_LOCK GlobalLock;
`
`UCHAR GlobalLockState;
`
`PIRP GlobalLockRequest; // IRP to acquire/release global lock
`
`
`.
`
`
`.
`
`
`.
`MYDEVDATA, *PMYDEVDATA;
`
`VOID
`AcpiMyDriverAcquireGlobalLock (
` IN PMYDEVDATA MyDevData
` )
`/*
`Routine Description:
` Call ACPI driver to obtain the global lock
`Arguments:
` MyDevData - Pointer to my device to service.
`Return Value:
` None.
`*/
`{
` PIRP Irp;
` PIO_STACK_LOCATION IrpSp;
`
`// Call ACPI to obtain the lock
`
`Irp = MyDevData->GlobalLockRequest;
`
`IoInitializeIrp(Irp, MyDevData->IrpSize, MyDevData->LowerDeviceObject->StackSize);
`
`IrpSp = IoGetNextIrpStackLocation(Irp);
`
`IrpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
`
`IrpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_ACPI_ACQUIRE_GLOBAL_LOCK;
`
`IrpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(ACPI_GLOBAL_LOCK);
`
`Irp->AssociatedIrp.SystemBuffer = &MyDevData->GlobalLock;
` IoSetCompletionRoutine(Irp,AcpiMyDevGlobalLockAcquired,MyDevData,TRUE,TRUE,TRUE);
`
`// Send to ACPI driver
`
`IoCallDriver (MyDevData->LowerDeviceObject, Irp);
`}
`
`The following sample code releases the Global Lock. The KeAcquireSpinLock and KeReleaseSpinLock function
`calls are used when there can be multiple devices of this type in the system and/or when a driver has multiple
`threads. For more information about the KeAcquireSpinLock and KeReleaseSpinLock functions, see the NT DDK
`documentation on the MSDN Professional Level CD-ROM.
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0010
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 11
`
`
`VOID
`AcpiMyDevReleaseGlobalLock (
` IN PMYDEVDATA MyDevData
` )
`/*
`Routine Description:
` Call ACPI driver to release the global lock
`Arguments:
` MyDevData - Pointer to embedded controller to service.
`Return Value:
` None.
`*/
`{
` KIRQL OldIrql;
` PIRP Irp;
` PIO_STACK_LOCATION IrpSp;
` KEVENT pdoStartedEvent;
`
`
`
`KeAcquireSpinLock(&MyDevData->Lock, &OldIrql);
`
`if (MyDevData->InServiceLoop) {
`
`
`// InServiceLoop is set, so GlobalLock is going to be needed
`
`
`// immediately. Don't bother with the release of it
`
`
`KeReleaseSpinLock (&MyDevData->Lock, OldIrql);
`
`
`return;
` }
`
`// Mark releasing
`
`MyDevData->GlobalLockState = MYDEV_GL_RELEASING;
`
`KeReleaseSpinLock (&MyDevData->Lock, OldIrql);
`
`// Call ACPI to release the Global Lock
`
`KeInitializeEvent (&pdoStartedEvent, SynchronizationEvent, FALSE);
`
`Irp = MyDevData->GlobalLockRequest;
`
`IoInitializeIrp(Irp, MyDevData->IrpSize,MyDevData->LowerDeviceObject->StackSize);
`
`IrpSp = IoGetNextIrpStackLocation(Irp);
`
`IrpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
`
`IrpSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_ACPI_RELEASE_GLOBAL_LOCK;
`
`IrpSp->Parameters.DeviceIoControl.InputBufferLength = sizeof(ACPI_GLOBAL_LOCK);
`
`Irp->AssociatedIrp.SystemBuffer = &MyDevData->GlobalLock;
`
`IoSetCompletionRoutine(Irp,AcpiMyDevIoCompletion,&pdoStartedEvent,TRUE,TRUE,TRUE);
`
`// Send to ACPI driver
`
`IoCallDriver (MyDevData->LowerDeviceObject, Irp);
`
`// Mark released
`
`KeAcquireSpinLock (&MyDevData->Lock, &OldIrql);
`
`MyDevData->GlobalLockState = MYDEV_GL_NOT_OWNED;
`
`KeReleaseSpinLock (&MyDevData->Lock, OldIrql);
`}
`
`
`
`Using Direct Function Calls
`To get pointers to the direct call functions offered by the ACPI driver, a kernel-mode driver uses an
`IRP_MN_QUERY_INTERFACE request, which returns an ACPI_INTERFACE_STANDARD structure.
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0011
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 12
`
`typedef struct _ACPI_INTERFACE_STANDARD {
`
`// Generic interface header
`
`USHORT Size;
`
`USHORT Version;
` PVOID Context;
` PINTERFACE_REFERENCE InterfaceReference;
` PINTERFACE_DEREFERENCE InterfaceDereference; This structure is allowed to change. This is
`version #1.]
` //
` // ACPI interfaces
` //
` PGPE_CONNECT_VECTOR GpeConnectVector;
` PGPE_DISCONNECT_VECTOR GpeDisconnectVector;
` PGPE_ENABLE_EVENT GpeEnableEvent;
` PGPE_DISABLE_EVENT GpeDisableEvent;
` PGPE_CLEAR_STATUS GpeClearStatus;
` PREGISTER_FOR_DEVICE_NOTIFICATIONS RegisterForDeviceNotifications;
` PUNREGISTER_FOR_DEVICE_NOTIFICATIONS UnregisterForDeviceNotifications;
`} ACPI_INTERFACE_STANDARD, *PACPI_INTERFACE_STANDARD;
`
`The Acpi.sys functions that can be called directly by kernel-mode drivers are listed in the following table. The
`callback functions that a kernel-mode driver can offer to Acpi.sys are documented under the
`DEVICE_NOTIFY_CALLBACK function and the GPE_SERVICE_ROUTINE function in “ACPI Driver
`Function and Callback Reference,” below.
`
`Function
`GpeClearStatus
`GpeConnectVector
`
`GpeDisableEvent
`GpeDisconnectVector
`
`GpeEnableEvent
`RegisterForDeviceNotifications
`
`UnregisterForDeviceNotifications
`
`Description
`Clears the status bit associated with a GPE bit.
`Connects a driver to a GPE bit so the driver can handle events
`associated with that bit.
`Clears the enable bit associated with a GPE bit.
`Disconnects a driver from a GPE bit; the driver no longer handles
`events associated with that bit.
`Sets the enable bit associated with a GPE bit.
`Registers a callback routine to be called when AML code executes a
`Notify operation on a particular device.
`Removes a driver’s registration for notifications on a particular device.
`
`
`
`Using the Device Notification Direct Interfaces and Callback
`This section provides sample code that carries out the scenarios described earlier in “Example Hot Key Driver
`Scenarios.”
`Registering for Notification
`This section provides sample code that carries out the scenarios described earlier in “Example Setup and Event
`Scenarios Using Event Notification.”
`A driver can register a callback routine for device notifications. Call the RegisterForDeviceNotifications
`function, passing a pointer to the driver’s PDO and a pointer to the driver’s callback routine. After that, every
`time AML code executes a Notify operation that has a notification code 0x80 or above, the registered callback
`is called. The callback routine acts as an event handler for the specified events.
`To register for device notifications:
`1. Send an IRP_MN_QUERY_INTERFACE request to the ACPI driver to get the currently loaded ACPI
`driver’s direct interfaces.
`2. Call AcpiInterfaces.RegisterForDeviceNotifications, Passing in a pointer to the ACPI DEVICE_OBJECT,
`typically a PDO. Since the driver only knows the PDO, the driver cannot perform this operation for the
`
`© 1998 Microsoft Corporation. All rights reserved.
`
`0012
`
`
`
` Draft ACPI Driver Interface Design Notes and Reference — 13
`
`stacks for which ACPI is a filter. Therefore this can only be accomplished for an ACPI-enumerated device
`and not for devices that can be enumerated via other means, for example, a PCI device.
`
`
`
`The block of sample code below shows one way to do step 1. It is a routine that sends an
`IRP_MN_