REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the OvmfPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			619 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			619 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  The SioBusDxe driver is used to create child devices on the ISA bus and
 | 
						|
  installs the Super I/O protocols on them.
 | 
						|
 | 
						|
  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "SioBusDxe.h"
 | 
						|
 | 
						|
//
 | 
						|
// SioBus Driver Binding Protocol
 | 
						|
//
 | 
						|
EFI_DRIVER_BINDING_PROTOCOL  gSioBusDriverBinding = {
 | 
						|
  SioBusDriverBindingSupported,
 | 
						|
  SioBusDriverBindingStart,
 | 
						|
  SioBusDriverBindingStop,
 | 
						|
  0x10,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Tests to see if this driver supports a given controller. If a child device is
 | 
						|
  provided, it further tests to see if this driver supports creating a handle
 | 
						|
  for the specified child device.
 | 
						|
 | 
						|
  This function checks to see if the driver specified by This supports the
 | 
						|
  device specified by ControllerHandle. Drivers will typically use the device
 | 
						|
  path attached to ControllerHandle and/or the services from the bus I/O
 | 
						|
  abstraction attached to ControllerHandle to determine if the driver supports
 | 
						|
  ControllerHandle. This function may be called many times during platform
 | 
						|
  initialization. In order to reduce boot times, the tests performed by this
 | 
						|
  function must be very small, and take as little time as possible to execute.
 | 
						|
  This function must not change the state of any hardware devices, and this
 | 
						|
  function must be aware that the device specified by ControllerHandle may
 | 
						|
  already be managed by the same driver or a different driver. This function
 | 
						|
  must match its calls to AllocatePages() with FreePages(), AllocatePool() with
 | 
						|
  FreePool(), and OpenProtocol() with CloseProtocol(). Since ControllerHandle
 | 
						|
  may have been previously started by the same driver, if a protocol is already
 | 
						|
  in the opened state, then it must not be closed with CloseProtocol(). This is
 | 
						|
  required to guarantee the state of ControllerHandle is not modified by this
 | 
						|
  function.
 | 
						|
 | 
						|
  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL
 | 
						|
                                   instance.
 | 
						|
  @param[in]  ControllerHandle     The handle of the controller to test. 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 bus drivers, if this parameter
 | 
						|
                                   is not NULL, then the bus driver must
 | 
						|
                                   determine if the bus controller specified by
 | 
						|
                                   ControllerHandle and the child controller
 | 
						|
                                   specified by RemainingDevicePath are both
 | 
						|
                                   supported by this bus driver.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              The device specified by ControllerHandle and
 | 
						|
                                   RemainingDevicePath is supported by the
 | 
						|
                                   driver specified by This.
 | 
						|
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
 | 
						|
                                   RemainingDevicePath is already being managed
 | 
						|
                                   by the driver specified by This.
 | 
						|
  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
 | 
						|
                                   RemainingDevicePath is already being managed
 | 
						|
                                   by a different driver or an application that
 | 
						|
                                   requires exclusive access.
 | 
						|
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
 | 
						|
                                   RemainingDevicePath is not supported by the
 | 
						|
                                   driver specified by This.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SioBusDriverBindingSupported (
 | 
						|
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN EFI_HANDLE                   Controller,
 | 
						|
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS           Status;
 | 
						|
  EFI_PCI_IO_PROTOCOL  *PciIo;
 | 
						|
  PCI_TYPE00           Pci;
 | 
						|
  UINTN                SegmentNumber;
 | 
						|
  UINTN                BusNumber;
 | 
						|
  UINTN                DeviceNumber;
 | 
						|
  UINTN                FunctionNumber;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get PciIo protocol instance
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  Controller,
 | 
						|
                  &gEfiPciIoProtocolGuid,
 | 
						|
                  (VOID **)&PciIo,
 | 
						|
                  This->DriverBindingHandle,
 | 
						|
                  Controller,
 | 
						|
                  EFI_OPEN_PROTOCOL_BY_DRIVER
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = PciIo->Pci.Read (
 | 
						|
                        PciIo,
 | 
						|
                        EfiPciIoWidthUint32,
 | 
						|
                        0,
 | 
						|
                        sizeof (Pci) / sizeof (UINT32),
 | 
						|
                        &Pci
 | 
						|
                        );
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    Status = EFI_UNSUPPORTED;
 | 
						|
    if ((Pci.Hdr.Command & 0x03) == 0x03) {
 | 
						|
      if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
 | 
						|
        //
 | 
						|
        // See if this is a standard PCI to ISA Bridge from the Base Code and
 | 
						|
        // Class Code
 | 
						|
        //
 | 
						|
        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
 | 
						|
          Status = EFI_SUCCESS;
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
 | 
						|
        //
 | 
						|
        if ((Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) &&
 | 
						|
            (Pci.Hdr.VendorId     == 0x8086))
 | 
						|
        {
 | 
						|
          //
 | 
						|
          // See if this is on Function #0 to avoid false positives on
 | 
						|
          // PCI_CLASS_BRIDGE_OTHER that has the same value as
 | 
						|
          // PCI_CLASS_BRIDGE_ISA_PDECODE
 | 
						|
          //
 | 
						|
          Status = PciIo->GetLocation (
 | 
						|
                            PciIo,
 | 
						|
                            &SegmentNumber,
 | 
						|
                            &BusNumber,
 | 
						|
                            &DeviceNumber,
 | 
						|
                            &FunctionNumber
 | 
						|
                            );
 | 
						|
          if (!EFI_ERROR (Status) && (FunctionNumber == 0)) {
 | 
						|
            Status = EFI_SUCCESS;
 | 
						|
          } else {
 | 
						|
            Status = EFI_UNSUPPORTED;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  gBS->CloseProtocol (
 | 
						|
         Controller,
 | 
						|
         &gEfiPciIoProtocolGuid,
 | 
						|
         This->DriverBindingHandle,
 | 
						|
         Controller
 | 
						|
         );
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Stops a device controller or a bus controller.
 | 
						|
 | 
						|
  The Stop() function is designed to be invoked from the EFI boot service
 | 
						|
  DisconnectController(). As a result, much of the error checking on the
 | 
						|
  parameters to Stop() has been moved into this common boot service. It is
 | 
						|
  legal to call Stop() 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 that was used on a previous
 | 
						|
     call to this same driver's Start() function.
 | 
						|
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a
 | 
						|
     valid EFI_HANDLE. In addition, all of these handles must have been created
 | 
						|
     in this driver's Start() function, and the Start() function must have
 | 
						|
     called OpenProtocol() on ControllerHandle with an Attribute of
 | 
						|
     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
 | 
						|
 | 
						|
  @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
 | 
						|
SioBusDriverBindingStop (
 | 
						|
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
 | 
						|
  IN  EFI_HANDLE                   Controller,
 | 
						|
  IN  UINTN                        NumberOfChildren,
 | 
						|
  IN  EFI_HANDLE                   *ChildHandleBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                   Status;
 | 
						|
  SIO_BUS_DRIVER_PRIVATE_DATA  *Private;
 | 
						|
  UINTN                        Index;
 | 
						|
  BOOLEAN                      AllChildrenStopped;
 | 
						|
  EFI_SIO_PROTOCOL             *Sio;
 | 
						|
  SIO_DEV                      *SioDevice;
 | 
						|
  EFI_PCI_IO_PROTOCOL          *PciIo;
 | 
						|
 | 
						|
  if (NumberOfChildren == 0) {
 | 
						|
    //
 | 
						|
    // Restore PCI attributes
 | 
						|
    //
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    Controller,
 | 
						|
                    &gEfiCallerIdGuid,
 | 
						|
                    (VOID **)&Private,
 | 
						|
                    This->DriverBindingHandle,
 | 
						|
                    Controller,
 | 
						|
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = Private->PciIo->Attributes (
 | 
						|
                               Private->PciIo,
 | 
						|
                               EfiPciIoAttributeOperationSet,
 | 
						|
                               Private->OriginalAttributes,
 | 
						|
                               NULL
 | 
						|
                               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    gBS->UninstallProtocolInterface (
 | 
						|
           Controller,
 | 
						|
           &gEfiCallerIdGuid,
 | 
						|
           Private
 | 
						|
           );
 | 
						|
    FreePool (Private);
 | 
						|
 | 
						|
    //
 | 
						|
    // Close the bus driver
 | 
						|
    //
 | 
						|
    Status = gBS->CloseProtocol (
 | 
						|
                    Controller,
 | 
						|
                    &gEfiDevicePathProtocolGuid,
 | 
						|
                    This->DriverBindingHandle,
 | 
						|
                    Controller
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gBS->CloseProtocol (
 | 
						|
                    Controller,
 | 
						|
                    &gEfiPciIoProtocolGuid,
 | 
						|
                    This->DriverBindingHandle,
 | 
						|
                    Controller
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Stop all the children
 | 
						|
  //
 | 
						|
  AllChildrenStopped = TRUE;
 | 
						|
 | 
						|
  for (Index = 0; Index < NumberOfChildren; Index++) {
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    ChildHandleBuffer[Index],
 | 
						|
                    &gEfiSioProtocolGuid,
 | 
						|
                    (VOID **)&Sio,
 | 
						|
                    This->DriverBindingHandle,
 | 
						|
                    Controller,
 | 
						|
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                    );
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      SioDevice = SIO_DEV_FROM_SIO (Sio);
 | 
						|
 | 
						|
      //
 | 
						|
      // Close the child handle
 | 
						|
      //
 | 
						|
      Status = gBS->CloseProtocol (
 | 
						|
                      Controller,
 | 
						|
                      &gEfiPciIoProtocolGuid,
 | 
						|
                      This->DriverBindingHandle,
 | 
						|
                      ChildHandleBuffer[Index]
 | 
						|
                      );
 | 
						|
      Status = gBS->UninstallMultipleProtocolInterfaces (
 | 
						|
                      ChildHandleBuffer[Index],
 | 
						|
                      &gEfiDevicePathProtocolGuid,
 | 
						|
                      SioDevice->DevicePath,
 | 
						|
                      &gEfiSioProtocolGuid,
 | 
						|
                      &SioDevice->Sio,
 | 
						|
                      NULL
 | 
						|
                      );
 | 
						|
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        FreePool (SioDevice->DevicePath);
 | 
						|
        FreePool (SioDevice);
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // Re-open PCI IO Protocol on behalf of the child device
 | 
						|
        // because of failure of destroying the child device handle
 | 
						|
        //
 | 
						|
        gBS->OpenProtocol (
 | 
						|
               Controller,
 | 
						|
               &gEfiPciIoProtocolGuid,
 | 
						|
               (VOID **)&PciIo,
 | 
						|
               This->DriverBindingHandle,
 | 
						|
               ChildHandleBuffer[Index],
 | 
						|
               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | 
						|
               );
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      AllChildrenStopped = FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!AllChildrenStopped) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The entry point for the SioBusDxe driver.
 | 
						|
 | 
						|
  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | 
						|
  @param[in] SystemTable    A pointer to the EFI System Table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The entry point is executed successfully.
 | 
						|
  @retval other             Some error occurs when executing this entry point.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SioBusDxeDriverEntryPoint (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Install driver model protocol(s).
 | 
						|
  //
 | 
						|
  return EfiLibInstallDriverBindingComponentName2 (
 | 
						|
           ImageHandle,
 | 
						|
           SystemTable,
 | 
						|
           &gSioBusDriverBinding,
 | 
						|
           ImageHandle,
 | 
						|
           &gSioBusComponentName,
 | 
						|
           &gSioBusComponentName2
 | 
						|
           );
 | 
						|
}
 |