mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 03:03:46 +01:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the SourceLevelDebugPkg 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: Hao A Wu <hao.a.wu@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			537 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			537 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Debug Port Library implementation based on usb3 debug port.
 | |
| 
 | |
|   Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Base.h>
 | |
| #include <PiDxe.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/HobLib.h>
 | |
| #include <Protocol/PciIo.h>
 | |
| #include <Protocol/IoMmu.h>
 | |
| #include <Protocol/DxeSmmReadyToLock.h>
 | |
| #include "DebugCommunicationLibUsb3Internal.h"
 | |
| 
 | |
| GUID  gUsb3DbgGuid =  USB3_DBG_GUID;
 | |
| 
 | |
| USB3_DEBUG_PORT_HANDLE  mUsb3Instance         = { USB3DBG_UNINITIALIZED };
 | |
| EFI_PHYSICAL_ADDRESS    mUsb3InstanceAddr     = 0;
 | |
| EFI_PHYSICAL_ADDRESS    *mUsb3InstanceAddrPtr = NULL;
 | |
| EFI_PCI_IO_PROTOCOL     *mUsb3PciIo           = NULL;
 | |
| 
 | |
| /**
 | |
|   Creates a named event that can be signaled.
 | |
| 
 | |
|   This function creates an event using NotifyTpl, NotifyFunction.
 | |
|   If Name is NULL, then ASSERT().
 | |
|   If NotifyTpl is not a legal TPL value, then ASSERT().
 | |
|   If NotifyFunction is NULL, then ASSERT().
 | |
| 
 | |
|   @param  Name                  Supplies the GUID name of the event.
 | |
|   @param  NotifyTpl             Supplies the task priority level of the event notifications.
 | |
|   @param  NotifyFunction        Supplies the function to notify when the event is signaled.
 | |
|   @param  Event                 A pointer to the event created.
 | |
| 
 | |
|   @retval EFI_SUCCESS           A named event was created.
 | |
|   @retval EFI_OUT_OF_RESOURCES  There are not enough resource to create the named event.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| Usb3NamedEventListen (
 | |
|   IN CONST EFI_GUID    *Name,
 | |
|   IN EFI_TPL           NotifyTpl,
 | |
|   IN EFI_EVENT_NOTIFY  NotifyFunction,
 | |
|   IN EFI_EVENT         *Event
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   VOID        *RegistrationLocal;
 | |
| 
 | |
|   ASSERT (Name != NULL);
 | |
|   ASSERT (NotifyFunction != NULL);
 | |
|   ASSERT (NotifyTpl <= TPL_HIGH_LEVEL);
 | |
| 
 | |
|   //
 | |
|   // Create event
 | |
|   //
 | |
|   Status = gBS->CreateEvent (
 | |
|                   EVT_NOTIFY_SIGNAL,
 | |
|                   NotifyTpl,
 | |
|                   NotifyFunction,
 | |
|                   NULL,
 | |
|                   Event
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   //
 | |
|   // Register for an installation of protocol interface
 | |
|   //
 | |
|   Status = gBS->RegisterProtocolNotify (
 | |
|                   (EFI_GUID *)Name,
 | |
|                   *Event,
 | |
|                   &RegistrationLocal
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   USB3 map one DMA buffer.
 | |
| 
 | |
|   @param PciIo          Pointer to PciIo for USB3 debug port.
 | |
|   @param Address        DMA buffer address to be mapped.
 | |
|   @param NumberOfBytes  Number of bytes to be mapped.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| Usb3MapOneDmaBuffer (
 | |
|   IN EFI_PCI_IO_PROTOCOL   *PciIo,
 | |
|   IN EFI_PHYSICAL_ADDRESS  Address,
 | |
|   IN UINTN                 NumberOfBytes
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS            Status;
 | |
|   VOID                  *HostAddress;
 | |
|   EFI_PHYSICAL_ADDRESS  DeviceAddress;
 | |
|   VOID                  *Mapping;
 | |
| 
 | |
|   HostAddress = (VOID *)(UINTN)Address;
 | |
|   Status      = PciIo->Map (
 | |
|                          PciIo,
 | |
|                          EfiPciIoOperationBusMasterCommonBuffer,
 | |
|                          HostAddress,
 | |
|                          &NumberOfBytes,
 | |
|                          &DeviceAddress,
 | |
|                          &Mapping
 | |
|                          );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
|   ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   USB3 map DMA buffers.
 | |
| 
 | |
|   @param Instance       Pointer to USB3 debug port instance.
 | |
|   @param PciIo          Pointer to PciIo for USB3 debug port.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| Usb3MapDmaBuffers (
 | |
|   IN USB3_DEBUG_PORT_HANDLE  *Instance,
 | |
|   IN EFI_PCI_IO_PROTOCOL     *PciIo
 | |
|   )
 | |
| {
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     Instance->UrbIn.Data,
 | |
|     XHCI_DEBUG_DEVICE_MAX_PACKET_SIZE * 2 + USB3_DEBUG_PORT_WRITE_MAX_PACKET_SIZE
 | |
|     );
 | |
| 
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     Instance->TransferRingIn.RingSeg0,
 | |
|     sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
 | |
|     );
 | |
| 
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     Instance->TransferRingOut.RingSeg0,
 | |
|     sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER
 | |
|     );
 | |
| 
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     Instance->EventRing.EventRingSeg0,
 | |
|     sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER
 | |
|     );
 | |
| 
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     Instance->EventRing.ERSTBase,
 | |
|     sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER
 | |
|     );
 | |
| 
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     Instance->DebugCapabilityContext,
 | |
|     sizeof (XHC_DC_CONTEXT)
 | |
|     );
 | |
| 
 | |
|   Usb3MapOneDmaBuffer (
 | |
|     PciIo,
 | |
|     ((XHC_DC_CONTEXT *)(UINTN)Instance->DebugCapabilityContext)->DbcInfoContext.String0DescAddress,
 | |
|     STRING0_DESC_LEN + MANU_DESC_LEN + PRODUCT_DESC_LEN + SERIAL_DESC_LEN
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Invoke a notification event
 | |
| 
 | |
|   @param[in] Event              Event whose notification function is being invoked.
 | |
|   @param[in] Context            The pointer to the notification function's context,
 | |
|                                 which is implementation-dependent.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| Usb3DxeSmmReadyToLockNotify (
 | |
|   IN EFI_EVENT  Event,
 | |
|   IN VOID       *Context
 | |
|   )
 | |
| {
 | |
|   USB3_DEBUG_PORT_HANDLE  *Instance;
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
 | |
| 
 | |
|   Instance = GetUsb3DebugPortInstance ();
 | |
|   ASSERT (Instance != NULL);
 | |
| 
 | |
|   Instance->InNotify = TRUE;
 | |
| 
 | |
|   //
 | |
|   // For the case that the USB3 debug port instance and DMA buffers are
 | |
|   // from PEI HOB with IOMMU enabled.
 | |
|   // Reinitialize USB3 debug port with granted DXE DMA buffer accessible
 | |
|   // by SMM environment.
 | |
|   //
 | |
|   InitializeUsbDebugHardware (Instance);
 | |
| 
 | |
|   //
 | |
|   // Wait some time for host to be ready after re-initialization.
 | |
|   //
 | |
|   MicroSecondDelay (1000000);
 | |
| 
 | |
|   Instance->InNotify = FALSE;
 | |
|   gBS->CloseEvent (Event);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   USB3 get IOMMU protocol.
 | |
| 
 | |
|   @return Pointer to IOMMU protocol.
 | |
| 
 | |
| **/
 | |
| EDKII_IOMMU_PROTOCOL *
 | |
| Usb3GetIoMmu (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS            Status;
 | |
|   EDKII_IOMMU_PROTOCOL  *IoMmu;
 | |
| 
 | |
|   IoMmu  = NULL;
 | |
|   Status = gBS->LocateProtocol (
 | |
|                   &gEdkiiIoMmuProtocolGuid,
 | |
|                   NULL,
 | |
|                   (VOID **)&IoMmu
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status) && (IoMmu != NULL)) {
 | |
|     return IoMmu;
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Invoke a notification event
 | |
| 
 | |
|   @param[in] Event              Event whose notification function is being invoked.
 | |
|   @param[in] Context            The pointer to the notification function's context,
 | |
|                                 which is implementation-dependent.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| Usb3PciIoNotify (
 | |
|   IN  EFI_EVENT  Event,
 | |
|   IN  VOID       *Context
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS              Status;
 | |
|   UINTN                   PciIoHandleCount;
 | |
|   EFI_HANDLE              *PciIoHandleBuffer;
 | |
|   UINTN                   Index;
 | |
|   EFI_PCI_IO_PROTOCOL     *PciIo;
 | |
|   UINTN                   PciSegment;
 | |
|   UINTN                   PciBusNumber;
 | |
|   UINTN                   PciDeviceNumber;
 | |
|   UINTN                   PciFunctionNumber;
 | |
|   UINT32                  PciAddress;
 | |
|   USB3_DEBUG_PORT_HANDLE  *Instance;
 | |
|   EFI_EVENT               SmmReadyToLockEvent;
 | |
| 
 | |
|   Status = gBS->LocateHandleBuffer (
 | |
|                   ByProtocol,
 | |
|                   &gEfiPciIoProtocolGuid,
 | |
|                   NULL,
 | |
|                   &PciIoHandleCount,
 | |
|                   &PciIoHandleBuffer
 | |
|                   );
 | |
|   if (!EFI_ERROR (Status) &&
 | |
|       (PciIoHandleBuffer != NULL) &&
 | |
|       (PciIoHandleCount != 0))
 | |
|   {
 | |
|     for (Index = 0; Index < PciIoHandleCount; Index++) {
 | |
|       Status = gBS->HandleProtocol (
 | |
|                       PciIoHandleBuffer[Index],
 | |
|                       &gEfiPciIoProtocolGuid,
 | |
|                       (VOID **)&PciIo
 | |
|                       );
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|       Status = PciIo->GetLocation (PciIo, &PciSegment, &PciBusNumber, &PciDeviceNumber, &PciFunctionNumber);
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|       PciAddress = (UINT32)((PciBusNumber << 20) | (PciDeviceNumber << 15) | (PciFunctionNumber << 12));
 | |
|       if (PciAddress == PcdGet32 (PcdUsbXhciPciAddress)) {
 | |
|         //
 | |
|         // Found the PciIo for USB3 debug port.
 | |
|         //
 | |
|         DEBUG ((DEBUG_INFO, "%a()\n", __FUNCTION__));
 | |
|         if (Usb3GetIoMmu () != NULL) {
 | |
|           Instance = GetUsb3DebugPortInstance ();
 | |
|           ASSERT (Instance != NULL);
 | |
|           if (Instance->Ready) {
 | |
|             Instance->InNotify = TRUE;
 | |
|             Usb3MapDmaBuffers (Instance, PciIo);
 | |
|             Instance->InNotify = FALSE;
 | |
| 
 | |
|             if (Instance->FromHob) {
 | |
|               mUsb3PciIo = PciIo;
 | |
|               Usb3NamedEventListen (
 | |
|                 &gEfiDxeSmmReadyToLockProtocolGuid,
 | |
|                 TPL_NOTIFY,
 | |
|                 Usb3DxeSmmReadyToLockNotify,
 | |
|                 &SmmReadyToLockEvent
 | |
|                 );
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         gBS->CloseEvent (Event);
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     gBS->FreePool (PciIoHandleBuffer);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return USB3 debug instance address pointer.
 | |
| 
 | |
| **/
 | |
| EFI_PHYSICAL_ADDRESS *
 | |
| GetUsb3DebugPortInstanceAddrPtr (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   if (mUsb3InstanceAddrPtr == NULL) {
 | |
|     //
 | |
|     // Use the local variables temporarily.
 | |
|     //
 | |
|     mUsb3InstanceAddr    = (EFI_PHYSICAL_ADDRESS)(UINTN)&mUsb3Instance;
 | |
|     mUsb3InstanceAddrPtr = &mUsb3InstanceAddr;
 | |
|   }
 | |
| 
 | |
|   return mUsb3InstanceAddrPtr;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
 | |
|   OperationBusMasterCommonBuffer64 mapping.
 | |
| 
 | |
|   @param PciIo                  Pointer to PciIo for USB3 debug port.
 | |
|   @param Pages                  The number of pages to allocate.
 | |
|   @param Address                A pointer to store the base system memory address of the
 | |
|                                 allocated range.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The requested memory pages were allocated.
 | |
|   @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
 | |
|                                 MEMORY_WRITE_COMBINE and MEMORY_CACHED.
 | |
|   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
 | |
|   @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| Usb3AllocateDmaBuffer (
 | |
|   IN EFI_PCI_IO_PROTOCOL  *PciIo,
 | |
|   IN UINTN                Pages,
 | |
|   OUT VOID                **Address
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   *Address = NULL;
 | |
|   Status   = PciIo->AllocateBuffer (
 | |
|                       PciIo,
 | |
|                       AllocateAnyPages,
 | |
|                       EfiRuntimeServicesData,
 | |
|                       Pages,
 | |
|                       Address,
 | |
|                       0
 | |
|                       );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Usb3MapOneDmaBuffer (
 | |
|       PciIo,
 | |
|       (EFI_PHYSICAL_ADDRESS)(UINTN)*Address,
 | |
|       EFI_PAGES_TO_SIZE (Pages)
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Allocate aligned memory for XHC's usage.
 | |
| 
 | |
|   @param  BufferSize      The size, in bytes, of the Buffer.
 | |
| 
 | |
|   @return A pointer to the allocated buffer or NULL if allocation fails.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| AllocateAlignBuffer (
 | |
|   IN UINTN  BufferSize
 | |
|   )
 | |
| {
 | |
|   EFI_PHYSICAL_ADDRESS  TmpAddr;
 | |
|   EFI_STATUS            Status;
 | |
|   VOID                  *Buf;
 | |
| 
 | |
|   Buf = NULL;
 | |
| 
 | |
|   if (gBS != NULL) {
 | |
|     if (mUsb3PciIo != NULL) {
 | |
|       Usb3AllocateDmaBuffer (
 | |
|         mUsb3PciIo,
 | |
|         EFI_SIZE_TO_PAGES (BufferSize),
 | |
|         &Buf
 | |
|         );
 | |
|     } else {
 | |
|       TmpAddr = 0xFFFFFFFF;
 | |
|       Status  = gBS->AllocatePages (
 | |
|                        AllocateMaxAddress,
 | |
|                        EfiACPIMemoryNVS,
 | |
|                        EFI_SIZE_TO_PAGES (BufferSize),
 | |
|                        &TmpAddr
 | |
|                        );
 | |
|       if (!EFI_ERROR (Status)) {
 | |
|         Buf = (VOID *)(UINTN)TmpAddr;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return Buf;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   The constructor function initialize USB3 debug port.
 | |
| 
 | |
|   @param  ImageHandle   The firmware allocated handle for the EFI image.
 | |
|   @param  SystemTable   A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DebugCommunicationUsb3DxeConstructor (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_PHYSICAL_ADDRESS    *AddrPtr;
 | |
|   USB3_DEBUG_PORT_HANDLE  *Instance;
 | |
|   EFI_PHYSICAL_ADDRESS    Address;
 | |
|   EFI_STATUS              Status;
 | |
|   EFI_EVENT               Event;
 | |
| 
 | |
|   Status = EfiGetSystemConfigurationTable (&gUsb3DbgGuid, (VOID **)&AddrPtr);
 | |
|   if (EFI_ERROR (Status) || (AddrPtr == NULL)) {
 | |
|     //
 | |
|     // Instead of using local variables, install system configuration table for
 | |
|     // the local instance and the buffer to save instance address pointer.
 | |
|     //
 | |
|     Address = SIZE_4GB;
 | |
|     Status  = gBS->AllocatePages (
 | |
|                      AllocateMaxAddress,
 | |
|                      EfiACPIMemoryNVS,
 | |
|                      EFI_SIZE_TO_PAGES (sizeof (EFI_PHYSICAL_ADDRESS) + sizeof (USB3_DEBUG_PORT_HANDLE)),
 | |
|                      &Address
 | |
|                      );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     AddrPtr = (EFI_PHYSICAL_ADDRESS *)(UINTN)Address;
 | |
|     ZeroMem (AddrPtr, sizeof (EFI_PHYSICAL_ADDRESS) + sizeof (USB3_DEBUG_PORT_HANDLE));
 | |
|     Instance = (USB3_DEBUG_PORT_HANDLE *)(AddrPtr + 1);
 | |
|     CopyMem (Instance, &mUsb3Instance, sizeof (USB3_DEBUG_PORT_HANDLE));
 | |
|     *AddrPtr = (EFI_PHYSICAL_ADDRESS)(UINTN)Instance;
 | |
| 
 | |
|     Status = gBS->InstallConfigurationTable (&gUsb3DbgGuid, AddrPtr);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (mUsb3InstanceAddrPtr != NULL) {
 | |
|     *AddrPtr = *mUsb3InstanceAddrPtr;
 | |
|   }
 | |
| 
 | |
|   mUsb3InstanceAddrPtr = AddrPtr;
 | |
| 
 | |
|   Instance = GetUsb3DebugPortInstance ();
 | |
|   ASSERT (Instance != NULL);
 | |
| 
 | |
|   if (Instance->PciIoEvent == 0) {
 | |
|     Status = Usb3NamedEventListen (
 | |
|                &gEfiPciIoProtocolGuid,
 | |
|                TPL_NOTIFY,
 | |
|                Usb3PciIoNotify,
 | |
|                &Event
 | |
|                );
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       Instance->PciIoEvent = (EFI_PHYSICAL_ADDRESS)(UINTN)Event;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   The destructor function.
 | |
| 
 | |
|   @param  ImageHandle   The firmware allocated handle for the EFI image.
 | |
|   @param  SystemTable   A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS   The destructor always returns EFI_SUCCESS.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| DebugCommunicationUsb3DxeDestructor (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   USB3_DEBUG_PORT_HANDLE  *Instance;
 | |
| 
 | |
|   Instance = GetUsb3DebugPortInstance ();
 | |
|   ASSERT (Instance != NULL);
 | |
| 
 | |
|   if (Instance->PciIoEvent != 0) {
 | |
|     //
 | |
|     // Close the event created.
 | |
|     //
 | |
|     gBS->CloseEvent ((EFI_EVENT)(UINTN)Instance->PciIoEvent);
 | |
|     Instance->PciIoEvent = 0;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |