阅读:1372回复:2
USB总线驱动问题!(20)分
我做的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 failed\n")); 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 |
|
最新喜欢:litcra... |
沙发#
发布于:2004-03-03 11:30
没有人回答我啊!是不是我没有阐述清楚
|
|
板凳#
发布于:2004-03-04 10:33
The pages of the described memory object must be locked. When a driver other than a highest level driver receives a KMemory object, it is safe to assume it is locked. Memory allocated from the non-paged pool is locked.
A driver that uses direct I/O but not DMA can use this service to map the buffer provided in a I/O request from a user subsystem. The driver can then transfer data directly to or from the client buffer. If the underlying MDL has already been mapped, the function returns the same address to which it was originally mapped. The underlying system service is MmGetSystemAddressForMdl. 我觉得你既然不使用TransferBufferMDL就不应该再使用MDL,看看帮助文档吧,应该有新的收获。 |
|
|