123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073 |
- /** @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;
- 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;
- 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;
- }
|