WDF: Installing ISR for IRQ 9

Hello,

With the help of specialists in this forum I built an upper driver for
“Intel(R) ICH10 LPC Interface Controller – 3A18”.

The purpose of this driver was to control the GPIO in ICH10.

Now I need to get an interrupt from this GPIO.

According to the ICH spec, IRQ 9-11 (not sure) can be connected to create an
interrupt caused by GPIO.

How can I install an ISR for this interrupt ?

Best regards,
Z.V

On Dec 27, 2014, at 8:06 PM, Zvi Vered wrote:
>
> With the help of specialists in this forum I built an upper driver for
> “Intel(R) ICH10 LPC Interface Controller – 3A18”.
>
> The purpose of this driver was to control the GPIO in ICH10.
>
> Now I need to get an interrupt from this GPIO.
>
> According to the ICH spec, IRQ 9-11 (not sure) can be connected to create an
> interrupt caused by GPIO.
>
> How can I install an ISR for this interrupt ?

You don’t. The GPIO lines and interrupts should be be communicating with the ACPI BIOS. Your driver should be fetching the APCI interface from the bus driver. You use ACPI methods to manipulate the lines, and you register for GPE (GPIO events) to get notified of events. That way, you don’t worry about which IRQ it is — the BIOS does.

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

Can you please explain what do you mean by “fetching the ACPI interface from
the bus driver” ?
What are “ACPI methods” ?

The bus driver is Microsoft’s msisadrv.sys for which I do not have source
code.

Best regards,
Z.V

-----Original Message-----
From: Tim Roberts
Sent: Sunday, December 28, 2014 7:20 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WDF: Installing ISR for IRQ 9

On Dec 27, 2014, at 8:06 PM, Zvi Vered wrote:
>
> With the help of specialists in this forum I built an upper driver for
> “Intel(R) ICH10 LPC Interface Controller – 3A18”.
>
> The purpose of this driver was to control the GPIO in ICH10.
>
> Now I need to get an interrupt from this GPIO.
>
> According to the ICH spec, IRQ 9-11 (not sure) can be connected to create
> an
> interrupt caused by GPIO.
>
> How can I install an ISR for this interrupt ?

You don’t. The GPIO lines and interrupts should be be communicating with
the ACPI BIOS. Your driver should be fetching the APCI interface from the
bus driver. You use ACPI methods to manipulate the lines, and you register
for GPE (GPIO events) to get notified of events. That way, you don’t worry
about which IRQ it is — the BIOS does.
—
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Zvi Vered wrote:

Can you please explain what do you mean by “fetching the ACPI interface from
the bus driver” ?
What are “ACPI methods” ?

The bus driver is Microsoft’s msisadrv.sys for which I do not have source
code.

I should have gone back to read the previous messages on this topic. I
see you’ve been going at this for a long time.

When you mention IRQ 9-11, I assume you are referring to the ACPI_CNTL
register. That is the SCI interrupt – “system control interrupt” –
which is a general purpose interrupt used by the BIOS and the
motherboard hardware to notify the ACPI driver that something happened.
That IRQ is owned and managed by ACPI and the ACPI driver (which sits
below msisadrv in your case).

It’s true that you can configure things to have a GPIO change fire an
SCI. This is called a GPE – general purpose event. The way you ask to
be notified of a GPE is by registering with the ACPI driver. To do
that, you have to fetch the ACPI driver’s interface. You do that with
WdfFdoQueryForInterface for GUID_ACPI_INTERFACE_STANDARD. That returns
you an ACPI_INTERFACE_STANDARD structure, which has a set of function
pointers.

Your ACPI BIOS has to put the “vector number” somewhere in the ACPI DSDT
for your device. You have to call an ACPI method to fetch that “vector
number,” so you know what to register. That in itself is tricky enough.

You then use GpeConnectVector to register a callback when a particular
GPE fires, similar to WdfInterruptCreate. You use GpeEnableEvent and
GpeDisableEvent to enable and disable the interrupt. You use
GpeClearStatus to clear the event. You use GpeDisconnectVector when you
shut down. There is, to the best of my knowledge, no document that
describes this interface.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

Thank you for the detailed information.

