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。

posted @ 2011-04-05 22:09  andriod2012  阅读(753)  评论(0编辑  收藏  举报