📄 datatransfer.cpp
字号:
/*+++ *******************************************************************\
*
* Copyright and Disclaimer:
*
* ---------------------------------------------------------------
* This software is provided "AS IS" without warranty of any kind,
* either expressed or implied, including but not limited to the
* implied warranties of noninfringement, merchantability and/or
* fitness for a particular purpose.
* ---------------------------------------------------------------
*
* Copyright (c) 2008 Conexant Systems, Inc.
* All rights reserved.
*
\******************************************************************* ---*/
#include "DataTransfer.h"
#include "CUSBINTF.h"
#include "PolarisUsbInterface.h"
#include "pcbconfig.h"
#include "polaris_reg.h"
//On Windows XP, 32 is the maximum number of buffers allowed in the USB bus driver's queue.
//On Windows 2000, only 8 buffers are allowed.
// If the number of allocated buffers exceeds the maximum, we will spin the CPU on trying
// to send buffers that come back immediately with a failure status.
#define WIN2K_MAX_BUFFERS 8
#define WINXP_MAX_BUFFERS 32
//The following value is the number of buffers to send at once. It will be limited to
// be at most the maximum for the current OS version.
#define MAX_ALLOCATED_BUFFERS 8
/////////////////////////////////////////////////////////////////////////////////////////
DataTransfer::DataTransfer(
CUsbInterface* p_usb,
PolarisUsbInterface* p_usb_firmware,
PDEVICE_OBJECT pdo,
PcbConfig* p_current_config,
BYTE type) :
_p_usb(p_usb),
_p_usb_firmware(p_usb_firmware),
_stop_thread(FALSE),
_p_thread_object(NULL),
_pdo(pdo),
_buffers_need(0),
_buffer_count(0),
_digital_stream(0),
_p_current_config(p_current_config),
_is_bulk(0),
_media_type(type),
_polaris_engine_fail_count(0)
{
PPCB_CONFIG pcb_config;
pcb_config =_p_current_config->getCurrentPcb();
_enable_HANC_Audio = (type&0x80)? 1:0; // if we need HANC to transfer Audio
if(_p_current_config->getPowertype()==USB_BUS_POWER) //Bus-power
{
if(pcb_config->config_num==1)
{
switch (type)
{
case 0: //Video
_interface = pcb_config->hs_config_info[0].interface_info.video_index;
_pipe = 0;
_buffers_need = 8;
_ep_mask =ENABLE_EP4; //ep4 [00:1000]
break;
case 1: // Audio:
case 0x81:
if(_enable_HANC_Audio)
{
_interface = pcb_config->hs_config_info[0].interface_info.hanc_index;
_pipe = 0;
_buffers_need = 4;
_ep_mask =ENABLE_EP6; //ep6 [10:0000]
}
else
{
_interface = pcb_config->hs_config_info[0].interface_info.audio_index;
_pipe = 0;
_buffers_need = 4;
_ep_mask =ENABLE_EP3; // ep3 [00:0100]
}
break;
case 2: // Vbi:
_interface = pcb_config->hs_config_info[0].interface_info.vanc_index;
_pipe = 0;
_buffers_need = 2;
_ep_mask = ENABLE_EP5; //ep5 [01:0000]
break;
case 3: // Sliced_cc:
_interface = pcb_config->hs_config_info[0].interface_info.hanc_index;
_pipe = 0;
_buffers_need = 2;
_ep_mask = ENABLE_EP6; //ep6 [10:0000]
break;
case 4: // ts1
_interface = pcb_config->hs_config_info[0].interface_info.ts1_index;
_pipe = 0;
_buffers_need = 8;
_ep_mask = ENABLE_EP1;//ep1 [00:0001]
break;
case 5: // ts2:
_interface =pcb_config->hs_config_info[0].interface_info.ts2_index;
_pipe = 0;
_buffers_need = 8;
_ep_mask = ENABLE_EP2; //ep2 [00:0010]
break;
}
}
else if(pcb_config->config_num>1)
{
switch (type)
{
case 0: //Video
_interface = pcb_config->hs_config_info[1].interface_info.video_index;
_pipe = 0; // need check,only one pipe per interface
_buffers_need = 8;
_ep_mask = ENABLE_EP4; //ep4 [00:1000]
break;
case 1: // Audio:
case 0x81:
if(_enable_HANC_Audio)
{
_interface = pcb_config->hs_config_info[1].interface_info.hanc_index;
_pipe = 0;
_buffers_need = 4;
_ep_mask =ENABLE_EP6; //ep6 [10:0000]
}
else
{
_interface = pcb_config->hs_config_info[1].interface_info.audio_index;
_pipe = 0;
_buffers_need = 4;
_ep_mask = ENABLE_EP3; // ep3 [00:0100]
}
break;
case 2: // Vbi:
_interface = pcb_config->hs_config_info[1].interface_info.vanc_index;
_pipe = 0;
_buffers_need = 2;
_ep_mask = ENABLE_EP5; //ep5 [01:0000]
break;
case 3: // Sliced_cc:
_interface = pcb_config->hs_config_info[1].interface_info.hanc_index;
_pipe = 0;
_buffers_need = 2;
_ep_mask = ENABLE_EP6; //ep6 [10:0000]
break;
case 4: // ts1
_interface = pcb_config->hs_config_info[1].interface_info.ts1_index;
_pipe = 0;
_buffers_need = 8;
_ep_mask = ENABLE_EP1; //ep1 [00:0001]
break;
case 5: // ts2:
_interface = 0xff; //not exist
_pipe = 0;
_buffers_need = 0;
_ep_mask = ENABLE_EP2; //ep2 [00:0010]
break;
}
}
}
else //self-power
{
switch (type)
{
case 0: //Video
_interface = pcb_config->hs_config_info[0].interface_info.video_index;
_pipe = 0; // need check,only one pipe per interface
_buffers_need = 8;
_ep_mask = ENABLE_EP4; //ep4 [00:1000]
break;
case 1: // Audio:
case 0x81:
if(_enable_HANC_Audio)
{
_interface = pcb_config->hs_config_info[0].interface_info.hanc_index;
_pipe = 0;
_buffers_need = 4;
_ep_mask =ENABLE_EP6; //ep6 [10:0000]
}
else
{
_interface = pcb_config->hs_config_info[0].interface_info.audio_index;
_pipe = 0;
_buffers_need = 4;
_ep_mask = ENABLE_EP3; // ep3 [00:0100]
}
break;
case 2: // Vbi:
_interface = pcb_config->hs_config_info[0].interface_info.vanc_index;
_pipe = 0;
_buffers_need = 2;
_ep_mask = ENABLE_EP5; //ep5 [01:0000]
break;
case 3: // Sliced_cc:
_interface = pcb_config->hs_config_info[0].interface_info.hanc_index;
_pipe = 0;
_buffers_need = 2;
_ep_mask = ENABLE_EP6; //ep6 [10:0000]
break;
case 4: // ts1
_interface = pcb_config->hs_config_info[0].interface_info.ts1_index;
_pipe = 0;
_buffers_need = 8;
_ep_mask = ENABLE_EP1; //ep1 [00:0001]
break;
case 5: // ts2:
_interface = pcb_config->hs_config_info[0].interface_info.ts2_index;
_pipe = 0;
_buffers_need = 8;
_ep_mask = ENABLE_EP2; //ep2 [00:0010]
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
DataTransfer::~DataTransfer()
{
stop();
}
VOID DataTransfer::powerUp()
{
}
/////////////////////////////////////////////////////////////////////////////////////////
PBUFFER_ENTRY DataTransfer::allocateBuffer()
{
PBUFFER_ENTRY p_buffer = new BUFFER_ENTRY;
if(!p_buffer)
{
return NULL;
}
p_buffer->p_buffer = new BYTE[_buffer_size];
p_buffer->p_irp = IoAllocateIrp(_pdo->StackSize, FALSE);
p_buffer->p_urb = (PURB) new BYTE[_urb_size];
if(!p_buffer->p_buffer ||
!p_buffer->p_irp ||
!p_buffer->p_urb)
{
if(p_buffer->p_irp) IoFreeIrp(p_buffer->p_irp);
delete [] p_buffer->p_buffer;
delete [] p_buffer->p_urb;
delete p_buffer;
p_buffer=NULL;
return NULL;
}
RtlZeroMemory(p_buffer->p_buffer, _buffer_size);
RtlZeroMemory(p_buffer->p_urb, _urb_size);
p_buffer->buffer_in_list = FALSE;
InterlockedIncrement(&_buffer_count);
return p_buffer;
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID DataTransfer::freeBuffer(PBUFFER_ENTRY p_buffer)
{
if(p_buffer->p_irp) IoFreeIrp(p_buffer->p_irp);
delete [] p_buffer->p_buffer;
delete [] p_buffer->p_urb;
delete p_buffer;
InterlockedDecrement(&_buffer_count);
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID DataTransfer::getUrbAndBufferSizes()
{
USBD_PIPE_INFORMATION* p_pipe = _p_usb->getPipe(_interface, _pipe);
DWORD packet_size = 512;
DWORD packet_count = 320;
switch(p_pipe->PipeType)
{
case UsbdPipeTypeIsochronous:
{
//For isochronous pipes, we have to calculate the buffer size based on the number
// of packets in a buffer.
packet_size = _p_usb->getMaximumPaketSize(_pipe, _interface);
if(_p_current_config->getUsbSpeed()==1) //high speed
{
packet_count= 320;
}
else
{
packet_count= 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -