cannon
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2006-09-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1924回复:0

请教:在提高usb驱动传输率时遇到的问题!

楼主#
更多 发布于:2001-07-25 12:03
下面是本人在提高usb驱动传输率时遇到的问题!请高手指教!!!本人不胜感激。

    目前的情况是这样的,firmware、user mode application部分已经完全掌握,minidriver也已经大部分掌握,整个系统运行正常,从user mode application发送下去的数据都能正确地送到试验板上。
    
    现在所碰到的问题主要是在minidriver上,我当前的思路是,在app中定义的用户态缓冲区为64字节长,每次minidriver接收到app传送下来的irp,并将用户态缓冲区中的数据复制到核心态的mdl中,然后再将urb发送到下层驱动完成一次64字节的传送,如此循环直到将数据发送完成。但是,这样的数据传输率很不能令人满意,仅达到20k Bytes/sec左右。为此,希望能进一步提高传送速率,我进一步改进minidriver中的方法。即是,首先将app中的发送缓冲区长度增达其长度大于64字节小于64k Bytes(单个管道一次所能传送的最大长度),然后minidriver将接收到的上述数据拆分成64字节的irp放入队列中,采用嵌套方式将这些包发送出去(此思路是参考ddk例程)。
 
   下面是上述思路的完整代码,在SOFT-ICE下跟踪到下面这个函数时计算机就自动重起了,我一直找不到原因,望指教,谢谢!
UsbBuildInterruptOrBulkTransferRequest(ctx->urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
  hpipe, NULL, mdl, seglen, urbflags, NULL);
 
下面是我的函数:
 
 
NTSTATUS
USBsys_StagedReadWrite(
    IN PDEVICE_OBJECT fdo,
    IN PIRP Irp,
    IN BOOLEAN Read
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS,status;
 NTSTATUS resetPipeStatus;
    PFILE_OBJECT fileObject;
    PIO_STACK_LOCATION irpStack, nextStack,stack;
    PURB urb;
    PIRP irp;
    PMDL mdl;
 PULONG va;
    CHAR stackSize;
    KIRQL OldIrql;
 BOOLEAN fRes;
    NTSTATUS waitStatus;
    ULONG i, nIrps = 0, totalLength = 0, totalIrpsNeeded, used,length,seglen;
    PUSBD_PIPE_INFORMATION pipeHandle = NULL;
    PDEVICE_EXTENSION pdx,deviceExtension = fdo;
    PULONG pCon =  NULL;
 ULONG ChunkSize = 64;
 ULONG arraySize;
    PUDK_RW_CONTEXT context = NULL;
 
 BOOLEAN read;
 PRWCONTEXT ctx;
 ULONG urbflags;
 LONG haderr;
 USBD_PIPE_HANDLE hpipe;
 
    KdPrint (("enter BulkUsb_StagedReadWrite()\n"));
 pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
 
 status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
 if (!NT_SUCCESS(status))
  return CompleteRequest(Irp, status, 0);
  
 stack = IoGetCurrentIrpStackLocation(Irp);
 read = stack->MajorFunction == IRP_MJ_READ;
 
    fileObject = stack->FileObject;
 
    pipeHandle =  fileObject->FsContext;
 
 hpipe = pipeHandle->PipeHandle;
 
 if (read)
  haderr = InterlockedExchange(&pdx->inerror, 0);
 else
  haderr = InterlockedExchange(&pdx->outerror, 0);
 if (haderr && !NT_SUCCESS(ResetPipe(fdo, hpipe)))
  ResetDevice(fdo);
 
 ctx = (PRWCONTEXT) ExAllocatePool(NonPagedPool, sizeof(RWCONTEXT));
 if (!ctx)
  {
  KdPrint((" - Can't allocate memory for context structure\n"));
  IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
  return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
  }
 RtlZeroMemory(ctx, sizeof(RWCONTEXT));
 
 length = Irp->MdlAddress ?  MmGetMdlByteCount(Irp->MdlAddress) : 0;
 if (!length)
  {      // zero-length read
  IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
  return CompleteRequest(Irp, STATUS_SUCCESS, 0);
  }      // zero-length read
 va = (PULONG) MmGetMdlVirtualAddress(Irp->MdlAddress);
 
 urbflags =  USBD_SHORT_TRANSFER_OK | (read ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
 
 seglen = length;
 
 mdl = IoAllocateMdl((PVOID) va, length, FALSE, FALSE, NULL);
 if (!mdl)
  {     // can't allocate MDL
  KdPrint((" - Can't allocate memory for MDL\n"));
  ExFreePool(ctx);
  IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
  return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
  }     // can't allocate MDL
 
 IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) va, seglen);

=〉 运行到此处时,计算机重起(是否是因为在核心状态操作内存引起的???如果是,则原因何在???)
 UsbBuildInterruptOrBulkTransferRequest(ctx->urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
  hpipe, NULL, mdl, seglen, urbflags, NULL);
 
 ctx->va = va + seglen;
 ctx->length = length - seglen;
 ctx->mdl = mdl;
 ctx->numxfer = 0;
 
 stack = IoGetNextIrpStackLocation(Irp);
 stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
 stack->Parameters.Others.Argument1 = (PVOID)ctx;
 stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
 
 IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnReadWriteComplete,
  (PVOID) ctx, TRUE, TRUE, TRUE);
 
 IoMarkIrpPending(Irp);
 status = IoCallDriver(pdx->LowerDeviceObject, Irp);
 if (!NT_SUCCESS(status) && !NT_SUCCESS(ResetPipe(fdo, hpipe)))
  ResetDevice(fdo);
 
 return STATUS_PENDING;
}
 
游客

返回顶部