diff --git a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c index 993ad338b6..161731b211 100644 --- a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c @@ -22,12 +22,6 @@ EFI_HANDLE gEfiRedfishDiscoverControllerHandle = NULL; EFI_REDFISH_DISCOVER_PROTOCOL *gEfiRedfishDiscoverProtocol = NULL; BOOLEAN gRedfishDiscoverActivated = FALSE; BOOLEAN gRedfishServiceDiscovered = FALSE; -// -// Network interfaces discovered by EFI Redfish Discover Protocol. -// -UINTN gNumberOfNetworkInterfaces; -EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *gNetworkInterfaceInstances = NULL; -EFI_REDFISH_DISCOVERED_TOKEN *gRedfishDiscoveredToken = NULL; /// /// Driver Binding Protocol instance @@ -58,13 +52,6 @@ RedfishConfigStopRedfishDiscovery ( gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent); } - // - // Stop Redfish service discovery. - // - gEfiRedfishDiscoverProtocol->AbortAcquireRedfishService ( - gEfiRedfishDiscoverProtocol, - gNetworkInterfaceInstances - ); gEfiRedfishDiscoverControllerHandle = NULL; gEfiRedfishDiscoverProtocol = NULL; gRedfishDiscoverActivated = FALSE; @@ -318,36 +305,38 @@ RedfishServiceDiscoveredCallback ( EFI_REDFISH_DISCOVERED_TOKEN *RedfishDiscoveredToken; EFI_REDFISH_DISCOVERED_INSTANCE *RedfishInstance; - if (gRedfishServiceDiscovered) { - // - // Only support one Redfish service on platform. - // - return; - } - RedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)Context; - RedfishInstance = RedfishDiscoveredToken->DiscoverList.RedfishInstances; - // - // Only pick up the first found Redfish service. - // - if (RedfishInstance->Status == EFI_SUCCESS) { - gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle = RedfishInstance->Information.RedfishRestExHandle; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion = RedfishInstance->Information.RedfishVersion; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation = RedfishInstance->Information.Location; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid = RedfishInstance->Information.Uuid; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs = RedfishInstance->Information.Os; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion = RedfishInstance->Information.OsVersion; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct = RedfishInstance->Information.Product; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer = RedfishInstance->Information.ProductVer; - gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps = RedfishInstance->Information.UseHttps; - gRedfishServiceDiscovered = TRUE; - } + gBS->CloseEvent (RedfishDiscoveredToken->Event); // - // Invoke RedfishConfigHandlerInstalledCallback to execute - // the initialization of Redfish Configure Handler instance. + // Only support one Redfish service on platform. // - RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event, &gRedfishConfigData); + if (!gRedfishServiceDiscovered) { + RedfishInstance = RedfishDiscoveredToken->DiscoverList.RedfishInstances; + // + // Only pick up the first found Redfish service. + // + if (RedfishInstance->Status == EFI_SUCCESS) { + gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle = RedfishInstance->Information.RedfishRestExHandle; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion = RedfishInstance->Information.RedfishVersion; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation = RedfishInstance->Information.Location; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid = RedfishInstance->Information.Uuid; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs = RedfishInstance->Information.Os; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion = RedfishInstance->Information.OsVersion; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct = RedfishInstance->Information.Product; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer = RedfishInstance->Information.ProductVer; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps = RedfishInstance->Information.UseHttps; + gRedfishServiceDiscovered = TRUE; + } + + // + // Invoke RedfishConfigHandlerInstalledCallback to execute + // the initialization of Redfish Configure Handler instance. + // + RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event, &gRedfishConfigData); + } + + FreePool (RedfishDiscoveredToken); } /** @@ -371,6 +360,7 @@ RedfishDiscoverProtocolInstalled ( UINTN NetworkInterfaceIndex; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface; EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken; + UINTN NumberOfNetworkInterfaces; DEBUG ((DEBUG_INFO, "%a: New network interface is installed on system by EFI Redfish discover driver.\n", __func__)); @@ -408,36 +398,29 @@ RedfishDiscoverProtocolInstalled ( } } - // - // Check the new found network interface. - // - if (gNetworkInterfaceInstances != NULL) { - FreePool (gNetworkInterfaceInstances); - } - Status = gEfiRedfishDiscoverProtocol->GetNetworkInterfaceList ( gEfiRedfishDiscoverProtocol, gRedfishConfigData.Image, - &gNumberOfNetworkInterfaces, - &gNetworkInterfaceInstances + &NumberOfNetworkInterfaces, + &ThisNetworkInterface ); - if (EFI_ERROR (Status) || (gNumberOfNetworkInterfaces == 0)) { + if (EFI_ERROR (Status) || (NumberOfNetworkInterfaces == 0)) { DEBUG ((DEBUG_ERROR, "%a: No network interfaces found on the handle.\n", __func__)); return; } - gRedfishDiscoveredToken = AllocateZeroPool (gNumberOfNetworkInterfaces * sizeof (EFI_REDFISH_DISCOVERED_TOKEN)); - if (gRedfishDiscoveredToken == NULL) { - DEBUG ((DEBUG_ERROR, "%a: Not enough memory for EFI_REDFISH_DISCOVERED_TOKEN.\n", __func__)); - return; - } - - ThisNetworkInterface = gNetworkInterfaceInstances; - ThisRedfishDiscoveredToken = gRedfishDiscoveredToken; // // Loop to discover Redfish service on each network interface. // - for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex < gNumberOfNetworkInterfaces; NetworkInterfaceIndex++) { + for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex < NumberOfNetworkInterfaces; NetworkInterfaceIndex++) { + ThisRedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_TOKEN)); + if (ThisRedfishDiscoveredToken == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Not enough memory for EFI_REDFISH_DISCOVERED_TOKEN.\n", __func__)); + return; + } + + ThisRedfishDiscoveredToken->Signature = REDFISH_DISCOVER_TOKEN_SIGNATURE; + // // Initial this Redfish Discovered Token // @@ -449,13 +432,11 @@ RedfishDiscoverProtocolInstalled ( &ThisRedfishDiscoveredToken->Event ); if (EFI_ERROR (Status)) { + FreePool (ThisRedfishDiscoveredToken); DEBUG ((DEBUG_ERROR, "%a: Failed to create event for Redfish discovered token.\n", __func__)); - goto ErrorReturn; + return; } - ThisRedfishDiscoveredToken->Signature = REDFISH_DISCOVER_TOKEN_SIGNATURE; - ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound = 0; - ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances = NULL; // // Acquire for Redfish service which is reported by // Redfish Host Interface. @@ -467,21 +448,23 @@ RedfishDiscoverProtocolInstalled ( EFI_REDFISH_DISCOVER_HOST_INTERFACE, ThisRedfishDiscoveredToken ); - ThisNetworkInterface++; - ThisRedfishDiscoveredToken++; - } - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: Acquire Redfish service fail.\n", __func__)); - goto ErrorReturn; + // + // Free Redfish Discovered Token if Discover Instance was not created and + // Redfish Service Discovered Callback event was not triggered. + // + if ((ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound == 0) || + EFI_ERROR (ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances->Status)) + { + gBS->CloseEvent (ThisRedfishDiscoveredToken->Event); + DEBUG ((DEBUG_ERROR, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken)); + FreePool (ThisRedfishDiscoveredToken); + } + + ThisNetworkInterface++; } return; - -ErrorReturn: - if (gRedfishDiscoveredToken != NULL) { - FreePool (gRedfishDiscoveredToken); - } } /** @@ -498,25 +481,9 @@ RedfishConfigHandlerDriverUnload ( IN EFI_HANDLE ImageHandle ) { - EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken; - UINTN NumberOfNetworkInterfacesIndex; - RedfishConfigDriverCommonUnload (ImageHandle); RedfishConfigStopRedfishDiscovery (); - if (gRedfishDiscoveredToken != NULL) { - ThisRedfishDiscoveredToken = gRedfishDiscoveredToken; - for (NumberOfNetworkInterfacesIndex = 0; NumberOfNetworkInterfacesIndex < gNumberOfNetworkInterfaces; NumberOfNetworkInterfacesIndex++) { - if (ThisRedfishDiscoveredToken->Event != NULL) { - gBS->CloseEvent (ThisRedfishDiscoveredToken->Event); - } - - FreePool (ThisRedfishDiscoveredToken); - ThisRedfishDiscoveredToken++; - } - - gRedfishDiscoveredToken = NULL; - } return EFI_SUCCESS; } diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c index 583c6f78e1..0900a2479e 100644 --- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c +++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c @@ -1095,8 +1095,11 @@ RedfishServiceGetNetworkInterface ( { EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface; + EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; - if ((NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) || (ImageHandle == NULL)) { + if ((This == NULL) || (NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) || + (ImageHandle == NULL)) + { return EFI_INVALID_PARAMETER; } @@ -1107,12 +1110,26 @@ RedfishServiceGetNetworkInterface ( return EFI_NOT_FOUND; } + RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (This); + + // + // Check the new found network interface. + // + if (RestExInstance->NetworkInterfaceInstances != NULL) { + FreePool (RestExInstance->NetworkInterfaceInstances); + RestExInstance->NetworkInterfaceInstances = NULL; + } + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface); if (ThisNetworkInterface == NULL) { return EFI_OUT_OF_RESOURCES; } - *NetworkIntfInstances = ThisNetworkInterface; + *NetworkIntfInstances = ThisNetworkInterface; + + RestExInstance->NetworkInterfaceInstances = ThisNetworkInterface; + RestExInstance->NumberOfNetworkInterfaces = 0; + ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); while (TRUE) { ThisNetworkInterface->IsIpv6 = FALSE; @@ -1130,7 +1147,7 @@ RedfishServiceGetNetworkInterface ( ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength; ThisNetworkInterface->VlanId = ThisNetworkInterfaceIntn->VlanId; - (*NumberOfNetworkIntfs)++; + RestExInstance->NumberOfNetworkInterfaces++; if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) { break; } @@ -1139,6 +1156,8 @@ RedfishServiceGetNetworkInterface ( ThisNetworkInterface++; } + *NumberOfNetworkIntfs = RestExInstance->NumberOfNetworkInterfaces; + return EFI_SUCCESS; } @@ -1178,7 +1197,6 @@ RedfishServiceAcquireService ( { EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance; EFI_STATUS Status1; - EFI_STATUS Status2; BOOLEAN NewInstance; UINTN NumNetworkInterfaces; UINTN NetworkInterfacesIndex; @@ -1215,7 +1233,6 @@ RedfishServiceAcquireService ( for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex++) { Status1 = EFI_SUCCESS; - Status2 = EFI_SUCCESS; NewInstance = FALSE; Instance = GetInstanceByOwner (ImageHandle, TargetNetworkInterfaceInternal, Flags & ~EFI_REDFISH_DISCOVER_VALIDATION); // Check if we can re-use previous instance. if (Instance == NULL) { @@ -1223,6 +1240,7 @@ RedfishServiceAcquireService ( Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE)); if (Instance == NULL) { DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __func__)); + return EFI_OUT_OF_RESOURCES; } InitializeListHead (&Instance->Entry); @@ -1258,9 +1276,12 @@ RedfishServiceAcquireService ( DEBUG ((DEBUG_ERROR, "%a:Redfish service discovery through SSDP is not supported\n", __func__)); return EFI_UNSUPPORTED; } else { - if (EFI_ERROR (Status1) && EFI_ERROR (Status2)) { - FreePool ((VOID *)Instance); - DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%x, Status2=%x.\n", __func__, Status1, Status2)); + if (EFI_ERROR (Status1)) { + if (NewInstance) { + FreePool ((VOID *)Instance); + } + + DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1)); } else { if (NewInstance) { InsertTailList (&mRedfishDiscoverList, &Instance->Entry); @@ -1387,13 +1408,6 @@ ReleaseNext:; } } -EFI_REDFISH_DISCOVER_PROTOCOL mRedfishDiscover = { - RedfishServiceGetNetworkInterface, - RedfishServiceAcquireService, - RedfishServiceAbortAcquire, - RedfishServiceReleaseService -}; - /** This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the given network interface. @@ -1713,12 +1727,20 @@ BuildupNetworkInterface ( NewNetworkInterfaceInstalled = FALSE; NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL; - Status = gBS->InstallProtocolInterface ( - &NetworkInterface->EfiRedfishDiscoverProtocolHandle, - &gEfiRedfishDiscoverProtocolGuid, - EFI_NATIVE_INTERFACE, - (VOID *)&mRedfishDiscover - ); + + RestExInstance->Signature = EFI_REDFISH_DISCOVER_DATA_SIGNATURE; + + RestExInstance->RedfishDiscoverProtocol.GetNetworkInterfaceList = RedfishServiceGetNetworkInterface; + RestExInstance->RedfishDiscoverProtocol.AcquireRedfishService = RedfishServiceAcquireService; + RestExInstance->RedfishDiscoverProtocol.AbortAcquireRedfishService = RedfishServiceAbortAcquire; + RestExInstance->RedfishDiscoverProtocol.ReleaseRedfishService = RedfishServiceReleaseService; + + Status = gBS->InstallProtocolInterface ( + &NetworkInterface->EfiRedfishDiscoverProtocolHandle, + &gEfiRedfishDiscoverProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID *)&RestExInstance->RedfishDiscoverProtocol + ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __func__)); } @@ -1815,6 +1837,7 @@ StopServiceOnNetworkInterface ( EFI_HANDLE DiscoverProtocolHandle; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; + EFI_REDFISH_DISCOVER_PROTOCOL *RedfishDiscoverProtocol; for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) { Status = gBS->HandleProtocol ( @@ -1854,12 +1877,28 @@ StopServiceOnNetworkInterface ( // client which uses .EFI Redfish discover protocol. // if (DiscoverProtocolHandle != NULL) { - gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL); - Status = gBS->UninstallProtocolInterface ( + Status = gBS->HandleProtocol ( DiscoverProtocolHandle, &gEfiRedfishDiscoverProtocolGuid, - (VOID *)&mRedfishDiscover + (VOID **)&RedfishDiscoverProtocol ); + if (!EFI_ERROR (Status)) { + RestExInstance = EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL (RedfishDiscoverProtocol); + // + // Stop Redfish service discovery. + // + RedfishDiscoverProtocol->AbortAcquireRedfishService ( + RedfishDiscoverProtocol, + RestExInstance->NetworkInterfaceInstances + ); + + gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL); + Status = gBS->UninstallProtocolInterface ( + DiscoverProtocolHandle, + &gEfiRedfishDiscoverProtocolGuid, + (VOID *)&RestExInstance->RedfishDiscoverProtocol + ); + } } return Status; diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h index 2704cd955d..d24c4081d9 100644 --- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h +++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h @@ -117,17 +117,31 @@ typedef struct { ///< on this network interface. } EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL; +// +// Redfish Discover Instance signature +// + +#define EFI_REDFISH_DISCOVER_DATA_SIGNATURE SIGNATURE_32 ('E', 'R', 'D', 'D') + +#define EFI_REDFISH_DISOVER_DATA_FROM_DISCOVER_PROTOCOL(a) \ + CR (a, EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL, RedfishDiscoverProtocol, EFI_REDFISH_DISCOVER_DATA_SIGNATURE) + // // Internal structure used to maintain REST EX properties. // typedef struct { - LIST_ENTRY Entry; ///< Link list entry. - EFI_HANDLE OpenDriverAgentHandle; ///< The agent to open network protocol. - EFI_HANDLE OpenDriverControllerHandle; ///< The controller handle to open network protocol. - EFI_HANDLE RestExChildHandle; ///< The child handle created through REST EX Service Protocol. - EFI_HANDLE RestExControllerHandle; ///< The controller handle which provide REST EX protocol. - EFI_REST_EX_PROTOCOL *RestExProtocolInterface; ///< Pointer to EFI_REST_EX_PROTOCOL. - UINT32 RestExId; ///< The identifier installed on REST EX controller handle. + LIST_ENTRY Entry; ///< Link list entry. + UINT32 Signature; ///< Instance signature. + EFI_HANDLE OpenDriverAgentHandle; ///< The agent to open network protocol. + EFI_HANDLE OpenDriverControllerHandle; ///< The controller handle to open network protocol. + EFI_HANDLE RestExChildHandle; ///< The child handle created through REST EX Service Protocol. + EFI_HANDLE RestExControllerHandle; ///< The controller handle which provide REST EX protocol. + EFI_REST_EX_PROTOCOL *RestExProtocolInterface; ///< Pointer to EFI_REST_EX_PROTOCOL. + UINT32 RestExId; ///< The identifier installed on REST EX controller handle. + UINTN NumberOfNetworkInterfaces; ///< Number of network interfaces can do Redfish service discovery. + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *NetworkInterfaceInstances; ///< Network interface instances. It's an array of instances. The number of entries + ///< in array is indicated by NumberOfNetworkInterfaces. + EFI_REDFISH_DISCOVER_PROTOCOL RedfishDiscoverProtocol; ///< EFI_REDFISH_DISCOVER_PROTOCOL protocol. } EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL; /**