Пример #1
0
/**
  Add the ISO639-2 and RFC4646 component name both for the Serial IO device

  @param SerialDevice     A pointer to the SERIAL_DEV instance.
  @param Instance         Instance ID for the serial device.
**/
VOID
AddName (
  IN  SERIAL_DEV                               *SerialDevice,
  IN  UINT32                                   Instance
  )
{
  CHAR16                                       SerialPortName[SERIAL_PORT_NAME_LEN];
  UnicodeSPrint (
    SerialPortName,
    sizeof (SerialPortName),
    (SerialDevice->PciDeviceInfo != NULL) ? PCI_SERIAL_PORT_NAME : SIO_SERIAL_PORT_NAME,
    Instance
    );
  AddUnicodeString2 (
    "eng",
    gPciSioSerialComponentName.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    SerialPortName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gPciSioSerialComponentName2.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    SerialPortName,
    FALSE
    );

}
Пример #2
0
/**
  Add the component name for the floppy device

  @param[in]  FdcDev  A pointer to the FDC_BLK_IO_DEV instance.

**/
VOID
AddName (
  IN  FDC_BLK_IO_DEV  *FdcDev
  )
{
  CHAR16  FloppyDriveName[FLOPPY_DRIVE_NAME_LEN + 1];

  if (!(FeaturePcdGet(PcdComponentNameDisable) && FeaturePcdGet(PcdComponentName2Disable))) {
    StrCpyS (FloppyDriveName, FLOPPY_DRIVE_NAME_LEN + 1, FLOPPY_DRIVE_NAME);
    FloppyDriveName[FLOPPY_DRIVE_NAME_LEN - 1] = (CHAR16) (L'0' + FdcDev->Disk);

    AddUnicodeString2 (
      "eng",
      gIsaFloppyComponentName.SupportedLanguages,
      &FdcDev->ControllerNameTable,
      FloppyDriveName,
      TRUE
      );
    AddUnicodeString2 (
      "en",
      gIsaFloppyComponentName2.SupportedLanguages,
      &FdcDev->ControllerNameTable,
      FloppyDriveName,
      FALSE
      );
  }
}
Пример #3
0
/**
  Add the component name for the IDE/ATAPI device

  @param  IdeBlkIoDevicePtr A pointer to the IDE_BLK_IO_DEV instance.

**/
VOID
AddName (
  IN  IDE_BLK_IO_DEV               *IdeBlkIoDevicePtr
  )
{
  UINTN   StringIndex;
  CHAR16  ModelName[41];

  //
  // Add Component Name for the IDE/ATAPI device that was discovered.
  //
  IdeBlkIoDevicePtr->ControllerNameTable = NULL;
  for (StringIndex = 0; StringIndex < 41; StringIndex++) {
    ModelName[StringIndex] = IdeBlkIoDevicePtr->ModelName[StringIndex];
  }

  AddUnicodeString2 (
    "eng",
    gIDEBusComponentName.SupportedLanguages,
    &IdeBlkIoDevicePtr->ControllerNameTable,
    ModelName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gIDEBusComponentName2.SupportedLanguages,
    &IdeBlkIoDevicePtr->ControllerNameTable,
    ModelName,
    FALSE
    );

}
Пример #4
0
/**
  Add the ISO639-2 and RFC4646 component name both for the Serial IO device

  @param SerialDevice     A pointer to the SERIAL_DEV instance.

**/
VOID
AddName (
  IN  SERIAL_DEV                               *SerialDevice
  )
{
  CHAR16  SerialPortName[sizeof (SERIAL_PORT_NAME)];

  StrCpy (SerialPortName, L"IOH Serial Port # ");
  SerialPortName[sizeof (SERIAL_PORT_NAME) - 2] = (CHAR16) (L'0' + 1);
  AddUnicodeString2 (
    "eng",
    gIohSerialComponentName.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    (CHAR16 *) SerialPortName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gIohSerialComponentName2.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    (CHAR16 *) SerialPortName,
    FALSE
    );

}
Пример #5
0
/**
  Update the component name for the Tcp4 child handle.

  @param  Tcp4[in]                   A pointer to the EFI_TCP4_PROTOCOL.


  @retval EFI_SUCCESS                Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER      The input parameter is invalid.

**/
EFI_STATUS
UpdateTcp4Name (
  IN    EFI_TCP4_PROTOCOL             *Tcp4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  EFI_TCP4_CONFIG_DATA             Tcp4ConfigData;

  if (Tcp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
  //
  ZeroMem (&Tcp4ConfigData, sizeof (Tcp4ConfigData));
  Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
  if (!EFI_ERROR (Status)) {
    UnicodeSPrint (HandleName, sizeof (HandleName),
      L"TCPv4 (SrcPort=%d, DestPort=%d, ActiveFlag=%s)",
      Tcp4ConfigData.AccessPoint.StationPort,
      Tcp4ConfigData.AccessPoint.RemotePort,
      (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
      );
  } else if (Status == EFI_NOT_STARTED) {
    UnicodeSPrint (
      HandleName,
      sizeof (HandleName),
      L"TCPv4 (Not started)"
      );
  } else {
    return Status;
  }

  if (gTcpControllerNameTable != NULL) {
    FreeUnicodeStringTable (gTcpControllerNameTable);
    gTcpControllerNameTable = NULL;
  }

  Status = AddUnicodeString2 (
             "eng",
             gTcpComponentName.SupportedLanguages,
             &gTcpControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gTcpComponentName2.SupportedLanguages,
           &gTcpControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #6
0
/**
  Add the ISO639-2 and RFC4646 component name both for the Serial IO device

  @param SerialDevice     A pointer to the SERIAL_DEV instance.

  @param IsaIo            A pointer to the EFI_ISA_IO_PROTOCOL instance.

**/
VOID
AddName (
  IN  SERIAL_DEV                               *SerialDevice,
  IN  EFI_ISA_IO_PROTOCOL                      *IsaIo
  )
{
  CHAR16  SerialPortName[sizeof (SERIAL_PORT_NAME)];

  StrCpy (SerialPortName, L"ISA Serial Port # ");
  SerialPortName[sizeof (SERIAL_PORT_NAME) - 2] = (CHAR16) (L'0' + (UINT8) IsaIo->ResourceList->Device.UID);
  AddUnicodeString2 (
    "eng",
    gIsaSerialComponentName.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    (CHAR16 *) SerialPortName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gIsaSerialComponentName2.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    (CHAR16 *) SerialPortName,
    FALSE
    );

}
Пример #7
0
/**
  Update the component name for the Udp4 child handle.

  @param  Udp4[in]                   A pointer to the EFI_UDP4_PROTOCOL.


  @retval EFI_SUCCESS                Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER      The input parameter is invalid.

**/
EFI_STATUS
UpdateName (
  EFI_UDP4_PROTOCOL             *Udp4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[64];
  EFI_UDP4_CONFIG_DATA             Udp4ConfigData;

  if (Udp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // UDPv4 (SrcPort=59, DestPort=60)
  //
  Status = Udp4->GetModeData (Udp4, &Udp4ConfigData, NULL, NULL, NULL);
  if (!EFI_ERROR (Status)) {
    UnicodeSPrint (HandleName, sizeof (HandleName),
      L"UDPv4 (SrcPort=%d, DestPort=%d)",
      Udp4ConfigData.StationPort,
      Udp4ConfigData.RemotePort
      );
  } else if (Status == EFI_NOT_STARTED) {
    UnicodeSPrint (
      HandleName,
      sizeof (HandleName),
      L"UDPv4 (Not started)"
      );
  } else {
    return Status;
  }

  if (gUdpControllerNameTable != NULL) {
    FreeUnicodeStringTable (gUdpControllerNameTable);
    gUdpControllerNameTable = NULL;
  }

  Status = AddUnicodeString2 (
             "eng",
             gUdp4ComponentName.SupportedLanguages,
             &gUdpControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gUdp4ComponentName2.SupportedLanguages,
           &gUdpControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #8
0
/**
  Update the component name for the IP4 child handle.

  @param  Ip4[in]                 A pointer to the EFI_IP4_PROTOCOL.

  
  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.
  
**/
EFI_STATUS
UpdateName (
  IN     EFI_IP4_PROTOCOL         *Ip4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  EFI_IP4_MODE_DATA                Ip4ModeData;

  if (Ip4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1)
  //
  Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) {
    UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)");
  } else {
    UnicodeSPrint (HandleName, sizeof (HandleName),
      L"IPv4 (SrcIP=%d.%d.%d.%d)",
      Ip4ModeData.ConfigData.StationAddress.Addr[0],
      Ip4ModeData.ConfigData.StationAddress.Addr[1],
      Ip4ModeData.ConfigData.StationAddress.Addr[2],
      Ip4ModeData.ConfigData.StationAddress.Addr[3]
      );
  }

  if (gIp4ControllerNameTable != NULL) {
    FreeUnicodeStringTable (gIp4ControllerNameTable);
    gIp4ControllerNameTable = NULL;
  }
  Status = AddUnicodeString2 (
             "eng",
             gIp4ComponentName.SupportedLanguages,
             &gIp4ControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  return AddUnicodeString2 (
           "en",
           gIp4ComponentName2.SupportedLanguages,
           &gIp4ControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #9
0
/**
  Update the component name for the Mtftp4 child handle.

  @param  Mtftp4[in]                A pointer to the EFI_MTFTP4_PROTOCOL.


  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.

**/
EFI_STATUS
UpdateName (
  IN   EFI_MTFTP4_PROTOCOL             *Mtftp4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  EFI_MTFTP4_MODE_DATA             ModeData;

  if (Mtftp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // MTFTPv4 (ServerIp=192.168.1.10, ServerPort=69)
  //
  Status = Mtftp4->GetModeData (Mtftp4, &ModeData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  UnicodeSPrint (HandleName, sizeof (HandleName),
    L"MTFTPv4 (ServerIp=%d.%d.%d.%d, ServerPort=%d)",
    ModeData.ConfigData.ServerIp.Addr[0],
    ModeData.ConfigData.ServerIp.Addr[1],
    ModeData.ConfigData.ServerIp.Addr[2],
    ModeData.ConfigData.ServerIp.Addr[3],
    ModeData.ConfigData.InitialServerPort
    );

  if (gMtftp4ControllerNameTable != NULL) {
    FreeUnicodeStringTable (gMtftp4ControllerNameTable);
    gMtftp4ControllerNameTable = NULL;
  }

  Status = AddUnicodeString2 (
             "eng",
             gMtftp4ComponentName.SupportedLanguages,
             &gMtftp4ControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gMtftp4ComponentName2.SupportedLanguages,
           &gMtftp4ControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #10
0
/**
  Update the component name for the Dhcp6 child handle.

  @param  Dhcp6[in]                   A pointer to the EFI_DHCP6_PROTOCOL.

  
  @retval EFI_SUCCESS                 Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER       The input parameter is invalid.
  
**/
EFI_STATUS
UpdateName (
  IN   EFI_DHCP6_PROTOCOL             *Dhcp6
  )
{
  EFI_STATUS                       Status;
  EFI_DHCP6_MODE_DATA              Dhcp6ModeData;
  CHAR16                           HandleName[64];

  if (Dhcp6 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer.
  //
  Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  if (gDhcp6ControllerNameTable != NULL) {
    FreeUnicodeStringTable (gDhcp6ControllerNameTable);
    gDhcp6ControllerNameTable = NULL;
  }
  
  if (Dhcp6ModeData.Ia == NULL) {
    UnicodeSPrint (HandleName, sizeof (HandleName), L"DHCPv6 (No configured IA)");
  } else {
    StrCpy (HandleName, mDhcp6ControllerName[Dhcp6ModeData.Ia->State]);
  }
  
  Status = AddUnicodeString2 (
             "eng",
             gDhcp6ComponentName.SupportedLanguages,
             &gDhcp6ControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  return AddUnicodeString2 (
           "en",
           gDhcp6ComponentName2.SupportedLanguages,
           &gDhcp6ControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #11
0
/**
  Update the component name for the Dhcp4 child handle.

  @param  Dhcp4[in]               A pointer to the EFI_DHCP4_PROTOCOL.


  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.
  @retval EFI_DEVICE_ERROR        DHCP is in unknown state.

**/
EFI_STATUS
UpdateName (
  IN     EFI_DHCP4_PROTOCOL             *Dhcp4
  )
{
  EFI_STATUS                       Status;
  EFI_DHCP4_MODE_DATA              Dhcp4ModeData;

  if (Dhcp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer.
  //
  Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (gDhcpControllerNameTable != NULL) {
    FreeUnicodeStringTable (gDhcpControllerNameTable);
    gDhcpControllerNameTable = NULL;
  }

  if (Dhcp4ModeData.State > Dhcp4Rebooting) {
    return EFI_DEVICE_ERROR;
  }

  Status = AddUnicodeString2 (
             "eng",
             gDhcp4ComponentName.SupportedLanguages,
             &gDhcpControllerNameTable,
             mDhcp4ControllerName[Dhcp4ModeData.State],
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gDhcp4ComponentName2.SupportedLanguages,
           &gDhcpControllerNameTable,
           mDhcp4ControllerName[Dhcp4ModeData.State],
           FALSE
           );
}
Пример #12
0
/**
  Add the ISO639-2 and RFC4646 component name both for the Serial IO device

  @param SerialDevice     A pointer to the SERIAL_DEV instance.

  @param IsaIo            A pointer to the EFI_ISA_IO_PROTOCOL instance.

**/
VOID
AddName (
  IN  SERIAL_DEV                               *SerialDevice,
  IN  EFI_ISA_IO_PROTOCOL                      *IsaIo
  )
{
  mSerialPortName[(sizeof (mSerialPortName) / 2) - 2] = (CHAR16) (L'0' + (UINT8) IsaIo->ResourceList->Device.UID);
  AddUnicodeString2 (
    "eng",
    gIsaSerialComponentName.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    mSerialPortName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gIsaSerialComponentName2.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    mSerialPortName,
    FALSE
    );

}
Пример #13
0
/**
  Update the component name for the IP6 child handle.

  @param  Ip6[in]                   A pointer to the EFI_IP6_PROTOCOL.

  
  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.
  
**/
EFI_STATUS
UpdateName (
  IN    EFI_IP6_PROTOCOL         *Ip6
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[128];
  EFI_IP6_MODE_DATA                Ip6ModeData;
  UINTN                            Offset;
  CHAR16                           Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];

  if (Ip6 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer.
  //
  Offset = 0;
  Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL);
  if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) {
    Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address));
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Offset += UnicodeSPrint (
                HandleName,
                sizeof(HandleName),
                L"IPv6(StationAddress=%s, ",
                Address
                );
    Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address));
    if (EFI_ERROR (Status)) {
      return Status;
    }
    UnicodeSPrint (
      HandleName + Offset,
      sizeof(HandleName) - Offset * sizeof (CHAR16),
      L"DestinationAddress=%s)",
      Address
      );
  } else if (!Ip6ModeData.IsStarted) {
    UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)");
  } else {
    UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status);
  }

  if (gIp6ControllerNameTable != NULL) {
      FreeUnicodeStringTable (gIp6ControllerNameTable);
      gIp6ControllerNameTable = NULL;
  }
  
  Status = AddUnicodeString2 (
             "eng",
             gIp6ComponentName.SupportedLanguages,
             &gIp6ControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  return AddUnicodeString2 (
           "en",
           gIp6ComponentName2.SupportedLanguages,
           &gIp6ControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #14
0
/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failded to start the device.

**/
EFI_STATUS
EFIAPI
EmuBlockIoDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Handle,
  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
  )
{
  EFI_STATUS                  Status;
  EMU_IO_THUNK_PROTOCOL       *EmuIoThunk;
  EMU_BLOCK_IO_PRIVATE        *Private = NULL;

  //
  // Grab the protocols we need
  //

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEmuIoThunkProtocolGuid,
                  (void *)&EmuIoThunk,
                  This->DriverBindingHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!CompareGuid (EmuIoThunk->Protocol, &gEmuBlockIoProtocolGuid)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Status = EmuIoThunk->Open (EmuIoThunk);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Private = AllocatePool (sizeof (EMU_BLOCK_IO_PRIVATE));
  if (Private == NULL) {
    goto Done;
  }

  Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE;
  Private->IoThunk   = EmuIoThunk;
  Private->Io        = EmuIoThunk->Interface;
  Private->EfiHandle = Handle;

  Private->BlockIo.Revision    = EFI_BLOCK_IO_PROTOCOL_REVISION2;
  Private->BlockIo.Media       = &Private->Media;
  Private->BlockIo.Reset       = EmuBlockIoReset;
  Private->BlockIo.ReadBlocks  = EmuBlockIoReadBlocks;
  Private->BlockIo.WriteBlocks = EmuBlockIoWriteBlocks;
  Private->BlockIo.FlushBlocks = EmuBlockIoFlushBlocks;

  Private->BlockIo2.Media         = &Private->Media;
  Private->BlockIo2.Reset         = EmuBlockIo2Reset;
  Private->BlockIo2.ReadBlocksEx  = EmuBlockIo2ReadBlocksEx;
  Private->BlockIo2.WriteBlocksEx = EmuBlockIo2WriteBlocksEx;
  Private->BlockIo2.FlushBlocksEx = EmuBlockIo2Flush;

  Private->ControllerNameTable = NULL;

  Status = Private->Io->CreateMapping (Private->Io, &Private->Media);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  AddUnicodeString2 (
    "eng",
    gEmuBlockIoComponentName.SupportedLanguages,
    &Private->ControllerNameTable,
    EmuIoThunk->ConfigString,
    TRUE
    );

  AddUnicodeString2 (
    "en",
    gEmuBlockIoComponentName2.SupportedLanguages,
    &Private->ControllerNameTable,
    EmuIoThunk->ConfigString,
    FALSE
    );

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiBlockIoProtocolGuid,    &Private->BlockIo,
                  &gEfiBlockIo2ProtocolGuid,   &Private->BlockIo2,
                  NULL
                  );

Done:
  if (EFI_ERROR (Status)) {
    if (Private != NULL) {
      if (Private->ControllerNameTable != NULL) {
        FreeUnicodeStringTable (Private->ControllerNameTable);
      }

      gBS->FreePool (Private);

    }

    gBS->CloseProtocol (
          Handle,
          &gEmuIoThunkProtocolGuid,
          This->DriverBindingHandle,
          Handle
          );
  }

  return Status;
}
Пример #15
0
/**
  Starts the keyboard device with this driver.

  This function produces Simple Text Input Protocol and Simple Text Input Ex Protocol,
  initializes the keyboard device, and submit Asynchronous Interrupt Transfer to manage
  this keyboard device.

  @param  This                   The USB keyboard driver binding instance.
  @param  Controller             Handle of device to bind driver to.
  @param  RemainingDevicePath    Optional parameter use to pick a specific child
                                 device to start.

  @retval EFI_SUCCESS            The controller is controlled by the usb keyboard driver.
  @retval EFI_UNSUPPORTED        No interrupt endpoint can be found.
  @retval Other                  This controller cannot be started.

**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                    Status;
  EFI_USB_IO_PROTOCOL           *UsbIo;
  USB_KB_DEV                    *UsbKeyboardDevice;
  UINT8                         EndpointNumber;
  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;
  UINT8                         Index;
  UINT8                         EndpointAddr;
  UINT8                         PollingInterval;
  UINT8                         PacketSize;
  BOOLEAN                       Found;
  EFI_TPL                       OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  //
  // Open USB I/O Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsbIoProtocolGuid,
                  (VOID **) &UsbIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit1;
  }

  UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV));
  ASSERT (UsbKeyboardDevice != NULL);

  //
  // Get the Device Path Protocol on Controller's handle
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &UsbKeyboardDevice->DevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }
  //
  // Report that the USB keyboard is being enabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE),
    UsbKeyboardDevice->DevicePath
    );

  //
  // This is pretty close to keyboard detection, so log progress
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT),
    UsbKeyboardDevice->DevicePath
    );

  UsbKeyboardDevice->UsbIo = UsbIo;

  //
  // Get interface & endpoint descriptor
  //
  UsbIo->UsbGetInterfaceDescriptor (
           UsbIo,
           &UsbKeyboardDevice->InterfaceDescriptor
           );

  EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;

  //
  // Traverse endpoints to find interrupt endpoint
  //
  Found = FALSE;
  for (Index = 0; Index < EndpointNumber; Index++) {

    UsbIo->UsbGetEndpointDescriptor (
             UsbIo,
             Index,
             &EndpointDescriptor
             );

    if ((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) {
      //
      // We only care interrupt endpoint here
      //
      CopyMem(&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));
      Found = TRUE;
      break;
    }
  }

  if (!Found) {
    //
    // No interrupt endpoint found, then return unsupported.
    //
    Status = EFI_UNSUPPORTED;
    goto ErrorExit;
  }

  UsbKeyboardDevice->Signature                  = USB_KB_DEV_SIGNATURE;
  UsbKeyboardDevice->SimpleInput.Reset          = USBKeyboardReset;
  UsbKeyboardDevice->SimpleInput.ReadKeyStroke  = USBKeyboardReadKeyStroke;

  UsbKeyboardDevice->SimpleInputEx.Reset               = USBKeyboardResetEx;
  UsbKeyboardDevice->SimpleInputEx.ReadKeyStrokeEx     = USBKeyboardReadKeyStrokeEx;
  UsbKeyboardDevice->SimpleInputEx.SetState            = USBKeyboardSetState;
  UsbKeyboardDevice->SimpleInputEx.RegisterKeyNotify   = USBKeyboardRegisterKeyNotify;
  UsbKeyboardDevice->SimpleInputEx.UnregisterKeyNotify = USBKeyboardUnregisterKeyNotify;

  InitializeListHead (&UsbKeyboardDevice->NotifyList);

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  USBKeyboardTimerHandler,
                  UsbKeyboardDevice,
                  &UsbKeyboardDevice->TimerEvent
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->SetTimer (UsbKeyboardDevice->TimerEvent, TimerPeriodic, KEYBOARD_TIMER_INTERVAL);
  }
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  USBKeyboardWaitForKey,
                  UsbKeyboardDevice,
                  &(UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx)
                  );

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  USBKeyboardWaitForKey,
                  UsbKeyboardDevice,
                  &(UsbKeyboardDevice->SimpleInput.WaitForKey)
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Install Simple Text Input Protocol and Simple Text Input Ex Protocol
  // for the USB keyboard device.
  // USB keyboard is a hot plug device, and expected to work immediately
  // when plugging into system, other conventional console devices could
  // distinguish it by its device path.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  &UsbKeyboardDevice->SimpleInput,
                  &gEfiSimpleTextInputExProtocolGuid,
                  &UsbKeyboardDevice->SimpleInputEx,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  UsbKeyboardDevice->ControllerHandle = Controller;
  Status = InitKeyboardLayout (UsbKeyboardDevice);
  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
      Controller,
      &gEfiSimpleTextInProtocolGuid,
      &UsbKeyboardDevice->SimpleInput,
      &gEfiSimpleTextInputExProtocolGuid,
      &UsbKeyboardDevice->SimpleInputEx,
      NULL
      );
    goto ErrorExit;
  }


  //
  // Reset USB Keyboard Device exhaustively.
  //
  Status = UsbKeyboardDevice->SimpleInputEx.Reset (
                                            &UsbKeyboardDevice->SimpleInputEx,
                                            TRUE
                                            );
  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           Controller,
           &gEfiSimpleTextInProtocolGuid,
           &UsbKeyboardDevice->SimpleInput,
           &gEfiSimpleTextInputExProtocolGuid,
           &UsbKeyboardDevice->SimpleInputEx,
           NULL
           );
    goto ErrorExit;
  }

  //
  // Submit Asynchronous Interrupt Transfer to manage this device.
  //
  EndpointAddr    = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;
  PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;
  PacketSize      = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);

  Status = UsbIo->UsbAsyncInterruptTransfer (
                    UsbIo,
                    EndpointAddr,
                    TRUE,
                    PollingInterval,
                    PacketSize,
                    KeyboardHandler,
                    UsbKeyboardDevice
                    );

  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           Controller,
           &gEfiSimpleTextInProtocolGuid,
           &UsbKeyboardDevice->SimpleInput,
           &gEfiSimpleTextInputExProtocolGuid,
           &UsbKeyboardDevice->SimpleInputEx,
           NULL
           );
    goto ErrorExit;
  }

  UsbKeyboardDevice->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gUsbKeyboardComponentName.SupportedLanguages,
    &UsbKeyboardDevice->ControllerNameTable,
    L"Generic Usb Keyboard",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gUsbKeyboardComponentName2.SupportedLanguages,
    &UsbKeyboardDevice->ControllerNameTable,
    L"Generic Usb Keyboard",
    FALSE
    );

  gBS->RestoreTPL (OldTpl);
  return EFI_SUCCESS;

//
// Error handler
//
ErrorExit:
  if (UsbKeyboardDevice != NULL) {
    if (UsbKeyboardDevice->TimerEvent != NULL) {
      gBS->CloseEvent (UsbKeyboardDevice->TimerEvent);
    }
    if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) {
      gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
    }
    if (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx != NULL) {
      gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);
    }
    if (UsbKeyboardDevice->KeyboardLayoutEvent != NULL) {
      ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
      gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);
    }
    FreePool (UsbKeyboardDevice);
    UsbKeyboardDevice = NULL;
  }
  gBS->CloseProtocol (
         Controller,
         &gEfiUsbIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

ErrorExit1:
  gBS->RestoreTPL (OldTpl);

  return Status;

}
Пример #16
0
/**
  Update the component name for the Snp child handle.

  @param  Snp[in]                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL.

  
  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.
  
**/
EFI_STATUS
UpdateName (
  IN  EFI_SIMPLE_NETWORK_PROTOCOL   *Snp
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  UINTN                            OffSet;
  UINTN                            Index;

  if (Snp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  OffSet = 0;
  OffSet += UnicodeSPrint (
              HandleName,
              sizeof (HandleName),
              L"SNP (MAC="
              );
  for (Index = 0; Index < Snp->Mode->HwAddressSize; Index++) {
    OffSet += UnicodeSPrint (
                HandleName + OffSet,
                sizeof (HandleName) - OffSet * sizeof (CHAR16),
                L"%02X-",
                Snp->Mode->CurrentAddress.Addr[Index]
                );
  }
  //
  // Remove the last '-'
  //
  OffSet--;
  OffSet += UnicodeSPrint (
              HandleName + OffSet,
              sizeof (HandleName) - OffSet * sizeof (CHAR16),
              L")"
              );
  if (gSimpleNetworkControllerNameTable != NULL) {
    FreeUnicodeStringTable (gSimpleNetworkControllerNameTable);
    gSimpleNetworkControllerNameTable = NULL;
  }
  
  Status = AddUnicodeString2 (
             "eng",
             gSimpleNetworkComponentName.SupportedLanguages,
             &gSimpleNetworkControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  return AddUnicodeString2 (
           "en",
           gSimpleNetworkComponentName2.SupportedLanguages,
           &gSimpleNetworkControllerNameTable,
           HandleName,
           FALSE
           );
}
Пример #17
0
EFI_STATUS
EFIAPI
UnixGopDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
  IN  EFI_HANDLE                      Handle,
  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Handle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
{
  EFI_UNIX_IO_PROTOCOL  *UnixIo;
  EFI_STATUS              Status;
  GOP_PRIVATE_DATA        *Private;

  //
  // Grab the protocols we need
  //
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiUnixIoProtocolGuid,
                  (VOID **)&UnixIo,
                  This->DriverBindingHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Allocate Private context data for SGO inteface.
  //
  Private = NULL;
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (GOP_PRIVATE_DATA),
                  (VOID **)&Private
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Set up context record
  //
  Private->Signature           = GOP_PRIVATE_DATA_SIGNATURE;
  Private->Handle              = Handle;
  Private->UnixThunk           = UnixIo->UnixThunk;

  Private->ControllerNameTable  = NULL;

  AddUnicodeString (
    "eng",
    gUnixGopComponentName.SupportedLanguages,
    &Private->ControllerNameTable,
    UnixIo->EnvString
    );
  AddUnicodeString2 (
    "en",
    gUnixGopComponentName2.SupportedLanguages,
    &Private->ControllerNameTable,
    UnixIo->EnvString,
    FALSE
    );

  Private->WindowName = UnixIo->EnvString;

  Status              = UnixGopConstructor (Private);
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Publish the Gop interface to the world
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->Handle,
                  &gEfiGraphicsOutputProtocolGuid,    &Private->GraphicsOutput,
                  &gEfiSimpleTextInProtocolGuid,      &Private->SimpleTextIn,
                  &gEfiSimplePointerProtocolGuid,     &Private->SimplePointer,
//                  &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx,
                  NULL
                  );

Done:
  if (EFI_ERROR (Status)) {

    gBS->CloseProtocol (
          Handle,
          &gEfiUnixIoProtocolGuid,
          This->DriverBindingHandle,
          Handle
          );

    if (Private != NULL) {
      //
      // On Error Free back private data
      //
      if (Private->ControllerNameTable != NULL) {
        FreeUnicodeStringTable (Private->ControllerNameTable);
      }
      if (Private->SimpleTextIn.WaitForKey != NULL) {
        gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
      }
      if (Private->SimpleTextInEx.WaitForKeyEx != NULL) {
        gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
      }
      FreeNotifyList (&Private->NotifyList);

      gBS->FreePool (Private);
    }
  }

  return Status;
}
Пример #18
0
/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failded to start the device.

**/
EFI_STATUS
EFIAPI
EmuSimpleFileSystemDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EMU_IO_THUNK_PROTOCOL             *EmuIoThunk;
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE    *Private;

  Private = NULL;

  //
  // Open the IO Abstraction(s) needed
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEmuIoThunkProtocolGuid,
                  (VOID **)&EmuIoThunk,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Validate GUID
  //
  if (!CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Private = AllocateZeroPool (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE));
  if (Private == NULL) {
    goto Done;
  }

  Status = EmuIoThunk->Open (EmuIoThunk);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
  Private->IoThunk   = EmuIoThunk;
  Private->Io        = EmuIoThunk->Interface;

  Private->SimpleFileSystem.Revision    = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
  Private->SimpleFileSystem.OpenVolume  = EmuSimpleFileSystemOpenVolume;

  Private->ControllerNameTable = NULL;

  AddUnicodeString2 (
    "eng",
    gEmuSimpleFileSystemComponentName.SupportedLanguages,
    &Private->ControllerNameTable,
    EmuIoThunk->ConfigString,
    TRUE
    );

  AddUnicodeString2 (
    "en",
    gEmuSimpleFileSystemComponentName2.SupportedLanguages,
    &Private->ControllerNameTable,
    EmuIoThunk->ConfigString,
    FALSE
    );

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiSimpleFileSystemProtocolGuid,  &Private->SimpleFileSystem,
                  NULL
                  );

Done:
  if (EFI_ERROR (Status)) {
    if (Private != NULL) {
      if (Private->ControllerNameTable != NULL) {
        FreeUnicodeStringTable (Private->ControllerNameTable);
      }

      gBS->FreePool (Private);

    }

    gBS->CloseProtocol (
          ControllerHandle,
          &gEmuIoThunkProtocolGuid,
          This->DriverBindingHandle,
          ControllerHandle
          );
  }

  return Status;
}
Пример #19
0
/**
  Open the root directory on a volume.

  @param  This Protocol instance pointer.
  @param  Root Returns an Open file handle for the root directory

  @retval EFI_SUCCESS          The device was opened.
  @retval EFI_UNSUPPORTED      This volume does not support the file system.
  @retval EFI_NO_MEDIA         The device has no media.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.

**/
EFI_STATUS
EFIAPI
EmuSimpleFileSystemOpenVolume (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,
  OUT EFI_FILE_PROTOCOL               **Root
  )
{
  EFI_STATUS                        Status;
  EMU_SIMPLE_FILE_SYSTEM_PRIVATE    *Private;
  EMU_EFI_FILE_PRIVATE              *PrivateFile;
  EFI_TPL                           OldTpl;

  Status = EFI_UNSUPPORTED;

  if (This == NULL || Root == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);

  PrivateFile = AllocatePool (sizeof (EMU_EFI_FILE_PRIVATE));
  if (PrivateFile == NULL) {
    goto Done;
  }

  PrivateFile->Signature            = EMU_EFI_FILE_PRIVATE_SIGNATURE;
  PrivateFile->IoThunk              = Private->IoThunk;
  PrivateFile->SimpleFileSystem     = This;
  PrivateFile->EfiFile.Revision     = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
  PrivateFile->EfiFile.Open         = EmuSimpleFileSystemOpen;
  PrivateFile->EfiFile.Close        = EmuSimpleFileSystemClose;
  PrivateFile->EfiFile.Delete       = EmuSimpleFileSystemDelete;
  PrivateFile->EfiFile.Read         = EmuSimpleFileSystemRead;
  PrivateFile->EfiFile.Write        = EmuSimpleFileSystemWrite;
  PrivateFile->EfiFile.GetPosition  = EmuSimpleFileSystemGetPosition;
  PrivateFile->EfiFile.SetPosition  = EmuSimpleFileSystemSetPosition;
  PrivateFile->EfiFile.GetInfo      = EmuSimpleFileSystemGetInfo;
  PrivateFile->EfiFile.SetInfo      = EmuSimpleFileSystemSetInfo;
  PrivateFile->EfiFile.Flush        = EmuSimpleFileSystemFlush;

  *Root = &PrivateFile->EfiFile;

  Status = Private->Io->OpenVolume (Private->Io, &PrivateFile->Io);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  AddUnicodeString2 (
    "eng",
    gEmuSimpleFileSystemComponentName.SupportedLanguages,
    &Private->ControllerNameTable,
    Private->IoThunk->ConfigString,
    TRUE
    );

  AddUnicodeString2 (
    "en",
    gEmuSimpleFileSystemComponentName.SupportedLanguages,
    &Private->ControllerNameTable,
    Private->IoThunk->ConfigString,
    FALSE
    );


Done:
  if (EFI_ERROR (Status)) {
    if (PrivateFile) {
      gBS->FreePool (PrivateFile);
    }

    *Root = NULL;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}
Пример #20
0
EFI_STATUS
EFIAPI
WinNtSerialIoDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Handle,
  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Handle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_STATUS                          Status;
  EFI_WIN_NT_IO_PROTOCOL              *WinNtIo;
  WIN_NT_SERIAL_IO_PRIVATE_DATA       *Private;
  HANDLE                              NtHandle;
  UART_DEVICE_PATH                    UartNode;
  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
  UINTN                               EntryCount;
  UINTN                               Index;
  EFI_SERIAL_IO_PROTOCOL              *SerialIo;
  UART_DEVICE_PATH                    *Uart;
  UINT32                              FlowControlMap;
  UART_FLOW_CONTROL_DEVICE_PATH       *FlowControl;
  EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;
  UINT32                              Control;

  Private   = NULL;
  NtHandle  = INVALID_HANDLE_VALUE;

  //
  // Get the Parent Device Path
  //
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  //
  // Grab the IO abstraction we need to get any work done
  //
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiWinNtIoProtocolGuid,
                  (VOID **) &WinNtIo,
                  This->DriverBindingHandle,
                  Handle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    gBS->CloseProtocol (
          Handle,
          &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle,
          Handle
          );
    return Status;
  }

  if (Status == EFI_ALREADY_STARTED) {

    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath is NULL or is the End of Device Path Node
      //
      return EFI_SUCCESS;
    }

    //
    // Make sure a child handle does not already exist.  This driver can only
    // produce one child per serial port.
    //
    Status = gBS->OpenProtocolInformation (
                    Handle,
                    &gEfiWinNtIoProtocolGuid,
                    &OpenInfoBuffer,
                    &EntryCount
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = EFI_ALREADY_STARTED;
    for (Index = 0; Index < EntryCount; Index++) {
      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
        Status = gBS->OpenProtocol (
                        OpenInfoBuffer[Index].ControllerHandle,
                        &gEfiSerialIoProtocolGuid,
                        (VOID **) &SerialIo,
                        This->DriverBindingHandle,
                        Handle,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );
        if (!EFI_ERROR (Status)) {
          Uart   = (UART_DEVICE_PATH *) RemainingDevicePath;
          Status = SerialIo->SetAttributes (
                               SerialIo,
                               Uart->BaudRate,
                               SerialIo->Mode->ReceiveFifoDepth,
                               SerialIo->Mode->Timeout,
                               (EFI_PARITY_TYPE) Uart->Parity,
                               Uart->DataBits,
                               (EFI_STOP_BITS_TYPE) Uart->StopBits
                               );
          FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
          if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {
            Status = SerialIo->GetControl (SerialIo, &Control);
            if (!EFI_ERROR (Status)) {
              if (FlowControl->FlowControlMap == UART_FLOW_CONTROL_HARDWARE) {
                Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
              } else {
                Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
              }
              //
              // Clear the bits that are not allowed to pass to SetControl
              //
              Control &= (EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |
                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | 
                          EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
              Status = SerialIo->SetControl (SerialIo, Control);
            }
          }
        }
        break;
      }
    }

    FreePool (OpenInfoBuffer);
    return Status;
  }

  FlowControl    = NULL;
  FlowControlMap = 0;
  if (RemainingDevicePath == NULL) {
    //
    // Build the device path by appending the UART node to the ParentDevicePath
    // from the WinNtIo handle. The Uart setings are zero here, since
    // SetAttribute() will update them to match the default setings.
    //
    ZeroMem (&UartNode, sizeof (UART_DEVICE_PATH));
    UartNode.Header.Type     = MESSAGING_DEVICE_PATH;
    UartNode.Header.SubType  = MSG_UART_DP;
    SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &UartNode, sizeof (UART_DEVICE_PATH));

  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    //
    // If RemainingDevicePath isn't the End of Device Path Node, 
    // only scan the specified device by RemainingDevicePath
    //
    //
    // Match the configuration of the RemainingDevicePath. IsHandleSupported()
    // already checked to make sure the RemainingDevicePath contains settings
    // that we can support.
    //
    CopyMem (&UartNode, RemainingDevicePath, sizeof (UART_DEVICE_PATH));
    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
    if (IsUartFlowControlNode (FlowControl)) {
      FlowControlMap = FlowControl->FlowControlMap;
    } else {
      FlowControl    = NULL;
    }

  } else {
    //
    // If RemainingDevicePath is the End of Device Path Node,
    // skip enumerate any device and return EFI_SUCESSS
    // 
    return EFI_SUCCESS;
  }

  //
  // Check to see if we can access the hardware device. If it's Open in NT we
  // will not get access.
  //
  NtHandle = WinNtIo->WinNtThunk->CreateFile (
                                    WinNtIo->EnvString,
                                    GENERIC_READ | GENERIC_WRITE,
                                    0,
                                    NULL,
                                    OPEN_EXISTING,
                                    0,
                                    NULL
                                    );
  if (NtHandle == INVALID_HANDLE_VALUE) {
    Status = EFI_DEVICE_ERROR;
    goto Error;
  }

  //
  // Construct Private data
  //
  Private = AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA));
  if (Private == NULL) {
    goto Error;
  }

  //
  // This signature must be valid before any member function is called
  //
  Private->Signature              = WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE;
  Private->NtHandle               = NtHandle;
  Private->ControllerHandle       = Handle;
  Private->Handle                 = NULL;
  Private->WinNtThunk             = WinNtIo->WinNtThunk;
  Private->ParentDevicePath       = ParentDevicePath;
  Private->ControllerNameTable    = NULL;

  Private->SoftwareLoopbackEnable = FALSE;
  Private->HardwareLoopbackEnable = FALSE;
  Private->HardwareFlowControl    = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE);
  Private->Fifo.First             = 0;
  Private->Fifo.Last              = 0;
  Private->Fifo.Surplus           = SERIAL_MAX_BUFFER_SIZE;

  CopyMem (&Private->UartDevicePath, &UartNode, sizeof (UART_DEVICE_PATH));

  AddUnicodeString2 (
    "eng",
    gWinNtSerialIoComponentName.SupportedLanguages,
    &Private->ControllerNameTable,
    WinNtIo->EnvString,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gWinNtSerialIoComponentName2.SupportedLanguages,
    &Private->ControllerNameTable,
    WinNtIo->EnvString,
    FALSE
    );


  Private->SerialIo.Revision      = SERIAL_IO_INTERFACE_REVISION;
  Private->SerialIo.Reset         = WinNtSerialIoReset;
  Private->SerialIo.SetAttributes = WinNtSerialIoSetAttributes;
  Private->SerialIo.SetControl    = WinNtSerialIoSetControl;
  Private->SerialIo.GetControl    = WinNtSerialIoGetControl;
  Private->SerialIo.Write         = WinNtSerialIoWrite;
  Private->SerialIo.Read          = WinNtSerialIoRead;
  Private->SerialIo.Mode          = &Private->SerialIoMode;

  //
  // Build the device path by appending the UART node to the ParentDevicePath
  // from the WinNtIo handle. The Uart setings are zero here, since
  // SetAttribute() will update them to match the current setings.
  //
  Private->DevicePath = AppendDevicePathNode (
                          ParentDevicePath,
                          (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
                          );
  //
  // Only produce the FlowControl node when remaining device path has it
  //
  if (FlowControl != NULL) {
    TempDevicePath = Private->DevicePath;
    if (TempDevicePath != NULL) {
      Private->DevicePath = AppendDevicePathNode (
                              TempDevicePath,
                              (EFI_DEVICE_PATH_PROTOCOL *) FlowControl
                              );
      FreePool (TempDevicePath);
    }
  }
  if (Private->DevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  //
  // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
  //
  Private->SerialIoMode.ControlMask       = SERIAL_CONTROL_MASK;
  Private->SerialIoMode.Timeout           = SERIAL_TIMEOUT_DEFAULT;
  Private->SerialIoMode.BaudRate          = Private->UartDevicePath.BaudRate;
  Private->SerialIoMode.ReceiveFifoDepth  = SERIAL_FIFO_DEFAULT;
  Private->SerialIoMode.DataBits          = Private->UartDevicePath.DataBits;
  Private->SerialIoMode.Parity            = Private->UartDevicePath.Parity;
  Private->SerialIoMode.StopBits          = Private->UartDevicePath.StopBits;

  //
  // Issue a reset to initialize the COM port
  //
  Status = Private->SerialIo.Reset (&Private->SerialIo);
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // Create new child handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->Handle,
                  &gEfiSerialIoProtocolGuid,
                  &Private->SerialIo,
                  &gEfiDevicePathProtocolGuid,
                  Private->DevicePath,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // Open For Child Device
  //
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiWinNtIoProtocolGuid,
                  (VOID **) &WinNtIo,
                  This->DriverBindingHandle,
                  Private->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  return EFI_SUCCESS;

Error:
  //
  // Use the Stop() function to free all resources allocated in Start()
  //
  if (Private != NULL) {
    if (Private->Handle != NULL) {
      This->Stop (This, Handle, 1, &Private->Handle);
    } else {
      if (NtHandle != INVALID_HANDLE_VALUE) {
        Private->WinNtThunk->CloseHandle (NtHandle);
      }

      if (Private->DevicePath != NULL) {
        FreePool (Private->DevicePath);
      }

      FreeUnicodeStringTable (Private->ControllerNameTable);

      FreePool (Private);
    }
  }

  This->Stop (This, Handle, 0, NULL);

  return Status;
}
Пример #21
0
/**
  Starts the mouse device with this driver.

  This function consumes USB I/O Portocol, intializes USB mouse device,
  installs Simple Pointer Protocol, and submits Asynchronous Interrupt
  Transfer to manage the USB mouse device.

  @param  This                  The USB mouse driver binding instance.
  @param  Controller            Handle of device to bind driver to.
  @param  RemainingDevicePath   Optional parameter use to pick a specific child
                                device to start.

  @retval EFI_SUCCESS           This driver supports this device.
  @retval EFI_UNSUPPORTED       This driver does not support this device.
  @retval EFI_DEVICE_ERROR      This driver cannot be started due to device Error.
  @retval EFI_OUT_OF_RESOURCES  Can't allocate memory resources.
  @retval EFI_ALREADY_STARTED   This driver has been started.

**/
EFI_STATUS
EFIAPI
USBMouseDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                  Status;
  EFI_USB_IO_PROTOCOL         *UsbIo;
  USB_MOUSE_DEV               *UsbMouseDevice;
  UINT8                       EndpointNumber;
  EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
  UINT8                       Index;
  UINT8                       EndpointAddr;
  UINT8                       PollingInterval;
  UINT8                       PacketSize;
  BOOLEAN                     Found;
  EFI_TPL                     OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  //
  // Open USB I/O Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiUsbIoProtocolGuid,
                  (VOID **) &UsbIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit1;
  }

  UsbMouseDevice = AllocateZeroPool (sizeof (USB_MOUSE_DEV));
  ASSERT (UsbMouseDevice != NULL);

  UsbMouseDevice->UsbIo     = UsbIo;
  UsbMouseDevice->Signature = USB_MOUSE_DEV_SIGNATURE;

  //
  // Get the Device Path Protocol on Controller's handle
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &UsbMouseDevice->DevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Report Status Code here since USB mouse will be detected next.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT),
    UsbMouseDevice->DevicePath
    );

  //
  // Get interface & endpoint descriptor
  //
  UsbIo->UsbGetInterfaceDescriptor (
           UsbIo,
           &UsbMouseDevice->InterfaceDescriptor
           );

  EndpointNumber = UsbMouseDevice->InterfaceDescriptor.NumEndpoints;

  //
  // Traverse endpoints to find interrupt endpoint
  //
  Found = FALSE;
  for (Index = 0; Index < EndpointNumber; Index++) {
    UsbIo->UsbGetEndpointDescriptor (
             UsbIo,
             Index,
             &EndpointDescriptor
             );

    if ((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) {
      //
      // We only care interrupt endpoint here
      //
      CopyMem(&UsbMouseDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));
      Found = TRUE;
      break;
    }
  }

  if (!Found) {
    //
    // Report Status Code to indicate that there is no USB mouse
    //
    REPORT_STATUS_CODE (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED)
      );
    //
    // No interrupt endpoint found, then return unsupported.
    //
    Status = EFI_UNSUPPORTED;
    goto ErrorExit;
  }

  //
  // Report Status Code here since USB mouse has be detected.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED),
    UsbMouseDevice->DevicePath
    );

  Status = InitializeUsbMouseDevice (UsbMouseDevice);
  if (EFI_ERROR (Status)) {
    //
    // Fail to initialize USB mouse device.
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR),
      UsbMouseDevice->DevicePath
      );

    goto ErrorExit;
  }

  //
  // Initialize and install EFI Simple Pointer Protocol.
  //
  UsbMouseDevice->SimplePointerProtocol.GetState  = GetMouseState;
  UsbMouseDevice->SimplePointerProtocol.Reset     = UsbMouseReset;
  UsbMouseDevice->SimplePointerProtocol.Mode      = &UsbMouseDevice->Mode;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  UsbMouseWaitForInput,
                  UsbMouseDevice,
                  &((UsbMouseDevice->SimplePointerProtocol).WaitForInput)
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  Status = gBS->InstallProtocolInterface (
                  &Controller,
                  &gEfiSimplePointerProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &UsbMouseDevice->SimplePointerProtocol
                  );

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // The next step would be submitting Asynchronous Interrupt Transfer on this mouse device.
  // After that we will be able to get key data from it. Thus this is deemed as
  // the enable action of the mouse, so report status code accordingly.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE),
    UsbMouseDevice->DevicePath
    );

  //
  // Submit Asynchronous Interrupt Transfer to manage this device.
  //
  EndpointAddr    = UsbMouseDevice->IntEndpointDescriptor.EndpointAddress;
  PollingInterval = UsbMouseDevice->IntEndpointDescriptor.Interval;
  PacketSize      = (UINT8) (UsbMouseDevice->IntEndpointDescriptor.MaxPacketSize);

  Status = UsbIo->UsbAsyncInterruptTransfer (
                    UsbIo,
                    EndpointAddr,
                    TRUE,
                    PollingInterval,
                    PacketSize,
                    OnMouseInterruptComplete,
                    UsbMouseDevice
                    );

  if (EFI_ERROR (Status)) {
    //
    // If submit error, uninstall that interface
    //
    gBS->UninstallProtocolInterface (
           Controller,
           &gEfiSimplePointerProtocolGuid,
           &UsbMouseDevice->SimplePointerProtocol
           );
    goto ErrorExit;
  }

  UsbMouseDevice->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gUsbMouseComponentName.SupportedLanguages,
    &UsbMouseDevice->ControllerNameTable,
    L"Generic Usb Mouse",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gUsbMouseComponentName2.SupportedLanguages,
    &UsbMouseDevice->ControllerNameTable,
    L"Generic Usb Mouse",
    FALSE
    );

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;

//
// Error handler
//
ErrorExit:
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
          Controller,
          &gEfiUsbIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    if (UsbMouseDevice != NULL) {
      if ((UsbMouseDevice->SimplePointerProtocol).WaitForInput != NULL) {
        gBS->CloseEvent ((UsbMouseDevice->SimplePointerProtocol).WaitForInput);
      }

      FreePool (UsbMouseDevice);
      UsbMouseDevice = NULL;
    }
  }

ErrorExit1:
  gBS->RestoreTPL (OldTpl);
  return Status;
}
Пример #22
0
/**
  Scan SD Bus to discover the device.

  @param[in]  Private             The SD driver private data structure.
  @param[in]  Slot                The slot number to check device present.

  @retval EFI_SUCCESS             Successfully to discover the device and attach
                                  SdMmcIoProtocol to it.
  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack
                                  of resources.
  @retval EFI_ALREADY_STARTED     The device was discovered before.
  @retval Others                  Fail to discover the device.

**/
EFI_STATUS
EFIAPI
DiscoverSdDevice (
  IN  SD_DRIVER_PRIVATE_DATA      *Private,
  IN  UINT8                       Slot
  )
{
  EFI_STATUS                      Status;
  SD_DEVICE                       *Device;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *NewDevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath;
  EFI_HANDLE                      DeviceHandle;
  EFI_SD_MMC_PASS_THRU_PROTOCOL   *PassThru;

  Device              = NULL;
  DevicePath          = NULL;
  NewDevicePath       = NULL;
  RemainingDevicePath = NULL;
  PassThru = Private->PassThru;

  //
  // Build Device Path
  //
  Status = PassThru->BuildDevicePath (
                       PassThru,
                       Slot,
                       &DevicePath
                       );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  if (DevicePath->SubType != MSG_SD_DP) {
    Status = EFI_UNSUPPORTED;
    goto Error;
  }

  NewDevicePath = AppendDevicePathNode (
                    Private->ParentDevicePath,
                    DevicePath
                    );

  if (NewDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  DeviceHandle = NULL;
  RemainingDevicePath = NewDevicePath;
  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
    //
    // The device has been started, directly return to fast boot.
    //
    Status = EFI_ALREADY_STARTED;
    goto Error;
  }

  //
  // Allocate buffer to store SD_DEVICE private data.
  //
  Device = AllocateCopyPool (sizeof (SD_DEVICE), &mSdDeviceTemplate);
  if (Device == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  Device->DevicePath = NewDevicePath;
  Device->Slot       = Slot;
  Device->Private    = Private;
  InitializeListHead (&Device->Queue);

  //
  // Expose user area in the Sd memory card to upper layer.
  //
  Status = DiscoverUserArea (Device);
  if (EFI_ERROR(Status)) {
    goto Error;
  }

  Device->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gSdDxeComponentName.SupportedLanguages,
    &Device->ControllerNameTable,
    Device->ModelName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gSdDxeComponentName2.SupportedLanguages,
    &Device->ControllerNameTable,
    Device->ModelName,
    FALSE
    );

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Device->Handle,
                  &gEfiDevicePathProtocolGuid,
                  Device->DevicePath,
                  &gEfiBlockIoProtocolGuid,
                  &Device->BlockIo,
                  &gEfiBlockIo2ProtocolGuid,
                  &Device->BlockIo2,
                  &gEfiEraseBlockProtocolGuid,
                  &Device->EraseBlock,
                  &gEfiDiskInfoProtocolGuid,
                  &Device->DiskInfo,
                  NULL
                  );

  if (!EFI_ERROR (Status)) {
    gBS->OpenProtocol (
           Private->Controller,
           &gEfiSdMmcPassThruProtocolGuid,
           (VOID **) &(Private->PassThru),
           Private->DriverBindingHandle,
           Device->Handle,
           EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
           );
  }

Error:
  FreePool (DevicePath);

  if (EFI_ERROR (Status) && (NewDevicePath != NULL)) {
    FreePool (NewDevicePath);
  }

  if (EFI_ERROR (Status) && (Device != NULL)) {
    FreePool (Device);
  }

  return Status;
}
Пример #23
0
/**
  Scan EMMC Bus to discover the device.

  @param[in]  Private             The EMMC driver private data structure.
  @param[in]  Slot                The slot number to check device present.
  @param[in]  RemainingDevicePath The pointer to the remaining device path.

  @retval EFI_SUCCESS             Successfully to discover the device and attach
                                  SdMmcIoProtocol to it.
  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack
                                  of resources.
  @retval EFI_ALREADY_STARTED     The device was discovered before.
  @retval Others                  Fail to discover the device.

**/
EFI_STATUS
EFIAPI
DiscoverEmmcDevice (
  IN  EMMC_DRIVER_PRIVATE_DATA    *Private,
  IN  UINT8                       Slot,
  IN  EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
  )
{
  EFI_STATUS                      Status;
  EMMC_DEVICE                     *Device;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *NewDevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *RemainingEmmcDevPath;
  EFI_DEV_PATH                    *Node;
  EFI_HANDLE                      DeviceHandle;
  EFI_SD_MMC_PASS_THRU_PROTOCOL   *PassThru;
  UINT8                           Index;

  Device              = NULL;
  DevicePath          = NULL;
  NewDevicePath       = NULL;
  RemainingDevicePath = NULL;
  PassThru = Private->PassThru;
  Device   = &Private->Device[Slot];

  //
  // Build Device Path to check if the EMMC device present at the slot.
  //
  Status = PassThru->BuildDevicePath (
                       PassThru,
                       Slot,
                       &DevicePath
                       );
  if (EFI_ERROR(Status)) {
    return Status;
  }

  if (DevicePath->SubType != MSG_EMMC_DP) {
    Status = EFI_UNSUPPORTED;
    goto Error;
  }

  NewDevicePath = AppendDevicePathNode (
                    Private->ParentDevicePath,
                    DevicePath
                    );
  if (NewDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  DeviceHandle         = NULL;
  RemainingEmmcDevPath = NewDevicePath;
  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingEmmcDevPath, &DeviceHandle);
  //
  // The device path to the EMMC device doesn't exist. It means the corresponding device private data hasn't been initialized.
  //
  if (EFI_ERROR (Status) || (DeviceHandle == NULL) || !IsDevicePathEnd (RemainingEmmcDevPath)) {
    Device->DevicePath = NewDevicePath;
    Device->Slot       = Slot;
    Device->Private    = Private;
    //
    // Expose user area in the Sd memory card to upper layer.
    //
    Status = DiscoverAllPartitions (Device);
    if (EFI_ERROR(Status)) {
      FreePool (NewDevicePath);
      goto Error;
    }

    Status = gBS->InstallProtocolInterface (
                    &Device->Handle,
                    &gEfiDevicePathProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    Device->DevicePath
                    );
    if (EFI_ERROR(Status)) {
      FreePool (NewDevicePath);
      goto Error;
    }

    Device->ControllerNameTable = NULL;
    GetEmmcModelName (Device, &Device->Cid);
    AddUnicodeString2 (
      "eng",
      gEmmcDxeComponentName.SupportedLanguages,
      &Device->ControllerNameTable,
      Device->ModelName,
      TRUE
      );
    AddUnicodeString2 (
      "en",
      gEmmcDxeComponentName.SupportedLanguages,
      &Device->ControllerNameTable,
      Device->ModelName,
      FALSE
      );
  }

  if (RemainingDevicePath == NULL) {
    //
    // Expose all partitions in the Emmc device to upper layer.
    //
    for (Index = 0; Index < EMMC_MAX_PARTITIONS; Index++) {
      InstallProtocolOnPartition (Device, Index);
    }
  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    //
    // Enumerate the specified partition
    //
    Node = (EFI_DEV_PATH *) RemainingDevicePath;
    if ((DevicePathType (&Node->DevPath) != HARDWARE_DEVICE_PATH) ||
        (DevicePathSubType (&Node->DevPath) != HW_CONTROLLER_DP) ||
        (DevicePathNodeLength (&Node->DevPath) != sizeof (CONTROLLER_DEVICE_PATH))) {
      Status = EFI_INVALID_PARAMETER;
      goto Error;
    }

    Index = (UINT8)Node->Controller.ControllerNumber;
    if (Index >= EMMC_MAX_PARTITIONS) {
      Status = EFI_INVALID_PARAMETER;
      goto Error;
    }

    Status = InstallProtocolOnPartition (Device, Index);
  }

Error:
  FreePool (DevicePath);

  return Status;
}
Пример #24
0
/**
  Update the component name for the Dhcp6 child handle.

  @param  Dhcp6[in]                   A pointer to the EFI_DHCP6_PROTOCOL.


  @retval EFI_SUCCESS                 Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER       The input parameter is invalid.

**/
EFI_STATUS
UpdateName (
    IN   EFI_DHCP6_PROTOCOL             *Dhcp6
)
{
    EFI_STATUS                       Status;
    EFI_DHCP6_MODE_DATA              Dhcp6ModeData;
    CHAR16                           *HandleName;

    if (Dhcp6 == NULL) {
        return EFI_INVALID_PARAMETER;
    }

    //
    // Format the child name into the string buffer.
    //
    Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);
    if (EFI_ERROR (Status)) {
        return Status;
    }

    if (gDhcp6ControllerNameTable != NULL) {
        FreeUnicodeStringTable (gDhcp6ControllerNameTable);
        gDhcp6ControllerNameTable = NULL;
    }

    if (Dhcp6ModeData.Ia == NULL) {
        HandleName = L"DHCPv6 (No configured IA)";
    } else {
        if (Dhcp6ModeData.Ia->State > Dhcp6Rebinding) {
            return EFI_DEVICE_ERROR;
        }
        HandleName = mDhcp6ControllerName[Dhcp6ModeData.Ia->State];
    }

    if (Dhcp6ModeData.Ia != NULL) {
        FreePool (Dhcp6ModeData.Ia);
    }
    if (Dhcp6ModeData.ClientId != NULL) {
        FreePool (Dhcp6ModeData.ClientId);
    }

    Status = AddUnicodeString2 (
                 "eng",
                 gDhcp6ComponentName.SupportedLanguages,
                 &gDhcp6ControllerNameTable,
                 HandleName,
                 TRUE
             );
    if (EFI_ERROR (Status)) {
        return Status;
    }

    return AddUnicodeString2 (
               "en",
               gDhcp6ComponentName2.SupportedLanguages,
               &gDhcp6ControllerNameTable,
               HandleName,
               FALSE
           );
}
Пример #25
0
/**
  Start this driver on ControllerHandle by opening a Sio protocol, creating
  PS2_MOUSE_DEV device and install gEfiSimplePointerProtocolGuid finally.

  @param  This                 Protocol instance pointer.
  @param  ControllerHandle     Handle of device to bind driver to
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
  @retval other                This driver does not support this device

**/
EFI_STATUS
EFIAPI
PS2MouseDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                          Status;
  EFI_STATUS                          EmptyStatus;
  EFI_SIO_PROTOCOL                    *Sio;
  PS2_MOUSE_DEV                       *MouseDev;
  UINT8                               Data;
  EFI_TPL                             OldTpl;
  EFI_STATUS_CODE_VALUE               StatusCode;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;

  StatusCode  = 0;

  //
  // Open the device path protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Report that the keyboard is being enabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,
    DevicePath
    );

  //
  // Get the ISA I/O Protocol on Controller's handle
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSioProtocolGuid,
                  (VOID **) &Sio,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Raise TPL to avoid keyboard operation impact
  //
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  //
  // Allocate private data
  //
  MouseDev = AllocateZeroPool (sizeof (PS2_MOUSE_DEV));
  if (MouseDev == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
  //
  // Setup the device instance
  //
  MouseDev->Signature       = PS2_MOUSE_DEV_SIGNATURE;
  MouseDev->Handle          = Controller;
  MouseDev->SampleRate      = SampleRate20;
  MouseDev->Resolution      = MouseResolution4;
  MouseDev->Scaling         = Scaling1;
  MouseDev->DataPackageSize = 3;
  MouseDev->DevicePath      = DevicePath;

  //
  // Resolution = 4 counts/mm
  //
  MouseDev->Mode.ResolutionX                = 4;
  MouseDev->Mode.ResolutionY                = 4;
  MouseDev->Mode.LeftButton                 = TRUE;
  MouseDev->Mode.RightButton                = TRUE;

  MouseDev->SimplePointerProtocol.Reset     = MouseReset;
  MouseDev->SimplePointerProtocol.GetState  = MouseGetState;
  MouseDev->SimplePointerProtocol.Mode      = &(MouseDev->Mode);

  //
  // Initialize keyboard controller if necessary
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,
    DevicePath
    );

  Data = IoRead8 (KBC_CMD_STS_PORT);
  //
  // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
  //
  if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
    //
    // If nobody decodes KBC I/O port, it will read back as 0xFF.
    // Check the Time-Out and Parity bit to see if it has an active KBC in system
    //
    Status     = EFI_DEVICE_ERROR;
    StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
    goto ErrorExit;
  }

  if ((Data & KBC_SYSF) != KBC_SYSF) {
    Status = KbcSelfTest ();
    if (EFI_ERROR (Status)) {
      StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;
      goto ErrorExit;
    }
  }

  KbcEnableAux ();

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,
    DevicePath
    );

  //
  // Reset the mouse
  //
  Status = MouseDev->SimplePointerProtocol.Reset (
                     &MouseDev->SimplePointerProtocol,
                     FeaturePcdGet (PcdPs2MouseExtendedVerification)
                     );
  if (EFI_ERROR (Status)) {
    //
    // mouse not connected
    //
    Status      = EFI_SUCCESS;
    StatusCode  = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
    goto ErrorExit;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED,
    DevicePath
    );

  //
  // Setup the WaitForKey event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  MouseWaitForInput,
                  MouseDev,
                  &((MouseDev->SimplePointerProtocol).WaitForInput)
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
  //
  // Setup a periodic timer, used to poll mouse state
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  PollMouse,
                  MouseDev,
                  &MouseDev->TimerEvent
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
  //
  // Start timer to poll mouse (100 samples per second)
  //
  Status = gBS->SetTimer (MouseDev->TimerEvent, TimerPeriodic, 100000);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  MouseDev->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gPs2MouseComponentName.SupportedLanguages,
    &MouseDev->ControllerNameTable,
    L"PS/2 Mouse Device",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gPs2MouseComponentName2.SupportedLanguages,
    &MouseDev->ControllerNameTable,
    L"PS/2 Mouse Device",
    FALSE
    );


  //
  // Install protocol interfaces for the mouse device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiSimplePointerProtocolGuid,
                  &MouseDev->SimplePointerProtocol,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;

ErrorExit:

  if (Status != EFI_DEVICE_ERROR) {
    KbcDisableAux ();
  }

  if (StatusCode != 0) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      StatusCode,
      DevicePath
      );
  }

  if ((MouseDev != NULL) && (MouseDev->SimplePointerProtocol.WaitForInput != NULL)) {
    gBS->CloseEvent (MouseDev->SimplePointerProtocol.WaitForInput);
  }

  if ((MouseDev != NULL) && (MouseDev->TimerEvent != NULL)) {
    gBS->CloseEvent (MouseDev->TimerEvent);
  }

  if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) {
    FreeUnicodeStringTable (MouseDev->ControllerNameTable);
  }

  if (Status != EFI_DEVICE_ERROR) {
    //
    // Since there will be no timer handler for mouse input any more,
    // exhaust input data just in case there is still mouse data left
    //
    EmptyStatus = EFI_SUCCESS;
    while (!EFI_ERROR (EmptyStatus)) {
      EmptyStatus = In8042Data (&Data);
    }
  }

  if (MouseDev != NULL) {
    FreePool (MouseDev);
  }

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

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

  gBS->RestoreTPL (OldTpl);

  return Status;
}
Пример #26
0
/**
  Start this driver on ControllerHandle by opening a IsaIo protocol, creating
  PS2_MOUSE_ABSOLUTE_POINTER_DEV device and install gEfiAbsolutePointerProtocolGuid
  finally.

  @param  This                 Protocol instance pointer.
  @param  ControllerHandle     Handle of device to bind driver to
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
  @retval other                This driver does not support this device

**/
EFI_STATUS
EFIAPI
PS2MouseAbsolutePointerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                          Status;
  EFI_STATUS                          EmptyStatus;
  EFI_ISA_IO_PROTOCOL                 *IsaIo;
  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev;
  UINT8                               Data;
  EFI_TPL                             OldTpl;
  EFI_STATUS_CODE_VALUE               StatusCode;
  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;

  StatusCode  = 0;
  MouseAbsolutePointerDev    = NULL;
  IsaIo       = NULL;

  //
  // Open the device path protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Report that the keyboard is being enabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE,
    ParentDevicePath
    );

  //
  // Get the ISA I/O Protocol on Controller's handle
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIsaIoProtocolGuid,
                  (VOID **) &IsaIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return EFI_INVALID_PARAMETER;
  }
  //
  // Raise TPL to avoid keyboard operation impact
  //
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  //
  // Allocate private data
  //
  MouseAbsolutePointerDev = AllocateZeroPool (sizeof (PS2_MOUSE_ABSOLUTE_POINTER_DEV));
  if (MouseAbsolutePointerDev == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
  //
  // Setup the device instance
  //
  MouseAbsolutePointerDev->Signature       = PS2_MOUSE_ABSOLUTE_POINTER_DEV_SIGNATURE;
  MouseAbsolutePointerDev->Handle          = Controller;
  MouseAbsolutePointerDev->SampleRate      = SampleRate20;
  MouseAbsolutePointerDev->Resolution      = MouseResolution4;
  MouseAbsolutePointerDev->Scaling         = Scaling1;
  MouseAbsolutePointerDev->DataPackageSize = 3;
  MouseAbsolutePointerDev->IsaIo           = IsaIo;
  MouseAbsolutePointerDev->DevicePath      = ParentDevicePath;

  //
  // Resolution = 4 counts/mm
  //
  MouseAbsolutePointerDev->Mode.AbsoluteMaxX               = 1024;
  MouseAbsolutePointerDev->Mode.AbsoluteMinX               = 0;
  MouseAbsolutePointerDev->Mode.AbsoluteMaxY               = 798;
  MouseAbsolutePointerDev->Mode.AbsoluteMinY               = 0;
  MouseAbsolutePointerDev->Mode.AbsoluteMaxZ               = 0;
  MouseAbsolutePointerDev->Mode.AbsoluteMinZ               = 0;
  MouseAbsolutePointerDev->Mode.Attributes                 = 0x03;

  MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset     = MouseAbsolutePointerReset;
  MouseAbsolutePointerDev->AbsolutePointerProtocol.GetState  = MouseAbsolutePointerGetState;
  MouseAbsolutePointerDev->AbsolutePointerProtocol.Mode      = &(MouseAbsolutePointerDev->Mode);

  //
  // Initialize keyboard controller if necessary
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_MOUSE_PC_SELF_TEST,
    ParentDevicePath
    );

  IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
  if ((Data & KBC_SYSF) != KBC_SYSF) {
    Status = KbcSelfTest (IsaIo);
    if (EFI_ERROR (Status)) {
      StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_CONTROLLER_ERROR;
      goto ErrorExit;
    }
  }

  KbcEnableAux (IsaIo);

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT,
    ParentDevicePath
    );

  //
  // Reset the mouse
  //
  Status = MouseAbsolutePointerDev->AbsolutePointerProtocol.Reset (
                     &MouseAbsolutePointerDev->AbsolutePointerProtocol,
                     FeaturePcdGet (PcdPs2MouseExtendedVerification)
                     );
  if (EFI_ERROR (Status)) {
    //
    // mouse not connected
    //
    Status      = EFI_SUCCESS;
    StatusCode  = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED;
    goto ErrorExit;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED,
    ParentDevicePath
    );

  //
  // Setup the WaitForKey event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  MouseAbsolutePointerWaitForInput,
                  MouseAbsolutePointerDev,
                  &((MouseAbsolutePointerDev->AbsolutePointerProtocol).WaitForInput)
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
  //
  // Setup a periodic timer, used to poll mouse state
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  PollMouseAbsolutePointer,
                  MouseAbsolutePointerDev,
                  &MouseAbsolutePointerDev->TimerEvent
                  );
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }
  //
  // Start timer to poll mouse (100 samples per second)
  //
  Status = gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerPeriodic, 100000);
  if (EFI_ERROR (Status)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  MouseAbsolutePointerDev->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gPs2MouseAbsolutePointerComponentName.SupportedLanguages,
    &MouseAbsolutePointerDev->ControllerNameTable,
    L"Faked PS/2 Touchpad Device",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gPs2MouseAbsolutePointerComponentName2.SupportedLanguages,
    &MouseAbsolutePointerDev->ControllerNameTable,
    L"Faked PS/2 Touchpad Device",
    FALSE
    );


  //
  // Install protocol interfaces for the mouse device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiAbsolutePointerProtocolGuid,
                  &MouseAbsolutePointerDev->AbsolutePointerProtocol,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;

ErrorExit:

  KbcDisableAux (IsaIo);

  if (StatusCode != 0) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      StatusCode,
      ParentDevicePath
      );
  }

  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput != NULL)) {
    gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);
  }

  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->TimerEvent != NULL)) {
    gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);
  }

  if ((MouseAbsolutePointerDev != NULL) && (MouseAbsolutePointerDev->ControllerNameTable != NULL)) {
    FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);
  }
  //
  // Since there will be no timer handler for mouse input any more,
  // exhaust input data just in case there is still mouse data left
  //
  EmptyStatus = EFI_SUCCESS;
  while (!EFI_ERROR (EmptyStatus)) {
    EmptyStatus = In8042Data (IsaIo, &Data);
  }

  if (MouseAbsolutePointerDev != NULL) {
    FreePool (MouseAbsolutePointerDev);
  }

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

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

  gBS->RestoreTPL (OldTpl);

  return Status;
}
/**
  Check if the specified Nvm Express device namespace is active, and create child handles
  for them with BlockIo and DiskInfo protocol instances.

  @param[in] Private         The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
  @param[in] NamespaceId     The NVM Express namespace ID  for which a device path node is to be
                             allocated and built. Caller must set the NamespaceId to zero if the
                             device path node will contain a valid UUID.

  @retval EFI_SUCCESS        All the namespaces in the device are successfully enumerated.
  @return Others             Some error occurs when enumerating the namespaces.

**/
EFI_STATUS
EnumerateNvmeDevNamespace (
  IN NVME_CONTROLLER_PRIVATE_DATA       *Private,
  UINT32                                NamespaceId
  )
{
  NVME_ADMIN_NAMESPACE_DATA             *NamespaceData;
  EFI_DEVICE_PATH_PROTOCOL              *NewDevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL              *DevicePath;
  EFI_HANDLE                            DeviceHandle;
  EFI_DEVICE_PATH_PROTOCOL              *ParentDevicePath;
  EFI_DEVICE_PATH_PROTOCOL              *RemainingDevicePath;
  NVME_DEVICE_PRIVATE_DATA              *Device;
  EFI_STATUS                            Status;
  UINT32                                Lbads;
  UINT32                                Flbas;
  UINT32                                LbaFmtIdx;
  UINT8                                 Sn[21];
  UINT8                                 Mn[41];
  VOID                                  *DummyInterface;

  NewDevicePathNode = NULL;
  DevicePath        = NULL;
  Device            = NULL;

  //
  // Allocate a buffer for Identify Namespace data
  //
  NamespaceData = AllocateZeroPool(sizeof (NVME_ADMIN_NAMESPACE_DATA));
  if(NamespaceData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  ParentDevicePath = Private->ParentDevicePath;
  //
  // Identify Namespace
  //
  Status = NvmeIdentifyNamespace (
             Private,
             NamespaceId,
             (VOID *)NamespaceData
             );
  if (EFI_ERROR(Status)) {
    goto Exit;
  }
  //
  // Validate Namespace
  //
  if (NamespaceData->Ncap == 0) {
    Status = EFI_DEVICE_ERROR;
  } else {
    //
    // allocate device private data for each discovered namespace
    //
    Device = AllocateZeroPool(sizeof(NVME_DEVICE_PRIVATE_DATA));
    if (Device == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    //
    // Initialize SSD namespace instance data
    //
    Device->Signature           = NVME_DEVICE_PRIVATE_DATA_SIGNATURE;
    Device->NamespaceId         = NamespaceId;
    Device->NamespaceUuid       = NamespaceData->Eui64;

    Device->ControllerHandle    = Private->ControllerHandle;
    Device->DriverBindingHandle = Private->DriverBindingHandle;
    Device->Controller          = Private;

    //
    // Build BlockIo media structure
    //
    Device->Media.MediaId        = 0;
    Device->Media.RemovableMedia = FALSE;
    Device->Media.MediaPresent   = TRUE;
    Device->Media.LogicalPartition = FALSE;
    Device->Media.ReadOnly       = FALSE;
    Device->Media.WriteCaching   = FALSE;
    Device->Media.IoAlign        = Private->PassThruMode.IoAlign;

    Flbas     = NamespaceData->Flbas;
    LbaFmtIdx = Flbas & 0xF;
    Lbads     = NamespaceData->LbaFormat[LbaFmtIdx].Lbads;
    Device->Media.BlockSize = (UINT32)1 << Lbads;

    Device->Media.LastBlock                     = NamespaceData->Nsze - 1;
    Device->Media.LogicalBlocksPerPhysicalBlock = 1;
    Device->Media.LowestAlignedLba              = 1;

    //
    // Create BlockIo Protocol instance
    //
    Device->BlockIo.Revision     = EFI_BLOCK_IO_PROTOCOL_REVISION2;
    Device->BlockIo.Media        = &Device->Media;
    Device->BlockIo.Reset        = NvmeBlockIoReset;
    Device->BlockIo.ReadBlocks   = NvmeBlockIoReadBlocks;
    Device->BlockIo.WriteBlocks  = NvmeBlockIoWriteBlocks;
    Device->BlockIo.FlushBlocks  = NvmeBlockIoFlushBlocks;

    //
    // Create BlockIo2 Protocol instance
    //
    Device->BlockIo2.Media          = &Device->Media;
    Device->BlockIo2.Reset          = NvmeBlockIoResetEx;
    Device->BlockIo2.ReadBlocksEx   = NvmeBlockIoReadBlocksEx;
    Device->BlockIo2.WriteBlocksEx  = NvmeBlockIoWriteBlocksEx;
    Device->BlockIo2.FlushBlocksEx  = NvmeBlockIoFlushBlocksEx;
    InitializeListHead (&Device->AsyncQueue);

    //
    // Create StorageSecurityProtocol Instance
    //
    Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData;
    Device->StorageSecurity.SendData    = NvmeStorageSecuritySendData;

    //
    // Create DiskInfo Protocol instance
    //
    CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA));
    InitializeDiskInfo (Device);

    //
    // Create a Nvm Express Namespace Device Path Node
    //
    Status = Private->Passthru.BuildDevicePath (
                                 &Private->Passthru,
                                 Device->NamespaceId,
                                 &NewDevicePathNode
                                 );

    if (EFI_ERROR(Status)) {
      goto Exit;
    }

    //
    // Append the SSD node to the controller's device path
    //
    DevicePath = AppendDevicePathNode (ParentDevicePath, NewDevicePathNode);
    if (DevicePath == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    DeviceHandle = NULL;
    RemainingDevicePath = DevicePath;
    Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
    if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {
      Status = EFI_ALREADY_STARTED;
      FreePool (DevicePath);
      goto Exit;
    }

    Device->DevicePath = DevicePath;

    //
    // Make sure the handle is NULL so we create a new handle
    //
    Device->DeviceHandle = NULL;

    Status = gBS->InstallMultipleProtocolInterfaces (
                    &Device->DeviceHandle,
                    &gEfiDevicePathProtocolGuid,
                    Device->DevicePath,
                    &gEfiBlockIoProtocolGuid,
                    &Device->BlockIo,
                    &gEfiBlockIo2ProtocolGuid,
                    &Device->BlockIo2,
                    &gEfiDiskInfoProtocolGuid,
                    &Device->DiskInfo,
                    NULL
                    );

    if(EFI_ERROR(Status)) {
      goto Exit;
    }

    //
    // Check if the NVMe controller supports the Security Send and Security Receive commands
    //
    if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) {
      Status = gBS->InstallProtocolInterface (
                      &Device->DeviceHandle,
                      &gEfiStorageSecurityCommandProtocolGuid,
                      EFI_NATIVE_INTERFACE,
                      &Device->StorageSecurity
                      );
      if(EFI_ERROR(Status)) {
        gBS->UninstallMultipleProtocolInterfaces (
               &Device->DeviceHandle,
               &gEfiDevicePathProtocolGuid,
               Device->DevicePath,
               &gEfiBlockIoProtocolGuid,
               &Device->BlockIo,
               &gEfiBlockIo2ProtocolGuid,
               &Device->BlockIo2,
               &gEfiDiskInfoProtocolGuid,
               &Device->DiskInfo,
               NULL
               );
        goto Exit;
      }
    }

    gBS->OpenProtocol (
           Private->ControllerHandle,
           &gEfiNvmExpressPassThruProtocolGuid,
           (VOID **) &DummyInterface,
           Private->DriverBindingHandle,
           Device->DeviceHandle,
           EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
           );

    //
    // Dump NvmExpress Identify Namespace Data
    //
    DEBUG ((EFI_D_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId));
    DEBUG ((EFI_D_INFO, "    NSZE        : 0x%x\n", NamespaceData->Nsze));
    DEBUG ((EFI_D_INFO, "    NCAP        : 0x%x\n", NamespaceData->Ncap));
    DEBUG ((EFI_D_INFO, "    NUSE        : 0x%x\n", NamespaceData->Nuse));
    DEBUG ((EFI_D_INFO, "    LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads)));

    //
    // Build controller name for Component Name (2) protocol.
    //
    CopyMem (Sn, Private->ControllerData->Sn, sizeof (Private->ControllerData->Sn));
    Sn[20] = 0;
    CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn));
    Mn[40] = 0;
    UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%x", Sn, Mn, NamespaceData->Eui64);

    AddUnicodeString2 (
      "eng",
      gNvmExpressComponentName.SupportedLanguages,
      &Device->ControllerNameTable,
      Device->ModelName,
      TRUE
      );

    AddUnicodeString2 (
      "en",
      gNvmExpressComponentName2.SupportedLanguages,
      &Device->ControllerNameTable,
      Device->ModelName,
      FALSE
      );
  }

Exit:
  if(NamespaceData != NULL) {
    FreePool (NamespaceData);
  }

  if (NewDevicePathNode != NULL) {
    FreePool (NewDevicePathNode);
  }

  if(EFI_ERROR(Status) && (Device != NULL) && (Device->DevicePath != NULL)) {
    FreePool (Device->DevicePath);
  }
  if(EFI_ERROR(Status) && (Device != NULL)) {
    FreePool (Device);
  }
  return Status;
}
Пример #28
0
EFI_STATUS
EFIAPI
WinNtBusDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    ControllerHandle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_STATUS                      Status;
  EFI_WIN_NT_THUNK_PROTOCOL       *WinNtThunk;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
  WIN_NT_BUS_DEVICE               *WinNtBusDevice;
  WIN_NT_IO_DEVICE                *WinNtDevice;
  UINTN                           Index;
  CHAR16                          *StartString;
  CHAR16                          *SubString;
  UINT16                          Count;
  UINTN                           StringSize;
  UINT16                          ComponentName[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH];
  WIN_NT_VENDOR_DEVICE_PATH_NODE  *Node;
  BOOLEAN                         CreateDevice;
  CHAR16                          *TempStr;
  CHAR16                          *PcdTempStr;
  UINTN                           TempStrSize;

  Status = EFI_UNSUPPORTED;

  //
  // Grab the protocols we need
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiWinNtThunkProtocolGuid,
                  (VOID **) &WinNtThunk,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  if (Status != EFI_ALREADY_STARTED) {
    WinNtBusDevice = AllocatePool (sizeof (WIN_NT_BUS_DEVICE));
    if (WinNtBusDevice == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    WinNtBusDevice->Signature           = WIN_NT_BUS_DEVICE_SIGNATURE;
    WinNtBusDevice->ControllerNameTable = NULL;

    AddUnicodeString2 (
      "eng",
      gWinNtBusDriverComponentName.SupportedLanguages,
      &WinNtBusDevice->ControllerNameTable,
      L"Windows Bus Controller",
      TRUE
      );
    AddUnicodeString2 (
      "en",
      gWinNtBusDriverComponentName2.SupportedLanguages,
      &WinNtBusDevice->ControllerNameTable,
      L"Windows Bus Controller",
      FALSE
      );


    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ControllerHandle,
                    &gWinNtBusDriverGuid,
                    WinNtBusDevice,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);
      FreePool (WinNtBusDevice);
      return Status;
    }
  }

  //
  // Loop on the Variable list. Parse each variable to produce a set of handles that
  // represent virtual hardware devices.
  //
  for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {
    PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);
    ASSERT (PcdTempStr != NULL);

    TempStrSize = StrLen (PcdTempStr);
    TempStr = AllocateMemory (((TempStrSize + 1) * sizeof (CHAR16)));
    StrCpy (TempStr, PcdTempStr);

    StartString = TempStr;

    //
    // Parse the envirnment variable into sub strings using '!' as a delimator.
    // Each substring needs it's own handle to be added to the system. This code
    // does not understand the sub string. Thats the device drivers job.
    //
    Count = 0;
    while (*StartString != '\0') {

      //
      // Find the end of the sub string
      //
      SubString = StartString;
      while (*SubString != '\0' && *SubString != '!') {
        SubString++;
      }

      if (*SubString == '!') {
        //
        // Replace token with '\0' to make sub strings. If this is the end
        //  of the string SubString will already point to NULL.
        //
        *SubString = '\0';
        SubString++;
      }

      CreateDevice = TRUE;
      if (RemainingDevicePath != NULL) {
        CreateDevice  = FALSE;
        //
        // Check if RemainingDevicePath is the End of Device Path Node, 
        // if yes, don't create any child device 
        //
        if (!IsDevicePathEnd (RemainingDevicePath)) {
          //
          // If RemainingDevicePath isn't the End of Device Path Node,
          // check its validation
          //
          Node          = (WIN_NT_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
          if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
              Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
              DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)
              ) {
            if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&
                Node->Instance == Count
                ) {
              CreateDevice = TRUE;
            }
          }
        }
      }

      if (CreateDevice) {

        //
        // Allocate instance structure, and fill in parent information.
        //
        WinNtDevice = AllocateMemory (sizeof (WIN_NT_IO_DEVICE));
        if (WinNtDevice == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        WinNtDevice->Handle             = NULL;
        WinNtDevice->ControllerHandle   = ControllerHandle;
        WinNtDevice->ParentDevicePath   = ParentDevicePath;

        WinNtDevice->WinNtIo.WinNtThunk = WinNtThunk;

        //
        // Plus 2 to account for the NULL at the end of the Unicode string
        //
        StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);
        WinNtDevice->WinNtIo.EnvString = AllocateMemory (StringSize);
        if (WinNtDevice->WinNtIo.EnvString != NULL) {
          CopyMem (WinNtDevice->WinNtIo.EnvString, StartString, StringSize);
        }

        WinNtDevice->ControllerNameTable = NULL;

        WinNtThunk->SPrintf (ComponentName, sizeof (ComponentName), L"%s", WinNtDevice->WinNtIo.EnvString);

        WinNtDevice->DevicePath = WinNtBusCreateDevicePath (
                                    ParentDevicePath,
                                    mPcdEnvironment[Index].DevicePathGuid,
                                    Count
                                    );
        if (WinNtDevice->DevicePath == NULL) {
          FreePool (WinNtDevice);
          return EFI_OUT_OF_RESOURCES;
        }

        AddUnicodeString2 (
          "eng",
          gWinNtBusDriverComponentName.SupportedLanguages,
          &WinNtDevice->ControllerNameTable,
          ComponentName,
          TRUE
          );
        AddUnicodeString2 (
          "en",
          gWinNtBusDriverComponentName2.SupportedLanguages,
          &WinNtDevice->ControllerNameTable,
          ComponentName,
          FALSE
          );


        WinNtDevice->WinNtIo.TypeGuid       = mPcdEnvironment[Index].DevicePathGuid;
        WinNtDevice->WinNtIo.InstanceNumber = Count;

        WinNtDevice->Signature              = WIN_NT_IO_DEVICE_SIGNATURE;

        Status = gBS->InstallMultipleProtocolInterfaces (
                        &WinNtDevice->Handle,
                        &gEfiDevicePathProtocolGuid,
                        WinNtDevice->DevicePath,
                        &gEfiWinNtIoProtocolGuid,
                        &WinNtDevice->WinNtIo,
                        NULL
                        );
        if (EFI_ERROR (Status)) {
          FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);
          FreePool (WinNtDevice);
        } else {
          //
          // Open For Child Device
          //
          Status = gBS->OpenProtocol (
                          ControllerHandle,
                          &gEfiWinNtThunkProtocolGuid,
                          (VOID **) &WinNtThunk,
                          This->DriverBindingHandle,
                          WinNtDevice->Handle,
                          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                          );
        }
      }

      //
      // Parse Next sub string. This will point to '\0' if we are at the end.
      //
      Count++;
      StartString = SubString;
    }

    FreePool (TempStr);
  }

  return EFI_SUCCESS;
}
Пример #29
0
/**
  Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
  
  @param This         Pointer of EFI_DRIVER_BINDING_PROTOCOL
  @param Controller   driver controller handle
  @param RemainingDevicePath Children's device path
  
  @retval whether success to create floppy control instance.
**/
EFI_STATUS
EFIAPI
KbdControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                                Status;
  EFI_STATUS                                Status1;
  EFI_ISA_IO_PROTOCOL                       *IsaIo;
  KEYBOARD_CONSOLE_IN_DEV                   *ConsoleIn;
  UINT8                                     Data;
  EFI_STATUS_CODE_VALUE                     StatusCode;
  EFI_DEVICE_PATH_PROTOCOL                  *ParentDevicePath;

  StatusCode = 0;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Report that the keyboard is being enabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
    ParentDevicePath
    );

  //
  // Get the ISA I/O Protocol on Controller's handle
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIsaIoProtocolGuid,
                  (VOID **) &IsaIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return EFI_INVALID_PARAMETER;
  }
  //
  // Allocate private data
  //
  ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
  if (ConsoleIn == NULL) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }
  //
  // Setup the device instance
  //
  ConsoleIn->Signature              = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
  ConsoleIn->Handle                 = Controller;
  (ConsoleIn->ConIn).Reset          = KeyboardEfiReset;
  (ConsoleIn->ConIn).ReadKeyStroke  = KeyboardReadKeyStroke;
  ConsoleIn->DataRegisterAddress    = KEYBOARD_8042_DATA_REGISTER;
  ConsoleIn->StatusRegisterAddress  = KEYBOARD_8042_STATUS_REGISTER;
  ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
  ConsoleIn->IsaIo                  = IsaIo;
  ConsoleIn->DevicePath             = ParentDevicePath;

  ConsoleIn->ConInEx.Reset               = KeyboardEfiResetEx;
  ConsoleIn->ConInEx.ReadKeyStrokeEx     = KeyboardReadKeyStrokeEx;
  ConsoleIn->ConInEx.SetState            = KeyboardSetState;
  ConsoleIn->ConInEx.RegisterKeyNotify   = KeyboardRegisterKeyNotify;
  ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;  
  
  InitializeListHead (&ConsoleIn->NotifyList);

  //
  // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
  // When KBC decode (IO port 0x60/0x64 decode) is not enabled, 
  // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
  // So instead we read status register to detect after read if KBC decode is enabled.
  //
  
  //
  // Return code is ignored on purpose.
  //
  if (!PcdGetBool (PcdFastPS2Detection)) {
    KeyboardRead (ConsoleIn, &Data);
    if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
      //
      // If nobody decodes KBC I/O port, it will read back as 0xFF.
      // Check the Time-Out and Parity bit to see if it has an active KBC in system
      //
      Status      = EFI_DEVICE_ERROR;
      StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
      goto ErrorExit;
    }
  }
  
  //
  // Setup the WaitForKey event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  KeyboardWaitForKey,
                  ConsoleIn,
                  &((ConsoleIn->ConIn).WaitForKey)
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }
  //
  // Setup the WaitForKeyEx event
  //  
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  KeyboardWaitForKeyEx,
                  ConsoleIn,
                  &(ConsoleIn->ConInEx.WaitForKeyEx)
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }
  // Setup a periodic timer, used for reading keystrokes at a fixed interval
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  KeyboardTimerHandler,
                  ConsoleIn,
                  &ConsoleIn->TimerEvent
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }

  Status = gBS->SetTimer (
                  ConsoleIn->TimerEvent,
                  TimerPeriodic,
                  KEYBOARD_TIMER_INTERVAL
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
    ParentDevicePath
    );

  //
  // Reset the keyboard device
  //
  Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
  if (EFI_ERROR (Status)) {
    Status      = EFI_DEVICE_ERROR;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
    goto ErrorExit;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
    ParentDevicePath
    );

  ConsoleIn->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gPs2KeyboardComponentName.SupportedLanguages,
    &ConsoleIn->ControllerNameTable,
    L"PS/2 Keyboard Device",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gPs2KeyboardComponentName2.SupportedLanguages,
    &ConsoleIn->ControllerNameTable,
    L"PS/2 Keyboard Device",
    FALSE
    );


  //
  // Install protocol interfaces for the keyboard device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  &ConsoleIn->ConIn,
                  &gEfiSimpleTextInputExProtocolGuid,
                  &ConsoleIn->ConInEx,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }

  return Status;

