阅读:1476回复:0
Bulk传输时KeWaitForSingleObject不返回,怎样断定是硬件还是驱动的问题?
我公司现在承接了一个由别的公司开发的手机的USB HOST驱动软件的修改业务.但是现在在测试PAKET传输时发现了以下问题.从应用软件向手机分10次传输PACKET数据时,在数次传输成功后中间失败.失败时应用软件上的数据送出后没有回应.
我在驱动程序里用DebugPrint查到在Bulk传输函数调用下层系统驱动后等待回应时因为没有回应而死等.用USB PROTCOL ANALYZER来测试时,发现传输失败时数据没有被传输到设备里.我不知道在这种情况下问题到底出在哪里.但只有下面的3种可能性. 1.应用软件有问题 2.驱动里有虫 3.设备的硬件问题 但从以上的现象来看,好象可以排除3,因为在失败时数据没有被传输到设备里.感觉可能性最大的是2,因为是调用下层系统驱动时出的问题.我以前从没开发过驱动,请大家原谅我说外行话.等待调用下层系统驱动后没有回应时一般采用什么方法来判断问题所在?我试了设定TIMEOUT,但是没有效果,应用软件还是没有回应. 请各位大侠指点捉虫方法. 附上Bulk传输程序代码和DebugPrint的显示结果. #pragma code_seg() // LOCKEDCODE NTSTATUS CallUSBDI3a(IN POMTUSB_POLLING_BUF pollingBuf, IN PVOID UrbEtc, IN ULONG TimeOut) { IO_STATUS_BLOCK IoStatus ; KEVENT event ; DebugPrintMsg(\" CallUSBDI3a() : Start\") ; BOOLEAN IrqlDown = FALSE ; KIRQL kirql = KeGetCurrentIrql() ; DebugPrint(\" CallUSBDI3a() : kirql = %d\", kirql) ; PDEVICE_OBJECT fdo = (PDEVICE_OBJECT)(pollingBuf->fdo) ; POMTUSB_DEVICE_EXTENSION dx = (POMTUSB_DEVICE_EXTENSION)(fdo->DeviceExtension) ; KeInitializeEvent(&event, NotificationEvent, FALSE) ; if(kirql > PASSIVE_LEVEL) { DebugPrintMsg(\" CallUSBDI3a() : kirql > PASSIVE_LEVEL, Next to Call KeLowerIqrl()\"); KeLowerIrql(PASSIVE_LEVEL) ; IrqlDown = TRUE ; DebugPrintMsg(\" CallUSBDI3a() : kirql > PASSIVE_LEVEL, KeLowerIqrl() has been called\"); } else { DebugPrint(\" CallUSBDI3a() : kirql <= PASSIVE_LEVEL, PASSIVE_LEVEL = %d\", PASSIVE_LEVEL); } // Build Internal IOCTL IRP PIRP Irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, dx->NextStackDevice, NULL, 0, // Input buffer NULL, 0, // Output buffer TRUE, &event, &IoStatus) ; DebugPrintMsg(\" CallUSBDI3a() : IoBuildDeviceIoControlRequest() has been called\"); if(Irp == NULL) { if(IrqlDown == TRUE) { KIRQL DummyIrql ; KeRaiseIrql(kirql, &DummyIrql) ; DebugPrint(\" CallUSBDI3a() : KeRaiseIrql() has been called, kirql = %x\", kirql) ; } DebugPrintMsg(\" CallUSBDI3a() : Irp == NULL, No IRP memory\") ; return STATUS_INSUFFICIENT_RESOURCES ; } else { DebugPrintMsg(\" CallUSBDI3a() : Irp != NULL\") ; } PIO_STACK_LOCATION NextIrpStack = IoGetNextIrpStackLocation(Irp) ; // Store pointer to the URB etc NextIrpStack->Parameters.Others.Argument1 = UrbEtc ; IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)ForwardedIrpCompletionRoutine , (PVOID)&event, TRUE, TRUE, TRUE) ; DebugPrintMsg(\" CallUSBDI3a() : IoSetCompletionRoutine() has been called\") ; pollingBuf->waitingIrp = Irp ; LARGE_INTEGER WkTimeOut ; if(TimeOut != NULL) { WkTimeOut.QuadPart = (LONGLONG)TimeOut * (LONGLONG)(-10000i64) ; DebugPrint(\" CallUSBDI3a() : TimeOut != NULL, TimeOut = %L, WkTimeOut = %L\", TimeOut, WkTimeOut.QuadPart) ; } else { DebugPrintMsg(\" CallUSBDI3a() : TimeOut == NULL\") ; } // Call the driver and wait for completion if necessary NTSTATUS status = IoCallDriver(dx->NextStackDevice, Irp) ; DebugPrintMsg(\" CallUSBDI3a() : IoCallDriver() has been called\") ; if(status == STATUS_PENDING) { DebugPrint(\" CallUSBDI3a() : status == STATUS_PENDING, status = %x\", status) ; if(TimeOut != NULL) { DebugPrintMsg(\" CallUSBDI3a() : TimeOut != NULL, Next to call KeWaitForSingleObject()\") ; status = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, &WkTimeOut) ; DebugPrintMsg(\" CallUSBDI3a() : TimeOut != NULL, KeWaitForSingleObject() has been called\") ; } else { DebugPrintMsg(\" CallUSBDI3a() : TimeOut == NULL, Next to call KeWaitForSingleObject()\") ; status = KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL) ; DebugPrintMsg(\" CallUSBDI3a() : TimeOut == NULL, KeWaitForSingleObject() has been called\") ; } if(status == STATUS_TIMEOUT) { DebugPrintMsg(\" CallUSBDI3a() : status == STATUS_TIMEOUT\") ; BOOLEAN ret = IoCancelIrp(Irp) ; KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL) ; } else { DebugPrintMsg(\" CallUSBDI3a() : status != STATUS_TIMEOUT\") ; } } else { DebugPrint(\" CallUSBDI3a() : status == STATUS_SUCCESS, status = %x\", status) ; IoStatus.Status = status ; } pollingBuf->waitingIrp = NULL ; KeClearEvent(&event) ; DebugPrintMsg(\" CallUSBDI3a() : KeClearEvent() has been called\") ; IoCompleteRequest(Irp, IO_NO_INCREMENT) ; DebugPrintMsg(\" CallUSBDI3a() : IoCompleteRequest() has been called\") ; KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL) ; status = IoStatus.Status ; if(IrqlDown == TRUE) { KIRQL DummyIrql ; KeRaiseIrql(kirql, &DummyIrql) ; } // return IRP completion status DebugPrint(\" CallUSBDI3a() returned %x\", status) ; DebugPrintMsg(\" CallUSBDI3a() : End\") ; return status ; } |
|