diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
index bf50c78c92..35dba40473 100644
--- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
+++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
@@ -3,6 +3,7 @@
The implementation of EFI Redfidh Discover Protocol.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -23,8 +24,6 @@ EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANC
EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;
EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;
-EFI_HANDLE EfiRedfishDiscoverProtocolHandle = NULL;
-
EFI_STATUS
EFIAPI
Tcp4GetSubnetInfo (
@@ -325,6 +324,38 @@ GetTargetNetworkInterfaceInternal (
return NULL;
}
+/**
+ This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
+ instance with the given Controller handle.
+
+ @param[in] ControllerHandle The controller handle associated with network interface.
+
+ @retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.
+ @retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.
+**/
+EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
+GetTargetNetworkInterfaceInternalByController (
+ IN EFI_HANDLE ControllerHandle
+ )
+{
+ EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
+
+ ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
+ while (TRUE) {
+ if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {
+ return ThisNetworkInterface;
+ }
+
+ if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
+ return NULL;
+ }
+
+ ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
+ }
+
+ return NULL;
+}
+
/**
This function validate if target network interface is ready for discovering
Redfish service.
@@ -1619,29 +1650,30 @@ BuildupNetworkInterface (
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (!EFI_ERROR (Status)) {
- if ((EfiRedfishDiscoverProtocolHandle == NULL) &&
- (gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx) &&
- !IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)
- )
- {
- // Install the fisrt Redfish Discover Protocol when EFI REST EX protcol is discovered.
- // This ensures EFI REST EX is ready while EFI_REDFISH_DISCOVER_PROTOCOL consumer acquires
- // Redfish serivce over network interface.
+ if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {
+ // Install Redfish Discover Protocol when EFI REST EX protcol is discovered.
+ // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
+ // acquires Redfish serivce over network interface.
- Status = gBS->InstallProtocolInterface (
- &EfiRedfishDiscoverProtocolHandle,
- &gEfiRedfishDiscoverProtocolGuid,
- EFI_NATIVE_INTERFACE,
- (VOID *)&mRedfishDiscover
- );
- } else if ((EfiRedfishDiscoverProtocolHandle != NULL) && NewNetworkInterfaceInstalled) {
- Status = gBS->ReinstallProtocolInterface (
- EfiRedfishDiscoverProtocolHandle,
- &gEfiRedfishDiscoverProtocolGuid,
- (VOID *)&mRedfishDiscover,
- (VOID *)&mRedfishDiscover
- );
- NewNetworkInterfaceInstalled = FALSE;
+ if (!NewNetworkInterfaceInstalled) {
+ NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);
+ if (NetworkInterface == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __FUNCTION__));
+ return Status;
+ }
+ }
+
+ NewNetworkInterfaceInstalled = FALSE;
+ NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &NetworkInterface->EfiRedfishDiscoverProtocolHandle,
+ &gEfiRedfishDiscoverProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *)&mRedfishDiscover
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __FUNCTION__));
+ }
}
}
@@ -1724,6 +1756,7 @@ StopServiceOnNetworkInterface (
EFI_STATUS Status;
VOID *Interface;
EFI_TPL OldTpl;
+ EFI_HANDLE DiscoverProtocolHandle;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
@@ -1743,8 +1776,11 @@ StopServiceOnNetworkInterface (
ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
while (TRUE) {
if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) {
+ DiscoverProtocolHandle = ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;
+ //
+ // Close protocol and destroy service.
+ //
Status = CloseProtocolService (
- // Close protocol and destroy service.
ThisBindingProtocol,
ControllerHandle,
&gRequiredProtocol[Index],
@@ -1756,17 +1792,18 @@ StopServiceOnNetworkInterface (
}
gBS->RestoreTPL (OldTpl);
- // Reinstall Redfish Discover protocol to notify network
- // interface change.
- Status = gBS->ReinstallProtocolInterface (
- EfiRedfishDiscoverProtocolHandle,
- &gEfiRedfishDiscoverProtocolGuid,
- (VOID *)&mRedfishDiscover,
- (VOID *)&mRedfishDiscover
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Reinstall gEfiRedfishDiscoverProtocolGuid fail.", __FUNCTION__));
+ //
+ // Disconnect EFI Redfish discover driver controller to notify the
+ // clinet which uses .EFI Redfish discover protocol.
+ //
+ if (DiscoverProtocolHandle != NULL) {
+ gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
+ Status = gBS->UninstallProtocolInterface (
+ DiscoverProtocolHandle,
+ &gEfiRedfishDiscoverProtocolGuid,
+ (VOID *)&mRedfishDiscover
+ );
}
return Status;
@@ -2032,20 +2069,5 @@ RedfishDiscoverUnload (
StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);
}
- // Disconnect EFI Redfish discover driver controller to notify the
- // clinet which uses .EFI Redfish discover protocol.
-
- if (EfiRedfishDiscoverProtocolHandle != NULL) {
- //
- // Notify user EFI_REDFISH_DISCOVER_PROTOCOL is unloaded.
- //
- gBS->DisconnectController (EfiRedfishDiscoverProtocolHandle, NULL, NULL);
- Status = gBS->UninstallProtocolInterface (
- EfiRedfishDiscoverProtocolHandle,
- &gEfiRedfishDiscoverProtocolGuid,
- (VOID *)&mRedfishDiscover
- );
- }
-
return Status;
}
diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h
index 4d1319b264..04fa09e1cc 100644
--- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h
+++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h
@@ -2,6 +2,7 @@
This file defines the EFI Redfish Discover Protocol interface.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -107,6 +108,12 @@ typedef struct {
///< NETWORK_INTERFACE_PROTOCOL_TYPE.
REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL NetworkInterfaceProtocolInfo; ///< Network interface protocol information.
EFI_HANDLE RestExHandle; ///< REST EX handle associated with this network interface.
+ //
+ // EFI_REDFISH_DISCOVER_PROTOCOL instance installed
+ // on this network interface.
+ //
+ EFI_HANDLE EfiRedfishDiscoverProtocolHandle; ///< EFI_REDFISH_DISCOVER_PROTOTOCOL instance installed
+ ///< on this network interface.
} EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL;
//