From f7da805b506034f50ebf7d9c2a247a80ee8e987a Mon Sep 17 00:00:00 2001 From: Abner Chang Date: Tue, 30 Aug 2022 12:15:47 +0800 Subject: [PATCH] RedfishPkg/RedfishDiscoverDxe: Install protocol on each network interface BZ 4037: Install EFI_DISCOVER_PROTOCOL on each network interface. This fixes the issue that causes the high-level Redfish driver on the network interface is stopped when: 1. EFI_DISCOVER_PROTOCOL is reinstalled on a new-found network interface, or 2. EFI_DISCOVER_PROTOCOL is stopped on the network interface other than the one which is used to communicate with Redfish service. Cc: Nickle Wang Cc: Igor Kulchytskyy Signed-off-by: Abner Chang Reviewed-by: Nickle Wang Reviewed-by: Igor Kulchytskyy --- .../RedfishDiscoverDxe/RedfishDiscoverDxe.c | 126 ++++++++++-------- .../RedfishDiscoverInternal.h | 7 + 2 files changed, 81 insertions(+), 52 deletions(-) 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. - - 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 ((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. + + 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; // -- 2.39.2