yushui213
驱动小牛
驱动小牛
  • 注册日期2006-04-17
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分1015分
  • 威望115点
  • 贡献值0点
  • 好评度102点
  • 原创分0分
  • 专家分0分
阅读:1483回复:1

USB等时传输的问题(急!!!)

楼主#
更多 发布于:2007-09-29 21:33
各位大侠
小弟遇到棘手的问题了,请大侠帮忙,万分感谢!!!
在USB驱动中做等时传输时(我以Driver Studio中的例子usbisoch做了一些小的修改),在开始一段时间里可以传输正确,但过了一段时间后,提交IRP时返回的结果是STATUS_UNSUCCESSFUL,
而且之后好像就不再继续读了。
我把代码贴在下面:
基本上都是例子中的代码。其中,StartIsocReads  在   OnStartDevice()   之后就调用。
NTSTATUS UsbDriverDevice::StartIsocReads()
{
 NTSTATUS status;
 for (int i=0; i<ISOC_NUM_READ_URBS; i++)
 {
  UCHAR *p = new (NonPagedPool) UCHAR[ISOC_URB_DATA_SIZE];
  ASSERT(p);
  if ( !p )  break;
  
  PURB pUrb =
   m_Endpoint2IN.BuildIsochronousTransfer(
    ISOC_NUM_PACKETS_PER_URB, // # packets
    ISOC_PACKET_SIZE,   // packet size
    TRUE,      // bIn
    TRUE,      // bASAP
    USBD_ISO_START_FRAME_RANGE,// Start Frame
    p,       // pBuffer
    ISOC_URB_DATA_SIZE   // Length
    );
  ASSERT(pUrb);
  if ( !pUrb ) {
   delete p;
   break;
  }
  // Do not get an error on short or zero length packets
  pUrb->UrbIsochronousTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
  PISOC_CONTEXT pContext = new (NonPagedPool) ISOC_CONTEXT;
  ASSERT(pContext);
  if ( !pContext ) {
   delete pUrb;
   delete p;
   break;
  }
  // Create the accompanying IRP once, since the kernel
  //   does not like us deleting and allocating IRPs
  //   on every completion routine.
  //CCHAR stackSize = m_Usb.StackRequirement() + 1;
  CCHAR stackSize = m_Lower.StackRequirement() + 1;
  PIRP pIrp = IoAllocateIrp(stackSize, FALSE);
  pContext->pNext = m_pReadContexts;
  pContext->bUsed = TRUE;
  pContext->pDev  = this;
  pContext->pIrp  = pIrp;
  pContext->pUrb  = pUrb;
  pContext->pData = p;
  pContext->pMdl  = NULL;
  
  m_pReadContexts = pContext;
  IncrementOutstandingRequestCount();
  status = QueueIsocRead(pContext);
  if ( !NT_SUCCESS(status) )
   break;
 }
 if ( i != ISOC_NUM_READ_URBS )
 {
  t << "StartReads() allocation FAILURE!\n";
  return STATUS_INSUFFICIENT_RESOURCES;
 }
 return STATUS_SUCCESS;
}

NTSTATUS
UsbDriverDevice::QueueIsocRead(PISOC_CONTEXT pContext)
{
 NTSTATUS status;
 _URB_HEADER         *pUHdr = (_URB_HEADER *)pContext->pUrb;
 _URB_ISOCH_TRANSFER *pIsoc = &pContext->pUrb->UrbIsochronousTransfer;
 pUHdr->UsbdDeviceHandle     = NULL;
 pUHdr->UsbdFlags            = 0;
 pIsoc->TransferBufferLength = ISOC_URB_DATA_SIZE;
 pIsoc->TransferBufferMDL    = NULL;
 pIsoc->StartFrame           = 0;
 memset(&pIsoc->hca, 0, sizeof(_URB_HCD_AREA));
  status = m_Endpoint2IN.SubmitUrb(
    pContext->pIrp,
    pContext->pUrb,
    LinkTo(UsbIsocReadComplete),
    pContext
    );
 if ( !NT_SUCCESS(status) )
 {
  t << "Submission of Isoc Read URB FAILED (status="
     << (ULONG)status << ")!\n";
 }
 return status;
}

NTSTATUS
UsbDriverDevice::UsbIsocReadComplete(KIrp I, PISOC_CONTEXT pContext)
{
 NTSTATUS status;
 if ( m_State.m_StopPending ||
   m_State.m_RemovePending ||
   m_State.m_Removed ||
   m_State.m_SurpriseRemoval
    )
 {
  // Do not re-submit this URB
  pContext->bUsed = FALSE;
  DecrementOutstandingRequestCount();
  return STATUS_MORE_PROCESSING_REQUIRED;
 }
 if ( !NT_SUCCESS(I.Status()) )
 {
 // URB submission FAILED!
  t << "Isoc Read IRP FAILED (status="<< (ULONG)I.Status() << ")!\n";

 pContext->bUsed = FALSE;
  DecrementOutstandingRequestCount();
  return STATUS_MORE_PROCESSING_REQUIRED;

 }
 // If we have nowhere to put its data, just re-cycle this buffer.
 if ( !m_pReadFifo ) {
  status = QueueIsocRead(pContext);
  return STATUS_MORE_PROCESSING_REQUIRED;
 }
 
 _URB_ISOCH_TRANSFER *pIsoc = &pContext->pUrb->UrbIsochronousTransfer;
 
 PUSBD_ISO_PACKET_DESCRIPTOR ppd;
 UCHAR   temp[ISOC_PACKET_SIZE];
 BOOLEAN bOverflow   = FALSE;
 ULONG   dwDataCount = 0;
 // Take data from URB completion, and copy it into our FIFO
 //   If our FIFO fills up, then clear out enough for the new data!
 for (int i=0; i<ISOC_NUM_PACKETS_PER_URB; i++)
 {
  ppd = &pIsoc->IsoPacket;
  // We ignore zero length packets in the data stream for now.
  //   You might want to have a zero length packet signal the
  //   end of a large block of data.  If so, then you need to
  //   handle a zero length packet arriving at any time!
  if ( USBD_SUCCESS(ppd->Status) && (ppd->Length > 0) )
  {
   PUCHAR p = ((UCHAR *)pIsoc->TransferBuffer) + ppd->Offset;
   m_pReadFifo->Lock();
   if ( ISOC_PACKET_SIZE > m_pReadFifo->NumberOfItemsAvailableForWrite() )
   {
    bOverflow = TRUE;
    // Discard oldest data from the Read FIFO
    m_pReadFifo->Read(temp, ppd->Length);
   }
   m_pReadFifo->Write(p, ppd->Length);
   m_pReadFifo->Unlock();
   dwDataCount += ppd->Length;
  }
 }
 if ( bOverflow )
 {
  t << "Read FIFO overflow!\n";
  m_readOverflow++;
 }
 if ( (dwDataCount > 0))
  t << "Isoc Read received " << dwDataCount << " bytes\n";
 
 // Resubmit this URB.
 status = QueueIsocRead(pContext);
 return STATUS_MORE_PROCESSING_REQUIRED;
}


红色部分就是我的问题所在部分。
求求大侠们了
这两天都郁闷得做不下去了。

谢谢,谢谢!!

yushui213
驱动小牛
驱动小牛
  • 注册日期2006-04-17
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分1015分
  • 威望115点
  • 贡献值0点
  • 好评度102点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-09-30 12:41
没人知道么?

求求大家了。。。。

有遇到同样问题的xdjm也留个言吧,我们讨论讨论呀。。。

我的MSN:yushui213@hotmail.com
游客

返回顶部