ehci.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,436 行 · 第 1/5 页

C
2,436
字号
  //
  // Create and Init Perodic Frame List
  //
  Status = EhciGetCapability (
             &HcDev->Usb2Hc,
             &MaxSpeed,
             &PortNumber,
             &Is64BitCapable
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto uninstall_usb2hc_protocol;
  }
  HcDev->Is64BitCapable = Is64BitCapable;

  //
  // Create and Init Perodic Frame List
  //
  Status = InitialPeriodicFrameList (
             HcDev,
             EHCI_MAX_FRAME_LIST_LENGTH
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto uninstall_usb2hc_protocol;
  }

  //
  // Init memory pool management
  //
  Status = InitialMemoryManagement (HcDev);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto deinit_perodic_frame_list;
  }

  Status = CreateNULLQH (HcDev);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto deinit_perodic_frame_list;
  }



  //
  // Create AsyncRequest Polling Timer
  //
  Status = CreatePollingTimer (HcDev, AsyncRequestMoniter);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto deinit_null_qh;
  }

  //
  // Default Maxximum Interrupt Interval is 8,
  // it means that 8 micro frame = 1ms
  //

  //
  // Start the Host Controller
  //
  if (IsEhcHalted (HcDev)) {
    Status = StartScheduleExecution (HcDev);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto deinit_timer;
    }
  }

  //
  // Set all ports routing to EHC
  //
  Status = SetPortRoutingEhc (HcDev);
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto deinit_timer;
  }

  //
  // Component name protocol
  //
  Status = EfiLibAddUnicodeString (
             "eng",
             gEhciComponentName.SupportedLanguages,
             &HcDev->ControllerNameTable,
             L"Usb Enhanced Host Controller"
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto deinit_timer;
  }

  goto exit;

  //
  // Error handle process
  //
deinit_timer:
  DestoryPollingTimer (HcDev);
deinit_null_qh:
  DestroyNULLQH(HcDev);
  DeinitialMemoryManagement (HcDev);
deinit_perodic_frame_list:
  DeinitialPeriodicFrameList (HcDev);
uninstall_usb2hc_protocol:
  gBS->UninstallProtocolInterface (
         Controller,
         &gEfiUsb2HcProtocolGuid,
         &HcDev->Usb2Hc
         );
free_pool:
  gBS->FreePool (HcDev);
close_pciio_protocol:
  gBS->CloseProtocol (
         Controller,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

exit:
  return Status;
}

EFI_STATUS
EFIAPI
EhciDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  )
/*++

  Routine Description:

    Stop this driver on ControllerHandle. Support stoping any child handles
    created by this driver.

  Arguments:

    This              - Protocol instance pointer.
    Controller        - Handle of device to stop driver on
    NumberOfChildren  - Number of Children in the ChildHandleBuffer
    ChildHandleBuffer - List of handles for the children we need to stop.

  Returns:

    EFI_SUCCESS         Success
    EFI_DEVICE_ERROR    Fail
--*/
{
  EFI_STATUS            Status;
  EFI_USB2_HC_PROTOCOL  *Usb2Hc;
  USB2_HC_DEV           *HcDev;

  //
  // Test whether the Controller handler passed in is a valid
  // Usb controller handle that should be supported, if not,
  // return the error status directly
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsb2HcProtocolGuid,
                  &Usb2Hc,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  HcDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);

  //
  // free all the controller related memory and uninstall UHCI Protocol.
  //
  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiUsb2HcProtocolGuid,
                  Usb2Hc
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  //
  // Set Host Controller state as halt
  //
  Status = Usb2Hc->SetState (
                     Usb2Hc,
                     EfiUsbHcStateHalt
                     );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  //
  // Stop AsyncRequest Polling Timer
  //
  Status = StopPollingTimer (HcDev);
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  //
  // Destroy Asynchronous Request Event
  //
  DestoryPollingTimer (HcDev);

  //
  // Destroy Perodic Frame List
  //
  DeinitialPeriodicFrameList (HcDev);

  //
  // Destroy NULLQH
  //
  DestroyNULLQH (HcDev);

  //
  // Deinit Ehci pool memory management
  //
  DeinitialMemoryManagement (HcDev);

  //
  // Denint Unicode String Table
  //
  EfiLibFreeUnicodeStringTable (HcDev->ControllerNameTable);

  //
  // Disable the USB Host Controller
  //
  Status = HcDev->PciIo->Attributes (
                           HcDev->PciIo,
                           EfiPciIoAttributeOperationDisable,
                           EFI_PCI_DEVICE_ENABLE,
                           NULL
                           );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  gBS->FreePool (HcDev);

  gBS->CloseProtocol (
        Controller,
        &gEfiPciIoProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

exit:
  return Status;
}

EFI_STATUS
EFIAPI
EhciGetCapability (
  IN  EFI_USB2_HC_PROTOCOL *This,
  OUT UINT8                *MaxSpeed,
  OUT UINT8                *PortNumber,
  OUT UINT8                *Is64BitCapable
  )
