⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uhci.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (EFI_ERROR(Status)) {
    return Status;
  }
  
  switch (State) {
    
    case EfiUsbHcStateHalt:      
      if (CurrentState == EfiUsbHcStateHalt) {
        return EFI_SUCCESS;
      }
      
      Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
      Command &= ~USBCMD_RS ;
      WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
      StatusRegAddr = (UINT32)(USBSTS);
      //
      // ensure the HC is in halt status after send the stop command
      //
      if(WaitForUHCHalt(HcDev->PciIo,StatusRegAddr,STALL_1_SECOND) == EFI_TIMEOUT) {
        return EFI_DEVICE_ERROR ;
      }
      break;
      
    case EfiUsbHcStateOperational:
      if (IsHostSysErr(HcDev->PciIo,StatusRegAddr) 
          || IsHCProcessErr(HcDev->PciIo,StatusRegAddr)) {
        return EFI_DEVICE_ERROR;
      }
      
      switch (CurrentState) {
        
        case EfiUsbHcStateOperational:
          return EFI_SUCCESS;
        
        case EfiUsbHcStateHalt:
          //
          // Set Run/Stop bit to 1.
          //
          Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
          Command |= USBCMD_RS ;
          WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command) ;
          break;
          
        case EfiUsbHcStateSuspend:
          Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
          
          //
          // FGR(Force Global Resume) bit is 0
          //
          if((Command | (~USBCMD_FGR)) != 0xFF) {
            //
            // Write FGR bit to 1
            //
            Command |= USBCMD_FGR;
            WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);       
          }
          
          //
          // wait 20ms to let resume complete
          // (20ms is specified by UHCI spec)
          //
          gBS->Stall(20000);
        
          //
          // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0 
          //
          Command &= ~USBCMD_FGR;
          Command &= ~USBCMD_EGSM;
          WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr, Command);
          break;
      }
      break;
      
    case EfiUsbHcStateSuspend:  
      if (CurrentState == EfiUsbHcStateSuspend) {
        return EFI_SUCCESS;
      }
      
      Status = UHCISetState (This,EfiUsbHcStateHalt);
      if (EFI_ERROR(Status)) {
        return Status;
      }
      //
      // Set Enter Global Suspend Mode bit to 1.
      //
      Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
      Command |= USBCMD_EGSM ;
      WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
      break;
      
    default:
      return EFI_INVALID_PARAMETER;
  }
  
  return EFI_SUCCESS;
}    


EFI_STATUS
UHCIGetRootHubPortNumber (
  IN  EFI_USB_HC_PROTOCOL    *This,
  OUT UINT8                  *PortNumber
  )
/*++
  
  Routine Description:
    Retrieves the number of root hub ports.
    
  Arguments:
  
    This        A pointer to the EFI_USB_HC_PROTOCOL instance.
    
    PortNumber  A pointer to the number of the root hub ports.
  
  Returns:
    EFI_SUCCESS 
          The port number was retrieved successfully.
    EFI_INVALID_PARAMETER 
          PortNumber is NULL.
    EFI_DEVICE_ERROR  
          An error was encountered while attempting to 
          retrieve the port number.  
--*/  
{
  USB_HC_DEV    *HcDev;
  UINT32        PSAddr;
  UINT16        RHPortControl;
  UINT32        Index;

  HcDev = USB_HC_DEV_FROM_THIS(This);
  
  if (PortNumber == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  *PortNumber = 0;
  
  for (Index = 0 ; Index < 2; Index ++) {
    PSAddr = (UINT32)(USBPORTSC1 + Index * 2);
    RHPortControl = ReadRootPortReg (HcDev->PciIo, PSAddr);
    //
    // Port Register content is valid
    //
    if (RHPortControl != 0xff) {
      (*PortNumber) ++;
    }
  }
  
  return EFI_SUCCESS;
}

    
EFI_STATUS
UHCIGetRootHubPortStatus (
  IN  EFI_USB_HC_PROTOCOL    *This,
  IN  UINT8                  PortNumber,
  OUT EFI_USB_PORT_STATUS    *PortStatus
  )
/*++
  
  Routine Description:
    Retrieves the current status of a USB root hub port.
  
  Arguments:
  
    This        A pointer to the EFI_USB_HC_PROTOCOL.
    
    PortNumber  Specifies the root hub port from which the status 
                is to be retrieved.  This value is zero-based. For example, 
                if a root hub has two ports, then the first port is numbered 0,
                and the second port is numbered 1.
    
    PortStatus  A pointer to the current port status bits and 
                port status change bits.  
  
  Returns:
    EFI_SUCCESS 
        The status of the USB root hub port specified by PortNumber 
        was returned in PortStatus.
    EFI_INVALID_PARAMETER 
        PortNumber is invalid.  
--*/
{
  USB_HC_DEV    *HcDev;
  UINT32        PSAddr;
  UINT16        RHPortStatus;    // root hub port status
  UINT8         TotalPortNumber;

  if (PortStatus == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  UHCIGetRootHubPortNumber(This,&TotalPortNumber);
  if(PortNumber >= TotalPortNumber) {
    return EFI_INVALID_PARAMETER;
  }
  
  HcDev       = USB_HC_DEV_FROM_THIS(This) ;

  PSAddr      = (UINT32)(USBPORTSC1 + PortNumber * 2);

  PortStatus -> PortStatus = 0 ;
  PortStatus -> PortChangeStatus = 0 ; 

  RHPortStatus = ReadRootPortReg(HcDev->PciIo,PSAddr) ;

  //
  //    Fill Port Status bits
  //
  
  //
  // Current Connect Status
  //
  if(RHPortStatus & USBPORTSC_CCS) {
    PortStatus -> PortStatus |= USB_PORT_STAT_CONNECTION ;
  }

  //
  // Port Enabled/Disabled
  //
  if(RHPortStatus & USBPORTSC_PED) {
    PortStatus -> PortStatus |= USB_PORT_STAT_ENABLE ;
  }
  
  //
  // Port Suspend
  //
  if(RHPortStatus & USBPORTSC_SUSP) {
    PortStatus -> PortStatus |= USB_PORT_STAT_SUSPEND ;
  }
  
  //
  // Port Reset
  //
  if(RHPortStatus & USBPORTSC_PR) {
    PortStatus -> PortStatus |= USB_PORT_STAT_RESET ;
  }
  
  //
  // Low Speed Device Attached
  //
  if(RHPortStatus & USBPORTSC_LSDA) {
    PortStatus -> PortStatus |= USB_PORT_STAT_LOW_SPEED ;
  }

  //
  //   Fill Port Status Change bits
  //
  
  //
  // Connect Status Change
  //
  if(RHPortStatus & USBPORTSC_CSC) {
    PortStatus -> PortChangeStatus |= USB_PORT_STAT_C_CONNECTION ;
  }
  
  //
  // Port Enabled/Disabled Change
  //
  if(RHPortStatus & USBPORTSC_PEDC) {
    PortStatus -> PortChangeStatus |= USB_PORT_STAT_C_ENABLE ;
  }

  return EFI_SUCCESS ;
}    

EFI_STATUS
UHCISetRootHubPortFeature (
  IN  EFI_USB_HC_PROTOCOL    *This,
  IN  UINT8                  PortNumber,
  IN  EFI_USB_PORT_FEATURE   PortFeature
  )
/*++
  
  Routine Description:
    Sets a feature for the specified root hub port.
  
  Arguments:
  
    This        A pointer to the EFI_USB_HC_PROTOCOL.
    
    PortNumber  Specifies the root hub port whose feature 
                is requested to be set.
    
    PortFeature Indicates the feature selector associated 
                with the feature set request. 
  
  Returns:
    EFI_SUCCESS 
        The feature specified by PortFeature was set for the 
        USB root hub port specified by PortNumber.
    EFI_INVALID_PARAMETER 
        PortNumber is invalid or PortFeature is invalid.
--*/
{
  USB_HC_DEV    *HcDev;
  UINT32        PSAddr;
  UINT32        CommandRegAddr;
  UINT16        RHPortControl;    // root hub port status
  UINT8         TotalPortNumber;
  
  UHCIGetRootHubPortNumber(This,&TotalPortNumber);
  if(PortNumber >= TotalPortNumber) {
    return EFI_INVALID_PARAMETER;
  }
  
  HcDev           = USB_HC_DEV_FROM_THIS(This) ;

  PSAddr          = (UINT32)(USBPORTSC1 + PortNumber * 2) ;
  CommandRegAddr  = (UINT32)(USBCMD) ;

  RHPortControl   = ReadRootPortReg(HcDev->PciIo,PSAddr) ;

  switch(PortFeature) {
    
    case EfiUsbPortSuspend:
      if(!(ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr) & USBCMD_EGSM)) {
        //
        // if global suspend is not active, can set port suspend
        //
        RHPortControl &= 0xfff5;
        RHPortControl |= USBPORTSC_SUSP;
      }
      break ;
      
    case EfiUsbPortReset:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_PR;        // Set the reset bit 
      break ;
  
    case EfiUsbPortPower:
      break ;
      
    case EfiUsbPortEnable:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_PED;
      break;
      
    default:
      return EFI_INVALID_PARAMETER;
  }

  WriteRootPortReg(HcDev->PciIo,PSAddr,RHPortControl) ;

  return EFI_SUCCESS ;
}    

EFI_STATUS
UHCIClearRootHubPortFeature (
  IN  EFI_USB_HC_PROTOCOL    *This,
  IN  UINT8                  PortNumber,
  IN  EFI_USB_PORT_FEATURE   PortFeature
  )
/*++
  
  Routine Description:
    Clears a feature for the specified root hub port.
  
  Arguments:
  
    This        A pointer to the EFI_USB_HC_PROTOCOL instance.
    
    PortNumber  Specifies the root hub port whose feature 
                is requested to be cleared.
    
    PortFeature Indicates the feature selector associated with the 
                feature clear request.
                  
  Returns:
    EFI_SUCCESS 
        The feature specified by PortFeature was cleared for the 
        USB root hub port specified by PortNumber.
    EFI_INVALID_PARAMETER 
        PortNumber is invalid or PortFeature is invalid.
--*/
{
  USB_HC_DEV    *HcDev;
  UINT32        PSAddr;
  UINT16        RHPortControl;
  UINT8         TotalPortNumber;
  
  UHCIGetRootHubPortNumber(This,&TotalPortNumber);
  
  if(PortNumber >= TotalPortNumber) {
    return EFI_INVALID_PARAMETER;
  }
  
  HcDev         = USB_HC_DEV_FROM_THIS(This);

  PSAddr        = (UINT32)(USBPORTSC1 + PortNumber * 2) ;

  RHPortControl = ReadRootPortReg(HcDev->PciIo,PSAddr) ;

  switch (PortFeature) {
    
    //
    // clear PORT_ENABLE feature means disable port.
    //
    case EfiUsbPortEnable:
      RHPortControl &= 0xfff5;
      RHPortControl &= ~USBPORTSC_PED ;             
      break;
    
    // 
    // clear PORT_SUSPEND feature means resume the port.
    // (cause a resume on the specified port if in suspend mode)
    //
    case EfiUsbPortSuspend:
      RHPortControl &= 0xfff5;
      RHPortControl &= ~USBPORTSC_SUSP ;            
      break;
    
    //
    // no operation
    //
    case EfiUsbPortPower:
      break;
    
    //
    // clear PORT_RESET means clear the reset signal.
    //  
    case EfiUsbPortReset:
      RHPortControl &= 0xfff5;
      RHPortControl &= ~USBPORTSC_PR ;        
      break ;
    
    //
    // clear connect status change
    //
    case EfiUsbPortConnectChange:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_CSC ;              
      break;
    
    //
    // clear enable/disable status change
    //
    case EfiUsbPortEnableChange:
      RHPortControl &= 0xfff5;
      RHPortControl |= USBPORTSC_PEDC ;             
      break;
    
    //
    // root hub does not support this request
    //
    case EfiUsbPortSuspendChange:                              
      break;
    
    //
    // root hub does not support this request
    //
    case EfiUsbPortOverCurrentChange:                         
      break;
    
    //
    // root hub does not support this request
    //
    case EfiUsbPortResetChange:
      break;
    
    default:
      return EFI_INVALID_PARAMETER ;
  }

  WriteRootPortReg(HcDev->PciIo,PSAddr,RHPortControl) ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -