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

📄 uhci.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 5 页
字号:
      gBS->FreePool(HcDev);
    }    
    
    gBS->CloseProtocol (
         Controller, 
         &gEfiPciIoProtocolGuid, 
         This->DriverBindingHandle,   
         Controller   
         );
    return EFI_OUT_OF_RESOURCES ;
  }
  
  //
  //  Init interrupt list head in the HcDev structure.
  //
  InitializeListHead (&(HcDev->InterruptListHead)) ;

  //
  //  Create timer for interrupt transfer result polling
  //
  Status = gBS->CreateEvent (
            EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL, 
            EFI_TPL_NOTIFY, 
            MonitorInterruptTrans, 
            HcDev, 
            &HcDev->InterruptTransTimer
            ) ;
  if (EFI_ERROR(Status)) {
    
    FreeFrameListEntry(HcDev);
    
    gBS->UninstallProtocolInterface(
                  Controller,
                  &gEfiUsbHcProtocolGuid,
                  &HcDev->UsbHc
                  ) ;
    
    if(HcDev != NULL) {
      gBS->FreePool(HcDev);
    }    
    
    gBS->CloseProtocol (
         Controller, 
         &gEfiPciIoProtocolGuid, 
         This->DriverBindingHandle,
         Controller   
         );
    return EFI_UNSUPPORTED;
  }

  //
  // Here set interrupt transfer polling timer in 50ms unit.
  //
  Status = gBS->SetTimer(HcDev->InterruptTransTimer, TimerPeriodic, 50*1000*10);
  if (EFI_ERROR(Status)) {
    gBS->CloseEvent(HcDev->InterruptTransTimer);
    
    FreeFrameListEntry(HcDev);
    
    gBS->UninstallProtocolInterface(
                  Controller,
                  &gEfiUsbHcProtocolGuid,
                  &HcDev->UsbHc
                  ) ;
    
    if(HcDev != NULL) {
      gBS->FreePool(HcDev);
    }    
    
    gBS->CloseProtocol (
         Controller, 
         &gEfiPciIoProtocolGuid, 
         This->DriverBindingHandle,   
         Controller
         );
    return EFI_UNSUPPORTED;
  }
  
  //
  // QH,TD structures must in common buffer that will be
  // accessed by both cpu and usb bus master at the same time.
  // so, there must has memory management for QH,TD structures.
  //
  Status = InitializeMemoryManagement (HcDev);
  if (EFI_ERROR(Status)) {

    gBS->SetTimer(HcDev->InterruptTransTimer,TimerCancel, 0) ;
    
    gBS->CloseEvent(HcDev->InterruptTransTimer);
    
    FreeFrameListEntry(HcDev);
    
    gBS->UninstallProtocolInterface(
                  Controller,
                  &gEfiUsbHcProtocolGuid,
                  &HcDev->UsbHc
                  ) ;
    
    if(HcDev != NULL) {
      gBS->FreePool(HcDev);
    }    
    
    gBS->CloseProtocol (
         Controller, 
         &gEfiPciIoProtocolGuid, 
         This->DriverBindingHandle,   
         Controller
         );
    return Status;
  }
  
  //
  // component name protocol.
  //
  HcDev->ControllerNameTable = NULL;
  EfiLibAddUnicodeString (
    "eng", 
    gUhciComponentName.SupportedLanguages, 
    &HcDev->ControllerNameTable, 
    L"Usb Universal Host Controller"
  );

  return EFI_SUCCESS ;    
}


