阅读:1051回复:0
USB设备驱动问题!我做的USB设备驱动,当我把IRP交给总线驱动后(IRP完成后应该标记event),总线返回STATUS_PENDING 后没有标记event事件,也就是没有完成该Irp.源代码如下: NTSTATUS CallUSBD( IN PDEVICE_OBJECT DeviceObject, IN PURB Urb ) { PIRP irp; KEVENT event; NTSTATUS ntStatus; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION nextStack; PDEVICE_EXTENSION deviceExtension; // // initialize the variables // irp = NULL; deviceExtension = DeviceObject->DeviceExtension; KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB, deviceExtension->TopOfStackDeviceObject, NULL, 0, NULL, 0, TRUE, &event, &ioStatus); if(!irp) { BulkUsb_DbgPrint(1, ("IoBuildDeviceIoControlRequest failedn")); return STATUS_INSUFFICIENT_RESOURCES; } nextStack = IoGetNextIrpStackLocation(irp); ASSERT(nextStack != NULL); nextStack->Parameters.Others.Argument1 = Urb; BulkUsb_DbgPrint(3, ("将要把Irp提交给总线驱动!::")); BulkUsb_IoIncrement(deviceExtension); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp); if(ntStatus == STATUS_PENDING) { BulkUsb_DbgPrint(1, ("总线驱动返回"等待状态" ,等待event被标记-ING")); KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); ntStatus = ioStatus.Status; } BulkUsb_DbgPrint(1, ("event被标记了!YEEH")); BulkUsb_IoDecrement(deviceExtension); return ntStatus; } 调用此例程的的例程为: NTSTATUS FX2_AnchorDownload( PDEVICE_OBJECT fdo, WORD offset, PUCHAR downloadBuffer, ULONG downloadSize ) { NTSTATUS ntStatus; PURB urb = NULL; int i; int chunkCount; PUCHAR ptr = downloadBuffer; BulkUsb_DbgPrint(1, ("!!!enter anchor download!haha!")); urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); if (urb) { chunkCount = ((downloadSize + CHUNK_SIZE - 1) / CHUNK_SIZE); // // The download will be split into CHUNK_SIZE pieces and // downloaded with multiple setup transfers. For the Rev B parts // CHUNK_SIZE should not exceed 64 bytes, as larger transfers can // result in data corruption when other USB devices are present. // for (i = 0; i < chunkCount; i++) { RtlZeroMemory(urb,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); urb->UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE; urb->UrbControlVendorClassRequest.TransferBufferLength = ((i == (chunkCount - 1)) && (downloadSize % CHUNK_SIZE)) ? (downloadSize % CHUNK_SIZE) : CHUNK_SIZE; urb->UrbControlVendorClassRequest.TransferBuffer =ptr ; urb->UrbControlVendorClassRequest.TransferBufferMDL = NULL; urb->UrbControlVendorClassRequest.Request = ANCHOR_LOAD_EXTERNAL ; urb->UrbControlVendorClassRequest.Value = (i * CHUNK_SIZE) + offset; urb->UrbControlVendorClassRequest.Index = 0; ntStatus =CallUSBD(fdo, urb); break; if (!NT_SUCCESS(ntStatus)) break; ptr += CHUNK_SIZE; } } else { ntStatus = STATUS_NO_MEMORY; } if (urb) ExFreePool(urb); return ntStatus; } 注意:这里的参数downloadBuffer为MDL地址,调用代码如下:(PUCHAR) MmGetSystemAddressForMdl(Irp->MdlAddress) 当在应用程序中不采用DMA方式传递时,即downloadBuffer不是MDL地址时,就可以完成此IRP |
|