📄 cpipe.cpp
字号:
{
if (pTransfer == NULL)
return FALSE;
DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("+CControlPipe::AreTransferParametersValid\n")) );
// these parameters aren't used by CControlPipe, so if they are non NULL,
// it doesn't present a serious problem. But, they shouldn't have been
// passed in as non-NULL by the calling driver.
DEBUGCHK( pTransfer->adwIsochErrors == NULL && // ISOCH
pTransfer->adwIsochLengths == NULL && // ISOCH
pTransfer->aLengths == NULL ); // ISOCH
// this is also not a serious problem, but shouldn't happen in normal
// circumstances. It would indicate a logic error in the calling driver.
DEBUGCHK( !(pTransfer->lpStartAddress == NULL && pTransfer->lpvNotifyParameter != NULL) );
// DWORD pTransfer->dwStartingFrame; (ignored - ISOCH)
// DWORD pTransfer->dwFrames; (ignored - ISOCH)
BOOL fValid = ( m_pPipeQHead != NULL &&
m_bDeviceAddress <= USB_MAX_ADDRESS &&
pTransfer->lpvControlHeader != NULL &&
pTransfer->lpfComplete != NULL &&
pTransfer->lpdwBytesTransferred != NULL &&
pTransfer->lpdwError != NULL );
if ( fValid ) {
if ( pTransfer->dwFlags & USB_IN_TRANSFER ) {
fValid = (pTransfer->lpvBuffer != NULL &&
// paClientBuffer could be 0 or !0
pTransfer->dwBufferSize > 0);
} else {
fValid = ( (pTransfer->lpvBuffer == NULL &&
pTransfer->paBuffer == 0 &&
pTransfer->dwBufferSize == 0) ||
(pTransfer->lpvBuffer != NULL &&
// paClientBuffer could be 0 or !0
pTransfer->dwBufferSize > 0) );
}
}
ASSERT(fValid);
DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("-CControlPipe::AreTransferParametersValid, returning BOOL %d\n"), fValid) );
return fValid;
}
// ******************************************************************
// Scope: public
CInterruptPipe::CInterruptPipe( 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 CInterruptPipe
//
// Parameters: See CQueuedPipe::CQueuedPipe
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
: CQueuedPipe( lpEndpointDescriptor, fIsLowSpeed, fIsHighSpeed, bDeviceAddress, bHubAddress,bHubPort, pCEhcd ) // constructor for base class
{
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CInterruptPipe::CInterruptPipe\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_INTERRUPT );
//TODO:I need Get S-MASK and C-MASK.
memset(&m_EndptBuget,0,sizeof(m_EndptBuget));
m_EndptBuget.max_packet= lpEndpointDescriptor->wMaxPacketSize & 0x7ff;
BYTE bInterval=lpEndpointDescriptor->bInterval;
if (bInterval==0)
bInterval=1;
if (fIsHighSpeed) { // Table 9-13
m_EndptBuget.max_packet *=(((lpEndpointDescriptor->wMaxPacketSize >>11) & 3)+1);
m_EndptBuget.period = (1<< (bInterval-1));
}
else {
m_EndptBuget.period = bInterval;
for (UCHAR uBit=0x80;uBit!=0;uBit>>=1) {
if ((m_EndptBuget.period & uBit)!=0) {
m_EndptBuget.period = uBit;
break;
}
}
}
ASSERT(m_EndptBuget.period!=0);
m_EndptBuget.ep_type = interrupt ;
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 = 0xff;
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("-CInterruptPipe::CInterruptPipe\n")) );
}
// ******************************************************************
// Scope: public
CInterruptPipe::~CInterruptPipe( )
//
// Purpose: Destructor for CInterruptPipe
//
// Parameters: None
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
{
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CInterruptPipe::~CInterruptPipe\n")) );
if (m_bSuccess)
m_pCEhcd->FreeUsb2BusTime( m_bHubAddress, m_bHubPort,&m_EndptBuget);
ClosePipe();
DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CInterruptPipe::~CInterruptPipe\n")) );
}
// ******************************************************************
// Scope: public (Implements CPipe::OpenPipe = 0)
HCD_REQUEST_STATUS CInterruptPipe::OpenPipe( void )
//
// Purpose: Create the data structures necessary to conduct
// transfers on this pipe
//
// Parameters: None
//
// Returns: requestOK - if pipe opened
//
// requestFailed - if pipe was not opened
//
// Notes:
// ******************************************************************
{
DEBUGMSG( ZONE_PIPE, (TEXT("+CInterruptPipe::OpenPipe\n") ) );
HCD_REQUEST_STATUS status = requestFailed;
m_pUnQueuedTransfer=NULL; // ptr to last transfer in queue
m_pQueuedTransfer=NULL;
if (!m_bSuccess)
return status;
EnterCriticalSection( &m_csPipeLock );
// if this fails, someone is trying to open
// an already opened pipe
DEBUGCHK(m_pPipeQHead == NULL );
if ( m_pPipeQHead == NULL )
m_pPipeQHead = new(m_pCEhcd->GetPhysMem()) CQH(this);
if (m_pPipeQHead) {
m_pPipeQHead->SetDTC(FALSE); // Auto Data Toggle for Interrupt.
m_pPipeQHead->SetReLoad(0xf);
if (!m_fIsHighSpeed)
m_pPipeQHead->SetINT(FALSE);
m_pCEhcd->PeriodQeueuQHead(m_pPipeQHead,(UCHAR)(m_EndptBuget.actual_period>=0x100?0xff:m_EndptBuget.actual_period),
m_fIsHighSpeed?(m_EndptBuget.start_frame*MICROFRAMES_PER_FRAME+ m_EndptBuget.start_microframe):m_EndptBuget.start_frame,
m_fIsHighSpeed);
// Interrupt QHs are a bit complicated. See comment
// in Initialize() routine as well.
//
status = requestOK;
}
LeaveCriticalSection( &m_csPipeLock );
if (status == requestOK) {
BOOL bReturn = m_pCEhcd->AddToBusyPipeList(this, FALSE);
ASSERT(bReturn == TRUE);
}
DEBUGMSG( ZONE_PIPE, (TEXT("-CInterruptPipe::OpenPipe, returning HCD_REQUEST_STATUS %d\n"), status) );
return status;
}
// ******************************************************************
// Scope: public (Implements CPipe::ClosePipe = 0)
HCD_REQUEST_STATUS CInterruptPipe::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("+CBulkPipe(%s)::ClosePipe\n"), GetPipeType() ) );
HCD_REQUEST_STATUS status = requestFailed;
m_pCEhcd->RemoveFromBusyPipeList(this );
EnterCriticalSection( &m_csPipeLock );
if ( m_pPipeQHead) {
AbortQueue( );
m_pCEhcd->PeriodDeQueueuQHead( m_pPipeQHead );
//delete m_pPipeQHead;
DWORD dwPhysAddr = m_pPipeQHead->GetPhysAddr();
m_pPipeQHead->~CQH();
m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)m_pPipeQHead, dwPhysAddr , CPHYSMEM_FLAG_HIGHPRIORITY | CPHYSMEM_FLAG_NOBLOCK);
m_pPipeQHead = NULL;
status = requestOK;
}
LeaveCriticalSection( &m_csPipeLock );
return status;
}
// ******************************************************************
// Scope: private (Implements CPipe::AreTransferParametersValid = 0)
BOOL CInterruptPipe::AreTransferParametersValid( const STransfer *pTransfer ) const
//
// Purpose: Check whether this class' transfer parameters are valid.
// This includes checking m_transfer, m_pPipeQH, etc
//
// Parameters: None (all parameters are vars of class)
//
// Returns: TRUE if parameters valid, else FALSE
//
// Notes: Assumes m_csPipeLock already held
// ******************************************************************
{
if (pTransfer == NULL)
return FALSE;
DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("+CInterruptPipe::AreTransferParametersValid\n")) );
// these parameters aren't used by CInterruptPipe, so if they are non NULL,
// it doesn't present a serious problem. But, they shouldn't have been
// passed in as non-NULL by the calling driver.
DEBUGCHK( pTransfer->adwIsochErrors == NULL && // ISOCH
pTransfer->adwIsochLengths == NULL && // ISOCH
pTransfer->aLengths == NULL && // ISOCH
pTransfer->lpvControlHeader == NULL ); // CONTROL
// this is also not a serious problem, but shouldn't happen in normal
// circumstances. It would indicate a logic error in the calling driver.
DEBUGCHK( !(pTransfer->lpStartAddress == NULL && pTransfer->lpvNotifyParameter != NULL) );
// DWORD pTransfer->dwStartingFrame (ignored - ISOCH)
// DWORD pTransfer->dwFrames (ignored - ISOCH)
BOOL fValid = ( m_pPipeQHead!= NULL &&
m_bDeviceAddress > 0 && m_bDeviceAddress <= USB_MAX_ADDRESS &&
(pTransfer->lpvBuffer != NULL || pTransfer->dwBufferSize == 0) &&
// paClientBuffer could be 0 or !0
pTransfer->lpfComplete != NULL &&
pTransfer->lpdwBytesTransferred != NULL &&
pTransfer->lpdwError != NULL );
DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("-CInterruptPipe::AreTransferParametersValid, returning BOOL %d\n"), fValid) );
return fValid;
}
#define NUM_OF_PRE_ALLOCATED_TD 0x100
// ******************************************************************
// 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -