hfy781108
驱动牛犊
驱动牛犊
  • 注册日期2002-08-19
  • 最后登录2005-12-10
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1051回复:0

USB设备驱动问题!

楼主#
更多 发布于:2004-03-03 11:04

我做的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
游客

返回顶部