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.
390 lines
9.2 KiB
390 lines
9.2 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
processor.c
|
|
|
|
Abstract:
|
|
|
|
Processor support
|
|
|
|
Author:
|
|
|
|
Stephane Plante (splante)
|
|
|
|
Environment:
|
|
|
|
NT Kernel Model Driver only
|
|
|
|
Revision History:
|
|
|
|
Adapted for processors from buttons - JakeO (3-28-2000)
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "..\shared\acpictl.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, ACPIButtonStartDevice)
|
|
#endif
|
|
|
|
//
|
|
// Spinlock to protect the processor list
|
|
//
|
|
KSPIN_LOCK AcpiProcessorLock;
|
|
|
|
//
|
|
// List entry to store the thermal requests on
|
|
//
|
|
LIST_ENTRY AcpiProcessorList;
|
|
|
|
|
|
VOID
|
|
ACPIProcessorCancelRequest(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine cancels an outstanding processor request
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - the device which as a request being cancelled
|
|
Irp - the cancelling irp
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
KIRQL oldIrql;
|
|
PDEVICE_EXTENSION deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
|
|
|
|
//
|
|
// We no longer need the cancel lock
|
|
//
|
|
IoReleaseCancelSpinLock( Irp->CancelIrql );
|
|
|
|
//
|
|
// We do however need the processor queue lock
|
|
//
|
|
KeAcquireSpinLock( &AcpiProcessorLock, &oldIrql );
|
|
|
|
//
|
|
// Remove the irp from the list that it is on
|
|
//
|
|
RemoveEntryList( &(Irp->Tail.Overlay.ListEntry) );
|
|
|
|
//
|
|
// Complete the irp now
|
|
//
|
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
|
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
|
}
|
|
|
|
BOOLEAN
|
|
ACPIProcessorCompletePendingIrps(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN ULONG ProcessorEvent
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine completes any pending processor irp sent to the specified
|
|
device object with the knowledge of which processor events have occured
|
|
|
|
The respective's processor's spinlock is held during this call
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - the target processor object
|
|
ProcessorEvent - the processor event that occured
|
|
|
|
Return Value:
|
|
|
|
TRUE if we completed an irp, FALSE, otherwise
|
|
|
|
--*/
|
|
{
|
|
BOOLEAN handledRequest = FALSE;
|
|
KIRQL oldIrql;
|
|
LIST_ENTRY doneList;
|
|
PDEVICE_OBJECT targetObject;
|
|
PIO_STACK_LOCATION irpSp;
|
|
PIRP irp;
|
|
PLIST_ENTRY listEntry;
|
|
PULONG resultBuffer;
|
|
|
|
//
|
|
// Initialize the list that will hold the requests that we need to
|
|
// complete
|
|
//
|
|
InitializeListHead( &doneList );
|
|
|
|
//
|
|
// Acquire the thermal lock so that we can pend these requests
|
|
//
|
|
KeAcquireSpinLock( &AcpiProcessorLock, &oldIrql );
|
|
|
|
//
|
|
// Walk the list of pending irps to see which ones match this extension
|
|
//
|
|
listEntry = AcpiProcessorList.Flink;
|
|
while (listEntry != &AcpiProcessorList) {
|
|
|
|
//
|
|
// Grab the irp from the list entry and update the next list entry
|
|
// that we will look at
|
|
//
|
|
irp = CONTAINING_RECORD( listEntry, IRP, Tail.Overlay.ListEntry );
|
|
listEntry = listEntry->Flink;
|
|
|
|
//
|
|
// We need the current irp stack location
|
|
//
|
|
irpSp = IoGetCurrentIrpStackLocation( irp );
|
|
|
|
//
|
|
// what is the target object for this irp?
|
|
//
|
|
targetObject = irpSp->DeviceObject;
|
|
|
|
//
|
|
// Is this an irp that we care about? IE: does the does target mage
|
|
// the ones specified in this function
|
|
//
|
|
if (targetObject != DeviceObject) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//
|
|
// At this point, we need to set the cancel routine to NULL because
|
|
// we are going to take care of this irp and we don't want it cancelled
|
|
// underneath us
|
|
//
|
|
if (IoSetCancelRoutine(irp, NULL) == NULL) {
|
|
|
|
//
|
|
// Cancel routine is active. stop processing this irp and move on
|
|
//
|
|
continue;
|
|
|
|
}
|
|
|
|
//
|
|
// set the data to return in the irp
|
|
//
|
|
resultBuffer = (PULONG) irp->AssociatedIrp.SystemBuffer;
|
|
*resultBuffer = ProcessorEvent;
|
|
irp->IoStatus.Status = STATUS_SUCCESS;
|
|
irp->IoStatus.Information = sizeof(ULONG);
|
|
|
|
//
|
|
// Remove the entry from the list
|
|
//
|
|
RemoveEntryList( &(irp->Tail.Overlay.ListEntry) );
|
|
|
|
//
|
|
// Insert the list onto the next queue, so that we know how to
|
|
// complete it later on
|
|
//
|
|
InsertTailList( &doneList, &(irp->Tail.Overlay.ListEntry) );
|
|
|
|
}
|
|
|
|
//
|
|
// At this point, droup our processor lock
|
|
//
|
|
KeReleaseSpinLock( &AcpiProcessorLock, oldIrql );
|
|
|
|
//
|
|
// Walk the list of irps to be completed
|
|
//
|
|
listEntry = doneList.Flink;
|
|
while (listEntry != &doneList) {
|
|
|
|
//
|
|
// Grab the irp from the list entry, update the next list entry
|
|
// that we will look at, and complete the request
|
|
//
|
|
irp = CONTAINING_RECORD( listEntry, IRP, Tail.Overlay.ListEntry );
|
|
listEntry = listEntry->Flink;
|
|
RemoveEntryList( &(irp->Tail.Overlay.ListEntry) );
|
|
|
|
//
|
|
// Complete the request and remember that we handled a request
|
|
//
|
|
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
|
handledRequest = TRUE;
|
|
|
|
|
|
}
|
|
|
|
//
|
|
// Return wether or not we handled a request
|
|
//
|
|
return handledRequest;
|
|
}
|
|
|
|
NTSTATUS
|
|
ACPIProcessorDeviceControl (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Fixed processor device IOCTL handler
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - fixed feature processor device object
|
|
Irp - the ioctl request
|
|
|
|
Return Value:
|
|
|
|
Status
|
|
|
|
--*/
|
|
{
|
|
KIRQL oldIrql;
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
|
|
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
PULONG resultBuffer;
|
|
OBJDATA data;
|
|
|
|
//
|
|
// Do not allow user mode IRPs in this routine
|
|
//
|
|
if (Irp->RequestorMode != KernelMode) {
|
|
|
|
return ACPIDispatchIrpInvalid( DeviceObject, Irp );
|
|
|
|
}
|
|
|
|
resultBuffer = (PULONG) Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
|
|
case IOCTL_GET_PROCESSOR_OBJ_INFO:
|
|
|
|
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(IOCTL_GET_PROCESSOR_OBJ_INFO)) {
|
|
|
|
Irp->IoStatus.Status = status = STATUS_INFO_LENGTH_MISMATCH;
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
} else {
|
|
|
|
status = AMLIEvalNameSpaceObject(deviceExtension->AcpiObject,
|
|
&data,
|
|
0,
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
ASSERT (data.dwDataType == OBJTYPE_PROCESSOR);
|
|
ASSERT (data.pbDataBuff != NULL);
|
|
|
|
(*(PPROCESSOR_OBJECT_INFO)resultBuffer).PhysicalID =
|
|
((PROCESSOROBJ *)data.pbDataBuff)->bApicID;
|
|
|
|
(*(PPROCESSOR_OBJECT_INFO)resultBuffer).PBlkAddress =
|
|
((PROCESSOROBJ *)data.pbDataBuff)->dwPBlk;
|
|
|
|
(*(PPROCESSOR_OBJECT_INFO)resultBuffer).PBlkLength =
|
|
(UCHAR)((PROCESSOROBJ *)data.pbDataBuff)->dwPBlkLen;
|
|
|
|
AMLIFreeDataBuffs(&data, 1);
|
|
|
|
status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = sizeof(PROCESSOR_OBJECT_INFO);
|
|
|
|
}
|
|
|
|
Irp->IoStatus.Status = status;
|
|
}
|
|
|
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
|
break;
|
|
|
|
case IOCTL_ACPI_ASYNC_EVAL_METHOD:
|
|
|
|
//
|
|
// Handle this elsewhere
|
|
//
|
|
status = ACPIIoctlAsyncEvalControlMethod(
|
|
DeviceObject,
|
|
Irp,
|
|
irpSp
|
|
);
|
|
break;
|
|
|
|
case IOCTL_ACPI_EVAL_METHOD:
|
|
|
|
//
|
|
// Handle this elsewhere
|
|
//
|
|
status = ACPIIoctlEvalControlMethod(
|
|
DeviceObject,
|
|
Irp,
|
|
irpSp
|
|
);
|
|
break;
|
|
|
|
default:
|
|
|
|
status = STATUS_NOT_SUPPORTED;
|
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS
|
|
ACPIProcessorStartDevice (
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Start device function for the fixed feature power and sleep device
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - fixed feature processor device object
|
|
Irp - the start request
|
|
|
|
Return Value:
|
|
|
|
Status
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = ACPIInternalSetDeviceInterface (
|
|
DeviceObject,
|
|
(LPGUID) &GUID_DEVICE_PROCESSOR
|
|
);
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
|
return Status;
|
|
|
|
}
|