阅读:1658回复:0
一个很奇怪的问题,各位高手请进, 送100分。
我正在port我们公司一个读卡器driver到Windows XP 64bit上,其中有一个filter driver,当S1或S3,或者S4回来时候,用来保存和配置一些寄存器的。我们的读卡器是被看作一个PCMCIA上的一个ATA device,
这个filter driver被加载到两个PCMCIA和读卡器driver上。 filter driver主要做的事情就是,在处理IRP_MJ_POWER时候,读写一些寄存器的。 在访问寄存器的时候,我用了WDM方式去访问,就是自己发送IRP去做。在Windows XP 32bit下,工作的很好,但是在64bit,电脑S4(休眠)回来后,有时侯会停在那里(进度条刚走完)死机,但不蓝屏。下面是我访问寄存器的代码: 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; } 在Windows 64bit 下,当从s4状态回来后,有时候call完 IoCallDriver后,系统就停在那里了。是把IRP发送到下层device driver后,下层driver在处理我发送的IRP出问题了,因为没有打印出Have sent IRP! 我一直都不知道其中的原因,因为在32bit没有问题,在64bit下,S1和S3状态下回来也没有什么问题。 有哪位高手可以指点下啊,谢谢。 |
|
|