阅读:975回复:0
求教:USB bulk 传输的问题。从应用程序调用驱动程序里的输入输出dispatch例程,输入输出是通过自定义IOCTL控制代码实现的!但在程序运行中发现,把相应的URB发送到 bus driver 后一直等待,而不返回。 //the following one routine is to // forward a urb to usb bus driver. NTSTATUS Evk_CallUSBD(IN PDEVICE_OBJECT fdo, IN PURB urb) { NTSTATUS ntStatus,status=STATUS_SUCCESS; PDEVICE_EXTENSION pdx; PIRP irp; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION nextStack; KEVENT event; Evk_KdPrint((\"enter Evk_CallUSBD()\\n\")); pdx=fdo->DeviceExtension; //issue a synchronous request KeInitializeEvent(&event,NotificationEvent,FALSE); //build irp which will be send to bus driver irp=IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB, pdx->LowerDeviceObject, NULL, 0, NULL, 0, TRUE, //internal &event, &ioStatus); //prepare for calling the usb bus driver nextStack=IoGetNextIrpStackLocation(irp); ASSERT(nextStack!=NULL); nextStack->Parameters.Others.Argument1=urb; Evk_KdPrint((\"Calling USB driver stack\")); //call the USB driver stack to perform the operation.if the return value is //PENDING ,wait for request to complete ntStatus=IoCallDriver(pdx->LowerDeviceObject,irp); Evk_KdPrint ((\"return from IoCallDriver USBD %x\\n\", ntStatus)); //STATUS_PENDING means the lower driver have not finished processing the IRP, //yet.we must wait. if(ntStatus==STATUS_PENDING) { Evk_KdPrint ((\"Wait for single object\\n\")); status=KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); Evk_KdPrint ((\"Wait for single object, returned %x\\n\", status)); } else { ioStatus.Status=ntStatus; } Evk_KdPrint ((\"URB status = %x status = %x irp status %x\\n\", urb->UrbHeader.Status, status, ioStatus.Status)); //USBD maps the error code for us,USBD uses error codes in its URB structure, //that are more insightful into USB behavior.in order to match the //NT status code,USBD maps its error codes into more general NT // error categories so higher level drivers can decipher the error codes // based on standard NT error code definitions. // ntStatus=ioStatus.Status; // // If the URB status was not USBD_STATUS_SUCCESS, we save a copy of the // URB status in the device extension. After a failure, another IOCTL, // IOCTL_EVK_GET_LAST_ERROR can be used to retrieve the URB status // for the most recently failed URB. Of course, this status gets // overwritten by subsequent failures, but it\'s better than nothing. // if(NT_SUCCESS(ntStatus)) { if(!USBD_SUCCESS(urb->UrbHeader.Status)) ntStatus=STATUS_UNSUCCESSFUL; } Evk_KdPrint((\"exit Evk_CallUSBD (%x)\\n\", ntStatus)); return ntStatus; } 也就是说 IoCallDriver 的返回值是STATUS_PENDING 从而执行 status=KeWaitForSingleObject(....); 当它一直完成不了。 高手们认为是什么原因呢? |
|
最新喜欢:![]() |