/*++

  Routine Description:

    Retrieves the capablility of root hub ports.

  Arguments:

    This            - A pointer to the EFI_USB_HC_PROTOCOL instance.
    MaxSpeed        - A pointer to the number of the host controller.
    PortNumber      - A pointer to the number of the root hub ports.
    Is64BitCapable  - A pointer to the flag for whether controller supports
                      64-bit memory addressing.

  Returns:

    EFI_SUCCESS            host controller capability were retrieved successfully.
    EFI_INVALID_PARAMETER  MaxSpeed or PortNumber or Is64BitCapable is NULL.
    EFI_DEVICE_ERROR       An error was encountered while attempting to retrieve the capabilities.

--*/
{
  EFI_STATUS  Status;
  USB2_HC_DEV *HcDev;
  UINT32      HcStructParamsAddr;
  UINT32      HcStructParamsReg;
  UINT32      HcCapParamsAddr;
  UINT32      HcCapParamsReg;

  if (MaxSpeed == NULL || PortNumber == NULL || Is64BitCapable == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto exit;
  }

  HcStructParamsAddr  = HCSPARAMS;
  HcCapParamsAddr     = HCCPARAMS;
  HcDev               = USB2_HC_DEV_FROM_THIS (This);

  Status = ReadEhcCapabiltiyReg (
             HcDev,
             HcStructParamsAddr,
             &HcStructParamsReg
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  Status = ReadEhcCapabiltiyReg (
             HcDev,
             HcCapParamsAddr,
             &HcCapParamsReg
             );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto exit;
  }

  *MaxSpeed       = EFI_USB_SPEED_HIGH;
  *PortNumber     = (UINT8) (HcStructParamsReg & HCSP_NPORTS);
  *Is64BitCapable = (UINT8) (HcCapParamsReg & HCCP_64BIT);

exit:
  return Status;
}

EFI_STATUS
EFIAPI
EhciReset (
  IN EFI_USB2_HC_PROTOCOL *This,
  IN UINT16               Attributes
  )
/*++

  Routine Description:

    Provides software reset for the USB host controller.

  Arguments:

  This        - A pointer to the EFI_USB2_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
  #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG  0x0004
  #define EFI_USB_HC_RESET_HOST_WITH_DEBUG  0x0008

  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.
  EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
        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.
        If this is an EHCI controller and the debug port has configured, then
        this is will still reset the host controller.
  EFI_USB_HC_RESET_HOST_WITH_DEBUG
        If this bit is set, the USB host controller hardware will be reset.
        If this is an EHCI controller and the debug port has been configured,
        then this will still reset the host controller.

  Returns:

    EFI_SUCCESS
        The reset operation succeeded.
    EFI_INVALID_PARAMETER
        Attributes is not valid.
    EFI_UNSUPPOURTED
        The type of reset specified by Attributes is not currently supported by
        the host controller hardware.
    EFI_ACCESS_DENIED
        Reset operation is rejected due to the debug port being configured and
        active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
        EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
        perform reset operation for this host controller.
    EFI_DEVICE_ERROR
        An error was encountered while attempting to perform
        the reset operation.

--*/
{
  EFI_STATUS        Status;
  USB2_HC_DEV       *HcDev;
  UINTN             FrameIndex;
  FRAME_LIST_ENTRY  *FrameEntryPtr;

  HcDev = USB2_HC_DEV_FROM_THIS (This);

  switch (Attributes) {

  case EFI_USB_HC_RESET_GLOBAL:

    //
    // Same behavior as Host Controller Reset
    //

  case EFI_USB_HC_RESET_HOST_CONTROLLER:

    //
    // Host Controller must be Halt when Reset it
    //
    if (IsEhcHalted (HcDev)) {
      Status = ResetEhc (HcDev);
      if (EFI_ERROR (Status)) {
        Status = EFI_DEVICE_ERROR;
        goto exit;
      }
      //
      // Set to zero by Host Controller when reset process completes
      //
      Status = WaitForEhcReset (HcDev, EHCI_GENERIC_TIMEOUT);
      if (EFI_ERROR (Status)) {
        Status = EFI_TIMEOUT;
        goto exit;
      }
    } else {
      Status = EFI_DEVICE_ERROR;
      goto exit;
    }

    //
    // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
    //
    CleanUpAllAsyncRequestTransfer (HcDev);
    Status = ClearEhcAllStatus (HcDev);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto exit;
    }

    //
    // Set appropriate 4G Segment Selector
    //
    Status = SetCtrlDataStructSeg (HcDev);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto exit;
    }

    //
    // Init Perodic List Base Addr and Frame List
    //
    Status = SetFrameListBaseAddr (
               HcDev,
               (UINT32) GET_0B_TO_31B (HcDev->PeriodicFrameListBuffer)
               );
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto exit;
    }
    FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;
    for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {
      FrameEntryPtr->LinkTerminate = TRUE;
      FrameEntryPtr++;
    }

    //
    // Start the Host Controller
    //
    if (IsEhcHalted (HcDev)) {
      Status = StartScheduleExecution (HcDev);
      if (EFI_ERROR (Status)) {
        Status = EFI_DEVICE_ERROR;
        goto exit;
      }
    }

    //
    // Set all ports routing to EHC
    //
    Status = SetPortRoutingEhc (HcDev);
    if (EFI_ERROR (Status)) {

⌨️ 快捷键说明

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