EFI_STATUS
UnInstallUHCInterface(
  IN  EFI_HANDLE            Controller,
  IN  EFI_USB_HC_PROTOCOL   *This
  )
{
  USB_HC_DEV    *HcDev ;  
  
  HcDev = USB_HC_DEV_FROM_THIS(This) ;
  
  gBS->UninstallProtocolInterface(
            Controller,
            &gEfiUsbHcProtocolGuid,
            &HcDev->UsbHc
            ) ;
  
  //
  // first stop USB Host Controller
  //
  This->SetState (This,EfiUsbHcStateHalt);
  
  //
  // Delete interrupt transfer polling timer
  //
  gBS->SetTimer(HcDev->InterruptTransTimer,TimerCancel, 0) ;
  gBS->CloseEvent(HcDev->InterruptTransTimer) ;
  
  //
  // Delete all the asynchronous interrupt transfers in the interrupt list 
  // and free associated memory
  //
  ReleaseInterruptList(HcDev,&(HcDev->InterruptListHead)) ;
  
  //
  // free Frame List Entry.
  //
  FreeFrameListEntry(HcDev);  
  
  //
  // Free common buffer allocated for QH,TD structures
  //
  DelMemoryManagement (HcDev);    

  if (HcDev->ControllerNameTable) {
    EfiLibFreeUnicodeStringTable (HcDev->ControllerNameTable);
  }

  //
  // Disable the USB Host Controller
  //
  HcDev->PciIo->Attributes (
                  HcDev->PciIo,
                  EfiPciIoAttributeOperationDisable,
                  EFI_PCI_DEVICE_ENABLE, 
                  NULL
                  );

  gBS->FreePool(HcDev) ;
  
  return EFI_SUCCESS ;  
}


EFI_STATUS
UHCIDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                     Controller,
  IN  UINTN                          NumberOfChildren,
  IN  EFI_HANDLE                     *ChildHandleBuffer
  )
/*++
  
  Routine Description:
  
  Arguments:
  
  Returns:
  
--*/       
{
  EFI_USB_HC_PROTOCOL   *UsbHc;
  EFI_STATUS            OpenStatus;

  OpenStatus = gBS->OpenProtocol(
                       Controller,   
                       &gEfiUsbHcProtocolGuid,  
                       &UsbHc,
                       This->DriverBindingHandle,     
                       Controller,   
                       EFI_OPEN_PROTOCOL_GET_PROTOCOL
                       );   

  //
  // Test whether the Controller handler passed in is a valid
  // Usb controller handle that should be supported, if not,
  // return the error status directly
  //
  if (EFI_ERROR (OpenStatus)) {
    return OpenStatus;
  }

  //
  // free all the controller related memory and uninstall UHCI Protocol.
  //         
  UnInstallUHCInterface(Controller,UsbHc);  
  
  gBS->CloseProtocol (
           Controller, 
           &gEfiPciIoProtocolGuid, 
           This->DriverBindingHandle, 
           Controller
           );
    
  return EFI_SUCCESS;

}


EFI_STATUS
UHCIReset(
  IN  EFI_USB_HC_PROTOCOL    *This,
  IN  UINT16                 Attributes
  )
/*++
  
  Routine Description:
    Provides software reset for the USB host controller.
  
  Arguments:
  
  This        A pointer to the EFI_USB_HC_PROTOCOL instance.  
  
  Attributes  A bit mask of the reset operation to perform. 
              See below for a list of the supported bit mask values.
  
  #define EFI_USB_HC_RESET_GLOBAL           0x0001
  #define EFI_USB_HC_RESET_HOST_CONTROLLER  0x0002

  EFI_USB_HC_RESET_GLOBAL 
        If this bit is set, a global reset signal will be sent to the USB bus.
        This resets all of the USB bus logic, including the USB host 
        controller hardware and all the devices attached on the USB bus.
  EFI_USB_HC_RESET_HOST_CONTROLLER  
        If this bit is set, the USB host controller hardware will be reset. 
        No reset signal will be sent to the USB bus.
  
  Returns:
    EFI_SUCCESS 
        The reset operation succeeded.
    EFI_INVALID_PARAMETER 
        Attributes is not valid.
    EFI_DEVICE_ERROR  
        An error was encountered while attempting to perform 
        the reset operation.
--*/
{  
  BOOLEAN       Match;
  USB_HC_DEV    *HcDev;
  UINT32        CommandRegAddr;
  UINT32        FlBaseAddrReg;
  UINT16        Command;
  
  Match           = FALSE;
  HcDev           = USB_HC_DEV_FROM_THIS(This);
  
  CommandRegAddr  = (UINT32)(USBCMD);
  FlBaseAddrReg   = (UINT32)(USBFLBASEADD);
  
  if ((Attributes & EFI_USB_HC_RESET_GLOBAL) != 0) {
    Match = TRUE;    
    //
    // set the Global Reset bit in the command register
    //
    Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
    Command |= USBCMD_GRESET;
    WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);

    //
    // wait 20ms to let reset complete
    // (the UHCI spec asks for a minimum of 10ms to let reset complete)
    //
    gBS->Stall(20000);
    
    //
    // Clear the Global Reset bit to zero.
    //
    Command &= ~USBCMD_GRESET;
    WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
    
    gBS->Stall(10000);     
  }
  
  if ((Attributes & EFI_USB_HC_RESET_HOST_CONTROLLER) != 0) {
    Match = TRUE;
    //
    // set Host Controller Reset bit to 1
    //
    Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
    Command |= USBCMD_HCRESET;
    WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
    //
    // this bit will be reset by Host Controller when reset is completed.
    //
    gBS->Stall(10000);     // wait 10ms to let reset complete
  }
  
  if (!Match) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Delete all old transactions on the USB bus
  //
  CleanUsbTransactions (HcDev);
  
  //
  // Initialize Universal Host Controller's Frame List Data Structure
  //
  InitFrameList (HcDev);
  
  // 
  // Reset may cause Frame List Base Address Register reset to zero,
  // so set the original value back again.
  //  
  SetFrameListBaseAddress(
    HcDev->PciIo,
    FlBaseAddrReg,
    (UINT32)((UINTN)HcDev->FrameListEntry)
  );
  
  return EFI_SUCCESS;  
} 

EFI_STATUS
UHCIGetState (
  IN  EFI_USB_HC_PROTOCOL    *This,
  OUT EFI_USB_HC_STATE      *State
  )
/*++
  
  Routine Description:
    Retrieves current state of the USB host controller.
  
  Arguments:
    
    This      A pointer to the EFI_USB_HC_PROTOCOL instance.
    
    State     A pointer to the EFI_USB_HC_STATE data structure that 
              indicates current state of the USB host controller.  
              Type EFI_USB_HC_STATE is defined below.
              
    typedef enum {
      EfiUsbHcStateHalt,
      EfiUsbHcStateOperational,
      EfiUsbHcStateSuspend,
      EfiUsbHcStateMaximum
    } EFI_USB_HC_STATE;
  
  Returns:
    EFI_SUCCESS 
            The state information of the host controller was returned in State.
    EFI_INVALID_PARAMETER 
            State is NULL.
    EFI_DEVICE_ERROR  
            An error was encountered while attempting to retrieve the 
            host controller's current state.  
--*/        
{
  USB_HC_DEV    *HcDev;
  UINT32        CommandRegAddr;
  UINT32        StatusRegAddr;
  UINT16        UhcCommand;
  UINT16        UhcStatus;
  
  if (State == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  HcDev           = USB_HC_DEV_FROM_THIS(This);

  CommandRegAddr  = (UINT32)(USBCMD);
  StatusRegAddr   = (UINT32)(USBSTS);
  
  UhcCommand = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
  UhcStatus = ReadUHCCommandReg(HcDev->PciIo,StatusRegAddr);
  
  if (UhcCommand & USBCMD_EGSM) {
    *State = EfiUsbHcStateSuspend;
    return EFI_SUCCESS;
  } 

  if ((UhcStatus & USBSTS_HCH) == 0) {
    *State = EfiUsbHcStateOperational;    
  } else {
    *State = EfiUsbHcStateHalt;
  }
    
  return EFI_SUCCESS;  
}


EFI_STATUS
UHCISetState (
  IN  EFI_USB_HC_PROTOCOL    *This,
  IN  EFI_USB_HC_STATE       State
  )
/*++
  
  Routine Description:
    Sets the USB host controller to a specific state.
  
  Arguments:
    
    This      A pointer to the EFI_USB_HC_PROTOCOL instance.

    State     Indicates the state of the host controller that will be set.
  
  Returns:
    EFI_SUCCESS 
          The USB host controller was successfully placed in the state 
          specified by State.
    EFI_INVALID_PARAMETER 
          State is invalid.
    EFI_DEVICE_ERROR  
          Failed to set the state specified by State due to device error.  
--*/
{
  USB_HC_DEV          *HcDev;
  UINT32              CommandRegAddr;
  UINT32              StatusRegAddr;
  UINT16              Command;
  EFI_USB_HC_STATE    CurrentState;
  EFI_STATUS          Status;

  HcDev           = USB_HC_DEV_FROM_THIS(This) ;

  CommandRegAddr  = (UINT32)(USBCMD);
  StatusRegAddr   = (UINT32)(USBSTS);
  
  Status = UHCIGetState (This,&CurrentState);

⌨️ 快捷键说明

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