ErrorExit:
  //
  // Report error code
  //
  if (StatusCode != 0) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      StatusCode,
      ParentDevicePath
      );
  }

  if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
    gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
  }

  if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
    gBS->CloseEvent (ConsoleIn->TimerEvent);
  }
  if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
    gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
  }
  KbdFreeNotifyList (&ConsoleIn->NotifyList);
  if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
    FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
  }
  //
  // Since there will be no timer handler for keyboard input any more,
  // exhaust input data just in case there is still keyboard data left
  //
  if (ConsoleIn != NULL) {
    Status1 = EFI_SUCCESS;
    while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
      Status1 = KeyboardRead (ConsoleIn, &Data);;
    }
  }
  
  if (ConsoleIn != NULL) {
    gBS->FreePool (ConsoleIn);
  }

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

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

  return Status;
}
Пример #30
0
/**
  Update the component name for the MNP child handle.

  @param  Mnp[in]                 A pointer to the EFI_MANAGED_NETWORK_PROTOCOL.

  
  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.
  
**/
EFI_STATUS
UpdateName (
  IN   EFI_MANAGED_NETWORK_PROTOCOL     *Mnp
  )
{
  EFI_STATUS                       Status;
  MNP_INSTANCE_DATA                *Instance;
  CHAR16                           HandleName[80];
  EFI_MANAGED_NETWORK_CONFIG_DATA  MnpConfigData;
  EFI_SIMPLE_NETWORK_MODE          SnpModeData;
  UINTN                            OffSet;
  UINTN                            Index;

  if (Mnp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (Mnp);
  //
  // Format the child name into the string buffer as:
  // MNP (MAC=FF-FF-FF-FF-FF-FF, ProtocolType=0x0800, VlanId=0)
  //
  Status = Mnp->GetModeData (Mnp, &MnpConfigData, &SnpModeData);
  if (!EFI_ERROR (Status)) {
    OffSet = 0;
    //
    // Print the MAC address.
    //
    OffSet += UnicodeSPrint (
                HandleName,
                sizeof (HandleName),
                L"MNP (MAC="
                );
    for (Index = 0; Index < SnpModeData.HwAddressSize; Index++) {
      OffSet += UnicodeSPrint (
                  HandleName + OffSet,
                  sizeof (HandleName) - OffSet * sizeof (CHAR16),
                  L"%02X-",
                  SnpModeData.CurrentAddress.Addr[Index]
                  );
    }
    //
    // Remove the last '-'
    //
    OffSet--;  
    //
    // Print the ProtocolType and VLAN ID for this instance.
    //
    OffSet += UnicodeSPrint (
                HandleName + OffSet,
                sizeof (HandleName) - OffSet * sizeof (CHAR16),
                L", ProtocolType=0x%X, VlanId=%d)",
                MnpConfigData.ProtocolTypeFilter,
                Instance->MnpServiceData->VlanId
                );
  } else if (Status == EFI_NOT_STARTED) {
    UnicodeSPrint (
      HandleName,
      sizeof (HandleName),
      L"MNP (Not started)"
      );
  } else {
    return Status;
  }
  
  if (gMnpControllerNameTable != NULL) {
    FreeUnicodeStringTable (gMnpControllerNameTable);
    gMnpControllerNameTable = NULL;
  }
  
  Status = AddUnicodeString2 (
             "eng",
             gMnpComponentName.SupportedLanguages,
             &gMnpControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  return AddUnicodeString2 (
           "en",
           gMnpComponentName2.SupportedLanguages,
           &gMnpControllerNameTable,
           HandleName,
           FALSE
           );
}