You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
3.5 KiB
158 lines
3.5 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
interrupt.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the functions for handling simulated interrupts
|
|
to the hotplug controller.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
Davis Walker (dwalker) Sept 6 2000
|
|
|
|
--*/
|
|
|
|
#include "hpsp.h"
|
|
|
|
BOOLEAN HpsInterruptPending = FALSE;
|
|
|
|
VOID
|
|
HpsInterruptExecution(
|
|
IN PHPS_DEVICE_EXTENSION Extension
|
|
)
|
|
{
|
|
KIRQL oldIrql;
|
|
|
|
HpsInterruptPending = TRUE;
|
|
|
|
oldIrql = KeGetCurrentIrql();
|
|
if (oldIrql >= PROFILE_LEVEL-1) {
|
|
//
|
|
// These interrupts are currently masked. This will
|
|
// only happen because we are in HpsSynchronizeExecution.
|
|
// So set a flag indicating that there is a pending interrupt
|
|
// so that SynchronizeExecution will execute the ISR.
|
|
//
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
HpsInterruptPending = FALSE;
|
|
|
|
KeRaiseIrql(PROFILE_LEVEL-1,
|
|
&oldIrql
|
|
);
|
|
|
|
KeAcquireSpinLockAtDpcLevel(&Extension->IntSpinLock);
|
|
|
|
Extension->IntServiceRoutine((PKINTERRUPT)Extension,
|
|
Extension->IntServiceContext
|
|
);
|
|
|
|
KeReleaseSpinLockFromDpcLevel(&Extension->IntSpinLock);
|
|
|
|
KeLowerIrql(oldIrql);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Interrupt Interface Functions
|
|
//
|
|
|
|
|
|
NTSTATUS
|
|
HpsConnectInterrupt(
|
|
IN PVOID Context,
|
|
IN PKSERVICE_ROUTINE ServiceRoutine,
|
|
IN PVOID ServiceContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the hps version of IoConnectInterrupt. It has the same
|
|
semantics and is called in the same situations. This is called by the
|
|
SHPC driver to register an ISR with the simulator so that the SHPC driver
|
|
can receive simulated interrupts.
|
|
|
|
Arguments:
|
|
|
|
ServiceRoutine - A pointer to the ISR
|
|
|
|
ServiceContext - The context with which this routine is called. In this
|
|
case, it is a device extension.
|
|
|
|
The rest of the arguments are ignored.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS
|
|
|
|
--*/
|
|
{
|
|
PHPS_DEVICE_EXTENSION deviceExtension;
|
|
|
|
deviceExtension = (PHPS_DEVICE_EXTENSION) Context;
|
|
deviceExtension->IntServiceRoutine = ServiceRoutine;
|
|
deviceExtension->IntServiceContext = ServiceContext;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
HpsDisconnectInterrupt(
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
PHPS_DEVICE_EXTENSION deviceExtension = (PHPS_DEVICE_EXTENSION)Context;
|
|
|
|
deviceExtension->IntServiceRoutine = NULL;
|
|
deviceExtension->IntServiceContext = NULL;
|
|
}
|
|
|
|
BOOLEAN
|
|
HpsSynchronizeExecution(
|
|
IN PVOID Context,
|
|
IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
|
|
IN PVOID SynchronizeContext
|
|
)
|
|
{
|
|
PHPS_DEVICE_EXTENSION Extension = (PHPS_DEVICE_EXTENSION)Context;
|
|
KIRQL oldIrql;
|
|
|
|
KeRaiseIrql(PROFILE_LEVEL-1,
|
|
&oldIrql
|
|
);
|
|
|
|
KeAcquireSpinLockAtDpcLevel(&Extension->IntSpinLock);
|
|
|
|
SynchronizeRoutine(SynchronizeContext);
|
|
|
|
//
|
|
// If there's a pending interrupt, it gets serviced at this
|
|
// IRQL as well, so call it.
|
|
//
|
|
if (HpsInterruptPending) {
|
|
HpsInterruptPending = FALSE;
|
|
Extension->IntServiceRoutine((PKINTERRUPT)Extension,
|
|
Extension->IntServiceContext
|
|
);
|
|
}
|
|
|
|
KeReleaseSpinLockFromDpcLevel(&Extension->IntSpinLock);
|
|
|
|
KeLowerIrql(oldIrql);
|
|
|
|
return TRUE;
|
|
}
|