hi All:
I am porting a 32bit driver to windows 64 bit platform, my drivers is
tow parts, one is a pcmcia ata driver for accessing media; the other is a
filter driver for handling s1 s3 s4 power status, which is hook on pcmica
bus drivers and my function driver.
my drivers works well on windows xp 32 bit, but system resuming from
hibernating(s4), sometimes after cover the progress of resuming, the system
is hung.I traced my drivers, found that, after filter driver calling
IoCallDriver, the system is hung.
the following source code is for reading/writing register instead of
HalGetBusData or HalGetBusOffset which are obsolete.
ULONG ReadDWord( PDEVICE_OBJECT DeviceObject,
USHORT Offset )
{
ULONG RawData = 0;
MBXConfigRegisterBufferRead( DeviceObject, &RawData,
Offset&0xFC, sizeof(ULONG) );
return RawData;
}
NTSTATUS MBXConfigRegisterBufferRead(
PDEVICE_OBJECT DeviceObject, // target device object
PVOID buffer, //the read buffer
ULONG offset, //buffer offset
ULONG Length //the length of buffer
)
{
PIRP pIrp = NULL;
KEVENT event;
NTSTATUS status;
PIO_STACK_LOCATION stack = NULL;
PDEVICE_OBJECT AttachedPDO = NULL;
IO_STATUS_BLOCK ioSattus;
PDEVICE_EXTENSION pdx = NULL ;
ULONG Transferred;
pdx =(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
KdPrint((" Enter MBXConfigRegisterBufferRead \n"));
if( KeGetCurrentIrql() < DISPATCH_LEVEL )
{
KdPrint(("KeGetCurrentIrql() < DISPATCH_LEVEL\n"));
RtlZeroMemory( buffer,Length);
KeInitializeEvent( &event, NotificationEvent, FALSE );
//
//get the pdo of function 0!
//
AttachedPDO = pdx->NextLowerDriver;//LowerDeviceObject;
if( NULL == AttachedPDO )
{
KdPrint(("Error! The AttachedPDO is NULL"));
return STATUS_UNSUCCESSFUL;
}
//
//allocate a irp for next stack.
//
KdPrint(("Begin to build IRP \n"));
pIrp = IoBuildSynchronousFsdRequest (
IRP_MJ_PNP,
AttachedPDO,
NULL,
0,
NULL,
&event,
&ioSattus
);
if ( pIrp == NULL )
{
KdPrint(("Failed to build IRP \n"));
return( STATUS_INSUFFICIENT_RESOURCES );
}
//get the next pci stack!
stack = IoGetNextIrpStackLocation( pIrp );
// Fill the IRP
pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
stack->MajorFunction = IRP_MJ_PNP;
stack->MinorFunction = IRP_MN_READ_CONFIG;
stack->Parameters.ReadWriteConfig.WhichSpace = 0;
stack->Parameters.ReadWriteConfig.Buffer = buffer;
stack->Parameters.ReadWriteConfig.Offset = offset;
stack->Parameters.ReadWriteConfig.Length = Length;
//
// this step will call the function 0 of pcmcia bus driver.
//
KdPrint(("Begin to send IRP \n"));
status = IoCallDriver( AttachedPDO, pIrp );
KdPrint(("Have sent IRP \n"));
if(!NT_SUCCESS(status))
{
KdPrint(("iocaller failed!"));
}
if (status == STATUS_PENDING)
{
// Wait for completion
KdPrint(("Wait the IRP completion \n"));
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE,
NULL );
status = pIrp->IoStatus.Status;
}
KdPrint(("Read %x = %x\n",offset, *((PULONG)buffer)));
}
else
{
//irp level>=dispatch_level
KdPrint(("KeGetCurrentIrql() >= DISPATCH_LEVEL \n"));
Transferred = pdx->BusInterfaceStandard.GetBusData(
pdx->BusInterfaceStandard.Context,
PCI_WHICHSPACE_CONFIG,
buffer,
offset,
Length
);
KdPrint(("Read %x = %x\n",offset, *((PULONG)buffer)));
if( Transferred == Length )
{
KdPrint(("KeGetCurrentIrql() = DISPATCH_LEVEL---success\n"));
status = STATUS_SUCCESS;
}
else
{
KdPrint(("KeGetCurrentIrql() = DISPATCH_LEVEL---failed\n"));
status = STATUS_UNSUCCESSFUL;
}
}
KdPrint((" Exit MBXConfigRegisterBufferRead\n"));
return status;
}
thanks
best regards
Leon