The mechanism you described is very complicated.

Do you have a sample code ?

It seems Microsoft / Intel does not want users to access ACPI.

Best regards,
Z.V

-----Original Message-----
From: Tim Roberts
Sent: Tuesday, December 30, 2014 7:57 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WDF: Installing ISR for IRQ 9

Zvi Vered wrote:

Can you please explain what do you mean by “fetching the ACPI interface
from
the bus driver” ?
What are “ACPI methods” ?

The bus driver is Microsoft’s msisadrv.sys for which I do not have source
code.

I should have gone back to read the previous messages on this topic. I
see you’ve been going at this for a long time.

When you mention IRQ 9-11, I assume you are referring to the ACPI_CNTL
register. That is the SCI interrupt – “system control interrupt” –
which is a general purpose interrupt used by the BIOS and the
motherboard hardware to notify the ACPI driver that something happened.
That IRQ is owned and managed by ACPI and the ACPI driver (which sits
below msisadrv in your case).

It’s true that you can configure things to have a GPIO change fire an
SCI. This is called a GPE – general purpose event. The way you ask to
be notified of a GPE is by registering with the ACPI driver. To do
that, you have to fetch the ACPI driver’s interface. You do that with
WdfFdoQueryForInterface for GUID_ACPI_INTERFACE_STANDARD. That returns
you an ACPI_INTERFACE_STANDARD structure, which has a set of function
pointers.

Your ACPI BIOS has to put the “vector number” somewhere in the ACPI DSDT
for your device. You have to call an ACPI method to fetch that “vector
number,” so you know what to register. That in itself is tricky enough.

You then use GpeConnectVector to register a callback when a particular
GPE fires, similar to WdfInterruptCreate. You use GpeEnableEvent and
GpeDisableEvent to enable and disable the interrupt. You use
GpeClearStatus to clear the event. You use GpeDisconnectVector when you
shut down. There is, to the best of my knowledge, no document that
describes this interface.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

On 31-Dec-2014 06:07, Zvi Vered wrote:

It seems Microsoft / Intel does not want users to access ACPI.

Why they would want to? ACPI is for system builders (those who
customize the BIOS to their platform).
With a new kind of platforms (SoC - likes), Windows 8+ supports
access to GPIOs.

– pa

Zvi Vered wrote:

Thank you for the detailed information.

The mechanism you described is very complicated.

Yes, it is. As with most driver tasks, when you go to drive a piece of
hardware, you are expected to be a “subject matter expert” in that
hardware. Windows is not an experimental microprocessor system – it’s
kernel does genuine resource management, so that resources are owned by
one particular component. Any request to use that component has to go
through the owner.

In this case, the GPIOs are not simply available for everyone to use.
They are owned by the BIOS, and the gateway to the BIOS is the ACPI
driver. So, you have to work with the BIOS developers, and you have to
follow the ACPI driver’s rules.

Do you have an account on Intel’s developer support forums? Since you
are accessing a resource that is exposed by Intel’s chipset, you should
go ask them about it. It is POSSIBLE that they have already created an
API layer to allow access to these pins, or perhaps have a chunk of
sample code you can use.

Do you have a sample code ?

The work I did was on a contract to Intel, so I’m not free to release
it. I suspect the Intel forums are your best plan for now.

It seems Microsoft / Intel does not want users to access ACPI.

I’m not sure why the interface is not documented. I suppose no one has
taken the time to write the documentation.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

In the following link:
download.microsoft.com/download/.../ACPIDriver_Vista.doc

I found the following structure:

typedef struct {
//
// Generic interface header
//
USHORT Size;
USHORT Version;
PVOID Context;
PINTERFACE_REFERENCE InterfaceReference;
PINTERFACE_DEREFERENCE InterfaceDereference;
//
// ACPI interfaces
//
PGPE_CONNECT_VECTOR2 GpeConnectVector;
PGPE_DISCONNECT_VECTOR2 GpeDisconnectVector;
PGPE_ENABLE_EVENT2 GpeEnableEvent;
PGPE_DISABLE_EVENT2 GpeDisableEvent;
PGPE_CLEAR_STATUS2 GpeClearStatus;
PREGISTER_FOR_DEVICE_NOTIFICATIONS2 RegisterForDeviceNotifications;
PUNREGISTER_FOR_DEVICE_NOTIFICATIONS2
UnregisterForDeviceNotifications;

} ACPI_INTERFACE_STANDARD2, *PACPI_INTERFACE_STANDARD2;

Is this the structure I should get by calling to: “WdfFdoQueryForInterface
for GUID_ACPI_INTERFACE_STANDARD” ?

In your reply you wrote:

Your ACPI BIOS has to put the “vector number” somewhere in the ACPI DSDT
for your device. You have to call an ACPI method to fetch that “vector
number,” so you know what to register. That in itself is tricky enough.

What is the ACPI method I should call to fetch that “vector number” ?

Best regards,
Z.V

-----Original Message-----
From: Tim Roberts
Sent: Wednesday, December 31, 2014 7:28 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WDF: Installing ISR for IRQ 9

Zvi Vered wrote:

Thank you for the detailed information.

The mechanism you described is very complicated.

Yes, it is. As with most driver tasks, when you go to drive a piece of
hardware, you are expected to be a “subject matter expert” in that
hardware. Windows is not an experimental microprocessor system – it’s
kernel does genuine resource management, so that resources are owned by
one particular component. Any request to use that component has to go
through the owner.

In this case, the GPIOs are not simply available for everyone to use.
They are owned by the BIOS, and the gateway to the BIOS is the ACPI
driver. So, you have to work with the BIOS developers, and you have to
follow the ACPI driver’s rules.

Do you have an account on Intel’s developer support forums? Since you
are accessing a resource that is exposed by Intel’s chipset, you should
go ask them about it. It is POSSIBLE that they have already created an
API layer to allow access to these pins, or perhaps have a chunk of
sample code you can use.

Do you have a sample code ?

The work I did was on a contract to Intel, so I’m not free to release
it. I suspect the Intel forums are your best plan for now.

It seems Microsoft / Intel does not want users to access ACPI.

I’m not sure why the interface is not documented. I suppose no one has
taken the time to write the documentation.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Zvi Vered wrote:

Hi Tim,

In the following link:
download.microsoft.com/download/.../ACPIDriver_Vista.doc

I found the following structure:

typedef struct {

} ACPI_INTERFACE_STANDARD2, *PACPI_INTERFACE_STANDARD2;

Is this the structure I should get by calling to: “WdfFdoQueryForInterface
for GUID_ACPI_INTERFACE_STANDARD” ?

Yes. That’s defined in <wdm.h>.

> In your reply you wrote:
>
> Your ACPI BIOS has to put the “vector number” somewhere in the ACPI DSDT
> for your device. You have to call an ACPI method to fetch that “vector
> number,” so you know what to register. That in itself is tricky enough.
>
> What is the ACPI method I should call to fetch that “vector number” ?

That is up to your BIOS author, or whoever writes the DSDT. They will
have to have created a method in their DSDT that exposes this to you.
It really is a very tight partnership between you and the BIOS author.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</wdm.h>

Hi Tim,

Can you confirm the following prototypes ?


NTSTATUS GpeConnectVector (PDEVICE_OBJECT Context,
ULONG GpeNumber,
KINTERRUPT_MODE Mode,
BOOLEAN Shareable,
PGPE_SERVICE_ROUTINE ServiceRoutine,
PVOID ServiceContext,
PVOID ObjectContext)

NTSTATUS GpeEnableEvent ( PDEVICE_OBJECT Context, PVOID ObjectContext)

NTSTATUS GpeDiableEvent ( PDEVICE_OBJECT Context, PVOID ObjectContext)

NTSTATUS GpeClearStatus ( PDEVICE_OBJECT Context, PVOID ObjectContext)

NTSTATUS GpeDisconnectVector (PVOID ObjectContext)

GpeConnectVector returns (by reference) an ObjectContext. Am I right ?

What is “ServiceContext” ? How should I get it ?

Best regards,
Z.V

-----Original Message-----
From: Tim Roberts
Sent: Saturday, January 03, 2015 2:18 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WDF: Installing ISR for IRQ 9

Zvi Vered wrote:

Hi Tim,

In the following link:
download.microsoft.com/download/.../ACPIDriver_Vista.doc

I found the following structure:

typedef struct {

} ACPI_INTERFACE_STANDARD2, *PACPI_INTERFACE_STANDARD2;

Is this the structure I should get by calling to: “WdfFdoQueryForInterface
for GUID_ACPI_INTERFACE_STANDARD” ?

Yes. That’s defined in <wdm.h>.

> In your reply you wrote:
>
> Your ACPI BIOS has to put the “vector number” somewhere in the ACPI DSDT
> for your device. You have to call an ACPI method to fetch that “vector
> number,” so you know what to register. That in itself is tricky enough.
>
> What is the ACPI method I should call to fetch that “vector number” ?

That is up to your BIOS author, or whoever writes the DSDT. They will
have to have created a method in their DSDT that exposes this to you.
It really is a very tight partnership between you and the BIOS author.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</wdm.h>

Zvi Vered wrote:

Can you confirm the following prototypes ?

These all come straight out of <wdm.h>. You shouldn’t need confirmation.

> --------------------------------------------------------------------------------------------------------
> NTSTATUS GpeConnectVector (PDEVICE_OBJECT Context,
> ULONG GpeNumber,
> KINTERRUPT_MODE Mode,
> BOOLEAN Shareable,
> PGPE_SERVICE_ROUTINE ServiceRoutine,
> PVOID ServiceContext,
> PVOID ObjectContext)
> …
> GpeConnectVector returns (by reference) an ObjectContext. Am I right ?

Right, which you then pass to the other functions. All of its
parameters are inputs except for ObjectContext, which is an output.

> What is “ServiceContext” ? How should I get it ?

ServiceContext is whatever you want passed as the second parameter to
your ServiceRoutine. It’s just passed straight through. For a KMDF
driver, you would probably want to pass either your WDFDEVICE or your
primary device context.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</wdm.h>

This whole thread hurts my head.

Wisdom! Let us be attentive!!

Peter
OSR
@OSRDrivers

Hi Tim,

I asked Intel for information and got nothing.

You wrote me: “The work I did was on a contract to Intel, so I’m not free
to release”

Can I specify your name in Intel’s support and ask them for the work you did
?

Best regards,
Z.V

-----Original Message-----
From: xxxxx@osr.com
Sent: Wednesday, January 07, 2015 9:50 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] WDF: Installing ISR for IRQ 9

This whole thread hurts my head.

Wisdom! Let us be attentive!!

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Zvi Vered wrote:

I asked Intel for information and got nothing.

Who did you ask?

Look, here’s the thing. The kind of work you are attempting to do
cannot be done in a vacuum. You are working at the interface layer
between software, BIOS, and chipset, and you need the cooperation of all
three teams to make that happen. It’s just like trying to write to a
device with a register set – you need to know the intended usage. For
you to consume ACPI resources, you need to know that the ACPI BIOS has
made those resources available. The people who know that will have code
they’ve used to test that. If they don’t have code, then they didn’t
intend for the resource to be consumed.

You wrote me: “The work I did was on a contract to Intel, so I’m not free
to release”

Can I specify your name in Intel’s support and ask them for the work you did?

No. Intel has 100,000 employees working on just about that many
projects, most of which go into the trash can before they see the light
of day. The project I did is long gone, the people have been dispersed
to other projects. I doubt you could find anyone who could match the
project name to a repository.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Zvi Vered wrote:

I asked Intel for information and got nothing.

The project I was on was a USB device on the motherboard that used a
side-door signal that was routed to a GPIO pin. The ACPI record for the
USB device included a method called MSD_ that returned the GPE vector
number. So, after fetching the ACPI interface pointer, the first step
was to call IOCTL_ACPI_EVAL_METHOD to get that vector number. Allocate
an input and output buffer, fill the input buffer with the arguments for
the call. One of the argument is a GUID, which is embedded in the
BIOS. The ACPI spec describes how to figure out the GUID (page 643,
TOUUID function).

size_t AcpiInBufferSize = sizeof(ACPI_EVAL_INPUT_BUFFER_COMPLEX) +
4 * sizeof(ACPI_METHOD_ARGUMENT) + 16;
auto_ptr<acpi_eval_input_buffer_complex> pInputBuffer(
new char[AcpiInBufferSize]
);
if (!pInputBuffer)
return STATUS_INSUFFICIENT_RESOURCES;

size_t AcpiOutBufferSize = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 2
(sizeof(ACPI_METHOD_ARGUMENT)) + 1;
auto_ptr pOutputBuffer(
new char[AcpiOutBufferSize]
);
if (!pOutputBuffer)
return STATUS_INSUFFICIENT_RESOURCES;

pInputBuffer->Signature =
ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
pInputBuffer->MethodNameAsUlong = (ULONG)(‘MSD_’);
pInputBuffer->Size = sizeof(ACPI_METHOD_ARGUMENT);
pInputBuffer->ArgumentCount = 4;

// First Argument – the GUID.

PACPI_METHOD_ARGUMENT pargument = pInputBuffer->Argument;
ACPI_METHOD_SET_ARGUMENT_BUFFER(pargument, &UIDVALUE, 16);

// Second Argument – method number.

pargument = ACPI_METHOD_NEXT_ARGUMENT( pargument );
ACPI_METHOD_SET_ARGUMENT_INTEGER(pargument, 1);

// Third Argument – method parameter.

pargument = ACPI_METHOD_NEXT_ARGUMENT( pargument );
ACPI_METHOD_SET_ARGUMENT_INTEGER(pargument, DSMParameter);

// Fourth Argument.

pargument = ACPI_METHOD_NEXT_ARGUMENT( pargument );
pargument->Type = ACPI_METHOD_ARGUMENT_PACKAGE;
pargument->DataLength = 0;// Not used right now
RtlZeroMemory(pargument->Data, pargument->DataLength);

I then use WdfIoTargetSendIoctlSynchronously to pass those buffers to
IOCTL_ACPI_EVAL_METHOD. The result is stored in devExt->GpeVector.
Once I have that, I can register the GPE handler and enable the event:

// Register GPE handler.

status = devExt->ACPIInterface.GpeConnectVector (
devExt->ACPIPdo,
devExt->GpeVector,
Latched,
FALSE,
(PGPE_SERVICE_ROUTINE)&GpeHandler,
Device, // WDFDEVICE
&devExt->GpeVectorContext
);

devExt->ACPIInterface.GpeClearStatus(
devExt->ACPIPdo,
devExt->GpeVectorContext
);

devExt->ACPIInterface.GpeEnableEvent(
devExt->ACPIPdo,
devExt->GpeVectorContext
);

Then, in the handler, I have to disable the event to prevent an
interrupt storm.

BOOLEAN
GpeHandler(
IN PVOID AcpiContext,
IN WDFDEVICE Device
)
{
DEVICE_EXTENSION
pdx = GetDeviceContext(Device);
KdPrint(( FUNCTION" - Starts\n"));

pdx->ACPIInterface.GpeDisableEvent(
pdx->ACPIPdo,
pdx->GpeVectorContext
);

I then go handle the event. In this case, the signal remained asserted
until I read status from the device, so I couldn’t re-enable the event
until that had occurred. During D0Exit, I then have to disconnect
everything:

if( devExt->GpeVectorContext )
{
devExt->ACPIInterface.GpeDisableEvent(
devExt->ACPIPdo,
devExt->GpeVectorContext
);

devExt->ACPIInterface.GpeDisconnectVector(devExt->GpeVectorContext);

devExt->GpeVectorContext = NULL;
}


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</acpi_eval_input_buffer_complex>

Hi Tim,

Your help is highly appreciated.
Thank you for your time and effort.

Best regards,
Z.V

-----Original Message-----
From: Tim Roberts
Sent: Friday, January 09, 2015 8:47 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] WDF: Installing ISR for IRQ 9

Zvi Vered wrote:

I asked Intel for information and got nothing.

The project I was on was a USB device on the motherboard that used a
side-door signal that was routed to a GPIO pin. The ACPI record for the
USB device included a method called MSD_ that returned the GPE vector
number. So, after fetching the ACPI interface pointer, the first step
was to call IOCTL_ACPI_EVAL_METHOD to get that vector number. Allocate
an input and output buffer, fill the input buffer with the arguments for
the call. One of the argument is a GUID, which is embedded in the
BIOS. The ACPI spec describes how to figure out the GUID (page 643,
TOUUID function).

size_t AcpiInBufferSize = sizeof(ACPI_EVAL_INPUT_BUFFER_COMPLEX) +
4 * sizeof(ACPI_METHOD_ARGUMENT) + 16;
auto_ptr<acpi_eval_input_buffer_complex> pInputBuffer(
new char[AcpiInBufferSize]
);
if (!pInputBuffer)
return STATUS_INSUFFICIENT_RESOURCES;

size_t AcpiOutBufferSize = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 2
(sizeof(ACPI_METHOD_ARGUMENT)) + 1;
auto_ptr pOutputBuffer(
new char[AcpiOutBufferSize]
);
if (!pOutputBuffer)
return STATUS_INSUFFICIENT_RESOURCES;

pInputBuffer->Signature =
ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
pInputBuffer->MethodNameAsUlong = (ULONG)(‘MSD_’);
pInputBuffer->Size = sizeof(ACPI_METHOD_ARGUMENT);
pInputBuffer->ArgumentCount = 4;

// First Argument – the GUID.

PACPI_METHOD_ARGUMENT pargument = pInputBuffer->Argument;
ACPI_METHOD_SET_ARGUMENT_BUFFER(pargument, &UIDVALUE, 16);

// Second Argument – method number.

pargument = ACPI_METHOD_NEXT_ARGUMENT( pargument );
ACPI_METHOD_SET_ARGUMENT_INTEGER(pargument, 1);

// Third Argument – method parameter.

pargument = ACPI_METHOD_NEXT_ARGUMENT( pargument );
ACPI_METHOD_SET_ARGUMENT_INTEGER(pargument, DSMParameter);

// Fourth Argument.

pargument = ACPI_METHOD_NEXT_ARGUMENT( pargument );
pargument->Type = ACPI_METHOD_ARGUMENT_PACKAGE;
pargument->DataLength = 0;// Not used right now
RtlZeroMemory(pargument->Data, pargument->DataLength);

I then use WdfIoTargetSendIoctlSynchronously to pass those buffers to
IOCTL_ACPI_EVAL_METHOD. The result is stored in devExt->GpeVector.
Once I have that, I can register the GPE handler and enable the event:

// Register GPE handler.

status = devExt->ACPIInterface.GpeConnectVector (
devExt->ACPIPdo,
devExt->GpeVector,
Latched,
FALSE,
(PGPE_SERVICE_ROUTINE)&GpeHandler,
Device, // WDFDEVICE
&devExt->GpeVectorContext
);

devExt->ACPIInterface.GpeClearStatus(
devExt->ACPIPdo,
devExt->GpeVectorContext
);

devExt->ACPIInterface.GpeEnableEvent(
devExt->ACPIPdo,
devExt->GpeVectorContext
);

Then, in the handler, I have to disable the event to prevent an
interrupt storm.

BOOLEAN
GpeHandler(
IN PVOID AcpiContext,
IN WDFDEVICE Device
)
{
DEVICE_EXTENSION
pdx = GetDeviceContext(Device);
KdPrint(( FUNCTION" - Starts\n"));

pdx->ACPIInterface.GpeDisableEvent(
pdx->ACPIPdo,
pdx->GpeVectorContext
);

I then go handle the event. In this case, the signal remained asserted
until I read status from the device, so I couldn’t re-enable the event
until that had occurred. During D0Exit, I then have to disconnect
everything:

if( devExt->GpeVectorContext )
{
devExt->ACPIInterface.GpeDisableEvent(
devExt->ACPIPdo,
devExt->GpeVectorContext
);

devExt->ACPIInterface.GpeDisconnectVector(devExt->GpeVectorContext);

devExt->GpeVectorContext = NULL;
}


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</acpi_eval_input_buffer_complex>

If there’s a Gxd that rewards people in the next life for patiently answering all manner of strange technical questions in semi-anonymous internet forums… I’m pretty sure Mr. Roberts is in for a pretty terrific afterlife.

Peter
OSR
@OSRDrivers