📄 cdevice.cpp
字号:
//
// See USB spec section 9.6.3
// ******************************************************************
{
DEBUGCHK( pDescriptor != NULL );
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("+Dump USB_INTERFACE_DESCRIPTOR\n")) );
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbLength = 0x%02x\n"), pDescriptor->bLength ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbDescriptorType = 0x%02x\n"), pDescriptor->bDescriptorType ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbInterfaceNumber = 0x%02x\n"), pDescriptor->bInterfaceNumber ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbAlternateSetting = 0x%02x\n"), pDescriptor->bAlternateSetting ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbNumEndpoints = 0x%02x\n"), pDescriptor->bNumEndpoints ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbInterfaceClass = 0x%02x\n"), pDescriptor->bInterfaceClass ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbInterfaceSubClass = 0x%02x\n"), pDescriptor->bInterfaceSubClass ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbInterfaceProtocol = 0x%02x\n"), pDescriptor->bInterfaceProtocol ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tiInterface = 0x%02x\n"), pDescriptor->iInterface ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("-Dump USB_INTERFACE_DESCRIPTOR\n")) );
}
#endif // DEBUG
#ifdef DEBUG
// ******************************************************************
void CDevice::DumpEndpointDescriptor( IN const PUSB_ENDPOINT_DESCRIPTOR pDescriptor ) const
//
// Purpose: print out the contents of the descriptor via DEBUGMSG
//
// Parameters: pDescriptor - pointer to descriptor
//
// Returns: Nothing.
//
// Notes: Used in debug mode only
//
// See USB spec section 9.6.4
// ******************************************************************
{
static const TCHAR* cszEndpointTypes[4] = {
TEXT("CONTROL"),
TEXT("ISOCHRONOUS"),
TEXT("BULK"),
TEXT("INTERRUPT")
};
DEBUGCHK( pDescriptor != NULL );
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("+Dump USB_ENDPOINT_DESCRIPTOR\n")) );
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbLength = 0x%02x\n"), pDescriptor->bLength ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbDescriptorType = 0x%02x\n"), pDescriptor->bDescriptorType ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbEndpointAddress = 0x%02x\n"), pDescriptor->bEndpointAddress ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\tbEndpointAddress, endpoint # = %d\n"), pDescriptor->bEndpointAddress & TD_ENDPOINT_MASK ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\tbEndpointAddress, direction = %s\n"), (USB_ENDPOINT_DIRECTION_IN(pDescriptor->bEndpointAddress) ? TEXT("IN") : TEXT("OUT")) ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbmAttributes = 0x%02x\n"), pDescriptor->bmAttributes ));
DEBUGCHK( (pDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) < 4 );
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\tbmAttributes, endpoint type = %s\n"), cszEndpointTypes[ pDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK ] ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\twMaxPacketSize = 0x%04x\n"), pDescriptor->wMaxPacketSize ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbInterval = 0x%02x\n"), pDescriptor->bInterval ));
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("-Dump USB_ENDPOINT_DESCRIPTOR\n")) );
}
#endif // DEBUG
#ifdef DEBUG
// ******************************************************************
void CDevice::DumpExtendedBytes( IN const PBYTE pByteArray, IN const DWORD dwSize ) const
//
// Purpose: print out the bytes of pByteArray
//
// Parameters: pByteArray - array of extended bytes for a descriptor
//
// dwSize - number of entries in pByteArray
//
// Returns: Nothing.
//
// Notes: Used in debug mode only
// ******************************************************************
{
DEBUGCHK( pByteArray != NULL && dwSize > 0 );
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("+Dump extended bytes, size = %d\n"), dwSize) );
for ( DWORD dwPrinted = 0; dwPrinted < dwSize; dwPrinted += 4 ) {
DWORD dwFourBytes = 0;
for ( UCHAR index = 0; index < 4; index++ ) {
dwFourBytes <<= 8;
if ( dwPrinted + index < dwSize ) {
dwFourBytes |= pByteArray[ dwPrinted + index ];
}
}
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tBytes %d to %d = 0x%08x\n"), dwPrinted + 1, dwPrinted + 4, dwFourBytes ) );
}
DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("-Dump extended bytes, size = %d\n"), dwSize) );
}
#endif // DEBUG
// ******************************************************************
CHub::CHub( IN const UCHAR address,
IN const USB_DEVICE_INFO& rDeviceInfo,
IN const BOOL fIsLowSpeed,IN const BOOL fIsHighSpeed,
IN const UCHAR tierNumber,
IN const USB_HUB_DESCRIPTOR& rUsbHubDescriptor,
IN CHcd * const pCHcd ,
IN CHub * const pAttachedHub,const UCHAR uAttachedPort)
//
// Purpose: Constructor for CHub
//
// Parameters: address, rDeviceInfo, fIsLowSpeed, tierNumber - see CDevice::CDevice
//
// rUsbHubDescriptor - USB descriptor for a hub
//
// Returns: Nothing.
//
// Notes: Do not initialize static variables here. Do that in
// the Initialize() routine
// ******************************************************************
: CDevice( address, rDeviceInfo, fIsLowSpeed,fIsHighSpeed, tierNumber,pCHcd , pAttachedHub,uAttachedPort ) // call base class constructor
, m_pCHcd(pCHcd)
, m_usbHubDescriptor( rUsbHubDescriptor ) // USB descriptor of this hub
, m_ppCDeviceOnPort( NULL ) // dynamic array of pointers to the devices on this hub's ports
, m_fHubThreadClosing( FALSE ) // indicator to thread that it should close
, m_hHubStatusChangeEvent( NULL ) // event for hub status change thread
, m_hHubStatusChangeThread( NULL ) // checks for connect changes on the hub's ports
{
TCHAR szUSBHostDetachName[30];
DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("+CHub::CHub\n")) );
m_pDetachedDevice=NULL;
m_pDetachedDeviceHandled = CreateEvent(NULL,TRUE,FALSE,NULL); // Manual Reset Event;
m_hHubSuspendBlockEvent = CreateEvent(NULL,TRUE,TRUE,NULL); // Manual Reset Event;
DEBUGCHK( rDeviceInfo.Descriptor.bDeviceClass == USB_DEVICE_CLASS_HUB &&
rUsbHubDescriptor.bDescriptorType == USB_HUB_DESCRIPTOR_TYPE &&
rUsbHubDescriptor.bDescriptorLength >= USB_HUB_DESCRIPTOR_MINIMUM_SIZE &&
rUsbHubDescriptor.bNumberOfPorts > 0 &&
tierNumber <= USB_MAXIMUM_HUB_TIER );
DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("-CHub::CHub\n")) );
// Add for Freescale
//RETAILMSG(1, (TEXT("CHUB::CHUB contructor\r\n")));
if (gfnIsOTGSupport() && (m_tierNumber == 0))
{
StringCbCopy(szUSBHostDetachName, sizeof(szUSBHostDetachName), USBHostDetachName);
StringCbCat(szUSBHostDetachName, sizeof(szUSBHostDetachName), gfnGetOTGGroup());
ghDetach = CreateEvent(NULL, FALSE, FALSE, szUSBHostDetachName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
DEBUGMSG(ZONE_FUNCTION, (TEXT("Cdevice: Opened an existing Func Event\r\n")));
else
DEBUGMSG(ZONE_FUNCTION, (TEXT("CDevice: Created a new Func Event\r\n")));
if (ghDetach == NULL)
DEBUGMSG(ZONE_FUNCTION, (TEXT("Cdevice: Create Event Failed for func!\r\n")));
}
}
// ******************************************************************
CHub::~CHub( )
//
// Purpose: Destructor for CHub
//
// Parameters: None
//
// Returns: Nothing.
//
// Notes: Do not delete static variables here. Do that in
// DeInitialize();
// ******************************************************************
{
DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("+CHub::~CHub\n")) );
// this should have been taken care of in HandleDetach,
// or if EnterOperationalState failed.
DEBUGCHK( m_hHubStatusChangeEvent == NULL );
DEBUGCHK( m_hHubStatusChangeThread == NULL );
DEBUGCHK( m_pDetachedDevice == NULL);
#ifdef DEBUG
if ( m_ppCDeviceOnPort != NULL ) {
for ( UCHAR port = 1; port <= m_usbHubDescriptor.bNumberOfPorts; port++ ) {
// devices should have been freed by HandleDetach
DEBUGCHK( m_ppCDeviceOnPort[ port - 1 ] == NULL );
}
}
#endif // DEBUG
//RETAILMSG(1, (TEXT("Free CHUB\r\n")));
if (m_ppCDeviceOnPort){
delete [] m_ppCDeviceOnPort;
m_ppCDeviceOnPort = NULL;
}
if (m_pPortState) {
delete m_pPortState;
m_pPortState = NULL;
}
if (m_pAddedTT){
delete m_pAddedTT;
m_pAddedTT = NULL;
}
if (m_pDetachedDeviceHandled)
CloseHandle(m_pDetachedDeviceHandled );
if (m_hHubSuspendBlockEvent)
CloseHandle(m_hHubSuspendBlockEvent);
// nothing to do with m_usbHubDescriptor
// nothing to do with m_fHubThreadClosing
// rest of work done in ~CDevice
DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("-CHub::~CHub\n")) );
}
// ******************************************************************
DWORD CALLBACK CHub::HubStatusChangeThreadStub( IN PVOID context )
//
// Purpose: Stub function for starting HubStatusChangeThread
//
// Parameters: context - pointer to descendant of CHub which contains
// the actual HubStatusChangeThread function
//
// Returns: Return value of HubStatusChangeThread
//
// Notes:
// ******************************************************************
{
return ((CHub*)context)->HubStatusChangeThread();
}
// ******************************************************************
DWORD CHub::HubStatusChangeThread( void )
//
// Purpose: Main hub thread for handling changes to the hub's ports
//
// Parameters: None
//
// Returns: 0 on thread exit
//
// Notes: This routine needs to work for both root/external hubs
// ******************************************************************
{
DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("+CHub(%s tier %d)::HubStatusChangeThread\n"), GetDeviceType(), m_tierNumber ) );
DEBUGCHK( m_hHubStatusChangeEvent != NULL && m_hHubStatusChangeThread != NULL );
UCHAR port;
USB_HUB_AND_PORT_STATUS hubStatus;
BOOL fSuccess = FALSE;
DWORD dwForceDetach = 0;
//DEBUGMSG(1, (TEXT("HubStatusChangeThread for %s\r\n"), GetUSBPortType()));
//RETAILMSG(1, (TEXT("+HubStatusChangeThread this(0x%x)\r\n"), this));
// before we can process port changes, we need
// to power all ports
while ( !m_fHubThreadClosing && !fSuccess) {
fSuccess = PowerAllHubPorts();
}
if ( !m_fHubThreadClosing ) {
#if 0
Sleep( 2 * m_usbHubDescriptor.bPowerOnToPowerGood );
#else
// According to the USB spec 1.1, section 7.1.7.1, there
// is supposed to be a delay of up to 100ms (t2) before the device
// can signal attach. I don't know if the software is
// supposed to implement this delay. No harm in implementing
// it though.
Sleep( 100 + 2 * m_usbHubDescriptor.bPowerOnToPowerGood );
#endif
}
SetOrClearRemoteWakup(TRUE);
while ( !m_fHubThreadClosing ) {
//Add for freescale
//Just need to wait for RootHUB to return
//if not RootHUB, ignore. Otherwise jump back to XVR
//it is instance of RootHUB then, check the m_pPortState[0] == 2
//RETAILMSG(1, (TEXT("m_pPortState[0] = 0x%x\r\n"), m_pPortState[0]));
if ((m_tierNumber == 0) && (m_pPortState[0]==2))
{
// Make sure the power up sequence is done properly before
// we switch back to transceiver mode. We have problem of not able to wakeup the backlight
if (dwForceDetach)
Sleep(500);
m_pPortState[0] = 0;
if (gfnIsOTGSupport())
{
DEBUGMSG(1, (TEXT("HubPortStatusChange request back to XVR now\r\n")));
SetEvent(ghDetach);
}
else
{
DEBUGMSG(1, (TEXT("GetForceReAttach = 0x%x\r\n"), m_pCHcd->GetForceReAttach()));
if (m_pCHcd->GetForceReAttach() == 1)
{
m_pCHcd->SetForceReAttach(2);
// This is the problem on H1, after resume from suspend, it doesn't
// generate an event to re-enumerate the host port again. We need to manually
// set the event again to make sure it is restore the system properly.
m_pCHcd->SignalHubStatusChange();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -