Wince USB otg驅動中關於函數CHub::HubStatusChangeThread .

來源:互聯網
上載者:User

 

該函數是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。

該函數是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。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.