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

📄 usbbus.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 4 页
字号:

    gBS->FreePool(RootHubController);
    gBS->FreePool(RootHub);
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);

    return EFI_UNSUPPORTED;
  }

  Status = gBS->SetTimer(
                  RootHubController->HubNotify,
                  TimerPeriodic,
                  ONESECOND
                );
  if (EFI_ERROR(Status)) {
     gBS->UninstallProtocolInterface(
            Controller,
            &mUsbBusProtocolGuid,
            &UsbBusDev->BusIdentify
          );

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

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

    gBS->CloseEvent(RootHubController->HubNotify);
    gBS->FreePool(RootHubController);
    gBS->FreePool(RootHub);
    gBS->FreePool(UsbBusDev);
    gBS->RestoreTPL(OldTPL);
    return EFI_UNSUPPORTED;
  }

  //
  // Reset USB Host Controller
  //
  UsbHCInterface->Reset (
                    UsbHCInterface,
                    EFI_USB_HC_RESET_GLOBAL
                  );

  //
  // Start USB Host Controller
  //
  UsbHCInterface->SetState (
                    UsbHCInterface,
                    EfiUsbHcStateOperational
                  );

  gBS->RestoreTPL(OldTPL);

  return EFI_SUCCESS;
}

//
// Stop the bus controller
//
EFI_STATUS
UsbBusControllerDriverStop (
  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.
    DeviceHandle      - 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_SUCCES
    others

--*/
{
  EFI_STATUS                  Status;
  USB_IO_DEVICE               *Root;
  USB_IO_CONTROLLER_DEVICE    *RootHubController;
  USB_BUS_CONTROLLER_DEVICE   *UsbBusController;
  EFI_USB_BUS_PROTOCOL        *UsbIdentifier;
  UINT8                       i;
  EFI_USB_HC_PROTOCOL         *UsbHCInterface;
  USB_IO_CONTROLLER_DEVICE    *UsbController;
  USB_IO_DEVICE               *UsbIoDevice;
  USB_IO_CONTROLLER_DEVICE    *HubController;
  UINTN                       Index;
  BOOLEAN                     AllChildrenStopped;
  EFI_USB_IO_PROTOCOL         *UsbIo;

  if (NumberOfChildren > 0) {
    
    AllChildrenStopped = TRUE;
    
    for (Index = 0; Index < NumberOfChildren; Index++) {
      Status = gBS->OpenProtocol (
                  ChildHandleBuffer[Index],
                  &gEfiUsbIoProtocolGuid,  
                  (VOID**)&UsbIo,
                  This->DriverBindingHandle,             
                  Controller,   
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
      if (EFI_ERROR(Status)) {
        AllChildrenStopped = FALSE;
      }
    }

    for (Index = 0; Index < NumberOfChildren; Index++) {
      Status = gBS->OpenProtocol (
                  ChildHandleBuffer[Index],
                  &gEfiUsbIoProtocolGuid,  
                  (VOID**)&UsbIo,
                  This->DriverBindingHandle,             
                  Controller,   
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
      if (EFI_ERROR(Status)) {
        continue;
      }
      UsbController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo);
      UsbIoDevice = UsbController->UsbDevice;
      HubController =  UsbController->Parent;
      UsbDeviceDeConfiguration(UsbIoDevice);
      for (i = 0; i < HubController->DownstreamPorts; i ++) {
        if (HubController->Children[i] == UsbIoDevice) {
          HubController->Children[i] = NULL;
        }
      }
    }
    if (!AllChildrenStopped) {
      return EFI_DEVICE_ERROR;
    }
    return EFI_SUCCESS;
  }

  //
  // Get the USB_BUS_CONTROLLER_DEVICE
  //
  Status = gBS->OpenProtocol(
                  Controller,
                  &mUsbBusProtocolGuid,
                  (VOID **)&UsbIdentifier,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  UsbBusController = USB_BUS_CONTROLLER_DEVICE_FROM_THIS(UsbIdentifier);

  //
  // Stop USB Host Controller
  //
  UsbHCInterface = UsbBusController->UsbHCInterface;

  UsbHCInterface->SetState (
                    UsbHCInterface,
                    EfiUsbHcStateHalt
                  );

  //
  // Deconfiguration all its devices
  //
  Root = UsbBusController->Root;
  RootHubController = Root->UsbController[0];
  
//  gBS->SetTimer (
//        RootHubController->HubNotify,
//        TimerCancel, 
//        0
//       );

  gBS->CloseEvent (RootHubController->HubNotify);
  
  for (i = 0; i < RootHubController->DownstreamPorts; i++) {
    if (RootHubController->Children[i]) {
      UsbDeviceDeConfiguration(RootHubController->Children[i]);
      RootHubController->Children[i] = NULL;
    }
  }  
  
  gBS->FreePool(RootHubController);
  gBS->FreePool(Root);

  //
  // Uninstall USB Bus Protocol
  //
  gBS->UninstallProtocolInterface(
         Controller,
         &mUsbBusProtocolGuid,
         &UsbBusController->BusIdentify
       );

  //
  // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
  // Opened by this Controller
  //
  gBS->CloseProtocol(
        Controller,
        &gEfiUsbHcProtocolGuid,
        This->DriverBindingHandle,
        Controller
       );
  
  gBS->CloseProtocol(
         Controller,
         &gEfiDevicePathProtocolGuid,
         This->DriverBindingHandle,
         Controller
       );

  gBS->FreePool(UsbBusController);

  return EFI_SUCCESS;
}

//
// USB Device Configuration
//
STATIC
EFI_STATUS
UsbDeviceConfiguration (
  IN  USB_IO_CONTROLLER_DEVICE      *ParentHubController,
  IN  EFI_HANDLE                    HostController,
  IN  UINT8                         ParentPort,
  IN  USB_IO_DEVICE                 *UsbIoDevice
  )
/*++

  Routine Description:
    Configurate a new device attached to the usb bus

  Arguments:
    ParentHubController   -   Parent Hub which this device is connected.
    ParentPort            -   Parent Hub port which this device is connected.
    UsbIoDevice           -   The device to be configured.

  Returns:
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  UINT8                       DevAddress;
  UINT8                       i;
  EFI_STATUS                  Result;
  UINT32                      Status;
  CHAR16                      *StrManufacturer;
  CHAR16                      *StrProduct;
  CHAR16                      *StrSerialNumber;
  EFI_USB_IO_PROTOCOL         *UsbIo;
  UINT8                       NumOfInterface;
  USB_IO_CONTROLLER_DEVICE    *FirstController;

  DEBUG ((EFI_D_USB, "Configuration Usb Device...\n"));
  
  //
  // Since a USB device must have at least on interface,
  // so create this instance first
  //
  FirstController = CreateUsbIoControllerDevice ();
  FirstController->UsbDevice = UsbIoDevice;
  UsbIoDevice->UsbController[0] = FirstController;
  FirstController->InterfaceNumber  = 0;
  FirstController->ParentPort       = ParentPort;
  FirstController->Parent           = ParentHubController;
  FirstController->HostController   = HostController;
  
  InitializeUsbIoInstance (FirstController);

  DevAddress = UsbAllocateAddress(UsbIoDevice->BusController->AddressPool);
  if (DevAddress == 0) {
    DEBUG ((EFI_D_USB, "Cannot allocate address\n"));
    gBS->FreePool(FirstController);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Ensure we used the correctly USB I/O instance
  //
  UsbIo = &FirstController->UsbIo;

  //
  // First retrieve the 1st 8 bytes of
  // in order to get the MaxPacketSize for Endpoint 0
  //
  Result = UsbGetDescriptor(
              UsbIo,
              0x0100,             // Value
              0,                  // Index
              8,                  // Length
              &UsbIoDevice->DeviceDescriptor,
              &Status
           );
  if (EFI_ERROR(Result) || (UsbIoDevice->DeviceDescriptor.MaxPacketSize0 == 0)) {    
    DEBUG ((EFI_D_USB, "Get Device Descriptor error\n"));
    //
    // Port Reset that controller, and try again
    //
    ParentPortReset(FirstController, FALSE);
    //
    // force the maximum packet size to 8 and try the command again.
    //
    UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;
    Result = UsbGetDescriptor(
               UsbIo,
               0x0100,             // Value
               0,                  // Index
               8,                  // Length
               &UsbIoDevice->DeviceDescriptor,
               &Status
             );
    if (EFI_ERROR(Result)) {
      DEBUG ((EFI_D_USB, "Get Device Descriptor error again\n"));
      UsbFreeAddress(
        DevAddress,
        UsbIoDevice->BusController->AddressPool
      );

      gBS->FreePool (FirstController);
      return EFI_DEVICE_ERROR;
    }
  }

  //
  // Assign a unique address to this device
  //
  Result = UsbSetDeviceAddress(UsbIo, DevAddress, &Status);

  if (EFI_ERROR (Result)) {
    DEBUG ((EFI_D_USB, "Set address error\n"));
    UsbFreeAddress(
      DevAddress,
      UsbIoDevice->BusController->AddressPool
    );

    gBS->FreePool(FirstController);
    return EFI_DEVICE_ERROR ;
  }

  UsbIoDevice->DeviceAddress = DevAddress ;

  //
  // Get the whole device descriptor
  //
  Result = UsbGetDescriptor(
              UsbIo,
              0x0100,
              0,
              sizeof(EFI_USB_DEVICE_DESCRIPTOR),
              &UsbIoDevice->DeviceDescriptor,
              &Status
          );
  if (EFI_ERROR(Result)) {
    DEBUG ((EFI_D_USB, "Get whole Device Descriptor error\n"));
    UsbFreeAddress(
      DevAddress,
      UsbIoDevice->BusController->AddressPool
    );

    gBS->FreePool(FirstController);
    return EFI_DEVICE_ERROR ;
  }

  InitializeListHead(&UsbIoDevice->ConfigDescListHead);

  //
  // Get & parse all configurations for this device, including
  // all configuration descriptors, all interface descriptors, all
  // endpoint descriptors
  //
  Result = UsbGetAllConfigurations(UsbIoDevice);

  if (EFI_ERROR (Result)) {
    DEBUG ((EFI_D_USB, "Failed to get device configuration\n")) ;
    UsbFreeAddress(
      DevAddress,
      UsbIoDevice->BusController->AddressPool
    );

    gBS->FreePool (FirstController);
    return EFI_DEVICE_ERROR ;
  }

  //
  // Set the 1st configuration value
  //
  Result = UsbSetDefaultConfiguration(UsbIoDevice);
  if (EFI_ERROR (Result)) {
    DEBUG ((EFI_D_USB, "Failed to set device configuration\n")) ;
    UsbFreeAddress(
      DevAddress,
      UsbIoDevice->BusController->AddressPool
    );

    gBS->FreePool (FirstController);
    return EFI_DEVICE_ERROR ;
  }

  UsbIoDevice->IsConfigured = TRUE;

  //
  // Get all string table if applicable
  //
  Result = UsbGetStringtable (UsbIoDevice);
  if(EFI_ERROR(Result)) {
    DEBUG((EFI_D_USB, "Failed to get device strings\n")) ;
//  return EFI_DEVICE_ERROR ;
  }

  StrManufacturer = NULL;
  UsbIo->UsbGetStringDescriptor(
           UsbIo,
           UsbIoDevice->LangID[0],
           (UsbIoDevice->DeviceDescriptor).StrManufacturer,
           &StrManufacturer
         );

  StrProduct = NULL;
  UsbIo->UsbGetStringDescriptor(
           UsbIo,
           UsbIoDevice->LangID[0],
           (UsbIoDevice->DeviceDescriptor).StrProduct,
           &StrProduct
         );

  StrSerialNumber = NULL;
  UsbIo->UsbGetStringDescriptor(
           UsbIo,
           UsbIoDevice->LangID[0],
           (UsbIoDevice->DeviceDescriptor).StrSerialNumber,
           &StrSerialNumber
        );

  if (StrManufacturer) {
    gBS->FreePool(StrManufacturer);
  }

  if (StrProduct) {
    gBS->FreePool(StrProduct);
  }

  if (StrSerialNumber) {
    gBS->FreePool(StrSerialNumber);
  }

  //
  // Create USB_IO_CONTROLLER_DEVICE for
  // each detected interface
  //
  FirstController->CurrentConfigValue = \
    UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;

  NumOfInterface = UsbIoDevice->ActiveConfig->CongfigDescriptor.NumInterfaces;
  UsbIoDevice->NumOfControllers = NumOfInterface;

  Result = InitUsbIoController (FirstController);
  if (EFI_ERROR (Result)) {
    gBS->FreePool(FirstController);
    UsbIoDevice->UsbController[0] = NULL;
    return EFI_DEVICE_ERROR;
  }

  for (i = 1; i < NumOfInterface; i++) {
    USB_IO_CONTROLLER_DEVICE    *UsbIoController;

    UsbIoController = CreateUsbIoControllerDevice();
    UsbIoController->UsbDevice = UsbIoDevice;
    UsbIoController->CurrentConfigValue = \
        UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
    UsbIoController->InterfaceNumber = i;
    UsbIoDevice->UsbController[i] = UsbIoController;
    UsbIoController->ParentPort = ParentPort;
    UsbIoController->Parent = ParentHubController;
    UsbIoController->HostController = HostController;

    //
    // First copy the USB_IO Protocol instance
    //
    EfiCopyMem (
      &UsbIoController->UsbIo,
      UsbIo,
      sizeof(EFI_USB_IO_PROTOCOL)
    );

    Result = InitUsbIoController (UsbIoController);
    if (EFI_ERROR(Result)) {
       gBS->FreePool (UsbIoController);
       UsbIoDevice->UsbController[i] = NULL;
    }
  }

  return EFI_SUCCESS ;
}

//
// USB Device DeConfiguration
//
STATIC EFI_STATUS
UsbDeviceDeConfiguration(
  IN  USB_IO_DEVICE  *UsbIoDevice
  )
/*++

  Routine Description:
    Remove Device, Device Handles, Uninstall Protocols.

  Parameters:
    UsbIoDevice     -   The device to be deconfigured.

  Return Value:
    EFI_SUCCESS
    EFI_DEVICE_ERROR

--*/
{
  USB_IO_CONTROLLER_DEVICE    *UsbController;
  UINT8                       index;
  USB_IO_DEVICE               *ChildDevice;
  UINT8                       i;
  EFI_USB_IO_PROTOCOL         *UsbIo;

  DEBUG ((EFI_D_USB, "Enter Usb Device Deconfiguration\n"));

  //
  // Double check UsbIoDevice exists
  //
  if (UsbIoDevice == NULL) {
    return EFI_SUCCESS;
  }

  for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {
    //

⌨️ 快捷键说明

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