123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607 |
- /** @file
- Miscellaneous routines for iSCSI driver.
- Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "IScsiImpl.h"
- GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 IScsiHexString[] = "0123456789ABCDEFabcdef";
- /**
- Removes (trims) specified leading and trailing characters from a string.
- @param[in, out] Str Pointer to the null-terminated string to be trimmed.
- On return, Str will hold the trimmed string.
- @param[in] CharC Character will be trimmed from str.
- **/
- VOID
- IScsiStrTrim (
- IN OUT CHAR16 *Str,
- IN CHAR16 CharC
- )
- {
- CHAR16 *Pointer1;
- CHAR16 *Pointer2;
- if (*Str == 0) {
- return;
- }
- //
- // Trim off the leading and trailing characters c
- //
- for (Pointer1 = Str; (*Pointer1 != 0) && (*Pointer1 == CharC); Pointer1++) {
- }
- Pointer2 = Str;
- if (Pointer2 == Pointer1) {
- while (*Pointer1 != 0) {
- Pointer2++;
- Pointer1++;
- }
- } else {
- while (*Pointer1 != 0) {
- *Pointer2 = *Pointer1;
- Pointer1++;
- Pointer2++;
- }
- *Pointer2 = 0;
- }
- for (Pointer1 = Str + StrLen (Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {
- }
- if (Pointer1 != Str + StrLen (Str) - 1) {
- *(Pointer1 + 1) = 0;
- }
- }
- /**
- Calculate the prefix length of the IPv4 subnet mask.
- @param[in] SubnetMask The IPv4 subnet mask.
- @return The prefix length of the subnet mask.
- @retval 0 Other errors as indicated.
- **/
- UINT8
- IScsiGetSubnetMaskPrefixLength (
- IN EFI_IPv4_ADDRESS *SubnetMask
- )
- {
- UINT8 Len;
- UINT32 ReverseMask;
- //
- // The SubnetMask is in network byte order.
- //
- ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);
- //
- // Reverse it.
- //
- ReverseMask = ~ReverseMask;
- if ((ReverseMask & (ReverseMask + 1)) != 0) {
- return 0;
- }
- Len = 0;
- while (ReverseMask != 0) {
- ReverseMask = ReverseMask >> 1;
- Len++;
- }
- return (UINT8)(32 - Len);
- }
- /**
- Convert the hexadecimal encoded LUN string into the 64-bit LUN.
- @param[in] Str The hexadecimal encoded LUN string.
- @param[out] Lun Storage to return the 64-bit LUN.
- @retval EFI_SUCCESS The 64-bit LUN is stored in Lun.
- @retval EFI_INVALID_PARAMETER The string is malformatted.
- **/
- EFI_STATUS
- IScsiAsciiStrToLun (
- IN CHAR8 *Str,
- OUT UINT8 *Lun
- )
- {
- UINTN Index, IndexValue, IndexNum, SizeStr;
- CHAR8 TemStr[2];
- UINT8 TemValue;
- UINT16 Value[4];
- ZeroMem (Lun, 8);
- ZeroMem (TemStr, 2);
- ZeroMem ((UINT8 *)Value, sizeof (Value));
- SizeStr = AsciiStrLen (Str);
- IndexValue = 0;
- IndexNum = 0;
- for (Index = 0; Index < SizeStr; Index++) {
- TemStr[0] = Str[Index];
- TemValue = (UINT8)AsciiStrHexToUint64 (TemStr);
- if ((TemValue == 0) && (TemStr[0] != '0')) {
- if ((TemStr[0] != '-') || (IndexNum == 0)) {
- //
- // Invalid Lun Char.
- //
- return EFI_INVALID_PARAMETER;
- }
- }
- if ((TemValue == 0) && (TemStr[0] == '-')) {
- //
- // Next Lun value.
- //
- if (++IndexValue >= 4) {
- //
- // Max 4 Lun value.
- //
- return EFI_INVALID_PARAMETER;
- }
- //
- // Restart str index for the next lun value.
- //
- IndexNum = 0;
- continue;
- }
- if (++IndexNum > 4) {
- //
- // Each Lun Str can't exceed size 4, because it will be as UINT16 value.
- //
- return EFI_INVALID_PARAMETER;
- }
- //
- // Combine UINT16 value.
- //
- Value[IndexValue] = (UINT16)((Value[IndexValue] << 4) + TemValue);
- }
- for (Index = 0; Index <= IndexValue; Index++) {
- *((UINT16 *)&Lun[Index * 2]) = HTONS (Value[Index]);
- }
- return EFI_SUCCESS;
- }
- /**
- Convert the 64-bit LUN into the hexadecimal encoded LUN string.
- @param[in] Lun The 64-bit LUN.
- @param[out] Str The storage to return the hexadecimal encoded LUN string.
- **/
- VOID
- IScsiLunToUnicodeStr (
- IN UINT8 *Lun,
- OUT CHAR16 *Str
- )
- {
- UINTN Index;
- CHAR16 *TempStr;
- TempStr = Str;
- for (Index = 0; Index < 4; Index++) {
- if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {
- CopyMem (TempStr, L"0-", sizeof (L"0-"));
- } else {
- TempStr[0] = (CHAR16)IScsiHexString[Lun[2 * Index] >> 4];
- TempStr[1] = (CHAR16)IScsiHexString[Lun[2 * Index] & 0x0F];
- TempStr[2] = (CHAR16)IScsiHexString[Lun[2 * Index + 1] >> 4];
- TempStr[3] = (CHAR16)IScsiHexString[Lun[2 * Index + 1] & 0x0F];
- TempStr[4] = L'-';
- TempStr[5] = 0;
- IScsiStrTrim (TempStr, L'0');
- }
- TempStr += StrLen (TempStr);
- }
- //
- // Remove the last '-'
- //
- ASSERT (StrLen (Str) >= 1);
- Str[StrLen (Str) - 1] = 0;
- for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {
- if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {
- Str[Index - 1] = 0;
- } else {
- break;
- }
- }
- }
- /**
- Convert the formatted IP address into the binary IP address.
- @param[in] Str The UNICODE string.
- @param[in] IpMode Indicates whether the IP address is v4 or v6.
- @param[out] Ip The storage to return the ASCII string.
- @retval EFI_SUCCESS The binary IP address is returned in Ip.
- @retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is
- invalid.
- **/
- EFI_STATUS
- IScsiAsciiStrToIp (
- IN CHAR8 *Str,
- IN UINT8 IpMode,
- OUT EFI_IP_ADDRESS *Ip
- )
- {
- EFI_STATUS Status;
- if ((IpMode == IP_MODE_IP4) || (IpMode == IP_MODE_AUTOCONFIG_IP4)) {
- return NetLibAsciiStrToIp4 (Str, &Ip->v4);
- } else if ((IpMode == IP_MODE_IP6) || (IpMode == IP_MODE_AUTOCONFIG_IP6)) {
- return NetLibAsciiStrToIp6 (Str, &Ip->v6);
- } else if (IpMode == IP_MODE_AUTOCONFIG) {
- Status = NetLibAsciiStrToIp4 (Str, &Ip->v4);
- if (!EFI_ERROR (Status)) {
- return Status;
- }
- return NetLibAsciiStrToIp6 (Str, &Ip->v6);
- }
- return EFI_INVALID_PARAMETER;
- }
- /**
- Convert the mac address into a hexadecimal encoded "-" separated string.
- @param[in] Mac The mac address.
- @param[in] Len Length in bytes of the mac address.
- @param[in] VlanId VLAN ID of the network device.
- @param[out] Str The storage to return the mac string.
- **/
- VOID
- IScsiMacAddrToStr (
- IN EFI_MAC_ADDRESS *Mac,
- IN UINT32 Len,
- IN UINT16 VlanId,
- OUT CHAR16 *Str
- )
- {
- UINT32 Index;
- CHAR16 *String;
- for (Index = 0; Index < Len; Index++) {
- Str[3 * Index] = (CHAR16)IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];
- Str[3 * Index + 1] = (CHAR16)IScsiHexString[Mac->Addr[Index] & 0x0F];
- Str[3 * Index + 2] = L':';
- }
- String = &Str[3 * Index - 1];
- if (VlanId != 0) {
- String += UnicodeSPrint (String, 6 * sizeof (CHAR16), L"\\%04x", (UINTN)VlanId);
- }
- *String = L'\0';
- }
- /**
- Convert the binary encoded buffer into a hexadecimal encoded string.
- @param[in] BinBuffer The buffer containing the binary data.
- @param[in] BinLength Length of the binary buffer.
- @param[in, out] HexStr Pointer to the string.
- @param[in, out] HexLength The length of the string.
- @retval EFI_SUCCESS The binary data is converted to the hexadecimal string
- and the length of the string is updated.
- @retval EFI_BUFFER_TOO_SMALL The string is too small.
- @retval EFI_BAD_BUFFER_SIZE BinLength is too large for hex encoding.
- @retval EFI_INVALID_PARAMETER The IP string is malformatted.
- **/
- EFI_STATUS
- IScsiBinToHex (
- IN UINT8 *BinBuffer,
- IN UINT32 BinLength,
- IN OUT CHAR8 *HexStr,
- IN OUT UINT32 *HexLength
- )
- {
- UINT32 HexLengthMin;
- UINT32 HexLengthProvided;
- UINT32 Index;
- if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Safely calculate: HexLengthMin := BinLength * 2 + 3.
- //
- if (RETURN_ERROR (SafeUint32Mult (BinLength, 2, &HexLengthMin)) ||
- RETURN_ERROR (SafeUint32Add (HexLengthMin, 3, &HexLengthMin)))
- {
- return EFI_BAD_BUFFER_SIZE;
- }
- HexLengthProvided = *HexLength;
- *HexLength = HexLengthMin;
- if (HexLengthProvided < HexLengthMin) {
- return EFI_BUFFER_TOO_SMALL;
- }
- //
- // Prefix for Hex String.
- //
- HexStr[0] = '0';
- HexStr[1] = 'x';
- for (Index = 0; Index < BinLength; Index++) {
- HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];
- HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];
- }
- HexStr[Index * 2 + 2] = '\0';
- return EFI_SUCCESS;
- }
- /**
- Convert the hexadecimal string into a binary encoded buffer.
- @param[in, out] BinBuffer The binary buffer.
- @param[in, out] BinLength Length of the binary buffer.
- @param[in] HexStr The hexadecimal string.
- @retval EFI_SUCCESS The hexadecimal string is converted into a
- binary encoded buffer.
- @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
- @retval EFI_BAD_BUFFER_SIZE The length of HexStr is too large for decoding:
- the decoded size cannot be expressed in
- BinLength on output.
- @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the
- converted data.
- **/
- EFI_STATUS
- IScsiHexToBin (
- IN OUT UINT8 *BinBuffer,
- IN OUT UINT32 *BinLength,
- IN CHAR8 *HexStr
- )
- {
- UINTN BinLengthMin;
- UINT32 BinLengthProvided;
- UINTN Index;
- UINTN Length;
- UINT8 Digit;
- CHAR8 TemStr[2];
- ZeroMem (TemStr, sizeof (TemStr));
- //
- // Find out how many hex characters the string has.
- //
- if ((HexStr[0] == '0') && ((HexStr[1] == 'x') || (HexStr[1] == 'X'))) {
- HexStr += 2;
- }
- Length = AsciiStrLen (HexStr);
- //
- // Reject an empty hex string; reject a stray nibble.
- //
- if ((Length == 0) || (Length % 2 != 0)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Check if the caller provides enough room for the decoded blob.
- //
- BinLengthMin = Length / 2;
- if (BinLengthMin > MAX_UINT32) {
- return EFI_BAD_BUFFER_SIZE;
- }
- BinLengthProvided = *BinLength;
- *BinLength = (UINT32)BinLengthMin;
- if (BinLengthProvided < BinLengthMin) {
- return EFI_BUFFER_TOO_SMALL;
- }
- for (Index = 0; Index < Length; Index++) {
- TemStr[0] = HexStr[Index];
- Digit = (UINT8)AsciiStrHexToUint64 (TemStr);
- if ((Digit == 0) && (TemStr[0] != '0')) {
- //
- // Invalid Hex Char.
- //
- return EFI_INVALID_PARAMETER;
- }
- if ((Index & 1) == 0) {
- BinBuffer[Index/2] = Digit;
- } else {
- BinBuffer[Index/2] = (UINT8)((BinBuffer[Index/2] << 4) + Digit);
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Convert the decimal-constant string or hex-constant string into a numerical value.
- @param[in] Str String in decimal or hex.
- @return The numerical value.
- **/
- UINTN
- IScsiNetNtoi (
- IN CHAR8 *Str
- )
- {
- if ((Str[0] == '0') && ((Str[1] == 'x') || (Str[1] == 'X'))) {
- Str += 2;
- return AsciiStrHexToUintn (Str);
- }
- return AsciiStrDecimalToUintn (Str);
- }
- /**
- Generate random numbers.
- @param[in, out] Rand The buffer to contain random numbers.
- @param[in] RandLength The length of the Rand buffer.
- **/
- VOID
- IScsiGenRandom (
- IN OUT UINT8 *Rand,
- IN UINTN RandLength
- )
- {
- UINT32 Random;
- while (RandLength > 0) {
- Random = NET_RANDOM (NetRandomInitSeed ());
- *Rand++ = (UINT8)(Random);
- RandLength--;
- }
- }
- /**
- Check whether UNDI protocol supports IPv6.
- @param[in] ControllerHandle Controller handle.
- @param[in] Image Handle of the image.
- @param[out] Ipv6Support TRUE if UNDI supports IPv6.
- @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
- @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.
- **/
- EFI_STATUS
- IScsiCheckIpv6Support (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE Image,
- OUT BOOLEAN *Ipv6Support
- )
- {
- EFI_HANDLE Handle;
- EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
- EFI_STATUS Status;
- EFI_GUID *InfoTypesBuffer;
- UINTN InfoTypeBufferCount;
- UINTN TypeIndex;
- BOOLEAN Supported;
- VOID *InfoBlock;
- UINTN InfoBlockSize;
- EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
- ASSERT (Ipv6Support != NULL);
- //
- // Check whether the UNDI supports IPv6 by NII protocol.
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
- (VOID **)&Nii,
- Image,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (Status == EFI_SUCCESS) {
- *Ipv6Support = Nii->Ipv6Supported;
- return EFI_SUCCESS;
- }
- //
- // Get the NIC handle by SNP protocol.
- //
- Handle = NetLibGetSnpHandle (ControllerHandle, NULL);
- if (Handle == NULL) {
- return EFI_NOT_FOUND;
- }
- Aip = NULL;
- Status = gBS->HandleProtocol (
- Handle,
- &gEfiAdapterInformationProtocolGuid,
- (VOID *)&Aip
- );
- if (EFI_ERROR (Status) || (Aip == NULL)) {
- return EFI_NOT_FOUND;
- }
- InfoTypesBuffer = NULL;
- InfoTypeBufferCount = 0;
- Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
- if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {
- FreePool (InfoTypesBuffer);
- return EFI_NOT_FOUND;
- }
- Supported = FALSE;
- for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
- if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
- Supported = TRUE;
- break;
- }
- }
- FreePool (InfoTypesBuffer);
- if (!Supported) {
- return EFI_NOT_FOUND;
- }
- //
- // We now have adapter information block.
- //
- InfoBlock = NULL;
- InfoBlockSize = 0;
- Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);
- if (EFI_ERROR (Status) || (InfoBlock == NULL)) {
- FreePool (InfoBlock);
- return EFI_NOT_FOUND;
- }
- *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InfoBlock)->Ipv6Support;
- FreePool (InfoBlock);
- return EFI_SUCCESS;
- }
- /**
- Record the NIC info in global structure.
- @param[in] Controller The handle of the controller.
- @param[in] Image Handle of the image.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
- operation.
- **/
- EFI_STATUS
- IScsiAddNic (
- IN EFI_HANDLE Controller,
- IN EFI_HANDLE Image
- )
- {
- EFI_STATUS Status;
- ISCSI_NIC_INFO *NicInfo;
- LIST_ENTRY *Entry;
- EFI_MAC_ADDRESS MacAddr;
- UINTN HwAddressSize;
- UINT16 VlanId;
- //
- // Get MAC address of this network device.
- //
- Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Get VLAN ID of this network device.
- //
- VlanId = NetLibGetVlanId (Controller);
- //
- // Check whether the NIC info already exists. Return directly if so.
- //
- NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
- NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
- if ((NicInfo->HwAddressSize == HwAddressSize) &&
- (CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0) &&
- (NicInfo->VlanId == VlanId))
- {
- mPrivate->CurrentNic = NicInfo->NicIndex;
- //
- // Set IPv6 available flag.
- //
- Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);
- if (EFI_ERROR (Status)) {
- //
- // Fail to get the data whether UNDI supports IPv6.
- // Set default value to TRUE.
- //
- NicInfo->Ipv6Available = TRUE;
- }
- return EFI_SUCCESS;
- }
- if (mPrivate->MaxNic < NicInfo->NicIndex) {
- mPrivate->MaxNic = NicInfo->NicIndex;
- }
- }
- //
- // Record the NIC info in private structure.
- //
- NicInfo = AllocateZeroPool (sizeof (ISCSI_NIC_INFO));
- if (NicInfo == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize);
- NicInfo->HwAddressSize = (UINT32)HwAddressSize;
- NicInfo->VlanId = VlanId;
- NicInfo->NicIndex = (UINT8)(mPrivate->MaxNic + 1);
- mPrivate->MaxNic = NicInfo->NicIndex;
- //
- // Set IPv6 available flag.
- //
- Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);
- if (EFI_ERROR (Status)) {
- //
- // Fail to get the data whether UNDI supports IPv6.
- // Set default value to TRUE.
- //
- NicInfo->Ipv6Available = TRUE;
- }
- //
- // Get the PCI location.
- //
- IScsiGetNICPciLocation (
- Controller,
- &NicInfo->BusNumber,
- &NicInfo->DeviceNumber,
- &NicInfo->FunctionNumber
- );
- InsertTailList (&mPrivate->NicInfoList, &NicInfo->Link);
- mPrivate->NicCount++;
- mPrivate->CurrentNic = NicInfo->NicIndex;
- return EFI_SUCCESS;
- }
- /**
- Delete the recorded NIC info from global structure. Also delete corresponding
- attempts.
- @param[in] Controller The handle of the controller.
- @retval EFI_SUCCESS The operation is completed.
- @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.
- **/
- EFI_STATUS
- IScsiRemoveNic (
- IN EFI_HANDLE Controller
- )
- {
- EFI_STATUS Status;
- ISCSI_NIC_INFO *NicInfo;
- LIST_ENTRY *Entry;
- LIST_ENTRY *NextEntry;
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
- ISCSI_NIC_INFO *ThisNic;
- EFI_MAC_ADDRESS MacAddr;
- UINTN HwAddressSize;
- UINT16 VlanId;
- //
- // Get MAC address of this network device.
- //
- Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Get VLAN ID of this network device.
- //
- VlanId = NetLibGetVlanId (Controller);
- //
- // Check whether the NIC information exists.
- //
- ThisNic = NULL;
- NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
- NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
- if ((NicInfo->HwAddressSize == HwAddressSize) &&
- (CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0) &&
- (NicInfo->VlanId == VlanId))
- {
- ThisNic = NicInfo;
- break;
- }
- }
- if (ThisNic == NULL) {
- return EFI_NOT_FOUND;
- }
- mPrivate->CurrentNic = ThisNic->NicIndex;
- RemoveEntryList (&ThisNic->Link);
- FreePool (ThisNic);
- mPrivate->NicCount--;
- //
- // Remove all attempts related to this NIC.
- //
- NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
- AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
- if (AttemptConfigData->NicIndex == mPrivate->CurrentNic) {
- RemoveEntryList (&AttemptConfigData->Link);
- mPrivate->AttemptCount--;
- if ((AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) && (mPrivate->MpioCount > 0)) {
- if (--mPrivate->MpioCount == 0) {
- mPrivate->EnableMpio = FALSE;
- }
- if ((AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) && (mPrivate->Krb5MpioCount > 0)) {
- mPrivate->Krb5MpioCount--;
- }
- } else if ((AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) && (mPrivate->SinglePathCount > 0)) {
- mPrivate->SinglePathCount--;
- if (mPrivate->ValidSinglePathCount > 0) {
- mPrivate->ValidSinglePathCount--;
- }
- }
- FreePool (AttemptConfigData);
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Create and initialize the Attempts.
- @param[in] AttemptNum The number of Attempts will be created.
- @retval EFI_SUCCESS The Attempts have been created successfully.
- @retval Others Failed to create the Attempt.
- **/
- EFI_STATUS
- IScsiCreateAttempts (
- IN UINTN AttemptNum
- )
- {
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
- ISCSI_SESSION_CONFIG_NVDATA *ConfigData;
- UINT8 *AttemptConfigOrder;
- UINTN AttemptConfigOrderSize;
- UINT8 *AttemptOrderTmp;
- UINTN TotalNumber;
- UINT8 Index;
- EFI_STATUS Status;
- for (Index = 1; Index <= AttemptNum; Index++) {
- //
- // Get the initialized attempt order. This is used to essure creating attempts by order.
- //
- AttemptConfigOrder = IScsiGetVariableAndSize (
- L"InitialAttemptOrder",
- &gIScsiConfigGuid,
- &AttemptConfigOrderSize
- );
- TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);
- if (TotalNumber == AttemptNum) {
- Status = EFI_SUCCESS;
- break;
- }
- TotalNumber++;
- //
- // Append the new created attempt to the end.
- //
- AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));
- if (AttemptOrderTmp == NULL) {
- if (AttemptConfigOrder != NULL) {
- FreePool (AttemptConfigOrder);
- }
- return EFI_OUT_OF_RESOURCES;
- }
- if (AttemptConfigOrder != NULL) {
- CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);
- FreePool (AttemptConfigOrder);
- }
- AttemptOrderTmp[TotalNumber - 1] = Index;
- AttemptConfigOrder = AttemptOrderTmp;
- AttemptConfigOrderSize = TotalNumber * sizeof (UINT8);
- Status = gRT->SetVariable (
- L"InitialAttemptOrder",
- &gIScsiConfigGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- AttemptConfigOrderSize,
- AttemptConfigOrder
- );
- FreePool (AttemptConfigOrder);
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
- "%r\n",
- __FUNCTION__,
- &gIScsiConfigGuid,
- Status
- ));
- return Status;
- }
- //
- // Create new Attempt
- //
- AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));
- if (AttemptConfigData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- ConfigData = &AttemptConfigData->SessionConfigData;
- ConfigData->TargetPort = ISCSI_WELL_KNOWN_PORT;
- ConfigData->ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;
- ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;
- AttemptConfigData->AuthenticationType = ISCSI_AUTH_TYPE_CHAP;
- AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;
- //
- // Configure the Attempt index and set variable.
- //
- AttemptConfigData->AttemptConfigIndex = Index;
- //
- // Set the attempt name according to the order.
- //
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"Attempt %d",
- (UINTN)AttemptConfigData->AttemptConfigIndex
- );
- UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);
- Status = gRT->SetVariable (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- ISCSI_CONFIG_VAR_ATTR,
- sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
- AttemptConfigData
- );
- FreePool (AttemptConfigData);
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
- "%r\n",
- __FUNCTION__,
- &gEfiIScsiInitiatorNameProtocolGuid,
- Status
- ));
- return Status;
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Create the iSCSI configuration Keywords for each attempt. You can find the keywords
- defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).
- @param[in] KeywordNum The number Sets of Keywords will be created.
- @retval EFI_SUCCESS The operation is completed.
- @retval Others Failed to create the Keywords.
- **/
- EFI_STATUS
- IScsiCreateKeywords (
- IN UINTN KeywordNum
- )
- {
- VOID *StartOpCodeHandle;
- EFI_IFR_GUID_LABEL *StartLabel;
- VOID *EndOpCodeHandle;
- EFI_IFR_GUID_LABEL *EndLabel;
- UINTN Index;
- EFI_STRING_ID StringToken;
- CHAR16 StringId[64];
- CHAR16 KeywordId[32];
- EFI_STATUS Status;
- Status = IScsiCreateOpCode (
- KEYWORD_ENTRY_LABEL,
- &StartOpCodeHandle,
- &StartLabel,
- &EndOpCodeHandle,
- &EndLabel
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- for (Index = 1; Index <= KeywordNum; Index++) {
- //
- // Create iSCSIAttemptName Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAttemptName:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_ATTEMPT_NAME_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_ATTEMPT_NAME_VAR_OFFSET + ATTEMPT_NAME_SIZE * (Index - 1) * sizeof (CHAR16)),
- StringToken,
- StringToken,
- EFI_IFR_FLAG_READ_ONLY,
- 0,
- 0,
- ATTEMPT_NAME_SIZE,
- NULL
- );
- //
- // Create iSCSIBootEnable Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_MODE_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIBootEnable:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_BOOTENABLE_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_BOOTENABLE_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- EFI_IFR_NUMERIC_SIZE_1,
- 0,
- 2,
- 0,
- NULL
- );
- //
- // Create iSCSIIpAddressType Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_IP_MODE_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIIpAddressType:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_ADDRESS_TYPE_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_ADDRESS_TYPE_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- EFI_IFR_NUMERIC_SIZE_1,
- 0,
- 2,
- 0,
- NULL
- );
- //
- // Create iSCSIConnectRetry Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectRetry:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CONNECT_RETRY_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CONNECT_RETRY_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- EFI_IFR_NUMERIC_SIZE_1,
- 0,
- 16,
- 0,
- NULL
- );
- //
- // Create iSCSIConnectTimeout Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectTimeout:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET + 2 * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- EFI_IFR_NUMERIC_SIZE_2,
- CONNECT_MIN_TIMEOUT,
- CONNECT_MAX_TIMEOUT,
- 0,
- NULL
- );
- //
- // Create ISID Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ISID_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIISID:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_ISID_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_ISID_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- STRING_TOKEN (STR_ISCSI_ISID_HELP),
- 0,
- 0,
- ISID_CONFIGURABLE_MIN_LEN,
- ISID_CONFIGURABLE_STORAGE,
- NULL
- );
- //
- // Create iSCSIInitiatorInfoViaDHCP Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorInfoViaDHCP:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- 0,
- 1,
- 0,
- NULL
- );
- //
- // Create iSCSIInitiatorIpAddress Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorIpAddress:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- IP4_MIN_SIZE,
- IP4_STR_MAX_SIZE,
- NULL
- );
- //
- // Create iSCSIInitiatorNetmask Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorNetmask:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- IP4_MIN_SIZE,
- IP4_STR_MAX_SIZE,
- NULL
- );
- //
- // Create iSCSIInitiatorGateway Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorGateway:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- IP4_MIN_SIZE,
- IP4_STR_MAX_SIZE,
- NULL
- );
- //
- // Create iSCSITargetInfoViaDHCP Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetInfoViaDHCP:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- 0,
- 1,
- 0,
- NULL
- );
- //
- // Create iSCSITargetTcpPort Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetTcpPort:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_TARGET_TCP_PORT_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET + 2 * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- EFI_IFR_NUMERIC_SIZE_2,
- TARGET_PORT_MIN_NUM,
- TARGET_PORT_MAX_NUM,
- 0,
- NULL
- );
- //
- // Create iSCSITargetName Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_NAME_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetName:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_TARGET_NAME_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_TARGET_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- ISCSI_NAME_IFR_MIN_SIZE,
- ISCSI_NAME_IFR_MAX_SIZE,
- NULL
- );
- //
- // Create iSCSITargetIpAddress Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetIpAddress:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- IP_MIN_SIZE,
- IP_STR_MAX_SIZE,
- NULL
- );
- //
- // Create iSCSILUN Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_LUN_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSILUN:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_LUN_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_LUN_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- LUN_MIN_SIZE,
- LUN_MAX_SIZE,
- NULL
- );
- //
- // Create iSCSIAuthenticationMethod Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAuthenticationMethod:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- 0,
- 1,
- 0,
- NULL
- );
- //
- // Create iSCSIChapType Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHARTYPE_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapType:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateNumericOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CHARTYPE_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CHARTYPE_VAR_OFFSET + (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- 0,
- 1,
- 0,
- NULL
- );
- //
- // Create iSCSIChapUsername Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapUsername:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CHAR_USER_NAME_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CHAR_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- 0,
- ISCSI_CHAP_NAME_MAX_LEN,
- NULL
- );
- //
- // Create iSCSIChapSecret Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapSecret:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CHAR_SECRET_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CHAR_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- ISCSI_CHAP_SECRET_MIN_LEN,
- ISCSI_CHAP_SECRET_MAX_LEN,
- NULL
- );
- //
- // Create iSCSIReverseChapUsername Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapUsername:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- 0,
- ISCSI_CHAP_NAME_MAX_LEN,
- NULL
- );
- //
- // Create iSCSIReverseChapSecret Keyword.
- //
- UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index);
- StringToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- StringId,
- NULL
- );
- UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapSecret:%d", Index);
- HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
- HiiCreateStringOpCode (
- StartOpCodeHandle,
- (EFI_QUESTION_ID)(ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID + (Index - 1)),
- CONFIGURATION_VARSTORE_ID,
- (UINT16)(ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
- StringToken,
- StringToken,
- 0,
- 0,
- ISCSI_CHAP_SECRET_MIN_LEN,
- ISCSI_CHAP_SECRET_MAX_LEN,
- NULL
- );
- }
- Status = HiiUpdateForm (
- mCallbackInfo->RegisteredHandle, // HII handle
- &gIScsiConfigGuid, // Formset GUID
- FORMID_ATTEMPT_FORM, // Form ID
- StartOpCodeHandle, // Label for where to insert opcodes
- EndOpCodeHandle // Replace data
- );
- HiiFreeOpCodeHandle (StartOpCodeHandle);
- HiiFreeOpCodeHandle (EndOpCodeHandle);
- return Status;
- }
- /**
- Free the attempt configure data variable.
- **/
- VOID
- IScsiCleanAttemptVariable (
- IN VOID
- )
- {
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
- UINT8 *AttemptConfigOrder;
- UINTN AttemptConfigOrderSize;
- UINTN Index;
- //
- // Get the initialized attempt order.
- //
- AttemptConfigOrder = IScsiGetVariableAndSize (
- L"InitialAttemptOrder",
- &gIScsiConfigGuid,
- &AttemptConfigOrderSize
- );
- if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
- return;
- }
- for (Index = 1; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"Attempt %d",
- Index
- );
- GetVariable2 (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- (VOID **)&AttemptConfigData,
- NULL
- );
- if (AttemptConfigData != NULL) {
- gRT->SetVariable (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- 0,
- 0,
- NULL
- );
- }
- }
- return;
- }
- /**
- Get the recorded NIC info from global structure by the Index.
- @param[in] NicIndex The index indicates the position of NIC info.
- @return Pointer to the NIC info, or NULL if not found.
- **/
- ISCSI_NIC_INFO *
- IScsiGetNicInfoByIndex (
- IN UINT8 NicIndex
- )
- {
- LIST_ENTRY *Entry;
- ISCSI_NIC_INFO *NicInfo;
- NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
- NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
- if (NicInfo->NicIndex == NicIndex) {
- return NicInfo;
- }
- }
- return NULL;
- }
- /**
- Get the NIC's PCI location and return it according to the composited
- format defined in iSCSI Boot Firmware Table.
- @param[in] Controller The handle of the controller.
- @param[out] Bus The bus number.
- @param[out] Device The device number.
- @param[out] Function The function number.
- @return The composited representation of the NIC PCI location.
- **/
- UINT16
- IScsiGetNICPciLocation (
- IN EFI_HANDLE Controller,
- OUT UINTN *Bus,
- OUT UINTN *Device,
- OUT UINTN *Function
- )
- {
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_HANDLE PciIoHandle;
- EFI_PCI_IO_PROTOCOL *PciIo;
- UINTN Segment;
- Status = gBS->HandleProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&DevicePath
- );
- if (EFI_ERROR (Status)) {
- return 0;
- }
- Status = gBS->LocateDevicePath (
- &gEfiPciIoProtocolGuid,
- &DevicePath,
- &PciIoHandle
- );
- if (EFI_ERROR (Status)) {
- return 0;
- }
- Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);
- if (EFI_ERROR (Status)) {
- return 0;
- }
- Status = PciIo->GetLocation (PciIo, &Segment, Bus, Device, Function);
- if (EFI_ERROR (Status)) {
- return 0;
- }
- return (UINT16)((*Bus << 8) | (*Device << 3) | *Function);
- }
- /**
- Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
- buffer, and the size of the buffer. If failure, return NULL.
- @param[in] Name String part of EFI variable name.
- @param[in] VendorGuid GUID part of EFI variable name.
- @param[out] VariableSize Returns the size of the EFI variable that was read.
- @return Dynamically allocated memory that contains a copy of the EFI variable.
- @return Caller is responsible freeing the buffer.
- @retval NULL Variable was not read.
- **/
- VOID *
- IScsiGetVariableAndSize (
- IN CHAR16 *Name,
- IN EFI_GUID *VendorGuid,
- OUT UINTN *VariableSize
- )
- {
- EFI_STATUS Status;
- UINTN BufferSize;
- VOID *Buffer;
- Buffer = NULL;
- //
- // Pass in a zero size buffer to find the required buffer size.
- //
- BufferSize = 0;
- Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- //
- // Allocate the buffer to return
- //
- Buffer = AllocateZeroPool (BufferSize);
- if (Buffer == NULL) {
- return NULL;
- }
- //
- // Read variable into the allocated buffer.
- //
- Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
- if (EFI_ERROR (Status)) {
- BufferSize = 0;
- }
- }
- *VariableSize = BufferSize;
- return Buffer;
- }
- /**
- Create the iSCSI driver data.
- @param[in] Image The handle of the driver image.
- @param[in] Controller The handle of the controller.
- @return The iSCSI driver data created.
- @retval NULL Other errors as indicated.
- **/
- ISCSI_DRIVER_DATA *
- IScsiCreateDriverData (
- IN EFI_HANDLE Image,
- IN EFI_HANDLE Controller
- )
- {
- ISCSI_DRIVER_DATA *Private;
- EFI_STATUS Status;
- Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));
- if (Private == NULL) {
- return NULL;
- }
- Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;
- Private->Image = Image;
- Private->Controller = Controller;
- Private->Session = NULL;
- //
- // Create an event to be signaled when the BS to RT transition is triggerd so
- // as to abort the iSCSI session.
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- IScsiOnExitBootService,
- Private,
- &gEfiEventExitBootServicesGuid,
- &Private->ExitBootServiceEvent
- );
- if (EFI_ERROR (Status)) {
- FreePool (Private);
- return NULL;
- }
- Private->ExtScsiPassThruHandle = NULL;
- CopyMem (&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof (EFI_EXT_SCSI_PASS_THRU_PROTOCOL));
- //
- // 0 is designated to the TargetId, so use another value for the AdapterId.
- //
- Private->ExtScsiPassThruMode.AdapterId = 2;
- Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
- Private->ExtScsiPassThruMode.IoAlign = 4;
- Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;
- return Private;
- }
- /**
- Clean the iSCSI driver data.
- @param[in] Private The iSCSI driver data.
- @retval EFI_SUCCESS The clean operation is successful.
- @retval Others Other errors as indicated.
- **/
- EFI_STATUS
- IScsiCleanDriverData (
- IN ISCSI_DRIVER_DATA *Private
- )
- {
- EFI_STATUS Status;
- Status = EFI_SUCCESS;
- if (Private->DevicePath != NULL) {
- Status = gBS->UninstallProtocolInterface (
- Private->ExtScsiPassThruHandle,
- &gEfiDevicePathProtocolGuid,
- Private->DevicePath
- );
- if (EFI_ERROR (Status)) {
- goto EXIT;
- }
- FreePool (Private->DevicePath);
- }
- if (Private->ExtScsiPassThruHandle != NULL) {
- Status = gBS->UninstallProtocolInterface (
- Private->ExtScsiPassThruHandle,
- &gEfiExtScsiPassThruProtocolGuid,
- &Private->IScsiExtScsiPassThru
- );
- if (!EFI_ERROR (Status)) {
- mPrivate->OneSessionEstablished = FALSE;
- }
- }
- EXIT:
- if (Private->ExitBootServiceEvent != NULL) {
- gBS->CloseEvent (Private->ExitBootServiceEvent);
- }
- mCallbackInfo->Current = NULL;
- FreePool (Private);
- return Status;
- }
- /**
- Check wheather the Controller handle is configured to use DHCP protocol.
- @param[in] Controller The handle of the controller.
- @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
- @retval TRUE The handle of the controller need the Dhcp protocol.
- @retval FALSE The handle of the controller does not need the Dhcp protocol.
- **/
- BOOLEAN
- IScsiDhcpIsConfigured (
- IN EFI_HANDLE Controller,
- IN UINT8 IpVersion
- )
- {
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;
- UINT8 *AttemptConfigOrder;
- UINTN AttemptConfigOrderSize;
- UINTN Index;
- EFI_STATUS Status;
- EFI_MAC_ADDRESS MacAddr;
- UINTN HwAddressSize;
- UINT16 VlanId;
- CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];
- CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];
- CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];
- AttemptConfigOrder = IScsiGetVariableAndSize (
- L"AttemptOrder",
- &gIScsiConfigGuid,
- &AttemptConfigOrderSize
- );
- if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
- return FALSE;
- }
- //
- // Get MAC address of this network device.
- //
- Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- //
- // Get VLAN ID of this network device.
- //
- VlanId = NetLibGetVlanId (Controller);
- IScsiMacAddrToStr (&MacAddr, (UINT32)HwAddressSize, VlanId, MacString);
- for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
- UnicodeSPrint (
- AttemptName,
- (UINTN)128,
- L"Attempt %d",
- (UINTN)AttemptConfigOrder[Index]
- );
- Status = GetVariable2 (
- AttemptName,
- &gEfiIScsiInitiatorNameProtocolGuid,
- (VOID **)&AttemptTmp,
- NULL
- );
- if ((AttemptTmp == NULL) || EFI_ERROR (Status)) {
- continue;
- }
- ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);
- if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {
- FreePool (AttemptTmp);
- continue;
- }
- if ((AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG) &&
- (AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)))
- {
- FreePool (AttemptTmp);
- continue;
- }
- AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));
- if ((AttemptTmp->Actived == ISCSI_ACTIVE_DISABLED) || StrCmp (MacString, AttemptMacString)) {
- continue;
- }
- if ((AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) ||
- (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE) ||
- (AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE))
- {
- FreePool (AttemptTmp);
- FreePool (AttemptConfigOrder);
- return TRUE;
- }
- FreePool (AttemptTmp);
- }
- FreePool (AttemptConfigOrder);
- return FALSE;
- }
- /**
- Check whether the Controller handle is configured to use DNS protocol.
- @param[in] Controller The handle of the controller.
- @retval TRUE The handle of the controller need the Dns protocol.
- @retval FALSE The handle of the controller does not need the Dns protocol.
- **/
- BOOLEAN
- IScsiDnsIsConfigured (
- IN EFI_HANDLE Controller
- )
- {
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;
- UINT8 *AttemptConfigOrder;
- UINTN AttemptConfigOrderSize;
- UINTN Index;
- EFI_STATUS Status;
- EFI_MAC_ADDRESS MacAddr;
- UINTN HwAddressSize;
- UINT16 VlanId;
- CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];
- CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];
- CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];
- AttemptConfigOrder = IScsiGetVariableAndSize (
- L"AttemptOrder",
- &gIScsiConfigGuid,
- &AttemptConfigOrderSize
- );
- if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
- return FALSE;
- }
- //
- // Get MAC address of this network device.
- //
- Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
- //
- // Get VLAN ID of this network device.
- //
- VlanId = NetLibGetVlanId (Controller);
- IScsiMacAddrToStr (&MacAddr, (UINT32)HwAddressSize, VlanId, MacString);
- for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
- UnicodeSPrint (
- AttemptName,
- (UINTN)128,
- L"Attempt %d",
- (UINTN)AttemptConfigOrder[Index]
- );
- Status = GetVariable2 (
- AttemptName,
- &gEfiIScsiInitiatorNameProtocolGuid,
- (VOID **)&AttemptTmp,
- NULL
- );
- if ((AttemptTmp == NULL) || EFI_ERROR (Status)) {
- continue;
- }
- ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);
- AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));
- if ((AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) || StrCmp (MacString, AttemptMacString)) {
- FreePool (AttemptTmp);
- continue;
- }
- if (AttemptTmp->SessionConfigData.DnsMode || AttemptTmp->SessionConfigData.TargetInfoFromDhcp) {
- FreePool (AttemptTmp);
- FreePool (AttemptConfigOrder);
- return TRUE;
- } else {
- FreePool (AttemptTmp);
- continue;
- }
- }
- FreePool (AttemptConfigOrder);
- return FALSE;
- }
- /**
- Get the various configuration data.
- @param[in] Private The iSCSI driver data.
- @retval EFI_SUCCESS The configuration data is retrieved.
- @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
- **/
- EFI_STATUS
- IScsiGetConfigData (
- IN ISCSI_DRIVER_DATA *Private
- )
- {
- EFI_STATUS Status;
- CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];
- CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];
- UINTN Index;
- ISCSI_NIC_INFO *NicInfo;
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
- ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;
- UINT8 *AttemptConfigOrder;
- UINTN AttemptConfigOrderSize;
- CHAR16 IScsiMode[64];
- CHAR16 IpMode[64];
- //
- // There should be at least one attempt configured.
- //
- AttemptConfigOrder = IScsiGetVariableAndSize (
- L"AttemptOrder",
- &gIScsiConfigGuid,
- &AttemptConfigOrderSize
- );
- if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
- return EFI_NOT_FOUND;
- }
- //
- // Get the iSCSI Initiator Name.
- //
- mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;
- Status = gIScsiInitiatorName.Get (
- &gIScsiInitiatorName,
- &mPrivate->InitiatorNameLength,
- mPrivate->InitiatorName
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Get the normal configuration.
- //
- for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
- //
- // Check whether the attempt exists in AttemptConfig.
- //
- AttemptTmp = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);
- if ((AttemptTmp != NULL) && (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED)) {
- continue;
- } else if ((AttemptTmp != NULL) && (AttemptTmp->SessionConfigData.Enabled != ISCSI_DISABLED)) {
- //
- // Check the autoconfig path to see whether it should be retried.
- //
- if ((AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
- !AttemptTmp->AutoConfigureSuccess)
- {
- if (mPrivate->Ipv6Flag &&
- (AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6))
- {
- //
- // Autoconfigure for IP6 already attempted but failed. Do not try again.
- //
- continue;
- } else if (!mPrivate->Ipv6Flag &&
- (AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4))
- {
- //
- // Autoconfigure for IP4 already attempted but failed. Do not try again.
- //
- continue;
- } else {
- //
- // Try another approach for this autoconfigure path.
- //
- AttemptTmp->AutoConfigureMode =
- (UINT8)(mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);
- AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp = TRUE;
- AttemptTmp->SessionConfigData.TargetInfoFromDhcp = TRUE;
- AttemptTmp->DhcpSuccess = FALSE;
- //
- // Get some information from the dhcp server.
- //
- if (!mPrivate->Ipv6Flag) {
- Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);
- if (!EFI_ERROR (Status)) {
- AttemptTmp->DhcpSuccess = TRUE;
- }
- } else {
- Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);
- if (!EFI_ERROR (Status)) {
- AttemptTmp->DhcpSuccess = TRUE;
- }
- }
- //
- // Refresh the state of this attempt to NVR.
- //
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"Attempt %d",
- (UINTN)AttemptTmp->AttemptConfigIndex
- );
- gRT->SetVariable (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- ISCSI_CONFIG_VAR_ATTR,
- sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
- AttemptTmp
- );
- continue;
- }
- } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp &&
- !AttemptTmp->ValidPath &&
- (AttemptTmp->NicIndex == mPrivate->CurrentNic))
- {
- //
- // If the attempt associates with the current NIC, we can
- // get DHCP information for already added, but failed, attempt.
- //
- AttemptTmp->DhcpSuccess = FALSE;
- if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) {
- Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);
- if (!EFI_ERROR (Status)) {
- AttemptTmp->DhcpSuccess = TRUE;
- }
- } else if (mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP6)) {
- Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);
- if (!EFI_ERROR (Status)) {
- AttemptTmp->DhcpSuccess = TRUE;
- }
- }
- //
- // Refresh the state of this attempt to NVR.
- //
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"Attempt %d",
- (UINTN)AttemptTmp->AttemptConfigIndex
- );
- gRT->SetVariable (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- ISCSI_CONFIG_VAR_ATTR,
- sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
- AttemptTmp
- );
- continue;
- } else {
- continue;
- }
- }
- //
- // This attempt does not exist in AttemptConfig. Try to add a new one.
- //
- NicInfo = IScsiGetNicInfoByIndex (mPrivate->CurrentNic);
- ASSERT (NicInfo != NULL);
- IScsiMacAddrToStr (&NicInfo->PermanentAddress, NicInfo->HwAddressSize, NicInfo->VlanId, MacString);
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"Attempt %d",
- (UINTN)AttemptConfigOrder[Index]
- );
- GetVariable2 (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- (VOID **)&AttemptConfigData,
- NULL
- );
- AsciiStrToUnicodeStrS (AttemptConfigData->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));
- if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_DISABLED) ||
- StrCmp (MacString, AttemptMacString))
- {
- continue;
- }
- ASSERT (AttemptConfigOrder[Index] == AttemptConfigData->AttemptConfigIndex);
- AttemptConfigData->NicIndex = NicInfo->NicIndex;
- AttemptConfigData->DhcpSuccess = FALSE;
- AttemptConfigData->ValidiBFTPath = (BOOLEAN)(mPrivate->EnableMpio ? TRUE : FALSE);
- AttemptConfigData->ValidPath = FALSE;
- if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
- AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp = TRUE;
- AttemptConfigData->SessionConfigData.TargetInfoFromDhcp = TRUE;
- AttemptConfigData->AutoConfigureMode =
- (UINT8)(mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);
- AttemptConfigData->AutoConfigureSuccess = FALSE;
- }
- //
- // Get some information from dhcp server.
- //
- if ((AttemptConfigData->SessionConfigData.Enabled != ISCSI_DISABLED) &&
- AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp)
- {
- if (!mPrivate->Ipv6Flag &&
- ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) ||
- (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4)))
- {
- Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptConfigData);
- if (!EFI_ERROR (Status)) {
- AttemptConfigData->DhcpSuccess = TRUE;
- }
- } else if (mPrivate->Ipv6Flag &&
- ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) ||
- (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6)))
- {
- Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptConfigData);
- if (!EFI_ERROR (Status)) {
- AttemptConfigData->DhcpSuccess = TRUE;
- }
- }
- //
- // Refresh the state of this attempt to NVR.
- //
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"Attempt %d",
- (UINTN)AttemptConfigData->AttemptConfigIndex
- );
- gRT->SetVariable (
- mPrivate->PortString,
- &gEfiIScsiInitiatorNameProtocolGuid,
- ISCSI_CONFIG_VAR_ATTR,
- sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
- AttemptConfigData
- );
- }
- //
- // Update Attempt Help Info.
- //
- if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) {
- UnicodeSPrint (IScsiMode, 64, L"Disabled");
- } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
- UnicodeSPrint (IScsiMode, 64, L"Enabled");
- } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
- UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");
- }
- if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {
- UnicodeSPrint (IpMode, 64, L"IP4");
- } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {
- UnicodeSPrint (IpMode, 64, L"IP6");
- } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
- UnicodeSPrint (IpMode, 64, L"Autoconfigure");
- }
- UnicodeSPrint (
- mPrivate->PortString,
- (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
- L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
- MacString,
- NicInfo->BusNumber,
- NicInfo->DeviceNumber,
- NicInfo->FunctionNumber,
- IScsiMode,
- IpMode
- );
- AttemptConfigData->AttemptTitleHelpToken = HiiSetString (
- mCallbackInfo->RegisteredHandle,
- 0,
- mPrivate->PortString,
- NULL
- );
- if (AttemptConfigData->AttemptTitleHelpToken == 0) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Record the attempt in global link list.
- //
- InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
- mPrivate->AttemptCount++;
- if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
- mPrivate->MpioCount++;
- mPrivate->EnableMpio = TRUE;
- if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {
- mPrivate->Krb5MpioCount++;
- }
- } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
- mPrivate->SinglePathCount++;
- }
- }
- //
- // Reorder the AttemptConfig by the configured order.
- //
- for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
- AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);
- if (AttemptConfigData == NULL) {
- continue;
- }
- RemoveEntryList (&AttemptConfigData->Link);
- InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
- }
- //
- // Update the Main Form.
- //
- IScsiConfigUpdateAttempt ();
- FreePool (AttemptConfigOrder);
- //
- // There should be at least one attempt configuration.
- //
- if (!mPrivate->EnableMpio) {
- if (mPrivate->SinglePathCount == 0) {
- return EFI_NOT_FOUND;
- }
- mPrivate->ValidSinglePathCount = mPrivate->SinglePathCount;
- }
- return EFI_SUCCESS;
- }
- /**
- Get the device path of the iSCSI tcp connection and update it.
- @param Session The iSCSI session.
- @return The updated device path.
- @retval NULL Other errors as indicated.
- **/
- EFI_DEVICE_PATH_PROTOCOL *
- IScsiGetTcpConnDevicePath (
- IN ISCSI_SESSION *Session
- )
- {
- ISCSI_CONNECTION *Conn;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_STATUS Status;
- EFI_DEV_PATH *DPathNode;
- UINTN PathLen;
- if (Session->State != SESSION_STATE_LOGGED_IN) {
- return NULL;
- }
- Conn = NET_LIST_USER_STRUCT_S (
- Session->Conns.ForwardLink,
- ISCSI_CONNECTION,
- Link,
- ISCSI_CONNECTION_SIGNATURE
- );
- Status = gBS->HandleProtocol (
- Conn->TcpIo.Handle,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&DevicePath
- );
- if (EFI_ERROR (Status)) {
- return NULL;
- }
- //
- // Duplicate it.
- //
- DevicePath = DuplicateDevicePath (DevicePath);
- if (DevicePath == NULL) {
- return NULL;
- }
- DPathNode = (EFI_DEV_PATH *)DevicePath;
- while (!IsDevicePathEnd (&DPathNode->DevPath)) {
- if (DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) {
- if (!Conn->Ipv6Flag && (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)) {
- DPathNode->Ipv4.LocalPort = 0;
- DPathNode->Ipv4.StaticIpAddress =
- (BOOLEAN)(!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);
- //
- // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
- // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
- // do not exist.
- // In new version of IPv4_DEVICE_PATH, structure length is 27.
- //
- PathLen = DevicePathNodeLength (&DPathNode->Ipv4);
- if (PathLen == IP4_NODE_LEN_NEW_VERSIONS) {
- IP4_COPY_ADDRESS (
- &DPathNode->Ipv4.GatewayIpAddress,
- &Session->ConfigData->SessionConfigData.Gateway
- );
- IP4_COPY_ADDRESS (
- &DPathNode->Ipv4.SubnetMask,
- &Session->ConfigData->SessionConfigData.SubnetMask
- );
- }
- break;
- } else if (Conn->Ipv6Flag && (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv6_DP)) {
- DPathNode->Ipv6.LocalPort = 0;
- //
- // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
- // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
- // and GatewayIpAddress do not exist.
- // In new version of IPv6_DEVICE_PATH, structure length is 60, while in
- // old versions, the length is 43.
- //
- PathLen = DevicePathNodeLength (&DPathNode->Ipv6);
- if (PathLen == IP6_NODE_LEN_NEW_VERSIONS ) {
- DPathNode->Ipv6.IpAddressOrigin = 0;
- DPathNode->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;
- ZeroMem (&DPathNode->Ipv6.GatewayIpAddress, sizeof (EFI_IPv6_ADDRESS));
- } else if (PathLen == IP6_NODE_LEN_OLD_VERSIONS) {
- //
- // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
- // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
- //
- *((UINT8 *)(&DPathNode->Ipv6) + IP6_OLD_IPADDRESS_OFFSET) =
- (BOOLEAN)(!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);
- }
- break;
- }
- }
- DPathNode = (EFI_DEV_PATH *)NextDevicePathNode (&DPathNode->DevPath);
- }
- return DevicePath;
- }
- /**
- Abort the session when the transition from BS to RT is initiated.
- @param[in] Event The event signaled.
- @param[in] Context The iSCSI driver data.
- **/
- VOID
- EFIAPI
- IScsiOnExitBootService (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- ISCSI_DRIVER_DATA *Private;
- Private = (ISCSI_DRIVER_DATA *)Context;
- gBS->CloseEvent (Private->ExitBootServiceEvent);
- Private->ExitBootServiceEvent = NULL;
- if (Private->Session != NULL) {
- IScsiSessionAbort (Private->Session);
- }
- }
- /**
- Tests whether a controller handle is being managed by IScsi driver.
- This function tests whether the driver specified by DriverBindingHandle is
- currently managing the controller specified by ControllerHandle. This test
- is performed by evaluating if the protocol specified by ProtocolGuid is
- present on ControllerHandle and is was opened by DriverBindingHandle and Nic
- Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
- If ProtocolGuid is NULL, then ASSERT().
- @param ControllerHandle A handle for a controller to test.
- @param DriverBindingHandle Specifies the driver binding handle for the
- driver.
- @param ProtocolGuid Specifies the protocol that the driver specified
- by DriverBindingHandle opens in its Start()
- function.
- @retval EFI_SUCCESS ControllerHandle is managed by the driver
- specified by DriverBindingHandle.
- @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver
- specified by DriverBindingHandle.
- **/
- EFI_STATUS
- EFIAPI
- IScsiTestManagedDevice (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE DriverBindingHandle,
- IN EFI_GUID *ProtocolGuid
- )
- {
- EFI_STATUS Status;
- VOID *ManagedInterface;
- EFI_HANDLE NicControllerHandle;
- ASSERT (ProtocolGuid != NULL);
- NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);
- if (NicControllerHandle == NULL) {
- return EFI_UNSUPPORTED;
- }
- Status = gBS->OpenProtocol (
- ControllerHandle,
- (EFI_GUID *)ProtocolGuid,
- &ManagedInterface,
- DriverBindingHandle,
- NicControllerHandle,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (!EFI_ERROR (Status)) {
- gBS->CloseProtocol (
- ControllerHandle,
- (EFI_GUID *)ProtocolGuid,
- DriverBindingHandle,
- NicControllerHandle
- );
- return EFI_UNSUPPORTED;
- }
- if (Status != EFI_ALREADY_STARTED) {
- return EFI_UNSUPPORTED;
- }
- return EFI_SUCCESS;
- }
|