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

USB总线驱动问题!(20)分

楼主#
更多 发布于:2004-03-01 18:16
我做的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

最新喜欢:

litcrazylitcra...
hfy781108
驱动牛犊
驱动牛犊
  • 注册日期2002-08-19
  • 最后登录2005-12-10
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-03-03 11:30
没有人回答我啊!是不是我没有阐述清楚
zmwk
驱动中牛
驱动中牛
  • 注册日期2001-05-15
  • 最后登录2009-04-05
  • 粉丝0
  • 关注0
  • 积分59分
  • 威望51点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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,看看帮助文档吧,应该有新的收获。
A strong man can save himself. A great man can save another.
游客

返回顶部