📄 cpipe.cpp
字号:
// ******************************************************************
// Scope: public
CIsochronousPipe::CIsochronousPipe( IN const LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDescriptor,
IN const BOOL fIsLowSpeed,IN const BOOL fIsHighSpeed,
IN const UCHAR bDeviceAddress,
IN const UCHAR bHubAddress,IN const UCHAR bHubPort,
IN CEhcd *const pCEhcd )
//
// Purpose: Constructor for CIsochronousPipe
//
// Parameters: See CPipe::CPipe
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
: CPipe(lpEndpointDescriptor, fIsLowSpeed,fIsHighSpeed, bDeviceAddress,bHubAddress,bHubPort, pCEhcd ) // constructor for base class
{
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CIsochronousPipe::CIsochronousPipe\n")) );
DEBUGCHK( m_usbEndpointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE &&
m_usbEndpointDescriptor.bLength >= sizeof( USB_ENDPOINT_DESCRIPTOR ) &&
(m_usbEndpointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS );
m_pQueuedTransfer = NULL;
memset(&m_EndptBuget,0,sizeof(m_EndptBuget));
m_EndptBuget.max_packet= lpEndpointDescriptor->wMaxPacketSize & 0x7ff;
BYTE bInterval = lpEndpointDescriptor->bInterval;
if ( bInterval==0)
bInterval=1;
m_pArrayOfCITD = NULL;
m_pArrayOfCSITD = NULL;
m_dwNumOfTDAvailable=0;
if (fIsHighSpeed) { // Table 9-13
m_pArrayOfCITD = (CITD **) new PVOID[NUM_OF_PRE_ALLOCATED_TD];
if (m_pArrayOfCITD) {
memset(m_pArrayOfCITD, 0, sizeof (CITD *) * NUM_OF_PRE_ALLOCATED_TD) ;
for (m_dwNumOfTDAvailable=0;m_dwNumOfTDAvailable<NUM_OF_PRE_ALLOCATED_TD;m_dwNumOfTDAvailable++) {
if ( (*(m_pArrayOfCITD + m_dwNumOfTDAvailable) = new (m_pCEhcd->GetPhysMem()) CITD(NULL)) == NULL)
break;
}
}
ASSERT(m_pArrayOfCITD);
ASSERT(m_dwNumOfTDAvailable == NUM_OF_PRE_ALLOCATED_TD);
m_EndptBuget.max_packet *=(((lpEndpointDescriptor->wMaxPacketSize >>11) & 3)+1);
m_EndptBuget.period = (1<< ( bInterval-1));
}
else {
m_pArrayOfCSITD = (CSITD **) new PVOID[NUM_OF_PRE_ALLOCATED_TD];
if (m_pArrayOfCSITD) {
memset(m_pArrayOfCSITD, 0, sizeof (CSITD *) * NUM_OF_PRE_ALLOCATED_TD) ;
for (m_dwNumOfTDAvailable=0;m_dwNumOfTDAvailable<NUM_OF_PRE_ALLOCATED_TD;m_dwNumOfTDAvailable++) {
if ( (*(m_pArrayOfCSITD + m_dwNumOfTDAvailable) = new (m_pCEhcd->GetPhysMem()) CSITD (NULL,NULL)) == NULL)
break;
}
}
ASSERT(m_pArrayOfCSITD);
ASSERT(m_dwNumOfTDAvailable == NUM_OF_PRE_ALLOCATED_TD);
m_EndptBuget.period = (1<< ( bInterval-1));
}
m_EndptBuget.ep_type = isoch ;
m_EndptBuget.type= lpEndpointDescriptor->bDescriptorType;
m_EndptBuget.direction =(USB_ENDPOINT_DIRECTION_OUT(lpEndpointDescriptor->bEndpointAddress)?OUTDIR:INDIR);
m_EndptBuget.speed=(fIsHighSpeed?HSSPEED:(fIsLowSpeed?LSSPEED:FSSPEED));
m_bSuccess=pCEhcd->AllocUsb2BusTime(bHubAddress,bHubPort,&m_EndptBuget);
ASSERT(m_bSuccess);
if (m_bSuccess ) {
if (fIsHighSpeed) { // Update SMask and CMask for Slit Interrupt Endpoitt
m_bFrameSMask=pCEhcd->GetSMASK(&m_EndptBuget);
m_bFrameCMask=0;
}
else {
m_bFrameSMask=pCEhcd->GetSMASK(&m_EndptBuget);
m_bFrameCMask=pCEhcd->GetCMASK(&m_EndptBuget);
}
}
else {
ASSERT(FALSE);
}
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CIsochronousPipe::CIsochronousPipe\n")) );
}
// ******************************************************************
// Scope: public
CIsochronousPipe::~CIsochronousPipe( )
//
// Purpose: Destructor for CIsochronousPipe
//
// Parameters: None
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
{
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CIsochronousPipe::~CIsochronousPipe\n")) );
// m_pWakeupTD should have been freed by the time we get here
if (m_bSuccess)
m_pCEhcd->FreeUsb2BusTime( m_bHubAddress, m_bHubPort,&m_EndptBuget);
ClosePipe();
if (m_pArrayOfCITD) {
for (m_dwNumOfTDAvailable=0;m_dwNumOfTDAvailable<NUM_OF_PRE_ALLOCATED_TD;m_dwNumOfTDAvailable++) {
if ( *(m_pArrayOfCITD + m_dwNumOfTDAvailable) !=NULL) {
(*(m_pArrayOfCITD + m_dwNumOfTDAvailable))->~CITD();
m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)*(m_pArrayOfCITD + m_dwNumOfTDAvailable),
m_pCEhcd->GetPhysMem()->VaToPa((PBYTE)*(m_pArrayOfCITD + m_dwNumOfTDAvailable)),
CPHYSMEM_FLAG_HIGHPRIORITY |CPHYSMEM_FLAG_NOBLOCK );
}
}
delete (m_pArrayOfCITD);
}
if (m_pArrayOfCSITD) {
for (m_dwNumOfTDAvailable=0;m_dwNumOfTDAvailable<NUM_OF_PRE_ALLOCATED_TD;m_dwNumOfTDAvailable++) {
if ( *(m_pArrayOfCSITD + m_dwNumOfTDAvailable) != NULL) {
(*(m_pArrayOfCSITD + m_dwNumOfTDAvailable))->~CSITD();
m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)*(m_pArrayOfCSITD + m_dwNumOfTDAvailable),
m_pCEhcd->GetPhysMem()->VaToPa((PBYTE)*(m_pArrayOfCSITD + m_dwNumOfTDAvailable)),
CPHYSMEM_FLAG_HIGHPRIORITY |CPHYSMEM_FLAG_NOBLOCK );
}
}
delete (m_pArrayOfCSITD);
}
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CIsochronousPipe::~CIsochronousPipe\n")) );
}
//******************************************************************************
CITD * CIsochronousPipe::AllocateCITD( CITransfer * pTransfer)
//
// Purpose: Isochronous Pipe: Allocate the Isochronous High Speed Transfer Descriptor
//
// Parameters: pTransfer - Pointer to CITransfer object containing all transfer information
//
// Returns: Pointer to CITD object, NULL - fail
//
// ******************************************************************
{
EnterCriticalSection( &m_csPipeLock );
ASSERT(m_pArrayOfCITD!=NULL) ;
CITD * pReturn = NULL;
if (m_pArrayOfCITD!=NULL ) {
ASSERT(m_dwNumOfTDAvailable <= NUM_OF_PRE_ALLOCATED_TD);
for (DWORD dwIndex=m_dwNumOfTDAvailable;dwIndex!=0;dwIndex--) {
if ((pReturn = *(m_pArrayOfCITD + dwIndex -1))!=NULL) {
m_dwNumOfTDAvailable = dwIndex-1;
*(m_pArrayOfCITD + m_dwNumOfTDAvailable) = NULL;
pReturn->ReInit(pTransfer);
break;
}
}
}
LeaveCriticalSection( &m_csPipeLock );
DEBUGMSG( ZONE_WARNING && (pReturn==NULL) , (TEXT("CIsochronousPipe::AllocateCITD: return NULL, run out of pre-allocated ITD\r\n")) );
return pReturn;
}
//********************************************************************************
CSITD * CIsochronousPipe::AllocateCSITD( CSITransfer * pTransfer,CSITD * pPrev)
//
// Purpose: Isochronous Pipe: Allocate the Spilt Isochronous (Full/Low Speed) Transfer Descriptor
//
// Parameters: pTransfer - Pointer to CSITransfer object containing all transfer information
// pPrev - Pointer to previous CSITD
//
// Returns: Pointer to CITD object, NULL - fail
//
// ******************************************************************
{
EnterCriticalSection( &m_csPipeLock );
ASSERT(m_pArrayOfCSITD!=NULL) ;
CSITD * pReturn = NULL;
if (m_pArrayOfCSITD!=NULL ) {
ASSERT(m_dwNumOfTDAvailable <= NUM_OF_PRE_ALLOCATED_TD);
for (DWORD dwIndex=m_dwNumOfTDAvailable;dwIndex!=0;dwIndex--) {
if ((pReturn = *(m_pArrayOfCSITD + dwIndex -1))!=NULL) {
m_dwNumOfTDAvailable = dwIndex -1;
*(m_pArrayOfCSITD + m_dwNumOfTDAvailable) = NULL;
pReturn->ReInit(pTransfer,pPrev);
break;
}
}
}
LeaveCriticalSection( &m_csPipeLock );
DEBUGMSG( ZONE_WARNING && (pReturn==NULL) , (TEXT("CIsochronousPipe::AllocateCSITD: return NULL, run out of pre-allocated CITD\r\n")) );
return pReturn;
}
//********************************************************************************
void CIsochronousPipe::FreeCITD(CITD * pITD)
//
// Purpose: Isochronous Pipe: Release and free the CITD being allocated
//
// Parameters: pITD - pointer to isochronous transfer descriptor
//
// Returns: Nothing
//
// ******************************************************************
{
EnterCriticalSection( &m_csPipeLock );
ASSERT(m_pArrayOfCITD!=NULL);
ASSERT(m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD);
if (m_pArrayOfCITD && pITD && m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD) {
ASSERT(*(m_pArrayOfCITD+m_dwNumOfTDAvailable)==NULL);
pITD->~CITD();
*(m_pArrayOfCITD+m_dwNumOfTDAvailable)= pITD;
m_dwNumOfTDAvailable ++;
}
LeaveCriticalSection( &m_csPipeLock );
}
//******************************************************************
void CIsochronousPipe::FreeCSITD(CSITD * pSITD)
//
// Purpose: Isochronous Pipe: Release and free the CSITD being allocated
//
// Parameters: pSITD - pointer to spilt isochronous transfer descriptor
//
// Returns: Nothing
//
// ******************************************************************
{
EnterCriticalSection( &m_csPipeLock );
ASSERT(m_pArrayOfCSITD );
ASSERT(m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD);
if (m_pArrayOfCSITD && pSITD && m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD ) {
ASSERT(*(m_pArrayOfCSITD+m_dwNumOfTDAvailable)==NULL);
pSITD->~CSITD();
*(m_pArrayOfCSITD+m_dwNumOfTDAvailable)= pSITD;
m_dwNumOfTDAvailable ++;
}
LeaveCriticalSection( &m_csPipeLock );
}
// ******************************************************************
// Scope: public (Implements CPipe::OpenPipe = 0)
HCD_REQUEST_STATUS CIsochronousPipe::OpenPipe( void )
//
// Purpose: Inserting the necessary (empty) items into the
// schedule to permit future transfers
//
// Parameters: None
//
// Returns: requestOK if pipe opened successfuly
// requestFailed if pipe not opened
//
// Notes:
// ******************************************************************
{
DEBUGMSG( ZONE_PIPE, (TEXT("+CIsochronousPipe::OpenPipe\n")) );
HCD_REQUEST_STATUS status = requestFailed;
m_pQueuedTransfer=NULL;
EnterCriticalSection( &m_csPipeLock );
DEBUGCHK( m_usbEndpointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE &&
m_usbEndpointDescriptor.bLength >= sizeof( USB_ENDPOINT_DESCRIPTOR ) &&
(m_usbEndpointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS );
m_dwLastValidFrame = 0;
m_pCEhcd->GetFrameNumber(&m_dwLastValidFrame);
// if this fails, someone is trying to open an already opened pipe
if ( m_pQueuedTransfer == NULL && m_bSuccess == TRUE) {
status = requestOK;
}
else
ASSERT(FALSE);
LeaveCriticalSection( &m_csPipeLock );
if (status == requestOK ) {
BOOL bReturn = m_pCEhcd->AddToBusyPipeList(this, TRUE);
ASSERT(bReturn == TRUE);
}
DEBUGMSG( ZONE_PIPE, (TEXT("-CIsochronousPipe::OpenPipe, returning HCD_REQUEST_STATUS %d\n"), status ) );
return status;
}
// ******************************************************************
// Scope: public (Implements CPipe::ClosePipe = 0)
HCD_REQUEST_STATUS CIsochronousPipe::ClosePipe( void )
//
// Purpose: Abort any transfers associated with this pipe, and
// remove its data structures from the schedule
//
// Parameters: None
//
// Returns: requestOK
//
// Notes:
// ******************************************************************
{
DEBUGMSG( ZONE_PIPE, (TEXT("+CIsochronousPipe::ClosePipe\n")) );
m_pCEhcd->RemoveFromBusyPipeList( this );
EnterCriticalSection( &m_csPipeLock );
CIsochTransfer * pCurTransfer = m_pQueuedTransfer;
m_pQueuedTransfer = NULL;
while ( pCurTransfer ) {
pCurTransfer->AbortTransfer();
CIsochTransfer * pNext = (CIsochTransfer *)pCurTransfer ->GetNextTransfer();
delete pCurTransfer;
pCurTransfer = pNext;
}
LeaveCriticalSection( &m_csPipeLock );
DEBUGMSG( ZONE_PIPE, (TEXT("-CIsochronousPipe::ClosePipe\n")) );
return requestOK;
}
// ******************************************************************
// Scope: public (Implements CPipe::AbortTransfer = 0)
HCD_REQUEST_STATUS CIsochronousPipe::AbortTransfer(
IN const LPTRANSFER_NOTIFY_ROUTINE lpCancelAddress,
IN const LPVOID lpvNotifyParameter,
IN LPCVOID lpvCancelId )
//
// Purpose: Abort an
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -