阅读:2290回复:6
为什么驱动只能Write两次?(内详)
我模仿WDK中的例子usbsamp改了个USB设备的驱动,发现在应用程序中通过WriteFile写数据时,前两次都是可以成功的,第三次应用程序就感觉想进入了死循环,没有响应了,请教这可能是哪里出了问题?下面是驱动中读写Bulk端点的代码,谢谢!
VOID ReadWriteBulkEndPoints( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG Length, IN WDF_REQUEST_TYPE RequestType ) { size_t totalLength = Length; size_t stageLength = 0; NTSTATUS status; PVOID virtualAddress = 0; PREQUEST_CONTEXT rwContext = NULL; PFILE_CONTEXT fileContext = NULL; WDFUSBPIPE pipe; WDFMEMORY reqMemory; WDFMEMORY_OFFSET offset; WDF_OBJECT_ATTRIBUTES objectAttribs; PDEVICE_CONTEXT deviceContext; UsbGateway_DbgPrint(3, ("UsbGateway_Dispatch ReadWrite - begins\n")); // // First validate input parameters. // deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); if (totalLength > deviceContext->MaximumTransferSize) { UsbGateway_DbgPrint(1, ("Transfer length > circular buffer\n")); status = STATUS_INVALID_PARAMETER; goto Exit; } if ((RequestType != WdfRequestTypeRead) && (RequestType != WdfRequestTypeWrite)) { UsbGateway_DbgPrint(1, ("RequestType has to be either Read or Write\n")); status = STATUS_INVALID_PARAMETER; goto Exit; } // // Get the pipe associate with this request. // fileContext = GetFileContext(WdfRequestGetFileObject(Request)); pipe = fileContext->Pipe; rwContext = GetRequestContext(Request); if(RequestType == WdfRequestTypeRead) { status = WdfRequestRetrieveOutputBuffer(Request, Length, &virtualAddress, &totalLength); rwContext->Read = TRUE; } else { //Write status = WdfRequestRetrieveInputBuffer(Request, Length, &virtualAddress, &totalLength); rwContext->Read = FALSE; } if(!NT_SUCCESS(status)){ UsbGateway_DbgPrint(1, ("WdfRequestRetrieveInputBuffer failed\n")); goto Exit; } // // If the totalLength exceeds MAX_TRANSFER_SIZE, we will break // that into multiple transfer of size no more than MAX_TRANSFER_SIZE // in each stage. // if (totalLength > MAX_TRANSFER_SIZE) { stageLength = MAX_TRANSFER_SIZE; } else { stageLength = totalLength; } WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs); objectAttribs.ParentObject = Request; status = WdfMemoryCreatePreallocated(&objectAttribs, virtualAddress, totalLength, &reqMemory); if(!NT_SUCCESS(status)){ UsbGateway_DbgPrint(1, ("WdfMemoryCreatePreallocated failed\n")); goto Exit; } offset.BufferOffset = 0; offset.BufferLength = stageLength; // // The framework format call validates to make sure that you are reading or // writing to the right pipe type, sets the appropriate transfer flags, // creates an URB and initializes the request. // if(RequestType == WdfRequestTypeRead) { UsbGateway_DbgPrint(3, ("Read operation\n")); status = WdfUsbTargetPipeFormatRequestForRead(pipe, Request, reqMemory, &offset); } else { UsbGateway_DbgPrint(3, ("Write operation\n")); status = WdfUsbTargetPipeFormatRequestForWrite(pipe, Request, reqMemory, &offset); } if (!NT_SUCCESS(status)) { UsbGateway_DbgPrint(1, ("WdfUsbTargetPipeFormatRequest failed 0x%x\n", status)); goto Exit; } WdfRequestSetCompletionRoutine( Request, ReadWriteCompletion, NULL); // // set REQUEST_CONTEXT parameters. // rwContext->Length = totalLength - stageLength; rwContext->Numxfer = 0; // // Send the request asynchronously. // if (WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS) == FALSE) { UsbGateway_DbgPrint(1, ("WdfRequestSend failed\n")); status = WdfRequestGetStatus(Request); goto Exit; } Exit: if (!NT_SUCCESS(status)) { WdfRequestCompleteWithInformation(Request, status, 0); } UsbGateway_DbgPrint(3, ("UsbGateway_DispatchReadWrite - ends\n")); return; } |
|
沙发#
发布于:2010-11-24 21:47
看看你的固件对不
|
|
板凳#
发布于:2010-11-25 08:55
引用第1楼flever于2010-11-24 21:47发表的 :
看看你的固件对不 你好,flever,固件不对也会造成这种情况吗,为什么会让应用程序没有响应呢? |
|
地板#
发布于:2010-11-25 18:03
给你一个建议:
建立双机调试,断到EvtIoWrite回调里面,看看阻塞在哪里。 如果根本没有进来,检查你的WDFIOQUEUE的属性,如果是序列化的,就说明前面的请求还没有结束呢。 你贴的代码太多了,有点头绪。 你的描述没有价值,我看了5分钟,不知道你自己发现了什么。别人能给你的帮助就很有限。 |
|
|
地下室#
发布于:2010-11-25 18:09
关键是你自己的分析。
|
|
|
5楼#
发布于:2010-11-26 10:28
引用第3楼Pegram于2010-11-25 18:03发表的 :
给你一个建议: 建立双机调试,断到EvtIoWrite回调里面,看看阻塞在哪里。 如果根本没有进来,检查你的WDFIOQUEUE的属性,如果是序列化的,就说明前面的请求还没有结束呢。 你贴的代码太多了,有点头绪。 ....... --------------------------------------- 不好意思,刚开始接触驱动方面的编程。 WDFIOQUEUE我采用的是WdfIoQueueDispatchParallel方式,在EvtIoWrite中,我使用的是异步方式,发现每次WdfRequestSend(Request,WdfUsbTargetPipeGetIoTarget(devCtx->UsbBulkOutPipe),WDF_NO_SEND_OPTIONS)返回的状态是STATUS_PENDING,这表明请求发送是成功的吧?但是为什么前两次可以完成IO请求,第三次就永远不会完成呢? |
|
6楼#
发布于:2010-11-30 10:56
还是没解决,感觉前两次写都是完全正常的,怎么第三次就不行了呢?抓狂!!
|
|