📄 pnpmanagement.c
字号:
deviceDescription.IgnoreCount = FALSE;
deviceDescription.InterfaceType = PCIBus ;
deviceDescription.DmaWidth = Width32Bits ; //PCI default width
deviceDescription.DmaSpeed = Compatible ;
deviceDescription.MaximumLength = MAX_DMA_LENGTH ;
//get adapter object
pdx->AdapterObject = IoGetDmaAdapter(pdx->pPhysicalDeviceObject,&deviceDescription,
&pdx->MaximumMapRegisters) ;
DebugPrint("the # of map register system provide is:%u\n",pdx->MaximumMapRegisters);
// If IoGetDmaAdapter fails, it is mostly likely that one of the parameters
// supplied in the DEVICE_DESCRIPTION structure is not valid. It can also fail because of insufficient
// resource, but not very likely.
if (pdx->AdapterObject == NULL) {
DebugPrint ("Sil3124: IoGetDmaAdapter failed.\n") ;
status = STATUS_DEVICE_CONFIGURATION_ERROR ;
return status;
}
DebugPrint("Start Device Start.");
DebugPrint("the ResourceListRaw->count is %x\n",ResourceListRaw->Count);
for (i = 0,m = 0; i < ResourceListRaw->Count; ++i, ++Resource, ++ResourceRaw)
{
switch (ResourceRaw->Type)
{
case CmResourceTypePort: //IO Port Resource
DebugPrint("ResourceType:Registers that provide indirect access to the registers of sil3124");
pdx->BaseAddress_Indirect_Access = Resource->u.Port.Start;
pdx->IORangeBytes = Resource->u.Port.Length;
DebugPrint("Indirect Access Register base address : 0x%x\n",pdx->BaseAddress_Indirect_Access);
DebugPrint("Indirect Access register's length :%ubytes\n",pdx->IORangeBytes);
if(ResourceRaw->Flags & CM_RESOURCE_PORT_IO)
{
DebugPrint("The TaskFile register of channel#0 is accessed in IO address space");
}
else
{
DebugPrint("The TaskFile register of channel#0 is accessed in Memory address space");
}
break;
case CmResourceTypeMemory: //Memory Resources
DebugPrint("ResourceType:Memory Registers that provide access for Global Register and 4 PCI Ports ");
switch(m)
{
case 0: //Base Address 0 Global register base address
pdx->BaseAddress_GlobalRegister = Resource->u.Memory.Start;
pdx->GlobalRegisterBytes = Resource->u.Memory.Length;
DebugPrint("Global register base address : 0x%x\n",pdx->BaseAddress_GlobalRegister);
DebugPrint("Global register's length :%ubytes\n",pdx->GlobalRegisterBytes);
if(ResourceRaw->Flags == CM_RESOURCE_MEMORY_READ_WRITE)
{
DebugPrint("the global registers could be read & write");
}
else
{
DebugPrint("the global registers could be read OR write");
}
pdx->Map_GlobalRegister = NULL;
break;
case 1: //Base Address 1 Port register and LRAM base address for 4 ports
pdx->BaseAddress_PortRegister = Resource->u.Memory.Start;
pdx->PortRegisterBytes = Resource->u.Memory.Length;
DebugPrint("Port register base address : 0x%x\n",pdx->BaseAddress_PortRegister);
DebugPrint("Port register's length :%ubytes\n",pdx->PortRegisterBytes);
if(ResourceRaw->Flags & CM_RESOURCE_MEMORY_READ_WRITE)
{
DebugPrint("the Port registers could be read & write");
}
else
{
DebugPrint("the Port registers could be read OR write");
}
pdx->Map_PortRegister = NULL;
break;
}
m++;
break;
case CmResourceTypeInterrupt: //Interrupt Resources
pdx->GotInterrupt = TRUE;
pdx->IrqL = (KIRQL) Resource->u.Interrupt.Level;
pdx->vector = Resource->u.Interrupt.Vector;
pdx->affinity = Resource->u.Interrupt.Affinity;
DebugPrint("the Interrupt Flags:%x\n",ResourceRaw->Flags);
if (ResourceRaw->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
{
pdx->mode = Latched;
}
else
{
pdx->mode = LevelSensitive;
}
pdx->irqshare = Resource->ShareDisposition == CmResourceShareShared;
DebugPrint("ResouceType: Interrupt:Vector:0x%x(Translated=0x%x)",
ResourceRaw->u.Interrupt.Vector, pdx->vector);
DebugPrint(" IRQL:0x%x(Translated=0x%x)Affinity:0x%x(Translated=0x%x).",
ResourceRaw->u.Interrupt.Level, pdx->IrqL,
ResourceRaw->u.Interrupt.Affinity, pdx->affinity);
break;
default:
DebugPrint("Type: ?Unknown Resource Type?");
break;
}
}
//connect to interrupt
if (pdx->GotInterrupt)
{
DebugPrint("Get Interrupt.");
// firstly,Disable the PCI interrupt
//DisablePciInterrupt(pdx);
//connect interrupt
status = IoConnectInterrupt(&pdx->InterruptObject,(PKSERVICE_ROUTINE)OnInterrupt,
(PVOID)pdx,NULL,pdx->vector,pdx->IrqL,pdx->IrqL,pdx->mode,pdx->irqshare,pdx->affinity,FALSE);
if (!NT_SUCCESS(status))
{
pdx->InterruptObject = NULL;
return status;
}
DebugPrint("OK, I haved Connect Interruput!");
}
else
{
DebugPrint("Sil3124: No interrupt found.");
pdx->InterruptObject = NULL;
}
// Initialize DPC object
IoInitializeDpcRequest(fdo, DpcForIsr);
pdx->NeedToHandle =FALSE;
DebugPrint("Start Device end.");
pdx->GotResource = TRUE;
return STATUS_SUCCESS;
}
//StartDevice
/******************************************************************************
*
* Function : OnRequestComplete
*
* Description: Set an event when a lower driver complete an IRP.
*
******************************************************************************/
NTSTATUS OnRequestComplete(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp,
IN PKEVENT pKEvent)
{ //OnRequestComplete
KeSetEvent(pKEvent,(KPRIORITY)0,FALSE);
return(STATUS_MORE_PROCESSING_REQUIRED);
} //OnRequestComplete
/******************************************************************************
*
* Function : HandleStopDevice
*
* Description: Handle the IRP_MN_STOP_DEVICE PnP request
*
******************************************************************************/
NTSTATUS PnpStopDevice(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{
DebugPrintMsg("PnpStopDeviceHandler");
// Wait for I/O to complete and stop device
StopDevice(fdo);
return DefaultPnpHandler(fdo,pIrp);
} //HandleStopDevice
/******************************************************************************
*
* Function : StopDevice
*
* Description: Stop a device
*
******************************************************************************/
VOID StopDevice(IN PDEVICE_OBJECT fdo)
{ //StopDevice
DEVICE_EXTENSION *pdx;
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
if (!pdx->GotResource)
return;
pdx->bStopping = TRUE;
DebugPrintMsg("StopDevice");
if( !pdx->GotResource)
return;
pdx->GotResource = FALSE;
} //StopDevice
/////////////////////////////////////////////////////////////////////////////
// PnpQueryRemoveDeviceHandler: Handle PnP query remove device
NTSTATUS PnpQueryRemoveDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
DebugPrintMsg("PnpQueryRemoveDeviceHandler");
if( pdx->OpenHandleCount>0)
{
DebugPrint("PnpQueryRemoveDeviceHandler: %d handles still open",pdx->OpenHandleCount);
return CompleteRequestInfo( Irp, STATUS_UNSUCCESSFUL, 0);
}
return DefaultPnpHandler(fdo,Irp);
}
/******************************************************************************
*
* Function : PnpRemoveDevice
*
* Description: Handle the IRP_MN_REMOVE_DEVICE PnP request
*
******************************************************************************/
NTSTATUS PnpRemoveDevice(IN PDEVICE_OBJECT fdo,
IN PIRP pIrp)
{ //HandleRemoveDevice
NTSTATUS status;
DEVICE_EXTENSION *pdx;
// Wait for any pending I/O operations to complete
pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS; // flag that we handled this IRP
DebugPrintMsg("call StopDevice");
StopDevice(fdo);
// disconnect the interrupt
if (pdx->InterruptObject != NULL)
{
// KeSynchronizeExecution(pdx->pInterruptObject,
// (PKSYNCHRONIZE_ROUTINE)DisablePciInterrupt,(PVOID)pdx);
IoDisconnectInterrupt(pdx->InterruptObject);
pdx->InterruptObject = NULL;
}
// free the adapter object
if(pdx->AdapterObject!=NULL)
{
(pdx->AdapterObject->DmaOperations->PutDmaAdapter)(pdx->AdapterObject);
pdx->AdapterObject = NULL;
}
// Let lower-level drivers handle this request & ignore the result
status = DefaultPnpHandler(fdo,pIrp);
IoSetDeviceInterfaceState(&pdx->InterfaceName, FALSE);
RtlFreeUnicodeString(&pdx->InterfaceName);
DebugPrint("the InterfaceName has been free");
// Detach device from the device object stack
if (pdx->pLowerDeviceObject)
{
IoDetachDevice(pdx->pLowerDeviceObject);
}
DebugPrint("Sil3124: Deleting device object...");
// Delete the functional device object
IoDeleteDevice(fdo);
DebugPrint("Sil3124 is removed.");
return status;
} //HandleRemoveDevice
/////////////////////////////////////////////////////////////////////////////
// PnpQueryCapabilitiesHandler: Print pdo device capabilities
#define SetMostPoweredState( SystemState, OurDeviceState) \
dps = deviceCapabilities->DeviceState[SystemState]; \
if( dps==PowerDeviceUnspecified || dps>OurDeviceState) \
deviceCapabilities->DeviceState[SystemState] = OurDeviceState
NTSTATUS PnpQueryCapabilitiesHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
NTSTATUS status = ForwardAndWait( fdo, Irp);
int ds;
DEVICE_POWER_STATE dps;
if( NT_SUCCESS(status))
{
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_CAPABILITIES deviceCapabilities;
deviceCapabilities = IrpStack->Parameters.DeviceCapabilities.Capabilities;
#if DBG
for(ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++)
DebugPrint("Capabilities from bus: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds]);
#endif
SetMostPoweredState( PowerSystemWorking, PowerDeviceD0);
SetMostPoweredState( PowerSystemSleeping1, PowerDeviceD3);
SetMostPoweredState( PowerSystemSleeping2, PowerDeviceD3);
SetMostPoweredState( PowerSystemSleeping3, PowerDeviceD3);
SetMostPoweredState( PowerSystemHibernate, PowerDeviceD3);
SetMostPoweredState( PowerSystemShutdown, PowerDeviceD3);
#if DBG
for(ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++)
DebugPrint("Capabilities now: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds]);
#endif
}
return CompleteRequestInfo( Irp, status, Irp->IoStatus.Information);
}
/******************************************************************************
*
* Function : ForwardAndWait
*
* Description: Forward request to lower level and await completion, used
* in PnP's IRP_MN_START_DEVICE
*
******************************************************************************/
#pragma code_seg() // end PAGE section
NTSTATUS ForwardAndWait(PDEVICE_OBJECT fdo,PIRP pIrp)
{ // ForwardAndWait
KEVENT event;
NTSTATUS status;
// Initialize a kernel event object to use in waiting for the lower-level
// driver to finish processing the object.
KeInitializeEvent(&event,NotificationEvent,FALSE);
DebugPrint("ForwardAndWait Start.");
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(pIrp,(PIO_COMPLETION_ROUTINE) OnRequestComplete,
(PVOID) &event,TRUE,TRUE,TRUE);
status = IoCallDriver(
((DEVICE_EXTENSION *) fdo->DeviceExtension)->pLowerDeviceObject,
pIrp);
if (status == STATUS_PENDING)
{
// Wait for completion
DebugPrintMsg("ForwardIrpAndWait: waiting for completion");
KeWaitForSingleObject((PVOID)&event,Executive,KernelMode,FALSE,NULL);
return pIrp->IoStatus.Status;
}
DebugPrint("ForwardAndWait End.");
return(pIrp->IoStatus.Status); //status;
} // ForwardAndWait
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -