1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077 |
- /** @file
- The implementation of EFI Redfidh Discover Protocol.
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
- Copyright (c) 2022, AMD Incorporated. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "RedfishDiscoverInternal.h"
- LIST_ENTRY mRedfishDiscoverList;
- LIST_ENTRY mRedfishInstanceList;
- EFI_SMBIOS_PROTOCOL *mSmbios = NULL;
- UINTN mNumNetworkInterface = 0;
- UINTN mNumRestExInstance = 0;
- LIST_ENTRY mEfiRedfishDiscoverNetworkInterface;
- LIST_ENTRY mEfiRedfishDiscoverRestExInstance;
- EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID;
- EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;
- EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;
- EFI_STATUS
- EFIAPI
- Tcp4GetSubnetInfo (
- IN EFI_HANDLE ImageHandle,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
- );
- EFI_STATUS
- EFIAPI
- Tcp6GetSubnetInfo (
- IN EFI_HANDLE ImageHandle,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
- );
- static REDFISH_DISCOVER_REQUIRED_PROTOCOL gRequiredProtocol[] = {
- {
- ProtocolTypeTcp4,
- L"TCP4 Service Binding Protocol",
- &gEfiTcp4ProtocolGuid,
- &gEfiTcp4ServiceBindingProtocolGuid,
- &mRedfishDiscoverTcp4InstanceGuid,
- Tcp4GetSubnetInfo
- },
- {
- ProtocolTypeTcp6,
- L"TCP6 Service Binding Protocol",
- &gEfiTcp6ProtocolGuid,
- &gEfiTcp6ServiceBindingProtocolGuid,
- &mRedfishDiscoverTcp6InstanceGuid,
- Tcp6GetSubnetInfo
- },
- {
- ProtocolTypeRestEx,
- L"REST EX Service Binding Protocol",
- &gEfiRestExProtocolGuid,
- &gEfiRestExServiceBindingProtocolGuid,
- &mRedfishDiscoverRestExInstanceGuid,
- NULL
- }
- };
- /**
- This function creates REST EX instance for the found Resfish service.
- by known owner handle.
- @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
- @param[in] Token Client token.
- @retval NULL Instance not found.
- @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.
- **/
- EFI_STATUS
- CreateRestExInstance (
- IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance,
- IN EFI_REDFISH_DISCOVERED_TOKEN *Token
- )
- {
- EFI_STATUS Status;
- Status = RestExLibCreateChild (
- Instance->Owner,
- FixedPcdGetBool (PcdRedfishDiscoverAccessModeInBand) ? EfiRestExServiceInBandAccess : EfiRestExServiceOutOfBandAccess,
- EfiRestExConfigHttp,
- EfiRestExServiceRedfish,
- &Token->DiscoverList.RedfishInstances->Information.RedfishRestExHandle
- );
- return Status;
- }
- /**
- This function gets EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
- by known owner handle.
- @param[in] ImageHandle Image handle owns EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
- @param[in] TargetNetworkInterface Target network interface used by this EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
- @param[in] DiscoverFlags EFI_REDFISH_DISCOVER_FLAG
- @retval NULL Instance not found.
- @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner.
- **/
- EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *
- GetInstanceByOwner (
- IN EFI_HANDLE ImageHandle,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterface,
- IN EFI_REDFISH_DISCOVER_FLAG DiscoverFlags
- )
- {
- EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *ThisInstance;
- if (IsListEmpty (&mRedfishDiscoverList)) {
- return NULL;
- }
- ThisInstance =
- (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetFirstNode (&mRedfishDiscoverList);
- while (TRUE) {
- if ((ThisInstance->Owner == ImageHandle) &&
- (ThisInstance->DiscoverFlags == DiscoverFlags) &&
- (ThisInstance->NetworkInterface == TargetNetworkInterface))
- {
- return ThisInstance;
- }
- if (IsNodeAtEnd (&mRedfishDiscoverList, &ThisInstance->Entry)) {
- break;
- }
- ThisInstance =
- (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetNextNode (&mRedfishDiscoverList, &ThisInstance->Entry);
- }
- return NULL;
- }
- /**
- This function gets the subnet information of this TCP4 instance.
- @param[in] ImageHandle EFI handle with this image.
- @param[in] Instance Instance of Network interface.
- @retval EFI_STATUS Get subnet information successfully.
- @retval Otherwise Fail to get subnet information.
- **/
- EFI_STATUS
- EFIAPI
- Tcp4GetSubnetInfo (
- IN EFI_HANDLE ImageHandle,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
- )
- {
- EFI_STATUS Status;
- EFI_TCP4_PROTOCOL *Tcp4;
- EFI_TCP4_CONFIG_DATA Tcp4CfgData;
- EFI_TCP4_OPTION Tcp4Option;
- EFI_IP4_MODE_DATA IpModedata;
- UINT8 SubnetMaskIndex;
- UINT8 BitMask;
- UINT8 PrefixLength;
- BOOLEAN GotPrefixLength;
- if (Instance == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Tcp4 = (EFI_TCP4_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
- ZeroMem ((VOID *)&Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));
- ZeroMem ((VOID *)&Tcp4Option, sizeof (EFI_TCP4_OPTION));
- // Give a local host IP address just for getting subnet information.
- Tcp4CfgData.AccessPoint.UseDefaultAddress = TRUE;
- Tcp4CfgData.AccessPoint.RemoteAddress.Addr[0] = 127;
- Tcp4CfgData.AccessPoint.RemoteAddress.Addr[1] = 0;
- Tcp4CfgData.AccessPoint.RemoteAddress.Addr[2] = 0;
- Tcp4CfgData.AccessPoint.RemoteAddress.Addr[3] = 1;
- Tcp4CfgData.AccessPoint.RemotePort = 80;
- Tcp4CfgData.AccessPoint.ActiveFlag = TRUE;
- Tcp4CfgData.ControlOption = &Tcp4Option;
- Tcp4Option.ReceiveBufferSize = 65535;
- Tcp4Option.SendBufferSize = 65535;
- Tcp4Option.MaxSynBackLog = 5;
- Tcp4Option.ConnectionTimeout = 60;
- Tcp4Option.DataRetries = 12;
- Tcp4Option.FinTimeout = 2;
- Tcp4Option.KeepAliveProbes = 6;
- Tcp4Option.KeepAliveTime = 7200;
- Tcp4Option.KeepAliveInterval = 30;
- Tcp4Option.EnableNagle = TRUE;
- Status = Tcp4->Configure (Tcp4, &Tcp4CfgData);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Can't get subnet information\n", __FUNCTION__));
- return Status;
- }
- Status = Tcp4->GetModeData (Tcp4, NULL, NULL, &IpModedata, NULL, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __FUNCTION__));
- return Status;
- }
- IP4_COPY_ADDRESS (&Instance->SubnetMask, &IpModedata.ConfigData.SubnetMask);
- Instance->SubnetAddr.v4.Addr[0] = IpModedata.ConfigData.StationAddress.Addr[0] & Instance->SubnetMask.v4.Addr[0];
- Instance->SubnetAddr.v4.Addr[1] = IpModedata.ConfigData.StationAddress.Addr[1] & Instance->SubnetMask.v4.Addr[1];
- Instance->SubnetAddr.v4.Addr[2] = IpModedata.ConfigData.StationAddress.Addr[2] & Instance->SubnetMask.v4.Addr[2];
- Instance->SubnetAddr.v4.Addr[3] = IpModedata.ConfigData.StationAddress.Addr[3] & Instance->SubnetMask.v4.Addr[3];
- //
- // Calculate the subnet mask prefix.
- //
- GotPrefixLength = FALSE;
- PrefixLength = 0;
- SubnetMaskIndex = 0;
- while (GotPrefixLength == FALSE && SubnetMaskIndex < 4) {
- BitMask = 0x80;
- while (BitMask != 0) {
- if ((Instance->SubnetMask.v4.Addr[SubnetMaskIndex] & BitMask) != 0) {
- PrefixLength++;
- } else {
- GotPrefixLength = TRUE;
- break;
- }
- BitMask = BitMask >> 1;
- }
- SubnetMaskIndex++;
- }
- Instance->SubnetPrefixLength = PrefixLength;
- return EFI_SUCCESS;
- }
- /**
- This function gets the subnet information of this TCP6 instance.
- @param[in] ImageHandle EFI handle with this image.
- @param[in] Instance Instance of Network interface.
- @retval EFI_STATUS Get subnet information successfully.
- @retval Otherwise Fail to get subnet information.
- **/
- EFI_STATUS
- EFIAPI
- Tcp6GetSubnetInfo (
- IN EFI_HANDLE ImageHandle,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance
- )
- {
- EFI_STATUS Status;
- EFI_TCP6_PROTOCOL *Tcp6;
- EFI_IP6_MODE_DATA IpModedata;
- if (Instance == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Tcp6 = (EFI_TCP6_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
- ZeroMem ((VOID *)&IpModedata, sizeof (EFI_IP6_MODE_DATA));
- Status = Tcp6->GetModeData (Tcp6, NULL, NULL, &IpModedata, NULL, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __FUNCTION__));
- return Status;
- }
- if (IpModedata.AddressCount == 0) {
- DEBUG ((DEBUG_INFO, "%a: No IPv6 address configured.\n", __FUNCTION__));
- }
- if (Instance->SubnetAddrInfoIPv6 != NULL) {
- FreePool (Instance->SubnetAddrInfoIPv6);
- }
- Instance->SubnetAddrInfoIPv6 = AllocateZeroPool (IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO));
- if (Instance->SubnetAddrInfoIPv6 == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory for IPv6 subnet address information\n", __FUNCTION__));
- return EFI_OUT_OF_RESOURCES;
- }
- Instance->SubnetAddrInfoIPv6Number = IpModedata.AddressCount;
- if ((IpModedata.AddressCount != 0) && (IpModedata.AddressList != NULL)) {
- CopyMem (
- (VOID *)Instance->SubnetAddrInfoIPv6,
- (VOID *)&IpModedata.AddressList,
- IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO)
- );
- FreePool (IpModedata.AddressList);
- }
- return EFI_SUCCESS;
- }
- /**
- This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
- instance with the given EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
- @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
- NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.
- @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 *
- GetTargetNetworkInterfaceInternal (
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface
- )
- {
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- while (TRUE) {
- if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {
- return ThisNetworkInterface;
- }
- if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
- return NULL;
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
- }
- 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.
- @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE.
- NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs.
- @param[in] Flags EFI_REDFISH_DISCOVER_FLAG
- @retval EFI_SUCCESS Target network interface is ready to use.
- @retval EFI_UNSUPPORTED Target network interface is not ready to use.
- **/
- EFI_STATUS
- ValidateTargetNetworkInterface (
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,
- IN EFI_REDFISH_DISCOVER_FLAG Flags
- )
- {
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
- if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) && (TargetNetworkInterface == NULL)) {
- return EFI_UNSUPPORTED;
- }
- if (TargetNetworkInterface == NULL) {
- return EFI_SUCCESS; // Return EFI_SUCCESS if no network interface is specified.
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- while (TRUE) {
- if (CompareMem ((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) {
- break;
- }
- if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
- return EFI_UNSUPPORTED;
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
- }
- if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
- // Validate if UDP4/6 is supported on the given network interface.
- // SSDP is not supported.
- return EFI_SUCCESS;
- }
- if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == NULL) {
- return EFI_UNSUPPORTED; // The required protocol on this network interface is not found.
- }
- return EFI_SUCCESS;
- }
- /**
- This function returns number of network interface instance.
- @retval UINTN Number of network interface instances.
- **/
- UINTN
- NumberOfNetworkInterface (
- VOID
- )
- {
- UINTN Num;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
- if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
- return 0;
- }
- Num = 1;
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- while (TRUE) {
- if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
- break;
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
- Num++;
- }
- return Num;
- }
- /**
- This function checks the IP version supported on this
- netwoek interface.
- @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
- @retval TRUE Is IPv6, otherwise IPv4.
- **/
- BOOLEAN
- CheckIsIpVersion6 (
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface
- )
- {
- if (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) {
- return TRUE;
- }
- return FALSE;
- }
- /**
- This function discover Redfish service through SMBIOS host interface.
- @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE
- @retval EFI_SUCCESS Redfish service is discovered through SMBIOS Host interface.
- @retval Others Fail to discover Redfish service throught SMBIOS host interface
- **/
- EFI_STATUS
- DiscoverRedfishHostInterface (
- IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance
- )
- {
- EFI_STATUS Status;
- REDFISH_OVER_IP_PROTOCOL_DATA *Data;
- REDFISH_INTERFACE_DATA *DeviceDescriptor;
- CHAR8 UuidStr[sizeof "00000000-0000-0000-0000-000000000000" + 1];
- CHAR16 Ipv6Str[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
- CHAR8 RedfishServiceLocateStr[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1];
- UINTN StrSize;
- UINTN MacCompareStstus;
- BOOLEAN IsHttps;
- Data = NULL;
- DeviceDescriptor = NULL;
- if (mSmbios == NULL) {
- Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h
- if (!EFI_ERROR (Status) && (Data != NULL) && (DeviceDescriptor != NULL)) {
- //
- // Chceck if we can reach out Redfish service using this network interface.
- // Check with MAC address using Device Descroptor Data Device Type 04 and Type 05.
- // Those two types of Redfish host interface device has MAC information.
- //
- if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
- MacCompareStstus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6);
- } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) {
- MacCompareStstus = CompareMem (&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6);
- } else {
- return EFI_UNSUPPORTED;
- }
- if (MacCompareStstus != 0) {
- return EFI_UNSUPPORTED;
- }
- if (Data->RedfishServiceIpAddressFormat == 1) {
- IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress);
- } else {
- IP6_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v6, (VOID *)Data->RedfishServiceIpAddress);
- }
- if (Instance->HostIntfValidation) {
- DEBUG ((DEBUG_ERROR, "%a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported.\n", __FUNCTION__));
- Status = EFI_UNSUPPORTED;
- } else {
- //
- // Add this istance to list without detial information of Redfish
- // service.
- //
- IsHttps = FALSE;
- if (Data->RedfishServiceIpPort == 443) {
- IsHttps = TRUE;
- }
- StrSize = sizeof (UuidStr);
- AsciiSPrint (UuidStr, StrSize, "%g", &Data->ServiceUuid);
- //
- // Generate Redfish service location string.
- //
- if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) {
- NetLibIp6ToStr ((IPv6_ADDRESS *)&Data->RedfishServiceIpAddress, Ipv6Str, sizeof (Ipv6Str));
- if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
- AsciiSPrintUnicodeFormat (
- RedfishServiceLocateStr,
- sizeof (RedfishServiceLocateStr),
- L"%s",
- Ipv6Str
- );
- } else {
- AsciiSPrintUnicodeFormat (
- RedfishServiceLocateStr,
- sizeof (RedfishServiceLocateStr),
- L"[%s]:%d",
- Ipv6Str,
- Data->RedfishServiceIpPort
- );
- }
- } else {
- if ((Data->RedfishServiceIpPort == 0) || (IsHttps == TRUE)) {
- AsciiSPrint (
- RedfishServiceLocateStr,
- sizeof (RedfishServiceLocateStr),
- "%d.%d.%d.%d",
- Data->RedfishServiceIpAddress[0],
- Data->RedfishServiceIpAddress[1],
- Data->RedfishServiceIpAddress[2],
- Data->RedfishServiceIpAddress[3]
- );
- } else {
- AsciiSPrint (
- RedfishServiceLocateStr,
- sizeof (RedfishServiceLocateStr),
- "%d.%d.%d.%d:%d",
- Data->RedfishServiceIpAddress[0],
- Data->RedfishServiceIpAddress[1],
- Data->RedfishServiceIpAddress[2],
- Data->RedfishServiceIpAddress[3],
- Data->RedfishServiceIpPort
- );
- }
- }
- Status = AddAndSignalNewRedfishService (
- Instance,
- NULL,
- RedfishServiceLocateStr,
- UuidStr,
- NULL,
- NULL,
- NULL,
- NULL,
- IsHttps
- );
- }
- }
- return Status;
- }
- /**
- The function adds a new found Redfish service to internal list and
- notify client.
- @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.
- @param[in] RedfishVersion Redfish version.
- @param[in] RedfishLocation Redfish location.
- @param[in] Uuid Service UUID string.
- @param[in] Os OS string.
- @param[in] OsVer OS version string.
- @param[in] Product Product string.
- @param[in] ProductVer Product verison string.
- @param[in] UseHttps Redfish service requires secured connection.
- @retval EFI_SUCCESS Redfish service is added to list successfully.
- **/
- EFI_STATUS
- AddAndSignalNewRedfishService (
- IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance,
- IN UINTN *RedfishVersion OPTIONAL,
- IN CHAR8 *RedfishLocation OPTIONAL,
- IN CHAR8 *Uuid OPTIONAL,
- IN CHAR8 *Os OPTIONAL,
- IN CHAR8 *OsVer OPTIONAL,
- IN CHAR8 *Product OPTIONAL,
- IN CHAR8 *ProductVer OPTIONAL,
- IN BOOLEAN UseHttps
- )
- {
- BOOLEAN NewFound;
- BOOLEAN InfoRefresh;
- BOOLEAN RestExOpened;
- BOOLEAN DeleteRestEx;
- EFI_STATUS Status;
- EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredList;
- EFI_REDFISH_DISCOVERED_INSTANCE *DiscoveredInstance;
- CHAR16 *Char16Uuid;
- EFI_REST_EX_PROTOCOL *RestEx;
- EFI_REST_EX_HTTP_CONFIG_DATA *RestExHttpConfigData;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface;
- NewFound = TRUE;
- InfoRefresh = FALSE;
- Char16Uuid = NULL;
- RestExOpened = FALSE;
- DeleteRestEx = FALSE;
- DEBUG ((DEBUG_INFO, "%a:Add this instance to Redfish instance list.\n", __FUNCTION__));
- if (Uuid != NULL) {
- Char16Uuid = (CHAR16 *)AllocateZeroPool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, Char16Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
- }
- DiscoveredList = NULL;
- DiscoveredInstance = NULL;
- RestExHttpConfigData = NULL;
- NetworkInterface = Instance->NetworkInterface;
- if (!IsListEmpty (&mRedfishInstanceList)) {
- //
- // Is this a duplicate redfish service.
- //
- DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
- NewFound = FALSE;
- do {
- if ((Char16Uuid == NULL) || (DiscoveredList->Instance->Information.Uuid == NULL)) {
- //
- // Check if this Redfish instance already found using IP addrress.
- //
- if (!CheckIsIpVersion6 (NetworkInterface)) {
- if (CompareMem (
- (VOID *)&Instance->TargetIpAddress.v4,
- (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v4,
- sizeof (EFI_IPv4_ADDRESS)
- ) == 0)
- {
- DiscoveredInstance = DiscoveredList->Instance;
- if ((DiscoveredList->Instance->Information.Uuid == NULL) &&
- (Char16Uuid != NULL))
- {
- InfoRefresh = TRUE;
- DiscoveredInstance = DiscoveredList->Instance;
- DEBUG ((DEBUG_INFO, "*** This Redfish Service information refresh ***\n"));
- }
- break;
- }
- } else {
- if (CompareMem (
- (VOID *)&Instance->TargetIpAddress.v6,
- (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v6,
- sizeof (EFI_IPv6_ADDRESS)
- ) == 0)
- {
- DiscoveredInstance = DiscoveredList->Instance;
- break;
- }
- }
- } else {
- //
- // Check if this Redfish instance already found using UUID.
- //
- if (StrCmp ((const CHAR16 *)Char16Uuid, (const CHAR16 *)DiscoveredList->Instance->Information.Uuid) == 0) {
- DiscoveredInstance = DiscoveredList->Instance;
- break;
- }
- }
- if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredList->NextInstance)) {
- NewFound = TRUE;
- break;
- }
- DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredList->NextInstance);
- } while (TRUE);
- }
- if (NewFound || InfoRefresh) {
- if (!InfoRefresh) {
- DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_LIST));
- if (DiscoveredList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- InitializeListHead (&DiscoveredList->NextInstance);
- DiscoveredInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
- if (DiscoveredInstance == NULL) {
- FreePool ((VOID *)DiscoveredList);
- return EFI_OUT_OF_RESOURCES;
- }
- }
- DEBUG ((DEBUG_INFO, "*** Redfish Service Information ***\n"));
- DiscoveredInstance->Information.UseHttps = UseHttps;
- if (RedfishVersion != NULL) {
- DiscoveredInstance->Information.RedfishVersion = *RedfishVersion;
- DEBUG ((DEBUG_INFO, "Redfish service version: %d.\n", DiscoveredInstance->Information.RedfishVersion));
- }
- if (RedfishLocation != NULL) {
- DiscoveredInstance->Information.Location = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)RedfishLocation, DiscoveredInstance->Information.Location, AsciiStrSize ((const CHAR8 *)RedfishLocation) * sizeof (CHAR16));
- DEBUG ((DEBUG_INFO, "Redfish service location: %s.\n", DiscoveredInstance->Information.Location));
- }
- if (Uuid != NULL) {
- DiscoveredInstance->Information.Uuid = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, DiscoveredInstance->Information.Uuid, AsciiStrSize ((const CHAR8 *)Uuid) * sizeof (CHAR16));
- DEBUG ((DEBUG_INFO, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
- }
- if (Os != NULL) {
- DiscoveredInstance->Information.Os = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)Os, DiscoveredInstance->Information.Os, AsciiStrSize ((const CHAR8 *)Os) * sizeof (CHAR16));
- DEBUG ((DEBUG_INFO, "Redfish service OS: %s, Version:%s.\n", DiscoveredInstance->Information.Os, DiscoveredInstance->Information.OsVersion));
- }
- if (OsVer != NULL) {
- DiscoveredInstance->Information.OsVersion = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)OsVer, DiscoveredInstance->Information.OsVersion, AsciiStrSize ((const CHAR8 *)OsVer) * sizeof (CHAR16));
- }
- if ((Product != NULL) && (ProductVer != NULL)) {
- DiscoveredInstance->Information.Product = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)Product, DiscoveredInstance->Information.Product, AsciiStrSize ((const CHAR8 *)Product) * sizeof (CHAR16));
- DiscoveredInstance->Information.ProductVer = (CHAR16 *)AllocatePool (AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));
- AsciiStrToUnicodeStrS ((const CHAR8 *)ProductVer, DiscoveredInstance->Information.ProductVer, AsciiStrSize ((const CHAR8 *)ProductVer) * sizeof (CHAR16));
- DEBUG ((DEBUG_INFO, "Redfish service product: %s, Version:%s.\n", DiscoveredInstance->Information.Product, DiscoveredInstance->Information.ProductVer));
- }
- if (RedfishLocation == NULL) {
- // This is the Redfish reported from SMBIOS 42h
- // without validation.
- IP4_COPY_ADDRESS ((VOID *)&DiscoveredInstance->Information.RedfishHostIpAddress.v4, (VOID *)&Instance->TargetIpAddress.v4);
- }
- if (!InfoRefresh) {
- DiscoveredList->Instance = DiscoveredInstance;
- InsertTailList (&mRedfishInstanceList, &DiscoveredList->NextInstance);
- }
- DiscoveredInstance->Status = EFI_SUCCESS;
- } else {
- if (DiscoveredList != NULL) {
- DEBUG ((DEBUG_INFO, "*** This Redfish Service was already found ***\n"));
- if (DiscoveredInstance->Information.Uuid != NULL) {
- DEBUG ((DEBUG_INFO, "Service UUID: %s.\n", DiscoveredInstance->Information.Uuid));
- } else {
- DEBUG ((DEBUG_INFO, "Service UUID: unknown.\n"));
- }
- }
- }
- if (Char16Uuid != NULL) {
- FreePool ((VOID *)Char16Uuid);
- }
- Status = EFI_SUCCESS;
- if (NewFound || InfoRefresh) {
- //
- // Build up EFI_REDFISH_DISCOVERED_LIST in token.
- //
- Instance->DiscoverToken->DiscoverList.NumberOfServiceFound = 1;
- Instance->DiscoverToken->DiscoverList.RedfishInstances = DiscoveredInstance;
- DiscoveredInstance->Status = EFI_SUCCESS;
- if (!InfoRefresh) {
- Status = CreateRestExInstance (Instance, Instance->DiscoverToken); // Create REST EX child.
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:Can't create REST EX child instance.\n", __FUNCTION__));
- goto ON_EXIT;
- }
- Status = gBS->OpenProtocol (
- // Configure local host information.
- Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
- &gEfiRestExProtocolGuid,
- (VOID **)&RestEx,
- Instance->NetworkInterface->OpenDriverAgentHandle,
- Instance->NetworkInterface->OpenDriverControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- DeleteRestEx = TRUE;
- goto ERROR_EXIT;
- }
- RestExOpened = TRUE;
- RestExHttpConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA));
- if (RestExHttpConfigData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- DeleteRestEx = TRUE;
- goto EXIT_FREE_CONFIG_DATA;
- }
- RestExHttpConfigData->SendReceiveTimeout = 5000;
- RestExHttpConfigData->HttpConfigData.HttpVersion = HttpVersion11;
- RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6 = CheckIsIpVersion6 (NetworkInterface);
- if (RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6) {
- RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT));
- if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto EXIT_FREE_CONFIG_DATA;
- }
- } else {
- RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT));
- if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto EXIT_FREE_CONFIG_DATA;
- }
- RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = TRUE;
- }
- Status = RestEx->Configure (
- RestEx,
- (EFI_REST_EX_CONFIG_DATA)(UINT8 *)RestExHttpConfigData
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:REST EX configured..\n", __FUNCTION__));
- DeleteRestEx = TRUE;
- goto EXIT_FREE_ALL;
- }
- //
- // Signal client, close REST EX before signaling client.
- //
- if (RestExOpened) {
- gBS->CloseProtocol (
- Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
- &gEfiRestExProtocolGuid,
- Instance->NetworkInterface->OpenDriverAgentHandle,
- Instance->NetworkInterface->OpenDriverControllerHandle
- );
- RestExOpened = FALSE;
- }
- }
- Status = gBS->SignalEvent (Instance->DiscoverToken->Event);
- if (!EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:No event to signal!\n", __FUNCTION__));
- }
- }
- EXIT_FREE_ALL:;
- if ((RestExHttpConfigData != NULL) && (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node != NULL)) {
- FreePool (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node);
- }
- EXIT_FREE_CONFIG_DATA:;
- if (RestExHttpConfigData != NULL) {
- FreePool ((VOID *)RestExHttpConfigData);
- }
- if (RestExOpened) {
- gBS->CloseProtocol (
- Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
- &gEfiRestExProtocolGuid,
- Instance->NetworkInterface->OpenDriverAgentHandle,
- Instance->NetworkInterface->OpenDriverControllerHandle
- );
- }
- ERROR_EXIT:;
- if (DeleteRestEx && RestExOpened) {
- gBS->CloseProtocol (
- Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle,
- &gEfiRestExProtocolGuid,
- Instance->NetworkInterface->OpenDriverAgentHandle,
- Instance->NetworkInterface->OpenDriverControllerHandle
- );
- }
- ON_EXIT:;
- return Status;
- }
- /**
- This function gets the subnet information of this network interface instance.
- can discover Redfish service on it.
- @param[in] Instance EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.
- @param[in] ImageHandle EFI Image handle request the network interface list.
- @retval EFI_SUCCESS
- **/
- EFI_STATUS
- NetworkInterfaceGetSubnetInfo (
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance,
- IN EFI_HANDLE ImageHandle
- )
- {
- EFI_STATUS Status;
- UINT32 ProtocolType;
- UINT32 IPv6InfoIndex;
- EFI_IP6_ADDRESS_INFO *ThisSubnetAddrInfoIPv6;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface;
- if (Instance->GotSubnetInfo) {
- return EFI_SUCCESS;
- }
- ProtocolType = Instance->NetworkProtocolType;
- if ((gRequiredProtocol[ProtocolType].GetSubnetInfo != NULL) && (Instance->GotSubnetInfo == FALSE)) {
- Status = gRequiredProtocol[ProtocolType].GetSubnetInfo (
- ImageHandle,
- Instance
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a:Faile to get Subnet infomation.\n", __FUNCTION__));
- return Status;
- } else {
- DEBUG ((DEBUG_INFO, "%a:MAC address: %s\n", __FUNCTION__, Instance->StrMacAddr));
- if (CheckIsIpVersion6 (Instance)) {
- if (Instance->SubnetAddrInfoIPv6Number == 0) {
- DEBUG ((DEBUG_ERROR, "%a: There is no Subnet infomation for IPv6 network interface.\n", __FUNCTION__));
- return EFI_NOT_FOUND;
- }
- ThisSubnetAddrInfoIPv6 = Instance->SubnetAddrInfoIPv6; // First IPv6 address information.
- IP6_COPY_ADDRESS (&Instance->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
- Instance->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
- DEBUG ((
- DEBUG_INFO,
- " IPv6 Subnet ID:%d, Prefix length: %d.\n",
- ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
- ThisSubnetAddrInfoIPv6->PrefixLength
- )
- );
- //
- // If this is IPv6, then we may have to propagate network interface for IPv6 network scopes
- // according to the Ipv6 address information.
- //
- ThisSubnetAddrInfoIPv6++;
- for (IPv6InfoIndex = 0; IPv6InfoIndex < Instance->SubnetAddrInfoIPv6Number - 1; IPv6InfoIndex++) {
- //
- // Build up addtional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances.
- //
- NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));
- if (NewNetworkInterface != NULL) {
- CopyMem ((VOID *)NewNetworkInterface, (VOID *)Instance, sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); // Clone information of first instance.
- IP6_COPY_ADDRESS (&NewNetworkInterface->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address);
- NewNetworkInterface->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength;
- NewNetworkInterface->GotSubnetInfo = TRUE;
- InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NewNetworkInterface->Entry);
- ThisSubnetAddrInfoIPv6++;
- mNumNetworkInterface++;
- DEBUG ((
- DEBUG_INFO,
- " IPv6 Subnet ID:%d, Prefix length: %d.\n",
- ThisSubnetAddrInfoIPv6->Address.Addr[7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr[6] * 256,
- ThisSubnetAddrInfoIPv6->PrefixLength
- )
- );
- } else {
- return EFI_OUT_OF_RESOURCES;
- }
- }
- } else {
- DEBUG ((
- DEBUG_INFO,
- " IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d.\n",
- Instance->SubnetAddr.v4.Addr[0],
- Instance->SubnetAddr.v4.Addr[1],
- Instance->SubnetAddr.v4.Addr[2],
- Instance->SubnetAddr.v4.Addr[3],
- Instance->SubnetMask.v4.Addr[0],
- Instance->SubnetMask.v4.Addr[1],
- Instance->SubnetMask.v4.Addr[2],
- Instance->SubnetMask.v4.Addr[3]
- ));
- }
- }
- }
- Instance->GotSubnetInfo = TRUE; // Only try to get Subnet Info once.
- return EFI_SUCCESS;
- }
- /**
- This function gets the network interface list which Redfish discover protocol
- can discover Redfish service on it.
- @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
- @param[in] ImageHandle EFI Image handle request the network interface list,
- @param[out] NumberOfNetworkIntfs Number of network interfaces can do Redfish service discovery.
- @param[out] NetworkIntfInstances Network interface instances. It's an array of instance. The number of entries
- in array is indicated by NumberOfNetworkIntfs.
- Caller has to release the memory
- allocated by Redfish discover protocol.
- @retval EFI_SUCCESS The information of network interface is returned in NumberOfNetworkIntfs and
- NetworkIntfInstances.
- @retval Others Fail to return the information of network interface.
- **/
- EFI_STATUS
- EFIAPI
- RedfishServiceGetNetworkInterface (
- IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
- IN EFI_HANDLE ImageHandle,
- OUT UINTN *NumberOfNetworkIntfs,
- OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances
- )
- {
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;
- if ((NetworkIntfInstances == NULL) || (NumberOfNetworkIntfs == NULL) || (ImageHandle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- *NumberOfNetworkIntfs = 0;
- *NetworkIntfInstances = NULL;
- if (IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
- return EFI_NOT_FOUND;
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface);
- if (ThisNetworkInterface == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- *NetworkIntfInstances = ThisNetworkInterface;
- ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- while (TRUE) {
- ThisNetworkInterface->IsIpv6 = FALSE;
- if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) {
- ThisNetworkInterface->IsIpv6 = TRUE;
- }
- CopyMem ((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize);
- NetworkInterfaceGetSubnetInfo (ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info.
- if (!ThisNetworkInterface->IsIpv6) {
- IP4_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information.
- } else {
- IP6_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v6, &ThisNetworkInterfaceIntn->SubnetAddr.v6); // IPv6 subnet information in IPv6 address information.
- }
- ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength;
- ThisNetworkInterface->VlanId = ThisNetworkInterfaceIntn->VlanId;
- (*NumberOfNetworkIntfs)++;
- if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) {
- break;
- }
- ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry);
- ThisNetworkInterface++;
- }
- return EFI_SUCCESS;
- }
- /**
- This function acquires Redfish services by discovering static Redfish setting
- according to Redfish Host Interface or through SSDP. Returns a list of EFI
- handles in EFI_REDFISH_DISCOVERED_LIST. Each of EFI handle has cooresponding
- EFI REST EX instance installed on it. Each REST EX isntance is a child instance which
- created through EFI REST EX serivce protoocl for communicating with specific
- Redfish service.
- @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
- @param[in] ImageHandle EFI image owns these Redfish service instances.
- @param[in] TargetNetworkInterface Target network interface to do the discovery.
- NULL means discover Redfish service on all network interfaces on platform.
- @param[in] Flags Redfish service discover flags.
- @param[in] Token EFI_REDFISH_DISCOVERED_TOKEN instance.
- The memory of EFI_REDFISH_DISCOVERED_LIST and the strings in
- EFI_REDFISH_DISCOVERED_INFORMATION are all allocated by Acquire()
- and must be freed when caller invoke Release().
- @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned.
- @retval EFI_INVALID_PARAMETERS ImageHandle == NULL, Flags == 0, Token == NULL, Token->Timeout > 5,
- or Token->Event == NULL.
- @retval Others Fail acquire Redfish services.
- **/
- EFI_STATUS
- EFIAPI
- RedfishServiceAcquireService (
- IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
- IN EFI_HANDLE ImageHandle,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface,
- IN EFI_REDFISH_DISCOVER_FLAG Flags,
- IN EFI_REDFISH_DISCOVERED_TOKEN *Token
- )
- {
- EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance;
- EFI_STATUS Status1;
- EFI_STATUS Status2;
- BOOLEAN NewInstance;
- UINTN NumNetworkInterfaces;
- UINTN NetworkInterfacesIndex;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterfaceInternal;
- DEBUG ((DEBUG_INFO, "%a:Entry.\n", __FUNCTION__));
- //
- // Validate parameters.
- //
- if ((ImageHandle == NULL) || (Token == NULL) || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) {
- DEBUG ((DEBUG_ERROR, "%a:Invalid parameters.\n", __FUNCTION__));
- return EFI_INVALID_PARAMETER;
- }
- //
- // Validate target network interface.
- //
- if (EFI_ERROR (ValidateTargetNetworkInterface (TargetNetworkInterface, Flags))) {
- return EFI_UNSUPPORTED;
- }
- if (TargetNetworkInterface != NULL) {
- TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface);
- NumNetworkInterfaces = 1;
- } else {
- TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- NumNetworkInterfaces = NumberOfNetworkInterface ();
- if (NumNetworkInterfaces == 0) {
- DEBUG ((DEBUG_ERROR, "%a:No network interface on platform.\n", __FUNCTION__));
- return EFI_UNSUPPORTED;
- }
- }
- 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) {
- DEBUG ((DEBUG_INFO, "%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __FUNCTION__));
- Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE));
- if (Instance == NULL) {
- DEBUG ((DEBUG_ERROR, "%a:Memory allocation fail.\n", __FUNCTION__));
- }
- InitializeListHead (&Instance->Entry);
- Instance->Owner = ImageHandle;
- Instance->DiscoverFlags = Flags & ~EFI_REDFISH_DISCOVER_VALIDATION;
- Instance->NetworkInterface = TargetNetworkInterfaceInternal;
- //
- // Get subnet information in case subnet information is not set because
- // RedfishServiceGetNetworkInterfaces hasn't been called yet.
- //
- NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle);
- NewInstance = TRUE;
- }
- if (TargetNetworkInterfaceInternal->StrMacAddr != NULL) {
- DEBUG ((DEBUG_INFO, "%a:Acquire Redfish service on network interface MAC address:%s.\n", __FUNCTION__, TargetNetworkInterfaceInternal->StrMacAddr));
- } else {
- DEBUG ((DEBUG_INFO, "%a:WARNING: No MAC address on this network interface.\n", __FUNCTION__));
- }
- Instance->DiscoverToken = Token; // Always use the latest Token passed by caller.
- if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) {
- DEBUG ((DEBUG_INFO, "%a:Redfish HOST interface discovery.\n", __FUNCTION__));
- Instance->HostIntfValidation = FALSE;
- if ((Flags & EFI_REDFISH_DISCOVER_VALIDATION) != 0) {
- Instance->HostIntfValidation = TRUE;
- }
- Status1 = DiscoverRedfishHostInterface (Instance); // Discover Redfish service through Redfish Host Interface.
- }
- if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) {
- DEBUG ((DEBUG_ERROR, "%a:Redfish service discovery through SSDP is not supported\n", __FUNCTION__));
- 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", __FUNCTION__, Status1, Status2));
- } else {
- if (NewInstance) {
- InsertTailList (&mRedfishDiscoverList, &Instance->Entry);
- }
- }
- }
- if (TargetNetworkInterface == NULL) {
- //
- // Discover Redfish services on all of network interfaces.
- //
- TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &TargetNetworkInterfaceInternal->Entry);
- }
- }
- return EFI_SUCCESS;
- }
- /**
- This function aborts Redfish service discovery on the given network interface.
- @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
- @param[in] TargetNetworkInterface Target network interface to do the discovery.
- @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned.
- @retval Others Fail to abort Redfish service discovery.
- **/
- EFI_STATUS
- EFIAPI
- RedfishServiceAbortAcquire (
- IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface OPTIONAL
- )
- {
- // This function is used to abort Redfish service discovery through SSDP
- // on the network interface. SSDP is optionally supprted by EFI_REDFISH_DISCOVER_PROTOCOL,
- // we dont have implementation for SSDP now.
- return EFI_UNSUPPORTED;
- }
- /**
- This function releases Redfish services found by RedfishServiceAcquire().
- @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance.
- @param[in] InstanceList The Redfish service to release.
- @retval EFI_SUCCESS REST EX instances of discovered Redfish are released.
- @retval Others Fail to remove the entry
- **/
- EFI_STATUS
- EFIAPI
- RedfishServiceReleaseService (
- IN EFI_REDFISH_DISCOVER_PROTOCOL *This,
- IN EFI_REDFISH_DISCOVERED_LIST *InstanceList
- )
- {
- UINTN NumService;
- BOOLEAN AnyFailRelease;
- EFI_REDFISH_DISCOVERED_INSTANCE *ThisRedfishInstance;
- EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredRedfishInstance;
- if (IsListEmpty (&mRedfishInstanceList)) {
- DEBUG ((DEBUG_ERROR, "%a:No any discovered Redfish service.\n", __FUNCTION__));
- return EFI_NOT_FOUND;
- }
- AnyFailRelease = FALSE;
- ThisRedfishInstance = InstanceList->RedfishInstances;
- for (NumService = 0; NumService < InstanceList->NumberOfServiceFound; NumService++) {
- DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList);
- do {
- if (DiscoveredRedfishInstance->Instance == ThisRedfishInstance) {
- RemoveEntryList (&DiscoveredRedfishInstance->NextInstance);
- if (ThisRedfishInstance->Information.Location != NULL) {
- FreePool (ThisRedfishInstance->Information.Location);
- }
- if (ThisRedfishInstance->Information.Uuid != NULL) {
- FreePool (ThisRedfishInstance->Information.Uuid);
- }
- if (ThisRedfishInstance->Information.Os != NULL) {
- FreePool (ThisRedfishInstance->Information.Os);
- }
- if (ThisRedfishInstance->Information.OsVersion != NULL) {
- FreePool (ThisRedfishInstance->Information.OsVersion);
- }
- if (ThisRedfishInstance->Information.Product != NULL) {
- FreePool (ThisRedfishInstance->Information.Product);
- }
- if (ThisRedfishInstance->Information.ProductVer != NULL) {
- FreePool (ThisRedfishInstance->Information.ProductVer);
- }
- FreePool ((VOID *)ThisRedfishInstance);
- goto ReleaseNext;
- }
- if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance)) {
- break;
- }
- DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance);
- } while (TRUE);
- AnyFailRelease = TRUE;
- ReleaseNext:;
- //
- // Release next discovered Redfish Service.
- //
- ThisRedfishInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)((UINT8 *)ThisRedfishInstance + sizeof (EFI_REDFISH_DISCOVERED_INSTANCE));
- }
- if (AnyFailRelease) {
- return EFI_NOT_FOUND;
- } else {
- return EFI_SUCCESS;
- }
- }
- EFI_REDFISH_DISCOVER_PROTOCOL mRedfishDiscover = {
- RedfishServiceGetNetworkInterface,
- RedfishServiceAcquireService,
- RedfishServiceAbortAcquire,
- RedfishServiceReleaseService
- };
- /**
- This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the
- given network interface.
- @param[in] ControllerHandle MAC address of this network interface.
- @param[in] NetworkProtocolType Network protocol type.
- @param[out] IsNewInstance BOOLEAN means new instance or not.
- @param[out] NetworkInterface Pointer to to EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL.
- @retval EFI_STATUS
- **/
- EFI_STATUS
- CreateRedfishDiscoverNetworkInterface (
- IN EFI_HANDLE ControllerHandle,
- IN UINT32 NetworkProtocolType,
- OUT BOOLEAN *IsNewInstance,
- OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL **NetworkInterface
- )
- {
- EFI_MAC_ADDRESS MacAddress;
- UINTN HwAddressSize;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface;
- NetLibGetMacAddress (ControllerHandle, &MacAddress, &HwAddressSize);
- NewNetworkInterface = NULL;
- *IsNewInstance = TRUE;
- if (!IsListEmpty ((const LIST_ENTRY *)&mEfiRedfishDiscoverNetworkInterface)) {
- //
- // Check if this instance already exist.
- //
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- if (ThisNetworkInterface != NULL) {
- while (TRUE) {
- if ((CompareMem ((CONST VOID *)&ThisNetworkInterface->MacAddress.Addr, (CONST VOID *)&MacAddress.Addr, HwAddressSize) == 0) &&
- (ThisNetworkInterface->NetworkProtocolType == NetworkProtocolType))
- {
- NewNetworkInterface = ThisNetworkInterface;
- *IsNewInstance = FALSE;
- break;
- }
- if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
- NewNetworkInterface = NULL;
- break;
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
- }
- }
- }
- if (NewNetworkInterface == NULL) {
- //
- // Create a new instance.
- //
- NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL));
- if (NewNetworkInterface == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- NewNetworkInterface->HwAddressSize = HwAddressSize;
- CopyMem (&NewNetworkInterface->MacAddress.Addr, &MacAddress.Addr, NewNetworkInterface->HwAddressSize);
- NetLibGetMacString (ControllerHandle, NULL, &NewNetworkInterface->StrMacAddr);
- NewNetworkInterface->VlanId = NetLibGetVlanId (ControllerHandle);
- }
- *NetworkInterface = NewNetworkInterface;
- return EFI_SUCCESS;
- }
- /**
- This function destory network interface
- @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance.
- @retval EFI_STATUS
- **/
- EFI_STATUS
- DestroyRedfishNetwrokInterface (
- IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface
- )
- {
- EFI_STATUS Status;
- Status = gBS->UninstallProtocolInterface (
- ThisNetworkInterface->OpenDriverControllerHandle,
- gRequiredProtocol[ThisNetworkInterface->NetworkProtocolType].DiscoveredProtocolGuid,
- &ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId
- );
- RemoveEntryList (&ThisNetworkInterface->Entry);
- mNumNetworkInterface--;
- FreePool (ThisNetworkInterface);
- return Status;
- }
- /**
- Tests to see if the required protocols are provided on the given
- controller handle.
- @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.
- @retval EFI_SUCCESS One of required protocol is found.
- @retval EFI_UNSUPPORTED None of required protocol is found.
- **/
- EFI_STATUS
- TestForRequiredProtocols (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle
- )
- {
- UINT32 Id;
- UINTN Index;
- EFI_STATUS Status;
- for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {
- Status = gBS->OpenProtocol (
- ControllerHandle,
- gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- ControllerHandle,
- gRequiredProtocol[Index].DiscoveredProtocolGuid,
- (VOID **)&Id,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: %s is found on this controller handle.\n", __FUNCTION__, gRequiredProtocol[Index].ProtocolName));
- return EFI_SUCCESS;
- }
- }
- }
- return EFI_UNSUPPORTED;
- }
- /**
- Build up network interface and create corresponding service through the given
- controller handle.
- @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.
- @retval EFI_SUCCESS One of required protocol is found.
- @retval EFI_UNSUPPORTED None of required protocol is found.
- @retval EFI_UNSUPPORTED Failed to build up network interface.
- **/
- EFI_STATUS
- BuildupNetworkInterface (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle
- )
- {
- UINT32 Id;
- UINT32 Index;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface;
- BOOLEAN IsNew;
- EFI_STATUS Status;
- VOID *TempInterface;
- VOID **Interface;
- UINT32 *ProtocolDiscoverIdPtr;
- EFI_HANDLE OpenDriverAgentHandle;
- EFI_HANDLE OpenDriverControllerHandle;
- EFI_HANDLE *HandleOfProtocolInterfacePtr;
- EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
- EFI_TPL OldTpl;
- BOOLEAN NewNetworkInterfaceInstalled;
- NewNetworkInterfaceInstalled = FALSE;
- Index = 0;
- do {
- Status = gBS->OpenProtocol (
- // Already in list?
- ControllerHandle,
- gRequiredProtocol[Index].DiscoveredProtocolGuid,
- (VOID **)&Id,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- Index++;
- if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
- break;
- }
- continue;
- }
- Status = gBS->OpenProtocol (
- ControllerHandle,
- gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
- &TempInterface,
- This->DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- Index++;
- if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
- break;
- }
- continue;
- }
- if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
- OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
- Status = CreateRedfishDiscoverNetworkInterface (ControllerHandle, gRequiredProtocol[Index].ProtocolType, &IsNew, &NetworkInterface);
- if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- NetworkInterface->NetworkProtocolType = gRequiredProtocol[Index].ProtocolType;
- NetworkInterface->OpenDriverAgentHandle = This->DriverBindingHandle;
- NetworkInterface->OpenDriverControllerHandle = ControllerHandle;
- NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid = \
- *gRequiredProtocol[Index].RequiredProtocolGuid;
- NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolServiceGuid = \
- *gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid;
- ProtocolDiscoverIdPtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId;
- OpenDriverAgentHandle = NetworkInterface->OpenDriverAgentHandle;
- OpenDriverControllerHandle = NetworkInterface->OpenDriverControllerHandle;
- HandleOfProtocolInterfacePtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle;
- Interface = &NetworkInterface->NetworkInterfaceProtocolInfo.NetworkProtocolInterface;
- NewNetworkInterfaceInstalled = TRUE;
- if (IsNew) {
- InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NetworkInterface->Entry);
- mNumNetworkInterface++;
- }
- gBS->RestoreTPL (OldTpl);
- } else {
- // Record REST_EX instance. REST_EX is created when clinet asks for Redfish service discovery.
- // Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
- // when discovery.
- RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL));
- if (RestExInstance == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- RestExInstance->OpenDriverAgentHandle = This->DriverBindingHandle;
- RestExInstance->OpenDriverControllerHandle = ControllerHandle;
- RestExInstance->RestExControllerHandle = ControllerHandle;
- InitializeListHead (&RestExInstance->Entry);
- InsertTailList (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
- mNumRestExInstance++;
- ProtocolDiscoverIdPtr = &RestExInstance->RestExId;
- OpenDriverAgentHandle = RestExInstance->OpenDriverAgentHandle;
- OpenDriverControllerHandle = RestExInstance->OpenDriverControllerHandle;
- HandleOfProtocolInterfacePtr = &RestExInstance->RestExChildHandle;
- Interface = (VOID **)&RestExInstance->RestExProtocolInterface;
- }
- Status = gBS->InstallProtocolInterface (
- &ControllerHandle,
- gRequiredProtocol[Index].DiscoveredProtocolGuid,
- EFI_NATIVE_INTERFACE,
- ProtocolDiscoverIdPtr
- );
- if (EFI_ERROR (Status)) {
- Index++;
- if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
- break;
- }
- continue;
- }
- //
- // Create service binding child and open it BY_DRIVER.
- //
- Status = NetLibCreateServiceChild (
- ControllerHandle,
- This->ImageHandle,
- gRequiredProtocol[Index].RequiredServiceBindingProtocolGuid,
- HandleOfProtocolInterfacePtr
- );
- if (!EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- *HandleOfProtocolInterfacePtr,
- gRequiredProtocol[Index].RequiredProtocolGuid,
- Interface,
- OpenDriverAgentHandle,
- OpenDriverControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (!EFI_ERROR (Status)) {
- 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__));
- }
- }
- }
- return Status;
- } else {
- Index++;
- if (Index == (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL))) {
- break;
- }
- continue;
- }
- } while (Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)));
- return EFI_UNSUPPORTED;
- }
- /**
- Close the protocol opened for Redfish discovery. This function also destories
- the network services.
- @param[in] ThisBindingProtocol 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] ThisRequiredProtocol Pointer to the instance of REDFISH_DISCOVER_REQUIRED_PROTOCOL.
- @param[in] DriverAgentHandle Driver agent handle which used to open protocol earlier.
- @param[in] DriverControllerHandle Driver controller handle which used to open protocol earlier.
- @retval EFI_SUCCESS Prorocol is closed successfully.
- @retval Others Prorocol is closed unsuccessfully.
- **/
- EFI_STATUS
- CloseProtocolService (
- IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,
- IN EFI_HANDLE ControllerHandle,
- IN REDFISH_DISCOVER_REQUIRED_PROTOCOL *ThisRequiredProtocol,
- IN EFI_HANDLE DriverAgentHandle,
- IN EFI_HANDLE DriverControllerHandle
- )
- {
- EFI_STATUS Status;
- Status = gBS->CloseProtocol (
- ControllerHandle,
- ThisRequiredProtocol->RequiredProtocolGuid,
- DriverAgentHandle,
- DriverControllerHandle
- );
- if (!EFI_ERROR (Status)) {
- NetLibDestroyServiceChild (
- ControllerHandle,
- ThisBindingProtocol->ImageHandle,
- ThisRequiredProtocol->RequiredServiceBindingProtocolGuid,
- ControllerHandle
- );
- }
- return Status;
- }
- /**
- Stop the services on network interface.
- @param[in] ThisBindingProtocol 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.
- @retval EFI_SUCCESS One of required protocol is found.
- @retval Others Faile to stop the services on network interface.
- **/
- EFI_STATUS
- StopServiceOnNetworkInterface (
- IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol,
- IN EFI_HANDLE ControllerHandle
- )
- {
- UINT32 Index;
- 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;
- for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index++) {
- Status = gBS->HandleProtocol (
- ControllerHandle,
- gRequiredProtocol[Index].RequiredProtocolGuid,
- (VOID **)&Interface
- );
- if (!EFI_ERROR (Status)) {
- if (gRequiredProtocol[Index].ProtocolType != ProtocolTypeRestEx) {
- if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
- return EFI_NOT_FOUND;
- }
- OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
- 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 (
- ThisBindingProtocol,
- ControllerHandle,
- &gRequiredProtocol[Index],
- ThisNetworkInterface->OpenDriverAgentHandle,
- ThisNetworkInterface->OpenDriverControllerHandle
- );
- if (!EFI_ERROR (Status)) {
- Status = DestroyRedfishNetwrokInterface (ThisNetworkInterface);
- }
- gBS->RestoreTPL (OldTpl);
- //
- // 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;
- }
- if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
- break;
- }
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
- }
- gBS->RestoreTPL (OldTpl);
- } else {
- if (IsListEmpty (&mEfiRedfishDiscoverRestExInstance)) {
- return EFI_NOT_FOUND;
- }
- OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL);
- RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverRestExInstance);
- while (TRUE) {
- if (RestExInstance->RestExChildHandle == ControllerHandle) {
- Status = CloseProtocolService (
- // Close REST_EX protocol.
- ThisBindingProtocol,
- ControllerHandle,
- &gRequiredProtocol[Index],
- RestExInstance->OpenDriverAgentHandle,
- RestExInstance->OpenDriverControllerHandle
- );
- RemoveEntryList (&RestExInstance->Entry);
- FreePool ((VOID *)RestExInstance);
- mNumRestExInstance--;
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
- if (IsNodeAtEnd (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry)) {
- break;
- }
- RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry);
- }
- gBS->RestoreTPL (OldTpl);
- }
- }
- }
- return EFI_NOT_FOUND;
- }
- /**
- 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().
- Because 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.
- Currently not implemented.
- @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
- RemainingDevicePath is not supported by the driver specified by This.
- **/
- EFI_STATUS
- EFIAPI
- RedfishDiscoverDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
- )
- {
- return TestForRequiredProtocols (This, ControllerHandle);
- }
- /**
- 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.Currently not implemented.
- @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
- RedfishDiscoverDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
- )
- {
- return BuildupNetworkInterface (This, ControllerHandle);
- }
- /**
- 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
- RedfishDiscoverDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
- )
- {
- return StopServiceOnNetworkInterface (This, ControllerHandle);
- }
- EFI_DRIVER_BINDING_PROTOCOL gRedfishDiscoverDriverBinding = {
- RedfishDiscoverDriverBindingSupported,
- RedfishDiscoverDriverBindingStart,
- RedfishDiscoverDriverBindingStop,
- REDFISH_DISCOVER_VERSION,
- NULL,
- NULL
- };
- /**
- This is the declaration of an EFI image entry point.
- @param ImageHandle The firmware allocated handle for the UEFI image.
- @param SystemTable A pointer to the EFI System Table.
- @retval EFI_SUCCESS The operation completed successfully.
- @retval Others An unexpected error occurred.
- **/
- EFI_STATUS
- EFIAPI
- RedfishDiscoverEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- Status = EFI_SUCCESS;
- InitializeListHead (&mRedfishDiscoverList);
- InitializeListHead (&mRedfishInstanceList);
- InitializeListHead (&mEfiRedfishDiscoverNetworkInterface);
- InitializeListHead (&mEfiRedfishDiscoverRestExInstance);
- //
- // Install binding protoocl to obtain UDP and REST EX protocol.
- //
- Status = EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &gRedfishDiscoverDriverBinding,
- ImageHandle,
- &gRedfishDiscoverComponentName,
- &gRedfishDiscoverComponentName2
- );
- return Status;
- }
- /**
- This is the unload handle for Redfish discover module.
- Disconnect the driver specified by ImageHandle from all the devices in the handle database.
- Uninstall all the protocols installed in the driver entry point.
- @param[in] ImageHandle The drivers' driver image.
- @retval EFI_SUCCESS The image is unloaded.
- @retval Others Failed to unload the image.
- **/
- EFI_STATUS
- EFIAPI
- RedfishDiscoverUnload (
- IN EFI_HANDLE ImageHandle
- )
- {
- EFI_STATUS Status;
- EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
- Status = EFI_SUCCESS;
- // Destroy all network interfaces found by EFI Redfish Discover driver and
- // stop services created for Redfish Discover.
- while (!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) {
- ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
- StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);
- }
- return Status;
- }
|