Wince USB otg驅動中關於函式CHub::HubStatusChangeThread
該函式是USB驅動中,監視hub狀態改變的執行緒函式。
Root hub的監視執行緒在OTG_Init函式被呼叫時建立。
External Hub的監視執行緒在External Hub插入到Root Hub時被建立。
線上程剛啟動的時候(線上程迴圈體之外),需要進行一些操作。
// before we can process port changes, we need
// to power all ports
// 函式PowerAllHubPorts在CRootHub類中的實現為空。
// 在類CExternalHub中,遍歷Hub上的所有Port,
// 呼叫函式SetOrClearFeature設定各個Port的Feature。
// 函式SetOrClearFeature中,呼叫Control Pipe的IssueTransfer函式進行設定
// status = m_ppCPipe[ ENDPOINT0_CONTROL_PIPE ]->IssueTransfer
// 然後等待設定的完成
// WaitForSingleObject( m_hHubStatusChangeEvent, INFINITE );
// 然後呼叫Control Pipe的AbortTransfer函式結束傳輸
// m_ppCPipe[ ENDPOINT0_CONTROL_PIPE ]->AbortTransfer
fSuccess = PowerAllHubPorts();
// Sleep 一段時間,等待Hub上電完成。
Sleep( 2 * m_usbHubDescriptor.bPowerOnToPowerGood );
// 設定External Hub的remove wakeup feature。
// 因為該設定只是針對External Hub的,所以Root Hub中該函式為空
// External Hub中,呼叫Control Pipe的IssueTransfer函式進行設定
// status = m_ppCPipe[ ENDPOINT0_CONTROL_PIPE ]->IssueTransfer
// 然後等待設定的完成
// WaitForSingleObject( m_hHubStatusChangeEvent, INFINITE );
// 然後呼叫Control Pipe的AbortTransfer函式結束傳輸
// m_ppCPipe[ ENDPOINT0_CONTROL_PIPE ]->AbortTransfer
// 下面進入執行緒迴圈體
// m_fHubThreadClosing在函式CHub::HandleDetach中被設定為True
while ( !m_fHubThreadClosing )
// 等待事件m_hHubSuspendBlockEvent
// 該事件在函式CHub::HandleDetach和函式CHub::ResumeNotification中被設定
fSuccess = (WaitForSingleObject(m_hHubSuspendBlockEvent,INFINITE) == WAIT_OBJECT_0);
// 呼叫函式WaitForPortStatusChange等待Port狀態改變
// 函式WaitForPortStatusChange在Root Hub和External Hub中有不同的實現。
// 在Root Hub中,首先看HCD中是否支援Root Hub Status Change,若不支援,則在此處等待m_hHubStatusChangeEvent。
// 然後遍歷Hub上的每個Port,呼叫函式CHW::DidPortStatusChange檢查Port狀態是否改變。
// 若改變,呼叫函式GetStatus獲取Port狀態。
// 在External Hub中,首先呼叫函式GetStatusChangeBitmap等待直到Port狀態改變的發生
// (通過呼叫control Pipe的IssueTransfer函式)。
// 通過獲取的BitMap處理所有的狀態改變。
// 呼叫函式GetStatus獲取狀態改變port的狀態,然後呼叫函式SetOrClearFeature清除Feature。
fSuccess = WaitForPortStatusChange( port, hubStatus );
// 判斷Port是否為over current(過電流)
if (hubStatus.change.port.OverCurrentChange ) {
if ( hubStatus.status.port.PortOverCurrent ) {
// 如果port為over current,呼叫函式DetachDevice去Detach port上的device
DetachDevice( port );
// 然後呼叫函式SetOrClearFeature清除Feature
SetOrClearFeature( port, USB_REQUEST_CLEAR_FEATURE, USB_HUB_FEATURE_PORT_POWER );
else
// 如果port為over current
hubStatus.change.port.ConnectStatusChange = 1;
// 判斷是否為suspend change,若是,進行Resume Notification
m_ppCDeviceOnPort[port-1]->ResumeNotification();
// 判斷是否是Enable change
if ( hubStatus.change.port.PortEnableChange &&
!hubStatus.status.port.PortEnabled &&
hubStatus.status.port.PortConnected ) {
// 若是,並且Device is present,呼叫函式DetachDevice,並設定ConnectStatusChange
DetachDevice( port );
hubStatus.change.port.ConnectStatusChange = 1;
// 檢查connect changes
// 如果是連線change,並且裝置已經存在,需要呼叫DetachDevice函式
DetachDevice(port);
// 在一個迴圈體中呼叫函式GetStatus獲取Port狀態(防抖動處理de-bouncing)
// 如果獲取失敗,設定port connect狀態,並退出迴圈
hubStatus.status.port.PortConnected = FALSE;
// 如果獲取成功,並且為連線狀態改變,呼叫函式SetOrClearFeature清除Feature,並且繼續迴圈
// ack the status change and wait again
// 否則,跳出迴圈
// 接下來需要Reset port並重新獲取speed information
// 函式ResetAndEnablePort在root hub和external hub中的實現不同
// root hub中,直接呼叫了HCD物件的ResetAndEnablePort函式
// BOOL fSuccess = m_pCHcd->ResetAndEnablePort( port );
// external hub中,呼叫SetOrClearFeature函式,
// 首先,設定USB_HUB_FEATURE_PORT_RESET
// 然後,清除USB_HUB_FEATURE_C_PORT_RESET
// 函式ResetAndEnablePort的註釋:
// reset/enable device on the given port so that when this
// function completes, the device is listening on address 0
ResetAndEnablePort( port );
Sleep(20);
GetStatus(port , hubStatus);
// 判斷獲取的狀態是否為連線狀態
if ( hubStatus.status.port.PortConnected ) {
// 若是
// 判斷是否為root hub上的otg port
// 若是
::OTGHNP_EventNotify(HNP_EVENT_HOST_CONNECT);
// 呼叫函式AttachDevice
AttachDevice( port,
hubStatus.status.port.DeviceIsLowSpeed,
m_fIsHighSpeed?hubStatus.status.port.DeviceIsHighSpeed:FALSE );
追加個參考結構體:
typedef struct _USB_HUB_DESCRIPTOR {
UCHAR bDescriptorLength; // Length of this descriptor
UCHAR bDescriptorType; // Hub configuration type
UCHAR bNumberOfPorts; // number of ports on this hub
USHORT wHubCharacteristics; // Hub Charateristics
UCHAR bPowerOnToPowerGood; // port power on till power good in 2ms
UCHAR bHubControlCurrent; // max current in mA
//
// room for 255 ports power control and removable bitmask
UCHAR bRemoveAndPowerMask[64];
} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
成員變數m_usbHubDescriptor的賦值是在建構函式中進行的。
Root Hub的該成員,是在函式CEhcd::DeviceInitialize中初始化結構體的各成員,然後以其為引數建立Root Hub物件。
External Hub的該成員,是在函式CHub::AttachDevice中,呼叫函式CHub::GetDescriptor獲取,然後以其為引數建立External Hub物件。函式CHub::GetDescriptor中通過呼叫Control Pipe的函式IssueTransfer來獲取Descriptor。