コード例 #1
0
ファイル: EfiKey.c プロジェクト: SunnyKi/bareBoot
/**
  Reset the input device and optionally run diagnostics

  There are 2 types of reset for USB keyboard.
  For non-exhaustive reset, only keyboard buffer is cleared.
  For exhaustive reset, in addition to clearance of keyboard buffer, the hardware status
  is also re-initialized.

  @param  This                 Protocol instance pointer.
  @param  ExtendedVerification Driver may perform diagnostics on reset.

  @retval EFI_SUCCESS          The device was reset.
  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could not be reset.

**/
EFI_STATUS
EFIAPI
USBKeyboardReset (
  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *This,
  IN  BOOLEAN                          ExtendedVerification
  )
{
  EFI_STATUS          Status;
  USB_KB_DEV          *UsbKeyboardDevice;

  UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET),
    UsbKeyboardDevice->DevicePath
    );

  //
  // Non-exhaustive reset:
  // only reset private data structures.
  //
  if (!ExtendedVerification) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_PROGRESS_CODE,
      (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER),
      UsbKeyboardDevice->DevicePath
      );
    //
    // Clear the key buffer of this USB keyboard
    //
    InitQueue (&UsbKeyboardDevice->UsbKeyQueue, sizeof (USB_KEY));
    InitQueue (&UsbKeyboardDevice->EfiKeyQueue, sizeof (EFI_KEY_DATA));
    InitQueue (&UsbKeyboardDevice->EfiKeyQueueForNotify, sizeof (EFI_KEY_DATA));

    return EFI_SUCCESS;
  }

  //
  // Exhaustive reset
  //
  Status = InitUSBKeyboard (UsbKeyboardDevice);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}
コード例 #2
0
ファイル: ScsiBus.c プロジェクト: bhanug/virtualbox
/**
  Resets the SCSI Bus that the SCSI Controller is attached to.

  @param  This  Protocol instance pointer.

  @retval  EFI_SUCCESS       The SCSI bus is reset successfully.
  @retval  EFI_DEVICE_ERROR  Errors encountered when resetting the SCSI bus.
  @retval  EFI_UNSUPPORTED   The bus reset operation is not supported by the
                             SCSI Host Controller.
  @retval  EFI_TIMEOUT       A timeout occurred while attempting to reset
                             the SCSI bus.
**/
EFI_STATUS
EFIAPI
ScsiResetBus (
  IN  EFI_SCSI_IO_PROTOCOL     *This
  )
{
  SCSI_IO_DEV *ScsiIoDevice;

  ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);

  //
  // Report Status Code to indicate reset happens
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
    ScsiIoDevice->ScsiBusDeviceData->DevicePath
    );

  if (ScsiIoDevice->ExtScsiSupport){
    return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);
  } else {
    return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);
  }
}
コード例 #3
0
ファイル: UsbMouse.c プロジェクト: bhanug/virtualbox
/**
  Resets the pointer device hardware.

  @param  This                  A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
  @param  ExtendedVerification  Indicates that the driver may perform a more exhaustive
                                verification operation of the device during reset.

  @retval EFI_SUCCESS           The device was reset.
  @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could not be reset.

**/
EFI_STATUS
EFIAPI
UsbMouseReset (
  IN EFI_SIMPLE_POINTER_PROTOCOL    *This,
  IN BOOLEAN                        ExtendedVerification
  )
{
  USB_MOUSE_DEV       *UsbMouseDevice;

  UsbMouseDevice  = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This);

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET),
    UsbMouseDevice->DevicePath
    );

  //
  // Clear mouse state.
  //
  ZeroMem (
    &UsbMouseDevice->State,
    sizeof (EFI_SIMPLE_POINTER_STATE)
    );
  UsbMouseDevice->StateChanged = FALSE;

  return EFI_SUCCESS;
}
コード例 #4
0
ファイル: TerminalConIn.c プロジェクト: B-Rich/edk2
/**
  Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().
  This driver only perform dependent serial device reset regardless of
  the value of ExtendeVerification

  @param  This                     Indicates the calling context.
  @param  ExtendedVerification     Skip by this driver.

  @retval EFI_SUCCESS              The reset operation succeeds.
  @retval EFI_DEVICE_ERROR         The dependent serial port reset fails.

**/
EFI_STATUS
EFIAPI
TerminalConInReset (
  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
  IN  BOOLEAN                         ExtendedVerification
  )
{
  EFI_STATUS    Status;
  TERMINAL_DEV  *TerminalDevice;

  TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);

  //
  // Report progress code here
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET),
    TerminalDevice->DevicePath
    );

  Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);

  //
  // Make all the internal buffer empty for keys
  //
  TerminalDevice->RawFiFo->Head     = TerminalDevice->RawFiFo->Tail;
  TerminalDevice->UnicodeFiFo->Head = TerminalDevice->UnicodeFiFo->Tail;
  TerminalDevice->EfiKeyFiFo->Head  = TerminalDevice->EfiKeyFiFo->Tail;

  if (EFI_ERROR (Status)) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),
      TerminalDevice->DevicePath
      );
  }

  return Status;
}
コード例 #5
0
ファイル: IsaFloppyBlock.c プロジェクト: etiago/vbox
/**
  Common report status code interface.
  
  @param This  Pointer of FDC_BLK_IO_DEV instance
  @param Read  Read or write operation when error occurrs
**/
VOID
FddReportStatus (
  IN  EFI_BLOCK_IO_PROTOCOL  *This,
  IN  BOOLEAN                Read
  )
{
  FDC_BLK_IO_DEV  *FdcDev;

  FdcDev = FDD_BLK_IO_FROM_THIS (This);

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_ERROR_CODE,
    ((Read) ? EFI_P_EC_INPUT_ERROR : EFI_P_EC_OUTPUT_ERROR) | EFI_PERIPHERAL_REMOVABLE_MEDIA,
    FdcDev->DevicePath
    );
}
コード例 #6
0
ファイル: IsaFloppyBlock.c プロジェクト: etiago/vbox
/**
  Reset the Block Device.

  @param  This                 Indicates a pointer to the calling context.
  @param  ExtendedVerification Driver may perform diagnostics on reset.

  @retval EFI_SUCCESS          The device was reset.
  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
                               not be reset.
**/
EFI_STATUS
EFIAPI
FdcReset (
  IN  EFI_BLOCK_IO_PROTOCOL  *This,
  IN  BOOLEAN                ExtendedVerification
  )
{
  FDC_BLK_IO_DEV  *FdcDev;

  //
  // Reset the Floppy Disk Controller
  //
  FdcDev = FDD_BLK_IO_FROM_THIS (This);

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_P_PC_RESET | EFI_PERIPHERAL_REMOVABLE_MEDIA,
    FdcDev->DevicePath
    );

  return FddReset (FdcDev);
}
コード例 #7
0
ファイル: ScsiBus.c プロジェクト: bhanug/virtualbox
/**
  Resets the SCSI Controller that the device handle specifies.

  @param  This  Protocol instance pointer.

  @retval  EFI_SUCCESS       Reset the SCSI controller successfully.
  @retval  EFI_DEVICE_ERROR  Errors are encountered when resetting the SCSI Controller.
  @retval  EFI_UNSUPPORTED   The SCSI bus does not support a device reset operation.
  @retval  EFI_TIMEOUT       A timeout occurred while attempting to reset the
                             SCSI Controller.
**/
EFI_STATUS
EFIAPI
ScsiResetDevice (
  IN  EFI_SCSI_IO_PROTOCOL     *This
  )
{
  SCSI_IO_DEV  *ScsiIoDevice;
  UINT8        Target[TARGET_MAX_BYTES];

  ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);

  //
  // Report Status Code to indicate reset happens
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
    ScsiIoDevice->ScsiBusDeviceData->DevicePath
    );

  CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);


  if (ScsiIoDevice->ExtScsiSupport) {
    return ScsiIoDevice->ExtScsiPassThru->ResetTargetLun (
                                        ScsiIoDevice->ExtScsiPassThru,
                                        Target,
                                        ScsiIoDevice->Lun
                                          );
  } else {
    return ScsiIoDevice->ScsiPassThru->ResetTarget (
                                          ScsiIoDevice->ScsiPassThru,
                                          ScsiIoDevice->Pun.ScsiId.Scsi,
                                          ScsiIoDevice->Lun
                                            );
  }
}
コード例 #8
0
ファイル: SioBusDxe.c プロジェクト: shijunjing/edk2
/**
  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.
  @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
SioBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                     Status;
  EFI_PCI_IO_PROTOCOL            *PciIo;
  EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath;
  UINT64                         Supports;
  UINT64                         OriginalAttributes;
  UINT64                         Attributes;
  BOOLEAN                        Enabled;
  SIO_BUS_DRIVER_PRIVATE_DATA    *Private;
  UINT32                         ChildDeviceNumber;

  Enabled            = FALSE;
  Supports           = 0;
  OriginalAttributes = 0;
  Private            = NULL;

  //
  // Open the PCI I/O Protocol Interface
  //
  PciIo = NULL;
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID**) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open Device Path Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiPciIoProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return Status;
  }

  //
  // Get supported PCI attributes
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Supports &= (UINT64) (EFI_PCI_IO_ATTRIBUTE_ISA_IO |
                        EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);
  if (Supports == 0 ||
      Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO |
                   EFI_PCI_IO_ATTRIBUTE_ISA_IO_16)) {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationGet,
                    0,
                    &OriginalAttributes
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Attributes = EFI_PCI_DEVICE_ENABLE |
               Supports |
               EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationEnable,
                    Attributes,
                    NULL
                    );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Enabled = TRUE;

  //
  // Store the OriginalAttributes for the restore in BindingStop()
  //
  Private = AllocateZeroPool (sizeof (SIO_BUS_DRIVER_PRIVATE_DATA));
  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }
  Private->PciIo              = PciIo;
  Private->OriginalAttributes = OriginalAttributes;

  Status = gBS->InstallProtocolInterface (
                  &Controller,
                  &gEfiCallerIdGuid,
                  EFI_NATIVE_INTERFACE,
                  Private
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Report status code for the start of general controller initialization
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),
    ParentDevicePath
    );

  //
  // Report status code for the start of enabling devices on the bus
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),
    ParentDevicePath
    );

  //
  // Create all the children upon the first entrance
  //
  ChildDeviceNumber = SioCreateAllChildDevices (
                        This,
                        Controller,
                        PciIo,
                        ParentDevicePath
                        );
  if (ChildDeviceNumber == 0) {
    Status = EFI_DEVICE_ERROR;
  }

Done:
  if (EFI_ERROR (Status)) {
    if (PciIo != NULL && Enabled) {
      PciIo->Attributes (
               PciIo,
               EfiPciIoAttributeOperationSet,
               OriginalAttributes,
               NULL
               );
    }

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

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

    if (Private != NULL) {
      gBS->UninstallMultipleProtocolInterfaces (
             Controller,
             &gEfiCallerIdGuid,
             Private,
             NULL
             );
      FreePool (Private);
    }

    return Status;
  }

  return EFI_SUCCESS;
}
コード例 #9
0
/**
  Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset()

  @param This                 Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
  @param ExtendedVerification Indicate that the driver may perform a more 
                              exhaustive verification operation of the device during 
                              reset, now this par is ignored in this driver    

**/
EFI_STATUS
EFIAPI
KeyboardEfiReset (
  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
  IN  BOOLEAN                         ExtendedVerification
  )
{
  EFI_STATUS              Status;
  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
  EFI_TPL                 OldTpl;

  ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
  if (ConsoleIn->KeyboardErr) {
    return EFI_DEVICE_ERROR;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,
    ConsoleIn->DevicePath
    );

  //
  // Enter critical section
  //
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  //
  // Call InitKeyboard to initialize the keyboard
  //
  Status = InitKeyboard (ConsoleIn, ExtendedVerification);
  if (EFI_ERROR (Status)) {
    //
    // Leave critical section and return
    //
    gBS->RestoreTPL (OldTpl);
    return EFI_DEVICE_ERROR;
  }
  //
  // Clear the status of ConsoleIn.Key
  //
  ConsoleIn->Key.ScanCode     = SCAN_NULL;
  ConsoleIn->Key.UnicodeChar  = 0x0000;

  //
  // Leave critical section and return
  //
  gBS->RestoreTPL (OldTpl);

  //
  // Report the status If a stuck key was detected
  //
  if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_STUCK_KEY,
      ConsoleIn->DevicePath
      );
  }
  //
  // Report the status If keyboard is locked
  //
  if ((KeyReadStatusRegister (ConsoleIn) & 0x10) == 0) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_LOCKED,
      ConsoleIn->DevicePath
      );
  }

  return EFI_SUCCESS;
}
コード例 #10
0
ファイル: UsbMouse.c プロジェクト: bhanug/virtualbox
/**
  Stop the USB mouse device handled by this driver.

  @param  This                   The USB mouse driver binding protocol.
  @param  Controller             The controller to release.
  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
  @param  ChildHandleBuffer      The array of child handle.

  @retval EFI_SUCCESS            The device was stopped.
  @retval EFI_UNSUPPORTED        Simple Pointer Protocol is not installed on Controller.
  @retval Others                 Fail to uninstall protocols attached on the device.

**/
EFI_STATUS
EFIAPI
USBMouseDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Controller,
  IN  UINTN                         NumberOfChildren,
  IN  EFI_HANDLE                    *ChildHandleBuffer
  )
{
  EFI_STATUS                  Status;
  USB_MOUSE_DEV               *UsbMouseDevice;
  EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;
  EFI_USB_IO_PROTOCOL         *UsbIo;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimplePointerProtocolGuid,
                  (VOID **) &SimplePointerProtocol,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

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

  UsbMouseDevice = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol);

  UsbIo = UsbMouseDevice->UsbIo;

  //
  // The key data input from this device will be disabled.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE),
    UsbMouseDevice->DevicePath
    );

  //
  // Delete the Asynchronous Interrupt Transfer from this device
  //
  UsbIo->UsbAsyncInterruptTransfer (
           UsbIo,
           UsbMouseDevice->IntEndpointDescriptor.EndpointAddress,
           FALSE,
           UsbMouseDevice->IntEndpointDescriptor.Interval,
           0,
           NULL,
           NULL
           );

  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiSimplePointerProtocolGuid,
                  &UsbMouseDevice->SimplePointerProtocol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

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

  //
  // Free all resources.
  //
  gBS->CloseEvent (UsbMouseDevice->SimplePointerProtocol.WaitForInput);

  if (UsbMouseDevice->DelayedRecoveryEvent != NULL) {
    gBS->CloseEvent (UsbMouseDevice->DelayedRecoveryEvent);
    UsbMouseDevice->DelayedRecoveryEvent = NULL;
  }

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

  FreePool (UsbMouseDevice);

  return EFI_SUCCESS;

}
コード例 #11
0
ファイル: UsbMouse.c プロジェクト: bhanug/virtualbox
/**
  Handler function for USB mouse's asynchronous interrupt transfer.

  This function is the handler function for USB mouse's asynchronous interrupt transfer
  to manage the mouse. It parses data returned from asynchronous interrupt transfer, and
  get button and movement state.

  @param  Data             A pointer to a buffer that is filled with key data which is
                           retrieved via asynchronous interrupt transfer.
  @param  DataLength       Indicates the size of the data buffer.
  @param  Context          Pointing to USB_KB_DEV instance.
  @param  Result           Indicates the result of the asynchronous interrupt transfer.

  @retval EFI_SUCCESS      Asynchronous interrupt transfer is handled successfully.
  @retval EFI_DEVICE_ERROR Hardware error occurs.

**/
EFI_STATUS
EFIAPI
OnMouseInterruptComplete (
  IN  VOID        *Data,
  IN  UINTN       DataLength,
  IN  VOID        *Context,
  IN  UINT32      Result
  )
{
  USB_MOUSE_DEV       *UsbMouseDevice;
  EFI_USB_IO_PROTOCOL *UsbIo;
  UINT8               EndpointAddr;
  UINT32              UsbResult;

  UsbMouseDevice  = (USB_MOUSE_DEV *) Context;
  UsbIo           = UsbMouseDevice->UsbIo;

  if (Result != EFI_USB_NOERROR) {
    //
    // Some errors happen during the process
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR),
      UsbMouseDevice->DevicePath
      );

    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
      EndpointAddr = UsbMouseDevice->IntEndpointDescriptor.EndpointAddress;

      UsbClearEndpointHalt (
        UsbIo,
        EndpointAddr,
        &UsbResult
        );
    }

    //
    // Delete & Submit this interrupt again
    // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
    //
    UsbIo->UsbAsyncInterruptTransfer (
             UsbIo,
             UsbMouseDevice->IntEndpointDescriptor.EndpointAddress,
             FALSE,
             0,
             0,
             NULL,
             NULL
             );
    //
    // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
    //
    gBS->SetTimer (
           UsbMouseDevice->DelayedRecoveryEvent,
           TimerRelative,
           EFI_USB_INTERRUPT_DELAY
           );
    return EFI_DEVICE_ERROR;
  }

  //
  // If no error and no data, just return EFI_SUCCESS.
  //
  if (DataLength == 0 || Data == NULL) {
    return EFI_SUCCESS;
  }

  UsbMouseDevice->StateChanged = TRUE;

  //
  // Check mouse Data
  // USB HID Specification specifies following data format:
  // Byte    Bits    Description
  // 0       0       Button 1
  //         1       Button 2
  //         2       Button 3
  //         4 to 7  Device-specific
  // 1       0 to 7  X displacement
  // 2       0 to 7  Y displacement
  // 3 to n  0 to 7  Device specific (optional)
  //
  UsbMouseDevice->State.LeftButton  = (BOOLEAN) ((*(UINT8 *) Data & BIT0) != 0);
  UsbMouseDevice->State.RightButton = (BOOLEAN) ((*(UINT8 *) Data & BIT1) != 0);
  UsbMouseDevice->State.RelativeMovementX += *((INT8 *) Data + 1);
  UsbMouseDevice->State.RelativeMovementY += *((INT8 *) Data + 2);

  if (DataLength > 3) {
    UsbMouseDevice->State.RelativeMovementZ += *((INT8 *) Data + 3);
  }

  return EFI_SUCCESS;
}
コード例 #12
0
ファイル: TerminalConIn.c プロジェクト: B-Rich/edk2
/**
  Timer handler to poll the key from serial.

  @param  Event                    Indicates the event that invoke this function.
  @param  Context                  Indicates the calling context.
**/
VOID
EFIAPI
TerminalConInTimerHandler (
  IN EFI_EVENT            Event,
  IN VOID                 *Context
  )
{
  EFI_STATUS              Status;
  TERMINAL_DEV            *TerminalDevice;
  UINT32                  Control;
  UINT8                   Input;
  EFI_SERIAL_IO_MODE      *Mode;
  EFI_SERIAL_IO_PROTOCOL  *SerialIo;
  UINTN                   SerialInTimeOut;

  TerminalDevice  = (TERMINAL_DEV *) Context;

  SerialIo        = TerminalDevice->SerialIo;
  if (SerialIo == NULL) {
    return ;
  }
  //
  //  if current timeout value for serial device is not identical with
  //  the value saved in TERMINAL_DEV structure, then recalculate the
  //  timeout value again and set serial attribute according to this value.
  //
  Mode = SerialIo->Mode;
  if (Mode->Timeout != TerminalDevice->SerialInTimeOut) {

    SerialInTimeOut = 0;
    if (Mode->BaudRate != 0) {
      //
      // According to BAUD rate to calculate the timeout value.
      //
      SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
    }

    Status = SerialIo->SetAttributes (
                        SerialIo,
                        Mode->BaudRate,
                        Mode->ReceiveFifoDepth,
                        (UINT32) SerialInTimeOut,
                        (EFI_PARITY_TYPE) (Mode->Parity),
                        (UINT8) Mode->DataBits,
                        (EFI_STOP_BITS_TYPE) (Mode->StopBits)
                        );

    if (EFI_ERROR (Status)) {
      TerminalDevice->SerialInTimeOut = 0;
    } else {
      TerminalDevice->SerialInTimeOut = SerialInTimeOut;
    }
  }
  //
  // Check whether serial buffer is empty.
  //
  Status = SerialIo->GetControl (SerialIo, &Control);

  if ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) == 0) {
    //
    // Fetch all the keys in the serial buffer,
    // and insert the byte stream into RawFIFO.
    //
    while (!IsRawFiFoFull (TerminalDevice)) {

      Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);

      if (EFI_ERROR (Status)) {
        if (Status == EFI_DEVICE_ERROR) {
          REPORT_STATUS_CODE_WITH_DEVICE_PATH (
            EFI_ERROR_CODE | EFI_ERROR_MINOR,
            (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR),
            TerminalDevice->DevicePath
            );
        }
        break;
      }

      RawFiFoInsertOneKey (TerminalDevice, Input);
    }
  }

  //
  // Translate all the raw data in RawFIFO into EFI Key,
  // according to different terminal type supported.
  //
  TranslateRawDataToEfiKey (TerminalDevice);
}
コード例 #13
0
ファイル: UsbMouse.c プロジェクト: bhanug/virtualbox
/**
  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;
}
コード例 #14
0
ファイル: Ps2Keyboard.c プロジェクト: hsienchieh/uefilab
/**
  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;
}
コード例 #15
0
ファイル: EfiKey.c プロジェクト: AshleyDeSimone/edk2
/**
  Stop the USB keyboard device handled by this driver.

  @param  This                   The USB keyboard driver binding protocol.
  @param  Controller             The controller to release.
  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
  @param  ChildHandleBuffer      The array of child handle.

  @retval EFI_SUCCESS            The device was stopped.
  @retval EFI_UNSUPPORTED        Simple Text In Protocol or Simple Text In Ex Protocol
                                 is not installed on Controller.
  @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.
  @retval Others                 Fail to uninstall protocols attached on the device.

**/
EFI_STATUS
EFIAPI
USBKeyboardDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN  EFI_HANDLE                     Controller,
  IN  UINTN                          NumberOfChildren,
  IN  EFI_HANDLE                     *ChildHandleBuffer
  )
{
  EFI_STATUS                     Status;
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput;
  USB_KB_DEV                     *UsbKeyboardDevice;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  (VOID **) &SimpleInput,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimpleTextInputExProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);

  //
  // The key data input from this device will be disabled.
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE),
    UsbKeyboardDevice->DevicePath
    );

  //
  // Delete the Asynchronous Interrupt Transfer from this device
  //
  UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (
                              UsbKeyboardDevice->UsbIo,
                              UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
                              FALSE,
                              UsbKeyboardDevice->IntEndpointDescriptor.Interval,
                              0,
                              NULL,
                              NULL
                              );

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

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  &UsbKeyboardDevice->SimpleInput,
                  &gEfiSimpleTextInputExProtocolGuid,
                  &UsbKeyboardDevice->SimpleInputEx,
                  NULL
                  );
  //
  // Free all resources.
  //
  gBS->CloseEvent (UsbKeyboardDevice->TimerEvent);
  gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
  gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
  gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
  gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);
  KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList);

  ReleaseKeyboardLayoutResources (UsbKeyboardDevice);
  gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);

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

  DestroyQueue (&UsbKeyboardDevice->UsbKeyQueue);
  DestroyQueue (&UsbKeyboardDevice->EfiKeyQueue);

  FreePool (UsbKeyboardDevice);

  return Status;
}
コード例 #16
0
ファイル: IdeBus.c プロジェクト: hsienchieh/uefilab
/**
  Start function of Driver binding protocol which start this driver on Controller
  by detecting all disks and installing BlockIo protocol on them.

  @param  This                Protocol instance pointer.
  @param  Controller          Handle of device to bind driver to.
  @param  RemainingDevicePath produce all possible children.

  @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
IDEBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        SavedStatus;
  EFI_PCI_IO_PROTOCOL               *PciIo;
  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
  EFI_DEV_PATH                      *Node;
  UINT8                             IdeChannel;
  UINT8                             BeginningIdeChannel;
  UINT8                             EndIdeChannel;
  UINT8                             IdeDevice;
  UINT8                             BeginningIdeDevice;
  UINT8                             EndIdeDevice;
  IDE_BLK_IO_DEV                    *IdeBlkIoDevice[IdeMaxChannel][IdeMaxDevice];
  IDE_BLK_IO_DEV                    *IdeBlkIoDevicePtr;
  IDE_REGISTERS_BASE_ADDR           IdeRegsBaseAddr[IdeMaxChannel];
  ATA_TRANSFER_MODE                 TransferMode;
  ATA_DRIVE_PARMS                   DriveParameters;
  EFI_DEV_PATH                      NewNode;
  UINT8                             ConfigurationOptions;
  UINT16                            CommandBlockBaseAddr;
  UINT16                            ControlBlockBaseAddr;
  UINTN                             DataSize;
  IDE_BUS_DRIVER_PRIVATE_DATA       *IdeBusDriverPrivateData;
  UINT64                            Supports;

  //
  // Local variables declaration for IdeControllerInit support
  //
  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
  BOOLEAN                           EnumAll;
  BOOLEAN                           ChannelEnabled;
  UINT8                             MaxDevices;
  EFI_IDENTIFY_DATA                 IdentifyData;
  EFI_ATA_COLLECTIVE_MODE           *SupportedModes;

  IdeBusDriverPrivateData = NULL;
  SupportedModes          = NULL;

  //
  // Perform IdeBus initialization
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
    return Status;
  }

  //
  // Now open the IDE_CONTROLLER_INIT protocol. Step7.1
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIdeControllerInitProtocolGuid,
                  (VOID **) &IdeInit,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  //
  // The following OpenProtocol function with _GET_PROTOCOL attribute and
  // will not return EFI_ALREADY_STARTED, so save it for now
  //
  SavedStatus = Status;

  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
    DEBUG ((EFI_D_ERROR, "Open Init, Status=%x", Status));
    //
    // open protocol is not SUCCESS or not ALREADY_STARTED, error exit
    //
    goto ErrorExit;
  }

  //
  // Save Enumall. Step7.2
  //
  EnumAll       = IdeInit->EnumAll;

  //
  // Consume PCI I/O protocol. Note that the OpenProtocol with _GET_PROTOCOL
  // attribute will not return EFI_ALREADY_STARTED
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Open PciIo, Status=%x", Status));
    goto ErrorExit;
  }

  //
  // We must check EFI_ALREADY_STARTED because many ATAPI devices are removable
  //
  if (SavedStatus != EFI_ALREADY_STARTED) {
    IdeBusDriverPrivateData = AllocatePool (sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
    if (IdeBusDriverPrivateData == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ErrorExit;
    }

    ZeroMem (IdeBusDriverPrivateData, sizeof (IDE_BUS_DRIVER_PRIVATE_DATA));
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &Controller,
                    &gEfiCallerIdGuid,
                    IdeBusDriverPrivateData,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

  } else {
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiCallerIdGuid,
                    (VOID **) &IdeBusDriverPrivateData,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      IdeBusDriverPrivateData = NULL;
      goto ErrorExit;
    }
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      Supports,
                      NULL
                      );
  }

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

  //
  // Read the environment variable that contains the IDEBus Driver's
  // Config options that were set by the Driver Configuration Protocol
  //
  DataSize = sizeof (ConfigurationOptions);
  Status = gRT->GetVariable (
                  (CHAR16 *) L"Configuration",
                  &gEfiCallerIdGuid,
                  NULL,
                  &DataSize,
                  &ConfigurationOptions
                  );
  if (EFI_ERROR (Status)) {
    ConfigurationOptions = 0x0f;
  }

   if (EnumAll || RemainingDevicePath == NULL) {
    //
    // If IdeInit->EnumAll is TRUE or RemainingDevicePath is NULL, 
    // must enumerate all IDE devices anyway
    //
    BeginningIdeChannel = IdePrimary;
    EndIdeChannel       = IdeSecondary;
    BeginningIdeDevice  = IdeMaster;
    EndIdeDevice        = IdeSlave;

  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    //
    // If RemainingDevicePath isn't the End of Device Path Node, 
    // only scan the specified device by RemainingDevicePath
    //
    Node                = (EFI_DEV_PATH *) RemainingDevicePath;
    BeginningIdeChannel = Node->Atapi.PrimarySecondary;
    EndIdeChannel       = BeginningIdeChannel;
    BeginningIdeDevice  = Node->Atapi.SlaveMaster;
    EndIdeDevice        = BeginningIdeDevice;
    if (BeginningIdeChannel >= IdeMaxChannel || EndIdeChannel >= IdeMaxChannel) {
      Status = EFI_INVALID_PARAMETER;
      goto ErrorExit;
    }
    if (BeginningIdeDevice >= IdeMaxDevice|| EndIdeDevice >= IdeMaxDevice) {
      Status = EFI_INVALID_PARAMETER;
      goto ErrorExit;
    }

  } else {
    //
    // If RemainingDevicePath is the End of Device Path Node,
    // skip enumerate any device and return EFI_SUCESSS
    // 
    BeginningIdeChannel = IdeMaxChannel;
    EndIdeChannel       = IdeMaxChannel - 1;
    BeginningIdeDevice  = IdeMaxDevice;
    EndIdeDevice        = IdeMaxDevice - 1;
  }

  //
  // Obtain IDE IO port registers' base addresses
  //
  Status = GetIdeRegistersBaseAddr (PciIo, IdeRegsBaseAddr);
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Report status code: begin IdeBus initialization
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),
    ParentDevicePath
    );

  //
  // Strictly follow the enumeration based on IDE_CONTROLLER_INIT protocol
  //
  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {

    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, IdeChannel);

    //
    // now obtain channel information fron IdeControllerInit protocol. Step9
    //
    Status = IdeInit->GetChannelInfo (
                        IdeInit,
                        IdeChannel,
                        &ChannelEnabled,
                        &MaxDevices
                        );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));
      continue;
    }

    if (!ChannelEnabled) {
      continue;
    }

    EndIdeDevice = (UINT8) MIN ((MaxDevices - 1), EndIdeDevice);
    ASSERT (EndIdeDevice < IdeMaxDevice);
    //
    // Now inform the IDE Controller Init Module. Sept10
    //
    IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelReset, IdeChannel);

    //
    // No reset channel function implemented. Sept11
    //
    IdeInit->NotifyPhase (IdeInit, EfiIdeAfterChannelReset, IdeChannel);

    //
    // Step13
    //
    IdeInit->NotifyPhase (
              IdeInit,
              EfiIdeBusBeforeDevicePresenceDetection,
              IdeChannel
              );

    //
    // Prepare to detect IDE device of this channel
    //
    InitializeIDEChannelData ();

    //
    // -- 1st inner loop --- Master/Slave ------------  Step14
    //
    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {
      //
      // Check whether the configuration options allow this device
      //
      if ((ConfigurationOptions & (1 << (IdeChannel * 2 + IdeDevice))) == 0) {
        continue;
      }

      //
      // The device has been scanned in another Start(), No need to scan it again
      // for perf optimization.
      //
      if (IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]) {
        continue;
      }

      //
      // create child handle for the detected device.
      //
      IdeBlkIoDevice[IdeChannel][IdeDevice] = AllocatePool (sizeof (IDE_BLK_IO_DEV));
      if (IdeBlkIoDevice[IdeChannel][IdeDevice] == NULL) {
        continue;
      }

      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];

      ZeroMem (IdeBlkIoDevicePtr, sizeof (IDE_BLK_IO_DEV));

      IdeBlkIoDevicePtr->Signature  = IDE_BLK_IO_DEV_SIGNATURE;
      IdeBlkIoDevicePtr->Channel    = (EFI_IDE_CHANNEL) IdeChannel;
      IdeBlkIoDevicePtr->Device     = (EFI_IDE_DEVICE) IdeDevice;

      //
      // initialize Block IO interface's Media pointer
      //
      IdeBlkIoDevicePtr->BlkIo.Media = &IdeBlkIoDevicePtr->BlkMedia;

      //
      // Initialize IDE IO port addresses, including Command Block registers
      // and Control Block registers
      //
      IdeBlkIoDevicePtr->IoPort = AllocatePool (sizeof (IDE_BASE_REGISTERS));
      if (IdeBlkIoDevicePtr->IoPort == NULL) {
        continue;
      }

      ZeroMem (IdeBlkIoDevicePtr->IoPort, sizeof (IDE_BASE_REGISTERS));
      CommandBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].CommandBlockBaseAddr;
      ControlBlockBaseAddr = IdeRegsBaseAddr[IdeChannel].ControlBlockBaseAddr;

      IdeBlkIoDevicePtr->IoPort->Data = CommandBlockBaseAddr;
      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg1) = (UINT16) (CommandBlockBaseAddr + 0x01);
      IdeBlkIoDevicePtr->IoPort->SectorCount = (UINT16) (CommandBlockBaseAddr + 0x02);
      IdeBlkIoDevicePtr->IoPort->SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x03);
      IdeBlkIoDevicePtr->IoPort->CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x04);
      IdeBlkIoDevicePtr->IoPort->CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x05);
      IdeBlkIoDevicePtr->IoPort->Head = (UINT16) (CommandBlockBaseAddr + 0x06);
      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Reg) = (UINT16) (CommandBlockBaseAddr + 0x07);

      (*(UINT16 *) &IdeBlkIoDevicePtr->IoPort->Alt) = ControlBlockBaseAddr;
      IdeBlkIoDevicePtr->IoPort->DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x01);

      IdeBlkIoDevicePtr->IoPort->MasterSlave = (UINT16) ((IdeDevice == IdeMaster) ? 1 : 0);

      IdeBlkIoDevicePtr->PciIo = PciIo;
      IdeBlkIoDevicePtr->IdeBusDriverPrivateData = IdeBusDriverPrivateData;
      IdeBlkIoDevicePtr->IoPort->BusMasterBaseAddr = IdeRegsBaseAddr[IdeChannel].BusMasterBaseAddr;

      //
      // Report Status code: is about to detect IDE drive
      //
      REPORT_STATUS_CODE_EX (
        EFI_PROGRESS_CODE,
        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_PRESENCE_DETECT),
        0,
        &gEfiCallerIdGuid,
        NULL,
        NULL,
        0
      );

      //
      // Discover device, now!
      //
      PERF_START (NULL, "DiscoverIdeDevice", "IDE", 0);
      Status = DiscoverIdeDevice (IdeBlkIoDevicePtr);
      PERF_END (NULL, "DiscoverIdeDevice", "IDE", 0);

      IdeBusDriverPrivateData->HaveScannedDevice[IdeChannel * 2 + IdeDevice]  = TRUE;
      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]    = FALSE;

      if (!EFI_ERROR (Status)) {
        //
        // Set Device Path
        //
        ZeroMem (&NewNode, sizeof (NewNode));
        NewNode.DevPath.Type    = MESSAGING_DEVICE_PATH;
        NewNode.DevPath.SubType = MSG_ATAPI_DP;
        SetDevicePathNodeLength (&NewNode.DevPath, sizeof (ATAPI_DEVICE_PATH));

        NewNode.Atapi.PrimarySecondary  = (UINT8) IdeBlkIoDevicePtr->Channel;
        NewNode.Atapi.SlaveMaster       = (UINT8) IdeBlkIoDevicePtr->Device;
        NewNode.Atapi.Lun               = IdeBlkIoDevicePtr->Lun;
        IdeBlkIoDevicePtr->DevicePath = AppendDevicePathNode (
                                          ParentDevicePath,
                                          &NewNode.DevPath
                                          );
        if (IdeBlkIoDevicePtr->DevicePath == NULL) {
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          continue;
        }

        //
        // Submit identify data to IDE controller init driver
        //
        CopyMem (&IdentifyData, IdeBlkIoDevicePtr->IdData, sizeof (IdentifyData));
        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = TRUE;
        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, &IdentifyData);
      } else {
        //
        // Device detection failed
        //
        IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
        IdeInit->SubmitData (IdeInit, IdeChannel, IdeDevice, NULL);
        ReleaseIdeResources (IdeBlkIoDevicePtr);
        IdeBlkIoDevicePtr = NULL;
      }
      //
      // end of 1st inner loop ---
      //
    }
    //
    // end of 1st outer loop =========
    //
  }

  //
  // = 2nd outer loop == Primary/Secondary =================
  //
  for (IdeChannel = BeginningIdeChannel; IdeChannel <= EndIdeChannel; IdeChannel++) {

    //
    // -- 2nd inner loop --- Master/Slave --------
    //
    for (IdeDevice = BeginningIdeDevice; IdeDevice <= EndIdeDevice; IdeDevice++) {

      ASSERT (IdeChannel * 2 + IdeDevice < MAX_IDE_DEVICE);
      if (IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice]) {
        continue;
      }

      if (!IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice]) {
        continue;
      }

      Status = IdeInit->CalculateMode (
                          IdeInit,
                          IdeChannel,
                          IdeDevice,
                          &SupportedModes
                          );
      if (EFI_ERROR (Status)) {
        DEBUG ((EFI_D_ERROR, "[bStStp20S=%x]", Status));
        continue;
      }

      ASSERT (IdeChannel < IdeMaxChannel && IdeDevice < IdeMaxDevice);
      IdeBlkIoDevicePtr = IdeBlkIoDevice[IdeChannel][IdeDevice];

      //
      // Set best supported PIO mode on this IDE device
      //
      if (SupportedModes->PioMode.Mode <= AtaPioMode2) {
        TransferMode.ModeCategory = ATA_MODE_CATEGORY_DEFAULT_PIO;
      } else {
        TransferMode.ModeCategory = ATA_MODE_CATEGORY_FLOW_PIO;
      }

      TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);

      if (SupportedModes->ExtModeCount == 0){
        Status                  = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

        if (EFI_ERROR (Status)) {
          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          IdeBlkIoDevicePtr = NULL;
          continue;
        }
      }

      //
      // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
      // be set together. Only one DMA mode can be set to a device. If setting
      // DMA mode operation fails, we can continue moving on because we only use
      // PIO mode at boot time. DMA modes are used by certain kind of OS booting
      //
      if (SupportedModes->UdmaMode.Valid) {

        TransferMode.ModeCategory = ATA_MODE_CATEGORY_UDMA;
        TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);
        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

        if (EFI_ERROR (Status)) {
          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          IdeBlkIoDevicePtr = NULL;
          continue;
        }
        //
        // Record Udma Mode
        //
        IdeBlkIoDevicePtr->UdmaMode.Valid = TRUE;
        IdeBlkIoDevicePtr->UdmaMode.Mode  = SupportedModes->UdmaMode.Mode;
        EnableInterrupt (IdeBlkIoDevicePtr);
      } else if (SupportedModes->MultiWordDmaMode.Valid) {

        TransferMode.ModeCategory = ATA_MODE_CATEGORY_MDMA;
        TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
        Status                    = SetDeviceTransferMode (IdeBlkIoDevicePtr, &TransferMode);

        if (EFI_ERROR (Status)) {
          IdeBusDriverPrivateData->DeviceFound[IdeChannel * 2 + IdeDevice] = FALSE;
          ReleaseIdeResources (IdeBlkIoDevicePtr);
          IdeBlkIoDevicePtr = NULL;
          continue;
        }

        EnableInterrupt (IdeBlkIoDevicePtr);
      }
      //
      // Init driver parameters
      //
      DriveParameters.Sector          = (UINT8) ((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->sectors_per_track;
      DriveParameters.Heads           = (UINT8) (((ATA5_IDENTIFY_DATA *) IdeBlkIoDevicePtr->IdData)->heads - 1);
      DriveParameters.MultipleSector  = (UINT8) IdeBlkIoDevicePtr->IdData->AtaData.multi_sector_cmd_max_sct_cnt;
      //
      // Set Parameters for the device:
      // 1) Init
      // 2) Establish the block count for READ/WRITE MULTIPLE (EXT) command
      //
      if ((IdeBlkIoDevicePtr->Type == IdeHardDisk) || (IdeBlkIoDevicePtr->Type == Ide48bitAddressingHardDisk)) {
        Status = SetDriveParameters (IdeBlkIoDevicePtr, &DriveParameters);
      }

      //
      // Record PIO mode used in private data
      //
      IdeBlkIoDevicePtr->PioMode = (ATA_PIO_MODE) SupportedModes->PioMode.Mode;

      //
      // Set IDE controller Timing Blocks in the PCI Configuration Space
      //
      IdeInit->SetTiming (IdeInit, IdeChannel, IdeDevice, SupportedModes);

      //
      // Add Component Name for the IDE/ATAPI device that was discovered.
      //
      IdeBlkIoDevicePtr->ControllerNameTable = NULL;
      ADD_IDE_ATAPI_NAME (IdeBlkIoDevicePtr);

      Status = gBS->InstallMultipleProtocolInterfaces (
                      &IdeBlkIoDevicePtr->Handle,
                      &gEfiDevicePathProtocolGuid,
                      IdeBlkIoDevicePtr->DevicePath,
                      &gEfiBlockIoProtocolGuid,
                      &IdeBlkIoDevicePtr->BlkIo,
                      &gEfiDiskInfoProtocolGuid,
                      &IdeBlkIoDevicePtr->DiskInfo,
                      NULL
                      );

      if (EFI_ERROR (Status)) {
        ReleaseIdeResources (IdeBlkIoDevicePtr);
      }

      gBS->OpenProtocol (
            Controller,
            &gEfiPciIoProtocolGuid,
            (VOID **) &PciIo,
            This->DriverBindingHandle,
            IdeBlkIoDevicePtr->Handle,
            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
            );

      IdeBusDriverPrivateData->DeviceProcessed[IdeChannel * 2 + IdeDevice] = TRUE;

      //
      // Report status code: device eanbled!
      //
      REPORT_STATUS_CODE_WITH_DEVICE_PATH (
        EFI_PROGRESS_CODE,
        (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_ENABLE),
        IdeBlkIoDevicePtr->DevicePath
        );

      //
      // Create event to clear pending IDE interrupt
      //
      Status = gBS->CreateEventEx (
                      EVT_NOTIFY_SIGNAL,
                      TPL_NOTIFY,
                      ClearInterrupt,
                      IdeBlkIoDevicePtr,
                      &gEfiEventExitBootServicesGuid,
                      &IdeBlkIoDevicePtr->ExitBootServiceEvent
                      );

      //
      // end of 2nd inner loop ----
      //
    }
    //
    // end of 2nd outer loop ==========
    //
  }

  //
  // All configurations done! Notify IdeController to do post initialization
  // work such as saving IDE controller PCI settings for S3 resume
  //
  IdeInit->NotifyPhase (IdeInit, EfiIdeBusPhaseMaximum, 0);

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

  PERF_START (NULL, "Finish IDE detection", "IDE", 1);
  PERF_END (NULL, "Finish IDE detection", "IDE", 0);

  return EFI_SUCCESS;

ErrorExit:

  //
  // Report error code: controller error
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_ERROR_CODE | EFI_ERROR_MINOR,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_EC_CONTROLLER_ERROR),
    ParentDevicePath
    );

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

  gBS->UninstallMultipleProtocolInterfaces (
        Controller,
        &gEfiCallerIdGuid,
        IdeBusDriverPrivateData,
        NULL
        );

  if (IdeBusDriverPrivateData != NULL) {
    gBS->FreePool (IdeBusDriverPrivateData);
  }

  if (SupportedModes != NULL) {
    gBS->FreePool (SupportedModes);
  }

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

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

  return Status;

}
コード例 #17
0
/**
  Stop this driver on ControllerHandle. Support stoping any child handles
  created by this driver.

  @param  This              Protocol instance pointer.
  @param  ControllerHandle  Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed ControllerHandle
  @retval other             This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
PS2MouseAbsolutePointerDriverStop (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN UINTN                          NumberOfChildren,
  IN EFI_HANDLE                     *ChildHandleBuffer
  )
{
  EFI_STATUS                            Status;
  EFI_ABSOLUTE_POINTER_PROTOCOL         *AbsolutePointerProtocol;
  PS2_MOUSE_ABSOLUTE_POINTER_DEV       *MouseAbsolutePointerDev;
  UINT8                                 Data;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiAbsolutePointerProtocolGuid,
                  (VOID **) &AbsolutePointerProtocol,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (AbsolutePointerProtocol);

  //
  // Report that the keyboard is being disabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE,
    MouseAbsolutePointerDev->DevicePath
    );

  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiAbsolutePointerProtocolGuid,
                  &MouseAbsolutePointerDev->AbsolutePointerProtocol
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Cancel mouse data polling timer, close timer event
  //
  gBS->SetTimer (MouseAbsolutePointerDev->TimerEvent, TimerCancel, 0);
  gBS->CloseEvent (MouseAbsolutePointerDev->TimerEvent);

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

  gBS->CloseEvent (MouseAbsolutePointerDev->AbsolutePointerProtocol.WaitForInput);
  FreeUnicodeStringTable (MouseAbsolutePointerDev->ControllerNameTable);
  FreePool (MouseAbsolutePointerDev);

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

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

  return EFI_SUCCESS;
}
コード例 #18
0
ファイル: ScsiBus.c プロジェクト: bhanug/virtualbox
/**
  Start this driver on ControllerHandle.

  This service is called by the EFI boot service ConnectController(). In order
  to make drivers as small as possible, there are a few calling restrictions for
  this service. ConnectController() must follow these calling restrictions. If
  any other agent wishes to call Start() it must also follow these calling
  restrictions.

  @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
SCSIBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  UINT64                                Lun;
  UINT8                                 *TargetId;
  BOOLEAN                               ScanOtherPuns;
  BOOLEAN                               FromFirstTarget;
  BOOLEAN                               ExtScsiSupport;
  EFI_STATUS                            Status;
  EFI_STATUS                            DevicePathStatus;
  EFI_STATUS                            PassThruStatus;
  SCSI_BUS_DEVICE                       *ScsiBusDev;
  SCSI_TARGET_ID                        ScsiTargetId;
  EFI_DEVICE_PATH_PROTOCOL              *ParentDevicePath;
  EFI_SCSI_PASS_THRU_PROTOCOL           *ScsiInterface;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL       *ExtScsiInterface;
  EFI_SCSI_BUS_PROTOCOL                 *BusIdentify;

  TargetId        = NULL;
  ScanOtherPuns   = TRUE;
  FromFirstTarget = FALSE;
  ExtScsiSupport  = FALSE;
  PassThruStatus  = EFI_SUCCESS;

  TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];
  SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);

  DevicePathStatus = gBS->OpenProtocol (
                            Controller,
                            &gEfiDevicePathProtocolGuid,
                            (VOID **) &ParentDevicePath,
                            This->DriverBindingHandle,
                            Controller,
                            EFI_OPEN_PROTOCOL_BY_DRIVER
                            );
  if (EFI_ERROR (DevicePathStatus) && (DevicePathStatus != EFI_ALREADY_STARTED)) {
    return DevicePathStatus;
  }

  //
  // Report Status Code to indicate SCSI bus starts
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),
    ParentDevicePath
    );

  //
  // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as
  // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly
  // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiExtScsiPassThruProtocolGuid,
                  (VOID **) &ExtScsiInterface,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  //
  // Fail to open UEFI ExtendPassThru Protocol, then try to open EFI PassThru Protocol instead.
  //
  if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiScsiPassThruProtocolGuid,
                    (VOID **) &ScsiInterface,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );
    //
    // Fail to open EFI PassThru Protocol, Close the DevicePathProtocol if it is opened by this time.
    //
    if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
      if (!EFI_ERROR(DevicePathStatus)) {
        gBS->CloseProtocol (
               Controller,
               &gEfiDevicePathProtocolGuid,
               This->DriverBindingHandle,
               Controller
               );
      }
      return Status;
    }
  } else {
    //
    // Succeed to open ExtPassThru Protocol, and meanwhile open PassThru Protocol
    // with BY_DRIVER if it is also present on the handle. The intent is to prevent
    // another SCSI Bus Driver to work on the same host handle.
    //
    ExtScsiSupport = TRUE;
    PassThruStatus = gBS->OpenProtocol (
                            Controller,
                            &gEfiScsiPassThruProtocolGuid,
                            (VOID **) &ScsiInterface,
                            This->DriverBindingHandle,
                            Controller,
                            EFI_OPEN_PROTOCOL_BY_DRIVER
                            );
  }

  if (Status != EFI_ALREADY_STARTED) {
    //
    // Go through here means either ExtPassThru or PassThru Protocol is successfully opened
    // on this handle for this time. Then construct Host controller private data.
    //
    ScsiBusDev = NULL;
    ScsiBusDev = AllocateZeroPool(sizeof(SCSI_BUS_DEVICE));
    if (ScsiBusDev == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ErrorExit;
    }
    ScsiBusDev->Signature        = SCSI_BUS_DEVICE_SIGNATURE;
    ScsiBusDev->ExtScsiSupport   = ExtScsiSupport;
    ScsiBusDev->DevicePath       = ParentDevicePath;
    if (ScsiBusDev->ExtScsiSupport) {
      ScsiBusDev->ExtScsiInterface = ExtScsiInterface;
    } else {
      ScsiBusDev->ScsiInterface    = ScsiInterface;
    }

    //
    // Install EFI_SCSI_BUS_PROTOCOL to the controller handle, So ScsiBusDev could be
    // retrieved on this controller handle. With ScsiBusDev, we can know which PassThru
    // Protocol is present on the handle, UEFI ExtPassThru Protocol or EFI PassThru Protocol.
    //
    Status = gBS->InstallProtocolInterface (
                    &Controller,
                    &gEfiCallerIdGuid,
                    EFI_NATIVE_INTERFACE,
                    &ScsiBusDev->BusIdentify
                    );
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
  } else {
    //
    // Go through here means Start() is re-invoked again, nothing special is required to do except
    // picking up Host controller private information.
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiCallerIdGuid,
                    (VOID **) &BusIdentify,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );

    if (EFI_ERROR (Status)) {
      return Status;
    }
    ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (BusIdentify);
  }

  //
  // Report Status Code to indicate detecting devices on bus
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),
    ParentDevicePath
    );

  Lun  = 0;
  if (RemainingDevicePath == NULL) {
    //
    // If RemainingDevicePath is NULL,
    // must enumerate all SCSI devices anyway
    //
    FromFirstTarget = TRUE;
  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    //
    // If RemainingDevicePath isn't the End of Device Path Node,
    // only scan the specified device by RemainingDevicePath
    //
    if (ScsiBusDev->ExtScsiSupport) {
      Status = ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);
    } else {
      Status = ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);
    }

    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    //
    // If RemainingDevicePath is the End of Device Path Node,
    // skip enumerate any device and return EFI_SUCESSS
    //
    ScanOtherPuns = FALSE;
  }

  while(ScanOtherPuns) {
    if (FromFirstTarget) {
      //
      // Remaining Device Path is NULL, scan all the possible Puns in the
      // SCSI Channel.
      //
      if (ScsiBusDev->ExtScsiSupport) {
        Status = ScsiBusDev->ExtScsiInterface->GetNextTargetLun (ScsiBusDev->ExtScsiInterface, &TargetId, &Lun);
      } else {
        Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId.ScsiId.Scsi, &Lun);
      }
      if (EFI_ERROR (Status)) {
        //
        // no legal Pun and Lun found any more
        //
        break;
      }
    } else {
      ScanOtherPuns = FALSE;
    }
    //
    // Avoid creating handle for the host adapter.
    //
    if (ScsiBusDev->ExtScsiSupport) {
      if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {
        continue;
      }
    } else {
      if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {
        continue;
      }
    }
    //
    // Scan for the scsi device, if it attaches to the scsi bus,
    // then create handle and install scsi i/o protocol.
    //
    Status = ScsiScanCreateDevice (This, Controller, &ScsiTargetId, Lun, ScsiBusDev);
  }
  return EFI_SUCCESS;

ErrorExit:

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

  if (ExtScsiSupport) {
    gBS->CloseProtocol (
           Controller,
           &gEfiExtScsiPassThruProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    if (!EFI_ERROR (PassThruStatus)) {
      gBS->CloseProtocol (
             Controller,
             &gEfiScsiPassThruProtocolGuid,
             This->DriverBindingHandle,
             Controller
             );
    }
  } else {
    gBS->CloseProtocol (
           Controller,
           &gEfiScsiPassThruProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
  }
  return Status;
}
コード例 #19
0
ファイル: ScsiBus.c プロジェクト: bhanug/virtualbox
/**
  Scan SCSI Bus to discover the device, and attach ScsiIoProtocol to it.

  @param  This           Protocol instance pointer
  @param  Controller     Controller handle
  @param  TargetId       Tartget to be scanned
  @param  Lun            The Lun of the SCSI device on the SCSI channel.
  @param  ScsiBusDev     The pointer of SCSI_BUS_DEVICE

  @retval EFI_SUCCESS           Successfully to discover the device and attach
                                ScsiIoProtocol to it.
  @retval EFI_OUT_OF_RESOURCES  Fail to discover the device.

**/
EFI_STATUS
EFIAPI
ScsiScanCreateDevice (
  IN     EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN     EFI_HANDLE                    Controller,
  IN     SCSI_TARGET_ID                *TargetId,
  IN     UINT64                        Lun,
  IN OUT SCSI_BUS_DEVICE               *ScsiBusDev
  )
{
  EFI_STATUS                Status;
  SCSI_IO_DEV               *ScsiIoDevice;
  EFI_DEVICE_PATH_PROTOCOL  *ScsiDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
  EFI_HANDLE                 DeviceHandle;

  DevicePath          = NULL;
  RemainingDevicePath = NULL;
  ScsiDevicePath      = NULL;
  ScsiIoDevice        = NULL;

  //
  // Build Device Path
  //
  if (ScsiBusDev->ExtScsiSupport){
    Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (
                                             ScsiBusDev->ExtScsiInterface,
                                             &TargetId->ScsiId.ExtScsi[0],
                                             Lun,
                                             &ScsiDevicePath
                                             );
  } else {
    Status = ScsiBusDev->ScsiInterface->BuildDevicePath (
                                          ScsiBusDev->ScsiInterface,
                                          TargetId->ScsiId.Scsi,
                                          Lun,
                                          &ScsiDevicePath
                                          );
  }

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

  DevicePath = AppendDevicePathNode (
                 ScsiBusDev->DevicePath,
                 ScsiDevicePath
                 );

  if (DevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  DeviceHandle = NULL;
  RemainingDevicePath = DevicePath;
  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 ErrorExit;
  }

  ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));
  if (ScsiIoDevice == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  ScsiIoDevice->Signature                 = SCSI_IO_DEV_SIGNATURE;
  ScsiIoDevice->ScsiBusDeviceData         = ScsiBusDev;
  CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);
  ScsiIoDevice->Lun                       = Lun;

  if (ScsiBusDev->ExtScsiSupport) {
    ScsiIoDevice->ExtScsiPassThru         = ScsiBusDev->ExtScsiInterface;
    ScsiIoDevice->ExtScsiSupport          = TRUE;
    ScsiIoDevice->ScsiIo.IoAlign          = ScsiIoDevice->ExtScsiPassThru->Mode->IoAlign;

  } else {
    ScsiIoDevice->ScsiPassThru            = ScsiBusDev->ScsiInterface;
    ScsiIoDevice->ExtScsiSupport          = FALSE;
    ScsiIoDevice->ScsiIo.IoAlign          = ScsiIoDevice->ScsiPassThru->Mode->IoAlign;
  }

  ScsiIoDevice->ScsiIo.GetDeviceType      = ScsiGetDeviceType;
  ScsiIoDevice->ScsiIo.GetDeviceLocation  = ScsiGetDeviceLocation;
  ScsiIoDevice->ScsiIo.ResetBus           = ScsiResetBus;
  ScsiIoDevice->ScsiIo.ResetDevice        = ScsiResetDevice;
  ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;

  //
  // Report Status Code here since the new SCSI device will be discovered
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),
    ScsiBusDev->DevicePath
    );

  if (!DiscoverScsiDevice (ScsiIoDevice)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  ScsiIoDevice->DevicePath = DevicePath;

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ScsiIoDevice->Handle,
                  &gEfiDevicePathProtocolGuid,
                  ScsiIoDevice->DevicePath,
                  &gEfiScsiIoProtocolGuid,
                  &ScsiIoDevice->ScsiIo,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  } else {
    if (ScsiBusDev->ExtScsiSupport) {
      gBS->OpenProtocol (
             Controller,
             &gEfiExtScsiPassThruProtocolGuid,
             (VOID **) &(ScsiBusDev->ExtScsiInterface),
             This->DriverBindingHandle,
             ScsiIoDevice->Handle,
             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
             );
     } else {
      gBS->OpenProtocol (
             Controller,
             &gEfiScsiPassThruProtocolGuid,
             (VOID **) &(ScsiBusDev->ScsiInterface),
             This->DriverBindingHandle,
             ScsiIoDevice->Handle,
             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
             );
     }
  }
  return EFI_SUCCESS;

ErrorExit:

  //
  // The memory space for ScsiDevicePath is allocated in
  // ScsiPassThru->BuildDevicePath() function; It is no longer used
  // after AppendDevicePathNode,so free the memory it occupies.
  //
  FreePool (ScsiDevicePath);

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

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

  return Status;
}
コード例 #20
0
ファイル: IdeBus.c プロジェクト: hsienchieh/uefilab
/**
  Deregister an IDE device and free resources

  @param  This Protocol instance pointer.
  @param  Controller Ide device handle
  @param  Handle Handle of device to deregister driver on

  @retval EFI_SUCCESS  Deregiter a specific IDE device successfully


**/
EFI_STATUS
DeRegisterIdeDevice (
  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN  EFI_HANDLE                     Controller,
  IN  EFI_HANDLE                     Handle
  )
{
  EFI_STATUS            Status;
  EFI_BLOCK_IO_PROTOCOL *BlkIo;
  IDE_BLK_IO_DEV        *IdeBlkIoDevice;
  EFI_PCI_IO_PROTOCOL   *PciIo;
  UINTN                 Index;

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &BlkIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  IdeBlkIoDevice = IDE_BLOCK_IO_DEV_FROM_THIS (BlkIo);

  //
  // Report Status code: Device disabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_P_PC_DISABLE),
    IdeBlkIoDevice->DevicePath
    );

  //
  // Close the child handle
  //
  Status = gBS->CloseProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  This->DriverBindingHandle,
                  Handle
                  );

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Handle,
                  &gEfiDevicePathProtocolGuid,
                  IdeBlkIoDevice->DevicePath,
                  &gEfiBlockIoProtocolGuid,
                  &IdeBlkIoDevice->BlkIo,
                  &gEfiDiskInfoProtocolGuid,
                  &IdeBlkIoDevice->DiskInfo,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    gBS->OpenProtocol (
          Controller,
          &gEfiPciIoProtocolGuid,
          (VOID **) &PciIo,
          This->DriverBindingHandle,
          Handle,
          EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
          );
    return Status;
  }

  //
  // Release allocated resources
  //
  Index = IdeBlkIoDevice->Channel * 2 + IdeBlkIoDevice->Device;
  if (Index < MAX_IDE_DEVICE) {
    IdeBlkIoDevice->IdeBusDriverPrivateData->HaveScannedDevice[Index] = FALSE;
  }
  ReleaseIdeResources (IdeBlkIoDevice);

  return EFI_SUCCESS;
}
コード例 #21
0
ファイル: IsaFloppyCtrl.c プロジェクト: AshleyDeSimone/edk2
/**
  Reset the Floppy Logic Drive.
  
  @param  FdcDev FDC_BLK_IO_DEV * : A pointer to the FDC_BLK_IO_DEV
  
  @retval EFI_SUCCESS:    The Floppy Logic Drive is reset
  @retval EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning correctly and
                      can not be reset

**/
EFI_STATUS
FddReset (
  IN FDC_BLK_IO_DEV  *FdcDev
  )
{
  UINT8 Data;
  UINT8 StatusRegister0;
  UINT8 PresentCylinderNumber;
  UINTN Index;

  //
  // Report reset progress code
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_RESET,
    FdcDev->DevicePath
    );

  //
  // Reset specified Floppy Logic Drive according to FdcDev -> Disk
  // Set Digital Output Register(DOR) to do reset work
  //   bit0 & bit1 of DOR : Drive Select
  //   bit2 : Reset bit
  //   bit3 : DMA and Int bit
  // Reset : a "0" written to bit2 resets the FDC, this reset will remain
  //         active until
  //         a "1" is written to this bit.
  // Reset step 1:
  //         use bit0 & bit1 to  select the logic drive
  //         write "0" to bit2
  //
  Data = 0x0;
  Data = (UINT8) (Data | (SELECT_DRV & FdcDev->Disk));
  FdcWritePort (FdcDev, FDC_REGISTER_DOR, Data);

  //
  // wait some time,at least 120us
  //
  MicroSecondDelay (500);

  //
  // Reset step 2:
  //   write "1" to bit2
  //   write "1" to bit3 : enable DMA
  //
  Data |= 0x0C;
  FdcWritePort (FdcDev, FDC_REGISTER_DOR, Data);

  //
  // Experience value
  //
  MicroSecondDelay (2000);

  //
  // wait specified floppy logic drive is not busy
  //
  if (EFI_ERROR (FddWaitForBSYClear (FdcDev, 1))) {
    return EFI_DEVICE_ERROR;
  }
  //
  // Set the Transfer Data Rate
  //
  FdcWritePort (FdcDev, FDC_REGISTER_CCR, 0x0);

  //
  // Experience value
  //
  MicroSecondDelay (100);

  //
  // Issue Sense interrupt command for each drive (total 4 drives)
  //
  for (Index = 0; Index < 4; Index++) {
    if (EFI_ERROR (SenseIntStatus (FdcDev, &StatusRegister0, &PresentCylinderNumber))) {
      return EFI_DEVICE_ERROR;
    }
  }
  //
  // issue Specify command
  //
  if (EFI_ERROR (Specify (FdcDev))) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}
コード例 #22
0
ファイル: Ps2Mouse.c プロジェクト: M1cha/edk2
/**
  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;
}
コード例 #23
0
ファイル: EfiKey.c プロジェクト: AshleyDeSimone/edk2
/**
  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;

}
コード例 #24
0
/**
  Enumerate and configure the new device on the port of this HUB interface.

  @param  HubIf                 The HUB that has the device connected.
  @param  Port                  The port index of the hub (started with zero).

  @retval EFI_SUCCESS           The device is enumerated (added or removed).
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for the device.
  @retval Others                Failed to enumerate the device.

**/
EFI_STATUS
UsbEnumerateNewDev (
  IN USB_INTERFACE        *HubIf,
  IN UINT8                Port
  )
{
  USB_BUS                 *Bus;
  USB_HUB_API             *HubApi;
  USB_DEVICE              *Child;
  USB_DEVICE              *Parent;
  EFI_USB_PORT_STATUS     PortState;
  UINTN                   Address;
  UINT8                   Config;
  EFI_STATUS              Status;

  Parent  = HubIf->Device;
  Bus     = Parent->Bus;
  HubApi  = HubIf->HubApi;  
  Address = Bus->MaxDevices;
  DBG("USB_WAIT_PORT_STABLE_STALL\n");
  gBS->Stall (USB_WAIT_PORT_STABLE_STALL); //100ms
  
  //
  // Hub resets the device for at least 10 milliseconds.
  // Host learns device speed. If device is of low/full speed
  // and the hub is a EHCI root hub, ResetPort will release
  // the device to its companion UHCI and return an error.
  //
  Status = HubApi->ResetPort (HubIf, Port);

  if (EFI_ERROR (Status)) {
 //   DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));

    return Status;
  }

//  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: hub port %d is reset\n", Port));

  Child = UsbCreateDevice (HubIf, Port);

  if (Child == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // OK, now identify the device speed. After reset, hub
  // fully knows the actual device speed.
  //
  DBG("GetPortStatus\n");
  Status = HubApi->GetPortStatus (HubIf, Port, &PortState);

  if (EFI_ERROR (Status)) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get speed of port %d\n", Port));
    goto ON_ERROR;
  }

  if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: No device presented at port %d\n", Port));
    goto ON_ERROR;
  } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_SUPER_SPEED)){
    Child->Speed      = EFI_USB_SPEED_SUPER;
    Child->MaxPacket0 = 512;
  } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_HIGH_SPEED)) {
    Child->Speed      = EFI_USB_SPEED_HIGH;
    Child->MaxPacket0 = 64;
  } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_LOW_SPEED)) {
    Child->Speed      = EFI_USB_SPEED_LOW;
    Child->MaxPacket0 = 8;
  } else {
    Child->Speed      = EFI_USB_SPEED_FULL;
    Child->MaxPacket0 = 8;
  }

//  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device is of %d speed\n", Child->Speed));
  DBG("UsbEnumerateNewDev: device is of %d speed\n", Child->Speed);
  if (((Child->Speed == EFI_USB_SPEED_LOW) || (Child->Speed == EFI_USB_SPEED_FULL)) &&
      (Parent->Speed == EFI_USB_SPEED_HIGH)) {
    //
    // If the child is a low or full speed device, it is necessary to
    // set the transaction translator. Port TT is 1-based.
    // This is quite simple:
    //  1. if parent is of high speed, then parent is our translator
    //  2. otherwise use parent's translator.
    //
    Child->Translator.TranslatorHubAddress  = Parent->Address;
    Child->Translator.TranslatorPortNumber  = (UINT8) (Port + 1);
  } else {
    Child->Translator = Parent->Translator;
  }
//  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device uses translator (%d, %d)\n",
//           Child->Translator.TranslatorHubAddress,
//           Child->Translator.TranslatorPortNumber));
  DBG("UsbEnumerateNewDev: device uses translator (%d, %d)\n", Child->Translator.TranslatorHubAddress, Child->Translator.TranslatorPortNumber);
  //
  // After port is reset, hub establishes a signal path between
  // the device and host (DEFALUT state). Device's registers are
  // reset, use default address 0 (host enumerates one device at
  // a time) , and ready to respond to control transfer at EP 0.
  //

  //
  // Host assigns an address to the device. Device completes the
  // status stage with default address, then switches to new address.
  // ADDRESS state. Address zero is reserved for root hub.
  //
//  ASSERT (Bus->MaxDevices <= 256);
  for (Address = 1; Address < Bus->MaxDevices; Address++) {
    if (Bus->Devices[Address] == NULL) {
      break;
    }
  }

  if (Address >= Bus->MaxDevices) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: address pool is full for port %d\n", Port));
    DBG("UsbEnumerateNewDev: address pool is full for port %d\n", Port);
    Status = EFI_ACCESS_DENIED;
    goto ON_ERROR;
  }

  Status                = UsbSetAddress (Child, (UINT8)Address);
  Child->Address        = (UINT8)Address;
  Bus->Devices[Address] = Child;

  if (EFI_ERROR (Status)) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set device address - %r\n", Status));
    goto ON_ERROR;
  }

  gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);

//  DEBUG ((EFI_D_INFO, "UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));
  DBG("UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address);
  //
  // Host sends a Get_Descriptor request to learn the max packet
  // size of default pipe (only part of the device's descriptor).
  //
  Status = UsbGetMaxPacketSize0 (Child);

  if (EFI_ERROR (Status)) {
 //   DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));
    DBG("UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status);
    goto ON_ERROR;
  }

//  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0));

  //
  // Host learns about the device's abilities by requesting device's
  // entire descriptions.
  //
  Status = UsbBuildDescTable (Child);

  if (EFI_ERROR (Status)) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status));
    DBG("UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status);
    goto ON_ERROR;
  }

  //
  // Select a default configuration: UEFI must set the configuration
  // before the driver can connect to the device.
  //
  Config = Child->DevDesc->Configs[0]->Desc.ConfigurationValue;
  Status = UsbSetConfig (Child, Config);

  if (EFI_ERROR (Status)) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status));
    DBG("UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status);
    goto ON_ERROR;
  }

 // DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address));
  DBG("UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address);
  //
  // Host assigns and loads a device driver.
  //
  Status = UsbSelectConfig (Child, Config);

  if (EFI_ERROR (Status)) {
//    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to create interfaces - %r\n", Status));
    DBG("UsbEnumerateNewDev: failed to create interfaces - %r\n", Status);
    goto ON_ERROR;
  }

  //
  // Report Status Code to indicate USB device has been detected by hotplug
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG),
    Bus->DevicePath
    );
  return EFI_SUCCESS;

ON_ERROR:
  //
  // If reach here, it means the enumeration process on a given port is interrupted due to error.
  // The s/w resources, including the assigned address(Address) and the allocated usb device data
  // structure(Bus->Devices[Address]), will NOT be freed here. These resources will be freed when
  // the device is unplugged from the port or DriverBindingStop() is invoked.
  //
  // This way is used to co-work with the lower layer EDKII UHCI/EHCI/XHCI host controller driver.
  // It's mainly because to keep UEFI spec unchanged EDKII XHCI driver have to maintain a state machine
  // to keep track of the mapping between actual address and request address. If the request address
  // (Address) is freed here, the Address value will be used by next enumerated device. Then EDKII XHCI
  // host controller driver will have wrong information, which will cause further transaction error.
  //
  // EDKII UHCI/EHCI doesn't get impacted as it's make sense to reserve s/w resource till it gets unplugged.
  //
/*
  if (Address != Bus->MaxDevices) {
    Bus->Devices[Address] = NULL;
  }

  if (Child != NULL) {
    UsbFreeDevice (Child);
  }
*/
  return Status;
}
コード例 #25
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;
}
コード例 #26
0
/**
  Start this driver on ControllerHandle and enumerate Pci bus and start
  all device under PCI bus.

  @param  This                 Protocol instance pointer.
  @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 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
PciBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                      Status;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;

  //
  // Initialize PciRootBridgeIo to suppress incorrect compiler warning.
  //
  PciRootBridgeIo = NULL;

  //
  // Check RemainingDevicePath validation
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node,
    // if yes, return EFI_SUCCESS
    //
    if (IsDevicePathEnd (RemainingDevicePath)) {
      return EFI_SUCCESS;
    }
  }

  gBS->LocateProtocol (
         &gEfiIncompatiblePciDeviceSupportProtocolGuid,
         NULL,
         (VOID **) &gIncompatiblePciDeviceSupport
         );

  //
  // If PCI Platform protocol is available, get it now.
  // If the platform implements this, it must be installed before BDS phase
  //
  gPciPlatformProtocol = NULL;
  gBS->LocateProtocol (
        &gEfiPciPlatformProtocolGuid,
        NULL,
        (VOID **) &gPciPlatformProtocol
        );

  //
  // If PCI Platform protocol doesn't exist, try to Pci Override Protocol.
  //
  if (gPciPlatformProtocol == NULL) {
    gPciOverrideProtocol = NULL;
    gBS->LocateProtocol (
          &gEfiPciOverrideProtocolGuid,
          NULL,
          (VOID **) &gPciOverrideProtocol
          );
  }

  if (mIoMmuProtocol == NULL) {
    gBS->LocateProtocol (
          &gEdkiiIoMmuProtocolGuid,
          NULL,
          (VOID **) &mIoMmuProtocol
          );
  }

  if (PcdGetBool (PcdPciDisableBusEnumeration)) {
    gFullEnumeration = FALSE;
  } else {
    gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
  }

  //
  // Open Device Path Protocol for PCI root bridge
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Report Status Code to indicate PCI bus starts
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT),
    ParentDevicePath
    );

  Status = EFI_SUCCESS;
  //
  // Enumerate the entire host bridge
  // After enumeration, a database that records all the device information will be created
  //
  //
  if (gFullEnumeration) {
    //
    // Get the rootbridge Io protocol to find the host bridge handle
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiPciRootBridgeIoProtocolGuid,
                    (VOID **) &PciRootBridgeIo,
                    gPciBusDriverBinding.DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );

    if (!EFI_ERROR (Status)) {
      Status = PciEnumerator (Controller, PciRootBridgeIo->ParentHandle);
    }
  } else {
    //
    // If PCI bus has already done the full enumeration, never do it again
    //
    Status = PciEnumeratorLight (Controller);
  }

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

  //
  // Start all the devices under the entire host bridge.
  //
  StartPciDevices (Controller);

  if (gFullEnumeration) {
    gFullEnumeration = FALSE;

    Status = gBS->InstallProtocolInterface (
                    &PciRootBridgeIo->ParentHandle,
                    &gEfiPciEnumerationCompleteProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);
  }

  return Status;
}
コード例 #27
0
/**
  Reset the Mouse and do BAT test for it, if ExtendedVerification isTRUE and there is a mouse device connectted to system.

  @param This                 - Pointer of simple pointer Protocol.
  @param ExtendedVerification - Whether configure mouse parameters. True: do; FALSE: skip.


  @retval EFI_SUCCESS         - The command byte is written successfully.
  @retval EFI_DEVICE_ERROR    - Errors occurred during reseting keyboard.

**/
EFI_STATUS
EFIAPI
MouseAbsolutePointerReset (
  IN EFI_ABSOLUTE_POINTER_PROTOCOL    *This,
  IN BOOLEAN                          ExtendedVerification
  )
{
  EFI_STATUS                       Status;
  PS2_MOUSE_ABSOLUTE_POINTER_DEV  *MouseAbsolutePointerDev;
  EFI_TPL                          OldTpl;
  BOOLEAN                          KeyboardEnable;
  UINT8                            Data;

  MouseAbsolutePointerDev = PS2_MOUSE_ABSOLUTE_POINTER_DEV_FROM_THIS (This);

  //
  // Report reset progress code
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET,
    MouseAbsolutePointerDev->DevicePath
    );

  KeyboardEnable = FALSE;

  //
  // Raise TPL to avoid keyboard operation impact
  //
  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  ZeroMem (&MouseAbsolutePointerDev->State, sizeof (EFI_ABSOLUTE_POINTER_STATE));
  MouseAbsolutePointerDev->StateChanged = FALSE;

  //
  // Exhaust input data
  //
  Status = EFI_SUCCESS;
  while (!EFI_ERROR (Status)) {
    Status = In8042Data (MouseAbsolutePointerDev->IsaIo, &Data);
  }

  CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);

  KbcDisableKb (MouseAbsolutePointerDev->IsaIo);

  MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);

  //
  // if there's data block on KBC data port, read it out
  //
  if ((Data & KBC_OUTB) == KBC_OUTB) {
    MouseAbsolutePointerDev->IsaIo->Io.Read (MouseAbsolutePointerDev->IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Data);
  }

  Status = EFI_SUCCESS;
  //
  // The PS2 mouse driver reset behavior is always successfully return no matter wheater or not there is mouse connected to system.
  // This behavior is needed by performance speed. The following mouse command only succeessfully finish when mouse device is
  // connected to system, so if PS2 mouse device not connect to system or user not ask for, we skip the mouse configuration and enabling
  //
  if (ExtendedVerification && CheckMouseAbsolutePointerConnect (MouseAbsolutePointerDev)) {
    //
    // Send mouse reset command and set mouse default configure
    //
    Status = PS2MouseReset (MouseAbsolutePointerDev->IsaIo);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseSetSampleRate (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->SampleRate);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseSetResolution (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Resolution);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseSetScaling (MouseAbsolutePointerDev->IsaIo, MouseAbsolutePointerDev->Scaling);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Status = PS2MouseEnable (MouseAbsolutePointerDev->IsaIo);
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto Exit;
    }
  }
Exit:
  gBS->RestoreTPL (OldTpl);

  if (KeyboardEnable) {
    KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
  }

  return Status;
}
コード例 #28
0
ファイル: IsaFloppy.c プロジェクト: bhanug/virtualbox
/**
  Start this driver on Controller.

  @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.

  @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
FdcControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  FDC_BLK_IO_DEV            *FdcDev;
  EFI_ISA_IO_PROTOCOL       *IsaIo;
  UINTN                     Index;
  LIST_ENTRY                *List;
  BOOLEAN                   Found;
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;

  FdcDev  = 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 enable progress code
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE,
    ParentDevicePath
    );

  //
  // Open the ISA I/O Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIsaIoProtocolGuid,
                  (VOID **) &IsaIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Allocate the floppy device's Device structure
  //
  FdcDev = AllocateZeroPool (sizeof (FDC_BLK_IO_DEV));
  if (FdcDev == NULL) {
    goto Done;
  }
  //
  // Initialize the floppy device's device structure
  //
  FdcDev->Signature       = FDC_BLK_IO_DEV_SIGNATURE;
  FdcDev->Handle          = Controller;
  FdcDev->IsaIo           = IsaIo;
  FdcDev->Disk            = (EFI_FDC_DISK) IsaIo->ResourceList->Device.UID;
  FdcDev->Cache           = NULL;
  FdcDev->Event           = NULL;
  FdcDev->ControllerState = NULL;
  FdcDev->DevicePath      = ParentDevicePath;

  FdcDev->ControllerNameTable = NULL;
  AddName (FdcDev);

  //
  // Look up the base address of the Floppy Disk Controller which controls this floppy device
  //
  for (Index = 0; FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {
    if (FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {
      FdcDev->BaseAddress = (UINT16) FdcDev->IsaIo->ResourceList->ResourceItem[Index].StartRange;
    }
  }
  //
  // Maintain the list of floppy disk controllers
  //
  Found = FALSE;
  List  = mControllerHead.ForwardLink;
  while (List != &mControllerHead) {
    FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List);
    if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) {
      Found = TRUE;
      break;
    }

    List = List->ForwardLink;
  }

  if (!Found) {
    //
    // A new floppy disk controller controlling this floppy disk drive is found
    //
    FdcDev->ControllerState = AllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT));
    if (FdcDev->ControllerState == NULL) {
      goto Done;
    }

    FdcDev->ControllerState->Signature          = FLOPPY_CONTROLLER_CONTEXT_SIGNATURE;
    FdcDev->ControllerState->FddResetPerformed  = FALSE;
    FdcDev->ControllerState->NeedRecalibrate    = FALSE;
    FdcDev->ControllerState->BaseAddress        = FdcDev->BaseAddress;
    FdcDev->ControllerState->NumberOfDrive      = 0;

    InsertTailList (&mControllerHead, &FdcDev->ControllerState->Link);
  }
  //
  // Create a timer event for each floppy disk drive device.
  // This timer event is used to control the motor on and off
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  FddTimerProc,
                  FdcDev,
                  &FdcDev->Event
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Reset the Floppy Disk Controller
  //
  if (!FdcDev->ControllerState->FddResetPerformed) {
    FdcDev->ControllerState->FddResetPerformed  = TRUE;
    FdcDev->ControllerState->FddResetStatus     = FddReset (FdcDev);
  }

  if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT,
    ParentDevicePath
    );

  //
  // Discover the Floppy Drive
  //
  Status = DiscoverFddDevice (FdcDev);
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }
  //
  // Install protocol interfaces for the serial device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiBlockIoProtocolGuid,
                  &FdcDev->BlkIo,
                  NULL
                  );
  if (!EFI_ERROR (Status)) {
    FdcDev->ControllerState->NumberOfDrive++;
  }

Done:
  if (EFI_ERROR (Status)) {

    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR,
      ParentDevicePath
      );

    //
    // If a floppy drive device structure was allocated, then free it
    //
    if (FdcDev != NULL) {
      if (FdcDev->Event != NULL) {
        //
        // Close the event for turning the motor off
        //
        gBS->CloseEvent (FdcDev->Event);
      }

      FreeUnicodeStringTable (FdcDev->ControllerNameTable);
      FreePool (FdcDev);
    }

    //
    // Close the ISA I/O Protocol
    //
    if (IsaIo != NULL) {
      gBS->CloseProtocol (
             Controller,
             &gEfiIsaIoProtocolGuid,
             This->DriverBindingHandle,
             Controller
             );
    }

    //
    // Close the device path protocol
    //
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
  }

  return Status;
}
コード例 #29
0
ファイル: Ps2Keyboard.c プロジェクト: hsienchieh/uefilab
/**
  Stop this driver on ControllerHandle. Support stoping any child handles
  created by this driver.

  @param  This              Protocol instance pointer.
  @param  ControllerHandle  Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed ControllerHandle
  @retval other             This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
KbdControllerDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN  EFI_HANDLE                     Controller,
  IN  UINTN                          NumberOfChildren,
  IN  EFI_HANDLE                     *ChildHandleBuffer
  )
{
  EFI_STATUS                     Status;
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
  KEYBOARD_CONSOLE_IN_DEV        *ConsoleIn;
  UINT8                          Data;

  //
  // Disable Keyboard
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  (VOID **) &ConIn,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimpleTextInputExProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);

  //
  // Report that the keyboard is being disabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,
    ConsoleIn->DevicePath
    );

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

  //
  // Since there will be no timer handler for keyboard input any more,
  // exhaust input data just in case there is still keyboard data left
  //
  Status = EFI_SUCCESS;
  while (!EFI_ERROR (Status)) {
    Status = KeyboardRead (ConsoleIn, &Data);;
  }
  //
  // Uninstall the SimpleTextIn and SimpleTextInEx protocols
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  &ConsoleIn->ConIn,
                  &gEfiSimpleTextInputExProtocolGuid,
                  &ConsoleIn->ConInEx,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

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

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

  //
  // Free other resources
  //
  if ((ConsoleIn->ConIn).WaitForKey != NULL) {
    gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
    (ConsoleIn->ConIn).WaitForKey = NULL;
  }
  if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
    gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
    ConsoleIn->ConInEx.WaitForKeyEx = NULL;
  }
  KbdFreeNotifyList (&ConsoleIn->NotifyList);
  FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
  gBS->FreePool (ConsoleIn);

  return EFI_SUCCESS;
}
コード例 #30
0
ファイル: IsaFloppy.c プロジェクト: bhanug/virtualbox
/**
  Stop this driver on ControllerHandle.

  @param[in] This               A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in] ControllerHandle   A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in] NumberOfChildren   The number of child device handles in ChildHandleBuffer.
  @param[in] ChildHandleBuffer  An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
**/
EFI_STATUS
EFIAPI
FdcControllerDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Controller,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS            Status;
  EFI_BLOCK_IO_PROTOCOL *BlkIo;
  FDC_BLK_IO_DEV        *FdcDev;

  //
  // Ignore NumberOfChildren since this is a device driver
  //

  //
  // Get the Block I/O Protocol on Controller
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &BlkIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Get the floppy drive device's Device structure
  //
  FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo);

  //
  // Report disable progress code
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE,
    FdcDev->DevicePath
    );

  //
  // Uninstall the Block I/O Protocol
  //
  Status = gBS->UninstallProtocolInterface (
                  Controller,
                  &gEfiBlockIoProtocolGuid,
                  &FdcDev->BlkIo
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the event for turning the motor off
  //
  gBS->CloseEvent (FdcDev->Event);

  //
  // Turn the motor off on the floppy drive device
  //
  FddTimerProc (FdcDev->Event, FdcDev);

  //
  // Close the device path protocol
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiDevicePathProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  //
  // Close the ISA I/O Protocol
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiIsaIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  //
  // Free the controller list if needed
  //
  FdcDev->ControllerState->NumberOfDrive--;

  //
  // Free the cache if one was allocated
  //
  FdcFreeCache (FdcDev);

  //
  // Free the floppy drive device's device structure
  //
  FreeUnicodeStringTable (FdcDev->ControllerNameTable);
  FreePool (FdcDev);

  return EFI_SUCCESS;
}