]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IScsiDxe/IScsiMisc.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiMisc.c
CommitLineData
4c5a5e0c 1/** @file\r
2 Miscellaneous routines for iSCSI driver.\r
3\r
a37c60b6 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
ecf98fbc 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
4c5a5e0c 6\r
7**/\r
8\r
9#include "IScsiImpl.h"\r
10\r
11GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 IScsiHexString[] = "0123456789ABCDEFabcdef";\r
12\r
13/**\r
14 Removes (trims) specified leading and trailing characters from a string.\r
15\r
16 @param[in, out] Str Pointer to the null-terminated string to be trimmed.\r
f75a7f56 17 On return, Str will hold the trimmed string.\r
4c5a5e0c 18\r
19 @param[in] CharC Character will be trimmed from str.\r
20\r
21**/\r
22VOID\r
23IScsiStrTrim (\r
d1050b9d
MK
24 IN OUT CHAR16 *Str,\r
25 IN CHAR16 CharC\r
4c5a5e0c 26 )\r
27{\r
28 CHAR16 *Pointer1;\r
29 CHAR16 *Pointer2;\r
f75a7f56 30\r
4c5a5e0c 31 if (*Str == 0) {\r
d1050b9d 32 return;\r
4c5a5e0c 33 }\r
f75a7f56 34\r
4c5a5e0c 35 //\r
36 // Trim off the leading and trailing characters c\r
37 //\r
38 for (Pointer1 = Str; (*Pointer1 != 0) && (*Pointer1 == CharC); Pointer1++) {\r
4c5a5e0c 39 }\r
f75a7f56 40\r
4c5a5e0c 41 Pointer2 = Str;\r
42 if (Pointer2 == Pointer1) {\r
43 while (*Pointer1 != 0) {\r
44 Pointer2++;\r
45 Pointer1++;\r
46 }\r
47 } else {\r
f75a7f56 48 while (*Pointer1 != 0) {\r
d1050b9d
MK
49 *Pointer2 = *Pointer1;\r
50 Pointer1++;\r
51 Pointer2++;\r
4c5a5e0c 52 }\r
d1050b9d 53\r
4c5a5e0c 54 *Pointer2 = 0;\r
55 }\r
f75a7f56 56\r
d1050b9d 57 for (Pointer1 = Str + StrLen (Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {\r
4c5a5e0c 58 }\r
d1050b9d
MK
59\r
60 if (Pointer1 != Str + StrLen (Str) - 1) {\r
4c5a5e0c 61 *(Pointer1 + 1) = 0;\r
62 }\r
63}\r
64\r
65/**\r
66 Calculate the prefix length of the IPv4 subnet mask.\r
67\r
68 @param[in] SubnetMask The IPv4 subnet mask.\r
69\r
70 @return The prefix length of the subnet mask.\r
71 @retval 0 Other errors as indicated.\r
72\r
73**/\r
74UINT8\r
75IScsiGetSubnetMaskPrefixLength (\r
76 IN EFI_IPv4_ADDRESS *SubnetMask\r
77 )\r
78{\r
79 UINT8 Len;\r
80 UINT32 ReverseMask;\r
81\r
82 //\r
83 // The SubnetMask is in network byte order.\r
84 //\r
85 ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);\r
86\r
87 //\r
88 // Reverse it.\r
89 //\r
90 ReverseMask = ~ReverseMask;\r
91\r
92 if ((ReverseMask & (ReverseMask + 1)) != 0) {\r
93 return 0;\r
94 }\r
95\r
96 Len = 0;\r
97\r
98 while (ReverseMask != 0) {\r
99 ReverseMask = ReverseMask >> 1;\r
100 Len++;\r
101 }\r
102\r
d1050b9d 103 return (UINT8)(32 - Len);\r
4c5a5e0c 104}\r
105\r
4c5a5e0c 106/**\r
107 Convert the hexadecimal encoded LUN string into the 64-bit LUN.\r
108\r
109 @param[in] Str The hexadecimal encoded LUN string.\r
110 @param[out] Lun Storage to return the 64-bit LUN.\r
111\r
112 @retval EFI_SUCCESS The 64-bit LUN is stored in Lun.\r
113 @retval EFI_INVALID_PARAMETER The string is malformatted.\r
114\r
115**/\r
116EFI_STATUS\r
117IScsiAsciiStrToLun (\r
118 IN CHAR8 *Str,\r
119 OUT UINT8 *Lun\r
120 )\r
121{\r
122 UINTN Index, IndexValue, IndexNum, SizeStr;\r
123 CHAR8 TemStr[2];\r
124 UINT8 TemValue;\r
125 UINT16 Value[4];\r
f75a7f56 126\r
4c5a5e0c 127 ZeroMem (Lun, 8);\r
128 ZeroMem (TemStr, 2);\r
d1050b9d 129 ZeroMem ((UINT8 *)Value, sizeof (Value));\r
f75a7f56 130 SizeStr = AsciiStrLen (Str);\r
4c5a5e0c 131 IndexValue = 0;\r
132 IndexNum = 0;\r
133\r
d1050b9d 134 for (Index = 0; Index < SizeStr; Index++) {\r
4c5a5e0c 135 TemStr[0] = Str[Index];\r
d1050b9d
MK
136 TemValue = (UINT8)AsciiStrHexToUint64 (TemStr);\r
137 if ((TemValue == 0) && (TemStr[0] != '0')) {\r
4c5a5e0c 138 if ((TemStr[0] != '-') || (IndexNum == 0)) {\r
139 //\r
140 // Invalid Lun Char.\r
141 //\r
142 return EFI_INVALID_PARAMETER;\r
143 }\r
144 }\r
f75a7f56 145\r
4c5a5e0c 146 if ((TemValue == 0) && (TemStr[0] == '-')) {\r
147 //\r
148 // Next Lun value.\r
149 //\r
150 if (++IndexValue >= 4) {\r
151 //\r
152 // Max 4 Lun value.\r
153 //\r
154 return EFI_INVALID_PARAMETER;\r
155 }\r
d1050b9d 156\r
4c5a5e0c 157 //\r
158 // Restart str index for the next lun value.\r
159 //\r
160 IndexNum = 0;\r
161 continue;\r
162 }\r
f75a7f56 163\r
4c5a5e0c 164 if (++IndexNum > 4) {\r
f75a7f56 165 //\r
4c5a5e0c 166 // Each Lun Str can't exceed size 4, because it will be as UINT16 value.\r
167 //\r
168 return EFI_INVALID_PARAMETER;\r
169 }\r
f75a7f56 170\r
4c5a5e0c 171 //\r
172 // Combine UINT16 value.\r
173 //\r
d1050b9d 174 Value[IndexValue] = (UINT16)((Value[IndexValue] << 4) + TemValue);\r
4c5a5e0c 175 }\r
f75a7f56 176\r
d1050b9d
MK
177 for (Index = 0; Index <= IndexValue; Index++) {\r
178 *((UINT16 *)&Lun[Index * 2]) = HTONS (Value[Index]);\r
4c5a5e0c 179 }\r
f75a7f56 180\r
4c5a5e0c 181 return EFI_SUCCESS;\r
182}\r
183\r
184/**\r
185 Convert the 64-bit LUN into the hexadecimal encoded LUN string.\r
186\r
187 @param[in] Lun The 64-bit LUN.\r
188 @param[out] Str The storage to return the hexadecimal encoded LUN string.\r
189\r
190**/\r
191VOID\r
192IScsiLunToUnicodeStr (\r
193 IN UINT8 *Lun,\r
194 OUT CHAR16 *Str\r
195 )\r
196{\r
197 UINTN Index;\r
198 CHAR16 *TempStr;\r
199\r
200 TempStr = Str;\r
201\r
202 for (Index = 0; Index < 4; Index++) {\r
4c5a5e0c 203 if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {\r
a4faf336 204 CopyMem (TempStr, L"0-", sizeof (L"0-"));\r
4c5a5e0c 205 } else {\r
d1050b9d
MK
206 TempStr[0] = (CHAR16)IScsiHexString[Lun[2 * Index] >> 4];\r
207 TempStr[1] = (CHAR16)IScsiHexString[Lun[2 * Index] & 0x0F];\r
208 TempStr[2] = (CHAR16)IScsiHexString[Lun[2 * Index + 1] >> 4];\r
209 TempStr[3] = (CHAR16)IScsiHexString[Lun[2 * Index + 1] & 0x0F];\r
210 TempStr[4] = L'-';\r
211 TempStr[5] = 0;\r
4c5a5e0c 212\r
213 IScsiStrTrim (TempStr, L'0');\r
214 }\r
215\r
216 TempStr += StrLen (TempStr);\r
217 }\r
d1050b9d 218\r
a4faf336
FS
219 //\r
220 // Remove the last '-'\r
221 //\r
d1050b9d 222 ASSERT (StrLen (Str) >= 1);\r
4c5a5e0c 223 Str[StrLen (Str) - 1] = 0;\r
224\r
225 for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {\r
226 if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {\r
227 Str[Index - 1] = 0;\r
228 } else {\r
229 break;\r
230 }\r
231 }\r
232}\r
233\r
234/**\r
235 Convert the formatted IP address into the binary IP address.\r
236\r
237 @param[in] Str The UNICODE string.\r
238 @param[in] IpMode Indicates whether the IP address is v4 or v6.\r
239 @param[out] Ip The storage to return the ASCII string.\r
240\r
241 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
242 @retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is\r
243 invalid.\r
244\r
245**/\r
246EFI_STATUS\r
247IScsiAsciiStrToIp (\r
d1050b9d
MK
248 IN CHAR8 *Str,\r
249 IN UINT8 IpMode,\r
250 OUT EFI_IP_ADDRESS *Ip\r
4c5a5e0c 251 )\r
252{\r
d1050b9d 253 EFI_STATUS Status;\r
4c5a5e0c 254\r
d1050b9d 255 if ((IpMode == IP_MODE_IP4) || (IpMode == IP_MODE_AUTOCONFIG_IP4)) {\r
4c5a5e0c 256 return NetLibAsciiStrToIp4 (Str, &Ip->v4);\r
d1050b9d 257 } else if ((IpMode == IP_MODE_IP6) || (IpMode == IP_MODE_AUTOCONFIG_IP6)) {\r
4c5a5e0c 258 return NetLibAsciiStrToIp6 (Str, &Ip->v6);\r
4c5a5e0c 259 } else if (IpMode == IP_MODE_AUTOCONFIG) {\r
260 Status = NetLibAsciiStrToIp4 (Str, &Ip->v4);\r
261 if (!EFI_ERROR (Status)) {\r
262 return Status;\r
263 }\r
4c5a5e0c 264\r
d1050b9d 265 return NetLibAsciiStrToIp6 (Str, &Ip->v6);\r
4c5a5e0c 266 }\r
267\r
268 return EFI_INVALID_PARAMETER;\r
269}\r
270\r
271/**\r
efb56593 272 Convert the mac address into a hexadecimal encoded "-" separated string.\r
4c5a5e0c 273\r
274 @param[in] Mac The mac address.\r
275 @param[in] Len Length in bytes of the mac address.\r
276 @param[in] VlanId VLAN ID of the network device.\r
277 @param[out] Str The storage to return the mac string.\r
278\r
279**/\r
280VOID\r
281IScsiMacAddrToStr (\r
282 IN EFI_MAC_ADDRESS *Mac,\r
283 IN UINT32 Len,\r
284 IN UINT16 VlanId,\r
285 OUT CHAR16 *Str\r
286 )\r
287{\r
288 UINT32 Index;\r
289 CHAR16 *String;\r
290\r
291 for (Index = 0; Index < Len; Index++) {\r
d1050b9d
MK
292 Str[3 * Index] = (CHAR16)IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];\r
293 Str[3 * Index + 1] = (CHAR16)IScsiHexString[Mac->Addr[Index] & 0x0F];\r
294 Str[3 * Index + 2] = L':';\r
4c5a5e0c 295 }\r
296\r
d1050b9d 297 String = &Str[3 * Index - 1];\r
4c5a5e0c 298 if (VlanId != 0) {\r
d1050b9d 299 String += UnicodeSPrint (String, 6 * sizeof (CHAR16), L"\\%04x", (UINTN)VlanId);\r
4c5a5e0c 300 }\r
301\r
302 *String = L'\0';\r
303}\r
304\r
305/**\r
306 Convert the binary encoded buffer into a hexadecimal encoded string.\r
307\r
308 @param[in] BinBuffer The buffer containing the binary data.\r
309 @param[in] BinLength Length of the binary buffer.\r
310 @param[in, out] HexStr Pointer to the string.\r
311 @param[in, out] HexLength The length of the string.\r
312\r
f75a7f56 313 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string\r
4c5a5e0c 314 and the length of the string is updated.\r
315 @retval EFI_BUFFER_TOO_SMALL The string is too small.\r
cf01b2dc 316 @retval EFI_BAD_BUFFER_SIZE BinLength is too large for hex encoding.\r
4c5a5e0c 317 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
318\r
319**/\r
320EFI_STATUS\r
321IScsiBinToHex (\r
d1050b9d
MK
322 IN UINT8 *BinBuffer,\r
323 IN UINT32 BinLength,\r
324 IN OUT CHAR8 *HexStr,\r
325 IN OUT UINT32 *HexLength\r
4c5a5e0c 326 )\r
327{\r
d1050b9d
MK
328 UINT32 HexLengthMin;\r
329 UINT32 HexLengthProvided;\r
330 UINT32 Index;\r
4c5a5e0c 331\r
332 if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {\r
333 return EFI_INVALID_PARAMETER;\r
334 }\r
335\r
cf01b2dc
LE
336 //\r
337 // Safely calculate: HexLengthMin := BinLength * 2 + 3.\r
338 //\r
339 if (RETURN_ERROR (SafeUint32Mult (BinLength, 2, &HexLengthMin)) ||\r
d1050b9d
MK
340 RETURN_ERROR (SafeUint32Add (HexLengthMin, 3, &HexLengthMin)))\r
341 {\r
cf01b2dc
LE
342 return EFI_BAD_BUFFER_SIZE;\r
343 }\r
344\r
345 HexLengthProvided = *HexLength;\r
d1050b9d 346 *HexLength = HexLengthMin;\r
cf01b2dc 347 if (HexLengthProvided < HexLengthMin) {\r
4c5a5e0c 348 return EFI_BUFFER_TOO_SMALL;\r
349 }\r
350\r
4c5a5e0c 351 //\r
352 // Prefix for Hex String.\r
353 //\r
354 HexStr[0] = '0';\r
355 HexStr[1] = 'x';\r
356\r
357 for (Index = 0; Index < BinLength; Index++) {\r
358 HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];\r
359 HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];\r
360 }\r
361\r
362 HexStr[Index * 2 + 2] = '\0';\r
363\r
364 return EFI_SUCCESS;\r
365}\r
366\r
4c5a5e0c 367/**\r
368 Convert the hexadecimal string into a binary encoded buffer.\r
369\r
dc469f13
LE
370 @param[in, out] BinBuffer The binary buffer.\r
371 @param[in, out] BinLength Length of the binary buffer.\r
372 @param[in] HexStr The hexadecimal string.\r
373\r
374 @retval EFI_SUCCESS The hexadecimal string is converted into a\r
375 binary encoded buffer.\r
47b76780 376 @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.\r
54e90eda
LE
377 @retval EFI_BAD_BUFFER_SIZE The length of HexStr is too large for decoding:\r
378 the decoded size cannot be expressed in\r
379 BinLength on output.\r
dc469f13
LE
380 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the\r
381 converted data.\r
4c5a5e0c 382**/\r
383EFI_STATUS\r
384IScsiHexToBin (\r
d1050b9d
MK
385 IN OUT UINT8 *BinBuffer,\r
386 IN OUT UINT32 *BinLength,\r
387 IN CHAR8 *HexStr\r
4c5a5e0c 388 )\r
389{\r
54e90eda
LE
390 UINTN BinLengthMin;\r
391 UINT32 BinLengthProvided;\r
4c5a5e0c 392 UINTN Index;\r
393 UINTN Length;\r
394 UINT8 Digit;\r
395 CHAR8 TemStr[2];\r
f75a7f56 396\r
4c5a5e0c 397 ZeroMem (TemStr, sizeof (TemStr));\r
398\r
399 //\r
400 // Find out how many hex characters the string has.\r
401 //\r
402 if ((HexStr[0] == '0') && ((HexStr[1] == 'x') || (HexStr[1] == 'X'))) {\r
403 HexStr += 2;\r
404 }\r
f75a7f56 405\r
4c5a5e0c 406 Length = AsciiStrLen (HexStr);\r
407\r
47b76780
LE
408 //\r
409 // Reject an empty hex string; reject a stray nibble.\r
410 //\r
d1050b9d 411 if ((Length == 0) || (Length % 2 != 0)) {\r
47b76780
LE
412 return EFI_INVALID_PARAMETER;\r
413 }\r
d1050b9d 414\r
54e90eda
LE
415 //\r
416 // Check if the caller provides enough room for the decoded blob.\r
417 //\r
418 BinLengthMin = Length / 2;\r
419 if (BinLengthMin > MAX_UINT32) {\r
420 return EFI_BAD_BUFFER_SIZE;\r
421 }\r
d1050b9d 422\r
54e90eda 423 BinLengthProvided = *BinLength;\r
d1050b9d 424 *BinLength = (UINT32)BinLengthMin;\r
54e90eda
LE
425 if (BinLengthProvided < BinLengthMin) {\r
426 return EFI_BUFFER_TOO_SMALL;\r
427 }\r
47b76780 428\r
d1050b9d 429 for (Index = 0; Index < Length; Index++) {\r
4c5a5e0c 430 TemStr[0] = HexStr[Index];\r
d1050b9d
MK
431 Digit = (UINT8)AsciiStrHexToUint64 (TemStr);\r
432 if ((Digit == 0) && (TemStr[0] != '0')) {\r
4c5a5e0c 433 //\r
47b76780 434 // Invalid Hex Char.\r
4c5a5e0c 435 //\r
47b76780 436 return EFI_INVALID_PARAMETER;\r
4c5a5e0c 437 }\r
d1050b9d 438\r
4c5a5e0c 439 if ((Index & 1) == 0) {\r
d1050b9d 440 BinBuffer[Index/2] = Digit;\r
4c5a5e0c 441 } else {\r
d1050b9d 442 BinBuffer[Index/2] = (UINT8)((BinBuffer[Index/2] << 4) + Digit);\r
4c5a5e0c 443 }\r
444 }\r
d1050b9d 445\r
4c5a5e0c 446 return EFI_SUCCESS;\r
447}\r
448\r
4c5a5e0c 449/**\r
450 Convert the decimal-constant string or hex-constant string into a numerical value.\r
451\r
452 @param[in] Str String in decimal or hex.\r
453\r
454 @return The numerical value.\r
455\r
456**/\r
457UINTN\r
458IScsiNetNtoi (\r
459 IN CHAR8 *Str\r
460 )\r
461{\r
462 if ((Str[0] == '0') && ((Str[1] == 'x') || (Str[1] == 'X'))) {\r
463 Str += 2;\r
464\r
465 return AsciiStrHexToUintn (Str);\r
466 }\r
467\r
468 return AsciiStrDecimalToUintn (Str);\r
469}\r
470\r
4c5a5e0c 471/**\r
472 Generate random numbers.\r
473\r
474 @param[in, out] Rand The buffer to contain random numbers.\r
475 @param[in] RandLength The length of the Rand buffer.\r
476\r
477**/\r
478VOID\r
479IScsiGenRandom (\r
480 IN OUT UINT8 *Rand,\r
481 IN UINTN RandLength\r
482 )\r
483{\r
484 UINT32 Random;\r
485\r
486 while (RandLength > 0) {\r
487 Random = NET_RANDOM (NetRandomInitSeed ());\r
d1050b9d 488 *Rand++ = (UINT8)(Random);\r
4c5a5e0c 489 RandLength--;\r
490 }\r
491}\r
492\r
6b08dd6e
JW
493/**\r
494 Check whether UNDI protocol supports IPv6.\r
495\r
496 @param[in] ControllerHandle Controller handle.\r
497 @param[in] Image Handle of the image.\r
498 @param[out] Ipv6Support TRUE if UNDI supports IPv6.\r
499\r
500 @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.\r
501 @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.\r
502\r
503**/\r
504EFI_STATUS\r
505IScsiCheckIpv6Support (\r
d1050b9d
MK
506 IN EFI_HANDLE ControllerHandle,\r
507 IN EFI_HANDLE Image,\r
508 OUT BOOLEAN *Ipv6Support\r
6b08dd6e
JW
509 )\r
510{\r
d1050b9d
MK
511 EFI_HANDLE Handle;\r
512 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
513 EFI_STATUS Status;\r
514 EFI_GUID *InfoTypesBuffer;\r
515 UINTN InfoTypeBufferCount;\r
516 UINTN TypeIndex;\r
517 BOOLEAN Supported;\r
518 VOID *InfoBlock;\r
519 UINTN InfoBlockSize;\r
520\r
521 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;\r
6b08dd6e
JW
522\r
523 ASSERT (Ipv6Support != NULL);\r
524\r
525 //\r
526 // Check whether the UNDI supports IPv6 by NII protocol.\r
527 //\r
528 Status = gBS->OpenProtocol (\r
529 ControllerHandle,\r
530 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
d1050b9d 531 (VOID **)&Nii,\r
6b08dd6e
JW
532 Image,\r
533 ControllerHandle,\r
534 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
535 );\r
536 if (Status == EFI_SUCCESS) {\r
537 *Ipv6Support = Nii->Ipv6Supported;\r
538 return EFI_SUCCESS;\r
539 }\r
540\r
541 //\r
542 // Get the NIC handle by SNP protocol.\r
f75a7f56 543 //\r
6b08dd6e
JW
544 Handle = NetLibGetSnpHandle (ControllerHandle, NULL);\r
545 if (Handle == NULL) {\r
546 return EFI_NOT_FOUND;\r
547 }\r
548\r
549 Aip = NULL;\r
550 Status = gBS->HandleProtocol (\r
551 Handle,\r
552 &gEfiAdapterInformationProtocolGuid,\r
d1050b9d 553 (VOID *)&Aip\r
6b08dd6e 554 );\r
d1050b9d 555 if (EFI_ERROR (Status) || (Aip == NULL)) {\r
6b08dd6e
JW
556 return EFI_NOT_FOUND;\r
557 }\r
558\r
559 InfoTypesBuffer = NULL;\r
560 InfoTypeBufferCount = 0;\r
d1050b9d
MK
561 Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);\r
562 if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {\r
6b08dd6e
JW
563 FreePool (InfoTypesBuffer);\r
564 return EFI_NOT_FOUND;\r
565 }\r
566\r
567 Supported = FALSE;\r
568 for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {\r
569 if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {\r
570 Supported = TRUE;\r
571 break;\r
572 }\r
573 }\r
574\r
575 FreePool (InfoTypesBuffer);\r
576 if (!Supported) {\r
577 return EFI_NOT_FOUND;\r
578 }\r
579\r
580 //\r
581 // We now have adapter information block.\r
582 //\r
583 InfoBlock = NULL;\r
584 InfoBlockSize = 0;\r
d1050b9d
MK
585 Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);\r
586 if (EFI_ERROR (Status) || (InfoBlock == NULL)) {\r
6b08dd6e
JW
587 FreePool (InfoBlock);\r
588 return EFI_NOT_FOUND;\r
f75a7f56 589 }\r
6b08dd6e 590\r
d1050b9d 591 *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InfoBlock)->Ipv6Support;\r
6b08dd6e 592 FreePool (InfoBlock);\r
f75a7f56 593\r
6b08dd6e
JW
594 return EFI_SUCCESS;\r
595}\r
596\r
4c5a5e0c 597/**\r
598 Record the NIC info in global structure.\r
599\r
600 @param[in] Controller The handle of the controller.\r
6b08dd6e 601 @param[in] Image Handle of the image.\r
4c5a5e0c 602\r
603 @retval EFI_SUCCESS The operation is completed.\r
604 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this\r
605 operation.\r
606\r
607**/\r
608EFI_STATUS\r
609IScsiAddNic (\r
6b08dd6e
JW
610 IN EFI_HANDLE Controller,\r
611 IN EFI_HANDLE Image\r
4c5a5e0c 612 )\r
613{\r
d1050b9d
MK
614 EFI_STATUS Status;\r
615 ISCSI_NIC_INFO *NicInfo;\r
616 LIST_ENTRY *Entry;\r
617 EFI_MAC_ADDRESS MacAddr;\r
618 UINTN HwAddressSize;\r
619 UINT16 VlanId;\r
4c5a5e0c 620\r
621 //\r
622 // Get MAC address of this network device.\r
623 //\r
624 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
625 if (EFI_ERROR (Status)) {\r
626 return Status;\r
627 }\r
628\r
629 //\r
630 // Get VLAN ID of this network device.\r
631 //\r
632 VlanId = NetLibGetVlanId (Controller);\r
633\r
634 //\r
635 // Check whether the NIC info already exists. Return directly if so.\r
636 //\r
637 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
638 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
d1050b9d
MK
639 if ((NicInfo->HwAddressSize == HwAddressSize) &&\r
640 (CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0) &&\r
641 (NicInfo->VlanId == VlanId))\r
642 {\r
4c5a5e0c 643 mPrivate->CurrentNic = NicInfo->NicIndex;\r
f75a7f56
LG
644\r
645 //\r
6b08dd6e 646 // Set IPv6 available flag.\r
f75a7f56 647 //\r
6b08dd6e
JW
648 Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);\r
649 if (EFI_ERROR (Status)) {\r
650 //\r
f75a7f56 651 // Fail to get the data whether UNDI supports IPv6.\r
6b08dd6e
JW
652 // Set default value to TRUE.\r
653 //\r
654 NicInfo->Ipv6Available = TRUE;\r
655 }\r
f75a7f56 656\r
4c5a5e0c 657 return EFI_SUCCESS;\r
658 }\r
659\r
660 if (mPrivate->MaxNic < NicInfo->NicIndex) {\r
661 mPrivate->MaxNic = NicInfo->NicIndex;\r
662 }\r
663 }\r
664\r
665 //\r
666 // Record the NIC info in private structure.\r
667 //\r
668 NicInfo = AllocateZeroPool (sizeof (ISCSI_NIC_INFO));\r
669 if (NicInfo == NULL) {\r
670 return EFI_OUT_OF_RESOURCES;\r
671 }\r
672\r
673 CopyMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize);\r
d1050b9d
MK
674 NicInfo->HwAddressSize = (UINT32)HwAddressSize;\r
675 NicInfo->VlanId = VlanId;\r
676 NicInfo->NicIndex = (UINT8)(mPrivate->MaxNic + 1);\r
677 mPrivate->MaxNic = NicInfo->NicIndex;\r
f75a7f56 678\r
6b08dd6e
JW
679 //\r
680 // Set IPv6 available flag.\r
f75a7f56 681 //\r
6b08dd6e
JW
682 Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);\r
683 if (EFI_ERROR (Status)) {\r
684 //\r
f75a7f56 685 // Fail to get the data whether UNDI supports IPv6.\r
6b08dd6e
JW
686 // Set default value to TRUE.\r
687 //\r
688 NicInfo->Ipv6Available = TRUE;\r
689 }\r
f75a7f56 690\r
4c5a5e0c 691 //\r
692 // Get the PCI location.\r
693 //\r
694 IScsiGetNICPciLocation (\r
695 Controller,\r
696 &NicInfo->BusNumber,\r
697 &NicInfo->DeviceNumber,\r
698 &NicInfo->FunctionNumber\r
699 );\r
700\r
701 InsertTailList (&mPrivate->NicInfoList, &NicInfo->Link);\r
702 mPrivate->NicCount++;\r
703\r
704 mPrivate->CurrentNic = NicInfo->NicIndex;\r
705 return EFI_SUCCESS;\r
706}\r
707\r
4c5a5e0c 708/**\r
709 Delete the recorded NIC info from global structure. Also delete corresponding\r
710 attempts.\r
711\r
712 @param[in] Controller The handle of the controller.\r
713\r
714 @retval EFI_SUCCESS The operation is completed.\r
715 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.\r
716\r
717**/\r
718EFI_STATUS\r
719IScsiRemoveNic (\r
720 IN EFI_HANDLE Controller\r
721 )\r
722{\r
d1050b9d
MK
723 EFI_STATUS Status;\r
724 ISCSI_NIC_INFO *NicInfo;\r
725 LIST_ENTRY *Entry;\r
726 LIST_ENTRY *NextEntry;\r
727 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
728 ISCSI_NIC_INFO *ThisNic;\r
729 EFI_MAC_ADDRESS MacAddr;\r
730 UINTN HwAddressSize;\r
731 UINT16 VlanId;\r
4c5a5e0c 732\r
733 //\r
734 // Get MAC address of this network device.\r
735 //\r
736 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
737 if (EFI_ERROR (Status)) {\r
738 return Status;\r
739 }\r
740\r
741 //\r
742 // Get VLAN ID of this network device.\r
743 //\r
744 VlanId = NetLibGetVlanId (Controller);\r
745\r
746 //\r
747 // Check whether the NIC information exists.\r
748 //\r
749 ThisNic = NULL;\r
750\r
751 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
752 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
d1050b9d
MK
753 if ((NicInfo->HwAddressSize == HwAddressSize) &&\r
754 (CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0) &&\r
755 (NicInfo->VlanId == VlanId))\r
756 {\r
4c5a5e0c 757 ThisNic = NicInfo;\r
758 break;\r
759 }\r
760 }\r
761\r
762 if (ThisNic == NULL) {\r
763 return EFI_NOT_FOUND;\r
764 }\r
765\r
766 mPrivate->CurrentNic = ThisNic->NicIndex;\r
767\r
768 RemoveEntryList (&ThisNic->Link);\r
769 FreePool (ThisNic);\r
770 mPrivate->NicCount--;\r
771\r
772 //\r
773 // Remove all attempts related to this NIC.\r
774 //\r
775 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {\r
776 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
777 if (AttemptConfigData->NicIndex == mPrivate->CurrentNic) {\r
778 RemoveEntryList (&AttemptConfigData->Link);\r
779 mPrivate->AttemptCount--;\r
780\r
d1050b9d 781 if ((AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) && (mPrivate->MpioCount > 0)) {\r
4c5a5e0c 782 if (--mPrivate->MpioCount == 0) {\r
783 mPrivate->EnableMpio = FALSE;\r
784 }\r
785\r
d1050b9d 786 if ((AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) && (mPrivate->Krb5MpioCount > 0)) {\r
4c5a5e0c 787 mPrivate->Krb5MpioCount--;\r
788 }\r
d1050b9d 789 } else if ((AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) && (mPrivate->SinglePathCount > 0)) {\r
4c5a5e0c 790 mPrivate->SinglePathCount--;\r
791\r
792 if (mPrivate->ValidSinglePathCount > 0) {\r
793 mPrivate->ValidSinglePathCount--;\r
794 }\r
795 }\r
796\r
797 FreePool (AttemptConfigData);\r
798 }\r
799 }\r
800\r
8d1f5e04
ZL
801 return EFI_SUCCESS;\r
802}\r
803\r
804/**\r
805 Create and initialize the Attempts.\r
806\r
807 @param[in] AttemptNum The number of Attempts will be created.\r
808\r
809 @retval EFI_SUCCESS The Attempts have been created successfully.\r
810 @retval Others Failed to create the Attempt.\r
811\r
812**/\r
813EFI_STATUS\r
814IScsiCreateAttempts (\r
d1050b9d
MK
815 IN UINTN AttemptNum\r
816 )\r
8d1f5e04 817{\r
d1050b9d
MK
818 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
819 ISCSI_SESSION_CONFIG_NVDATA *ConfigData;\r
820 UINT8 *AttemptConfigOrder;\r
821 UINTN AttemptConfigOrderSize;\r
822 UINT8 *AttemptOrderTmp;\r
823 UINTN TotalNumber;\r
824 UINT8 Index;\r
825 EFI_STATUS Status;\r
8d1f5e04 826\r
d1050b9d 827 for (Index = 1; Index <= AttemptNum; Index++) {\r
8d1f5e04
ZL
828 //\r
829 // Get the initialized attempt order. This is used to essure creating attempts by order.\r
830 //\r
831 AttemptConfigOrder = IScsiGetVariableAndSize (\r
832 L"InitialAttemptOrder",\r
833 &gIScsiConfigGuid,\r
834 &AttemptConfigOrderSize\r
835 );\r
836 TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
837 if (TotalNumber == AttemptNum) {\r
838 Status = EFI_SUCCESS;\r
839 break;\r
840 }\r
d1050b9d 841\r
8d1f5e04
ZL
842 TotalNumber++;\r
843\r
844 //\r
845 // Append the new created attempt to the end.\r
846 //\r
847 AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
848 if (AttemptOrderTmp == NULL) {\r
849 if (AttemptConfigOrder != NULL) {\r
850 FreePool (AttemptConfigOrder);\r
851 }\r
d1050b9d 852\r
8d1f5e04
ZL
853 return EFI_OUT_OF_RESOURCES;\r
854 }\r
855\r
856 if (AttemptConfigOrder != NULL) {\r
857 CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
858 FreePool (AttemptConfigOrder);\r
859 }\r
860\r
861 AttemptOrderTmp[TotalNumber - 1] = Index;\r
862 AttemptConfigOrder = AttemptOrderTmp;\r
863 AttemptConfigOrderSize = TotalNumber * sizeof (UINT8);\r
864\r
865 Status = gRT->SetVariable (\r
866 L"InitialAttemptOrder",\r
867 &gIScsiConfigGuid,\r
868 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
869 AttemptConfigOrderSize,\r
870 AttemptConfigOrder\r
871 );\r
872 FreePool (AttemptConfigOrder);\r
873 if (EFI_ERROR (Status)) {\r
d1050b9d
MK
874 DEBUG ((\r
875 DEBUG_ERROR,\r
a2481def
VS
876 "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "\r
877 "%r\n",\r
d1050b9d
MK
878 __FUNCTION__,\r
879 &gIScsiConfigGuid,\r
880 Status\r
881 ));\r
8d1f5e04
ZL
882 return Status;\r
883 }\r
884\r
885 //\r
886 // Create new Attempt\r
887 //\r
888 AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));\r
889 if (AttemptConfigData == NULL) {\r
890 return EFI_OUT_OF_RESOURCES;\r
891 }\r
d1050b9d 892\r
8d1f5e04
ZL
893 ConfigData = &AttemptConfigData->SessionConfigData;\r
894 ConfigData->TargetPort = ISCSI_WELL_KNOWN_PORT;\r
895 ConfigData->ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;\r
896 ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;\r
897\r
898 AttemptConfigData->AuthenticationType = ISCSI_AUTH_TYPE_CHAP;\r
899 AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;\r
900 //\r
901 // Configure the Attempt index and set variable.\r
902 //\r
903 AttemptConfigData->AttemptConfigIndex = Index;\r
904\r
905 //\r
906 // Set the attempt name according to the order.\r
907 //\r
908 UnicodeSPrint (\r
909 mPrivate->PortString,\r
d1050b9d 910 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 911 L"Attempt %d",\r
d1050b9d 912 (UINTN)AttemptConfigData->AttemptConfigIndex\r
8d1f5e04
ZL
913 );\r
914 UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);\r
915\r
916 Status = gRT->SetVariable (\r
917 mPrivate->PortString,\r
918 &gEfiIScsiInitiatorNameProtocolGuid,\r
919 ISCSI_CONFIG_VAR_ATTR,\r
920 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
921 AttemptConfigData\r
922 );\r
923 FreePool (AttemptConfigData);\r
924 if (EFI_ERROR (Status)) {\r
d1050b9d
MK
925 DEBUG ((\r
926 DEBUG_ERROR,\r
927 "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "\r
928 "%r\n",\r
929 __FUNCTION__,\r
930 &gEfiIScsiInitiatorNameProtocolGuid,\r
931 Status\r
932 ));\r
8d1f5e04
ZL
933 return Status;\r
934 }\r
c0d494b5 935 }\r
936\r
4c5a5e0c 937 return EFI_SUCCESS;\r
938}\r
939\r
8d1f5e04
ZL
940/**\r
941 Create the iSCSI configuration Keywords for each attempt. You can find the keywords\r
942 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).\r
943\r
944 @param[in] KeywordNum The number Sets of Keywords will be created.\r
945\r
946 @retval EFI_SUCCESS The operation is completed.\r
947 @retval Others Failed to create the Keywords.\r
948\r
949**/\r
950EFI_STATUS\r
951IScsiCreateKeywords (\r
d1050b9d
MK
952 IN UINTN KeywordNum\r
953 )\r
8d1f5e04 954{\r
d1050b9d
MK
955 VOID *StartOpCodeHandle;\r
956 EFI_IFR_GUID_LABEL *StartLabel;\r
957 VOID *EndOpCodeHandle;\r
958 EFI_IFR_GUID_LABEL *EndLabel;\r
959 UINTN Index;\r
960 EFI_STRING_ID StringToken;\r
961 CHAR16 StringId[64];\r
962 CHAR16 KeywordId[32];\r
963 EFI_STATUS Status;\r
8d1f5e04
ZL
964\r
965 Status = IScsiCreateOpCode (\r
966 KEYWORD_ENTRY_LABEL,\r
967 &StartOpCodeHandle,\r
968 &StartLabel,\r
969 &EndOpCodeHandle,\r
970 &EndLabel\r
971 );\r
972 if (EFI_ERROR (Status)) {\r
973 return EFI_OUT_OF_RESOURCES;\r
974 }\r
975\r
d1050b9d 976 for (Index = 1; Index <= KeywordNum; Index++) {\r
8d1f5e04
ZL
977 //\r
978 // Create iSCSIAttemptName Keyword.\r
979 //\r
980 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index);\r
981 StringToken = HiiSetString (\r
982 mCallbackInfo->RegisteredHandle,\r
983 0,\r
984 StringId,\r
985 NULL\r
986 );\r
987 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAttemptName:%d", Index);\r
988 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
989 HiiCreateStringOpCode (\r
990 StartOpCodeHandle,\r
d1050b9d 991 (EFI_QUESTION_ID)(ATTEMPT_ATTEMPT_NAME_QUESTION_ID + (Index - 1)),\r
8d1f5e04 992 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 993 (UINT16)(ATTEMPT_ATTEMPT_NAME_VAR_OFFSET + ATTEMPT_NAME_SIZE * (Index - 1) * sizeof (CHAR16)),\r
8d1f5e04
ZL
994 StringToken,\r
995 StringToken,\r
996 EFI_IFR_FLAG_READ_ONLY,\r
997 0,\r
998 0,\r
999 ATTEMPT_NAME_SIZE,\r
1000 NULL\r
1001 );\r
1002\r
1003 //\r
1004 // Create iSCSIBootEnable Keyword.\r
1005 //\r
1006 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_MODE_PROMPT%d", Index);\r
1007 StringToken = HiiSetString (\r
1008 mCallbackInfo->RegisteredHandle,\r
1009 0,\r
1010 StringId,\r
1011 NULL\r
1012 );\r
1013 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIBootEnable:%d", Index);\r
1014 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1015 HiiCreateNumericOpCode (\r
1016 StartOpCodeHandle,\r
d1050b9d 1017 (EFI_QUESTION_ID)(ATTEMPT_BOOTENABLE_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1018 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1019 (UINT16)(ATTEMPT_BOOTENABLE_VAR_OFFSET + (Index - 1)),\r
8d1f5e04
ZL
1020 StringToken,\r
1021 StringToken,\r
1022 0,\r
1023 EFI_IFR_NUMERIC_SIZE_1,\r
1024 0,\r
1025 2,\r
1026 0,\r
1027 NULL\r
1028 );\r
1029\r
1030 //\r
1031 // Create iSCSIIpAddressType Keyword.\r
1032 //\r
1033 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_IP_MODE_PROMPT%d", Index);\r
1034 StringToken = HiiSetString (\r
1035 mCallbackInfo->RegisteredHandle,\r
1036 0,\r
1037 StringId,\r
1038 NULL\r
1039 );\r
1040 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIIpAddressType:%d", Index);\r
1041 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1042 HiiCreateNumericOpCode (\r
1043 StartOpCodeHandle,\r
d1050b9d 1044 (EFI_QUESTION_ID)(ATTEMPT_ADDRESS_TYPE_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1045 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1046 (UINT16)(ATTEMPT_ADDRESS_TYPE_VAR_OFFSET + (Index - 1)),\r
8d1f5e04
ZL
1047 StringToken,\r
1048 StringToken,\r
1049 0,\r
1050 EFI_IFR_NUMERIC_SIZE_1,\r
1051 0,\r
1052 2,\r
1053 0,\r
1054 NULL\r
1055 );\r
1056\r
1057 //\r
1058 // Create iSCSIConnectRetry Keyword.\r
1059 //\r
1060 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index);\r
1061 StringToken = HiiSetString (\r
1062 mCallbackInfo->RegisteredHandle,\r
1063 0,\r
1064 StringId,\r
1065 NULL\r
1066 );\r
1067 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectRetry:%d", Index);\r
1068 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1069 HiiCreateNumericOpCode (\r
1070 StartOpCodeHandle,\r
d1050b9d 1071 (EFI_QUESTION_ID)(ATTEMPT_CONNECT_RETRY_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1072 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1073 (UINT16)(ATTEMPT_CONNECT_RETRY_VAR_OFFSET + (Index - 1)),\r
8d1f5e04
ZL
1074 StringToken,\r
1075 StringToken,\r
1076 0,\r
1077 EFI_IFR_NUMERIC_SIZE_1,\r
1078 0,\r
1079 16,\r
1080 0,\r
1081 NULL\r
1082 );\r
1083\r
1084 //\r
1085 // Create iSCSIConnectTimeout Keyword.\r
1086 //\r
1087 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index);\r
1088 StringToken = HiiSetString (\r
1089 mCallbackInfo->RegisteredHandle,\r
1090 0,\r
1091 StringId,\r
1092 NULL\r
1093 );\r
1094 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectTimeout:%d", Index);\r
1095 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1096 HiiCreateNumericOpCode (\r
1097 StartOpCodeHandle,\r
d1050b9d 1098 (EFI_QUESTION_ID)(ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1099 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1100 (UINT16)(ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET + 2 * (Index - 1)),\r
8d1f5e04
ZL
1101 StringToken,\r
1102 StringToken,\r
1103 0,\r
1104 EFI_IFR_NUMERIC_SIZE_2,\r
1105 CONNECT_MIN_TIMEOUT,\r
1106 CONNECT_MAX_TIMEOUT,\r
1107 0,\r
1108 NULL\r
1109 );\r
1110\r
1111 //\r
1112 // Create ISID Keyword.\r
1113 //\r
1114 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ISID_PROMPT%d", Index);\r
1115 StringToken = HiiSetString (\r
1116 mCallbackInfo->RegisteredHandle,\r
1117 0,\r
1118 StringId,\r
1119 NULL\r
1120 );\r
1121 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIISID:%d", Index);\r
1122 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1123 HiiCreateStringOpCode (\r
1124 StartOpCodeHandle,\r
d1050b9d 1125 (EFI_QUESTION_ID)(ATTEMPT_ISID_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1126 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1127 (UINT16)(ATTEMPT_ISID_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04 1128 StringToken,\r
41c9011c 1129 STRING_TOKEN (STR_ISCSI_ISID_HELP),\r
8d1f5e04
ZL
1130 0,\r
1131 0,\r
1132 ISID_CONFIGURABLE_MIN_LEN,\r
1133 ISID_CONFIGURABLE_STORAGE,\r
1134 NULL\r
1135 );\r
1136\r
1137 //\r
1138 // Create iSCSIInitiatorInfoViaDHCP Keyword.\r
1139 //\r
1140 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index);\r
1141 StringToken = HiiSetString (\r
1142 mCallbackInfo->RegisteredHandle,\r
1143 0,\r
1144 StringId,\r
1145 NULL\r
1146 );\r
1147 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorInfoViaDHCP:%d", Index);\r
1148 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1149 HiiCreateNumericOpCode (\r
d1050b9d
MK
1150 StartOpCodeHandle,\r
1151 (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID + (Index - 1)),\r
1152 CONFIGURATION_VARSTORE_ID,\r
1153 (UINT16)(ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET + (Index - 1)),\r
1154 StringToken,\r
1155 StringToken,\r
1156 0,\r
1157 0,\r
1158 0,\r
1159 1,\r
1160 0,\r
1161 NULL\r
1162 );\r
8d1f5e04
ZL
1163\r
1164 //\r
1165 // Create iSCSIInitiatorIpAddress Keyword.\r
1166 //\r
1167 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index);\r
1168 StringToken = HiiSetString (\r
1169 mCallbackInfo->RegisteredHandle,\r
1170 0,\r
1171 StringId,\r
1172 NULL\r
1173 );\r
1174 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorIpAddress:%d", Index);\r
1175 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1176 HiiCreateStringOpCode (\r
1177 StartOpCodeHandle,\r
d1050b9d 1178 (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1179 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1180 (UINT16)(ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1181 StringToken,\r
1182 StringToken,\r
1183 0,\r
1184 0,\r
1185 IP4_MIN_SIZE,\r
8b134dfd 1186 IP4_STR_MAX_SIZE,\r
8d1f5e04
ZL
1187 NULL\r
1188 );\r
1189\r
1190 //\r
1191 // Create iSCSIInitiatorNetmask Keyword.\r
1192 //\r
1193 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index);\r
1194 StringToken = HiiSetString (\r
1195 mCallbackInfo->RegisteredHandle,\r
1196 0,\r
1197 StringId,\r
1198 NULL\r
1199 );\r
1200 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorNetmask:%d", Index);\r
1201 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1202 HiiCreateStringOpCode (\r
1203 StartOpCodeHandle,\r
d1050b9d 1204 (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1205 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1206 (UINT16)(ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1207 StringToken,\r
1208 StringToken,\r
1209 0,\r
1210 0,\r
1211 IP4_MIN_SIZE,\r
8b134dfd 1212 IP4_STR_MAX_SIZE,\r
8d1f5e04
ZL
1213 NULL\r
1214 );\r
1215\r
1216 //\r
1217 // Create iSCSIInitiatorGateway Keyword.\r
1218 //\r
1219 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index);\r
1220 StringToken = HiiSetString (\r
1221 mCallbackInfo->RegisteredHandle,\r
1222 0,\r
1223 StringId,\r
1224 NULL\r
1225 );\r
1226 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorGateway:%d", Index);\r
1227 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1228 HiiCreateStringOpCode (\r
1229 StartOpCodeHandle,\r
d1050b9d 1230 (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1231 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1232 (UINT16)(ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1233 StringToken,\r
1234 StringToken,\r
1235 0,\r
1236 0,\r
1237 IP4_MIN_SIZE,\r
8b134dfd 1238 IP4_STR_MAX_SIZE,\r
8d1f5e04
ZL
1239 NULL\r
1240 );\r
1241\r
1242 //\r
1243 // Create iSCSITargetInfoViaDHCP Keyword.\r
1244 //\r
1245 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index);\r
1246 StringToken = HiiSetString (\r
1247 mCallbackInfo->RegisteredHandle,\r
1248 0,\r
1249 StringId,\r
1250 NULL\r
1251 );\r
1252 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetInfoViaDHCP:%d", Index);\r
1253 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1254 HiiCreateNumericOpCode (\r
d1050b9d
MK
1255 StartOpCodeHandle,\r
1256 (EFI_QUESTION_ID)(ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID + (Index - 1)),\r
1257 CONFIGURATION_VARSTORE_ID,\r
1258 (UINT16)(ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET + (Index - 1)),\r
1259 StringToken,\r
1260 StringToken,\r
1261 0,\r
1262 0,\r
1263 0,\r
1264 1,\r
1265 0,\r
1266 NULL\r
1267 );\r
8d1f5e04
ZL
1268\r
1269 //\r
1270 // Create iSCSITargetTcpPort Keyword.\r
1271 //\r
1272 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index);\r
1273 StringToken = HiiSetString (\r
1274 mCallbackInfo->RegisteredHandle,\r
1275 0,\r
1276 StringId,\r
1277 NULL\r
1278 );\r
1279 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetTcpPort:%d", Index);\r
1280 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1281 HiiCreateNumericOpCode (\r
1282 StartOpCodeHandle,\r
d1050b9d 1283 (EFI_QUESTION_ID)(ATTEMPT_TARGET_TCP_PORT_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1284 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1285 (UINT16)(ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET + 2 * (Index - 1)),\r
8d1f5e04
ZL
1286 StringToken,\r
1287 StringToken,\r
1288 0,\r
1289 EFI_IFR_NUMERIC_SIZE_2,\r
1290 TARGET_PORT_MIN_NUM,\r
1291 TARGET_PORT_MAX_NUM,\r
1292 0,\r
1293 NULL\r
1294 );\r
1295\r
1296 //\r
1297 // Create iSCSITargetName Keyword.\r
1298 //\r
1299 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_NAME_PROMPT%d", Index);\r
1300 StringToken = HiiSetString (\r
1301 mCallbackInfo->RegisteredHandle,\r
1302 0,\r
1303 StringId,\r
1304 NULL\r
1305 );\r
1306 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetName:%d", Index);\r
1307 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1308 HiiCreateStringOpCode (\r
1309 StartOpCodeHandle,\r
d1050b9d 1310 (EFI_QUESTION_ID)(ATTEMPT_TARGET_NAME_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1311 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1312 (UINT16)(ATTEMPT_TARGET_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1313 StringToken,\r
1314 StringToken,\r
1315 0,\r
1316 0,\r
1317 ISCSI_NAME_IFR_MIN_SIZE,\r
1318 ISCSI_NAME_IFR_MAX_SIZE,\r
1319 NULL\r
1320 );\r
1321\r
1322 //\r
1323 // Create iSCSITargetIpAddress Keyword.\r
1324 //\r
1325 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index);\r
1326 StringToken = HiiSetString (\r
1327 mCallbackInfo->RegisteredHandle,\r
1328 0,\r
1329 StringId,\r
1330 NULL\r
1331 );\r
1332 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetIpAddress:%d", Index);\r
1333 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1334 HiiCreateStringOpCode (\r
1335 StartOpCodeHandle,\r
d1050b9d 1336 (EFI_QUESTION_ID)(ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1337 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1338 (UINT16)(ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1339 StringToken,\r
1340 StringToken,\r
1341 0,\r
1342 0,\r
1343 IP_MIN_SIZE,\r
8b134dfd 1344 IP_STR_MAX_SIZE,\r
8d1f5e04
ZL
1345 NULL\r
1346 );\r
1347\r
1348 //\r
1349 // Create iSCSILUN Keyword.\r
1350 //\r
1351 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_LUN_PROMPT%d", Index);\r
1352 StringToken = HiiSetString (\r
1353 mCallbackInfo->RegisteredHandle,\r
1354 0,\r
1355 StringId,\r
1356 NULL\r
1357 );\r
1358 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSILUN:%d", Index);\r
1359 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1360 HiiCreateStringOpCode (\r
1361 StartOpCodeHandle,\r
d1050b9d 1362 (EFI_QUESTION_ID)(ATTEMPT_LUN_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1363 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1364 (UINT16)(ATTEMPT_LUN_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1365 StringToken,\r
1366 StringToken,\r
1367 0,\r
1368 0,\r
1369 LUN_MIN_SIZE,\r
1370 LUN_MAX_SIZE,\r
1371 NULL\r
1372 );\r
1373\r
1374 //\r
1375 // Create iSCSIAuthenticationMethod Keyword.\r
1376 //\r
1377 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index);\r
1378 StringToken = HiiSetString (\r
1379 mCallbackInfo->RegisteredHandle,\r
1380 0,\r
1381 StringId,\r
1382 NULL\r
1383 );\r
1384 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAuthenticationMethod:%d", Index);\r
1385 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1386 HiiCreateNumericOpCode (\r
d1050b9d
MK
1387 StartOpCodeHandle,\r
1388 (EFI_QUESTION_ID)(ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID + (Index - 1)),\r
1389 CONFIGURATION_VARSTORE_ID,\r
1390 (UINT16)(ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET + (Index - 1)),\r
1391 StringToken,\r
1392 StringToken,\r
1393 0,\r
1394 0,\r
1395 0,\r
1396 1,\r
1397 0,\r
1398 NULL\r
1399 );\r
8d1f5e04
ZL
1400\r
1401 //\r
1402 // Create iSCSIChapType Keyword.\r
1403 //\r
1404 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHARTYPE_PROMPT%d", Index);\r
1405 StringToken = HiiSetString (\r
1406 mCallbackInfo->RegisteredHandle,\r
1407 0,\r
1408 StringId,\r
1409 NULL\r
1410 );\r
1411 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapType:%d", Index);\r
1412 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1413 HiiCreateNumericOpCode (\r
d1050b9d
MK
1414 StartOpCodeHandle,\r
1415 (EFI_QUESTION_ID)(ATTEMPT_CHARTYPE_QUESTION_ID + (Index - 1)),\r
1416 CONFIGURATION_VARSTORE_ID,\r
1417 (UINT16)(ATTEMPT_CHARTYPE_VAR_OFFSET + (Index - 1)),\r
1418 StringToken,\r
1419 StringToken,\r
1420 0,\r
1421 0,\r
1422 0,\r
1423 1,\r
1424 0,\r
1425 NULL\r
1426 );\r
8d1f5e04
ZL
1427\r
1428 //\r
1429 // Create iSCSIChapUsername Keyword.\r
1430 //\r
1431 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index);\r
1432 StringToken = HiiSetString (\r
1433 mCallbackInfo->RegisteredHandle,\r
1434 0,\r
1435 StringId,\r
1436 NULL\r
1437 );\r
1438 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapUsername:%d", Index);\r
1439 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1440 HiiCreateStringOpCode (\r
1441 StartOpCodeHandle,\r
d1050b9d 1442 (EFI_QUESTION_ID)(ATTEMPT_CHAR_USER_NAME_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1443 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1444 (UINT16)(ATTEMPT_CHAR_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1445 StringToken,\r
1446 StringToken,\r
1447 0,\r
1448 0,\r
1449 0,\r
1450 ISCSI_CHAP_NAME_MAX_LEN,\r
1451 NULL\r
1452 );\r
1453\r
1454 //\r
1455 // Create iSCSIChapSecret Keyword.\r
1456 //\r
1457 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index);\r
1458 StringToken = HiiSetString (\r
1459 mCallbackInfo->RegisteredHandle,\r
1460 0,\r
1461 StringId,\r
1462 NULL\r
1463 );\r
1464 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapSecret:%d", Index);\r
1465 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1466 HiiCreateStringOpCode (\r
1467 StartOpCodeHandle,\r
d1050b9d 1468 (EFI_QUESTION_ID)(ATTEMPT_CHAR_SECRET_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1469 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1470 (UINT16)(ATTEMPT_CHAR_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1471 StringToken,\r
1472 StringToken,\r
1473 0,\r
1474 0,\r
1475 ISCSI_CHAP_SECRET_MIN_LEN,\r
1476 ISCSI_CHAP_SECRET_MAX_LEN,\r
1477 NULL\r
1478 );\r
1479\r
1480 //\r
1481 // Create iSCSIReverseChapUsername Keyword.\r
1482 //\r
1483 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index);\r
1484 StringToken = HiiSetString (\r
1485 mCallbackInfo->RegisteredHandle,\r
1486 0,\r
1487 StringId,\r
1488 NULL\r
1489 );\r
1490 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapUsername:%d", Index);\r
1491 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1492 HiiCreateStringOpCode (\r
1493 StartOpCodeHandle,\r
d1050b9d 1494 (EFI_QUESTION_ID)(ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1495 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1496 (UINT16)(ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1497 StringToken,\r
1498 StringToken,\r
1499 0,\r
1500 0,\r
1501 0,\r
1502 ISCSI_CHAP_NAME_MAX_LEN,\r
1503 NULL\r
1504 );\r
1505\r
1506 //\r
1507 // Create iSCSIReverseChapSecret Keyword.\r
1508 //\r
1509 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index);\r
1510 StringToken = HiiSetString (\r
1511 mCallbackInfo->RegisteredHandle,\r
1512 0,\r
1513 StringId,\r
1514 NULL\r
1515 );\r
1516 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapSecret:%d", Index);\r
1517 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1518 HiiCreateStringOpCode (\r
1519 StartOpCodeHandle,\r
d1050b9d 1520 (EFI_QUESTION_ID)(ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID + (Index - 1)),\r
8d1f5e04 1521 CONFIGURATION_VARSTORE_ID,\r
d1050b9d 1522 (UINT16)(ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
8d1f5e04
ZL
1523 StringToken,\r
1524 StringToken,\r
1525 0,\r
1526 0,\r
1527 ISCSI_CHAP_SECRET_MIN_LEN,\r
1528 ISCSI_CHAP_SECRET_MAX_LEN,\r
1529 NULL\r
1530 );\r
1531 }\r
1532\r
1533 Status = HiiUpdateForm (\r
1534 mCallbackInfo->RegisteredHandle, // HII handle\r
1535 &gIScsiConfigGuid, // Formset GUID\r
1536 FORMID_ATTEMPT_FORM, // Form ID\r
1537 StartOpCodeHandle, // Label for where to insert opcodes\r
1538 EndOpCodeHandle // Replace data\r
1539 );\r
1540\r
1541 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1542 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1543\r
1544 return Status;\r
1545}\r
1546\r
1547/**\r
1548\r
1549 Free the attempt configure data variable.\r
1550\r
1551**/\r
1552VOID\r
1553IScsiCleanAttemptVariable (\r
1554 IN VOID\r
d1050b9d 1555 )\r
8d1f5e04 1556{\r
d1050b9d
MK
1557 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
1558 UINT8 *AttemptConfigOrder;\r
1559 UINTN AttemptConfigOrderSize;\r
1560 UINTN Index;\r
8d1f5e04
ZL
1561\r
1562 //\r
1563 // Get the initialized attempt order.\r
1564 //\r
1565 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1566 L"InitialAttemptOrder",\r
1567 &gIScsiConfigGuid,\r
1568 &AttemptConfigOrderSize\r
1569 );\r
d1050b9d 1570 if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
8d1f5e04
ZL
1571 return;\r
1572 }\r
1573\r
1574 for (Index = 1; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1575 UnicodeSPrint (\r
1576 mPrivate->PortString,\r
d1050b9d 1577 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04
ZL
1578 L"Attempt %d",\r
1579 Index\r
1580 );\r
1581\r
1582 GetVariable2 (\r
1583 mPrivate->PortString,\r
1584 &gEfiIScsiInitiatorNameProtocolGuid,\r
d1050b9d 1585 (VOID **)&AttemptConfigData,\r
8d1f5e04
ZL
1586 NULL\r
1587 );\r
1588\r
1589 if (AttemptConfigData != NULL) {\r
1590 gRT->SetVariable (\r
1591 mPrivate->PortString,\r
1592 &gEfiIScsiInitiatorNameProtocolGuid,\r
1593 0,\r
1594 0,\r
1595 NULL\r
1596 );\r
1597 }\r
1598 }\r
d1050b9d 1599\r
8d1f5e04
ZL
1600 return;\r
1601}\r
4c5a5e0c 1602\r
1603/**\r
1604 Get the recorded NIC info from global structure by the Index.\r
1605\r
1606 @param[in] NicIndex The index indicates the position of NIC info.\r
1607\r
1608 @return Pointer to the NIC info, or NULL if not found.\r
1609\r
1610**/\r
1611ISCSI_NIC_INFO *\r
1612IScsiGetNicInfoByIndex (\r
d1050b9d 1613 IN UINT8 NicIndex\r
4c5a5e0c 1614 )\r
1615{\r
d1050b9d
MK
1616 LIST_ENTRY *Entry;\r
1617 ISCSI_NIC_INFO *NicInfo;\r
4c5a5e0c 1618\r
1619 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
1620 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
1621 if (NicInfo->NicIndex == NicIndex) {\r
1622 return NicInfo;\r
1623 }\r
1624 }\r
1625\r
1626 return NULL;\r
1627}\r
1628\r
4c5a5e0c 1629/**\r
59c0c1cb 1630 Get the NIC's PCI location and return it according to the composited\r
4c5a5e0c 1631 format defined in iSCSI Boot Firmware Table.\r
1632\r
1633 @param[in] Controller The handle of the controller.\r
1634 @param[out] Bus The bus number.\r
1635 @param[out] Device The device number.\r
1636 @param[out] Function The function number.\r
1637\r
1638 @return The composited representation of the NIC PCI location.\r
1639\r
1640**/\r
1641UINT16\r
1642IScsiGetNICPciLocation (\r
1643 IN EFI_HANDLE Controller,\r
1644 OUT UINTN *Bus,\r
1645 OUT UINTN *Device,\r
1646 OUT UINTN *Function\r
1647 )\r
1648{\r
1649 EFI_STATUS Status;\r
1650 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1651 EFI_HANDLE PciIoHandle;\r
1652 EFI_PCI_IO_PROTOCOL *PciIo;\r
1653 UINTN Segment;\r
1654\r
1655 Status = gBS->HandleProtocol (\r
1656 Controller,\r
1657 &gEfiDevicePathProtocolGuid,\r
d1050b9d 1658 (VOID **)&DevicePath\r
4c5a5e0c 1659 );\r
1660 if (EFI_ERROR (Status)) {\r
1661 return 0;\r
1662 }\r
1663\r
1664 Status = gBS->LocateDevicePath (\r
1665 &gEfiPciIoProtocolGuid,\r
1666 &DevicePath,\r
1667 &PciIoHandle\r
1668 );\r
1669 if (EFI_ERROR (Status)) {\r
1670 return 0;\r
1671 }\r
1672\r
d1050b9d 1673 Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);\r
4c5a5e0c 1674 if (EFI_ERROR (Status)) {\r
1675 return 0;\r
1676 }\r
1677\r
1678 Status = PciIo->GetLocation (PciIo, &Segment, Bus, Device, Function);\r
1679 if (EFI_ERROR (Status)) {\r
1680 return 0;\r
1681 }\r
1682\r
d1050b9d 1683 return (UINT16)((*Bus << 8) | (*Device << 3) | *Function);\r
4c5a5e0c 1684}\r
1685\r
4c5a5e0c 1686/**\r
1687 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
1688 buffer, and the size of the buffer. If failure, return NULL.\r
1689\r
1690 @param[in] Name String part of EFI variable name.\r
1691 @param[in] VendorGuid GUID part of EFI variable name.\r
1692 @param[out] VariableSize Returns the size of the EFI variable that was read.\r
1693\r
1694 @return Dynamically allocated memory that contains a copy of the EFI variable.\r
1695 @return Caller is responsible freeing the buffer.\r
1696 @retval NULL Variable was not read.\r
1697\r
1698**/\r
1699VOID *\r
1700IScsiGetVariableAndSize (\r
d1050b9d
MK
1701 IN CHAR16 *Name,\r
1702 IN EFI_GUID *VendorGuid,\r
1703 OUT UINTN *VariableSize\r
4c5a5e0c 1704 )\r
1705{\r
1706 EFI_STATUS Status;\r
1707 UINTN BufferSize;\r
1708 VOID *Buffer;\r
1709\r
1710 Buffer = NULL;\r
1711\r
1712 //\r
1713 // Pass in a zero size buffer to find the required buffer size.\r
1714 //\r
d1050b9d
MK
1715 BufferSize = 0;\r
1716 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
4c5a5e0c 1717 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1718 //\r
1719 // Allocate the buffer to return\r
1720 //\r
1721 Buffer = AllocateZeroPool (BufferSize);\r
1722 if (Buffer == NULL) {\r
1723 return NULL;\r
1724 }\r
d1050b9d 1725\r
4c5a5e0c 1726 //\r
1727 // Read variable into the allocated buffer.\r
1728 //\r
1729 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1730 if (EFI_ERROR (Status)) {\r
1731 BufferSize = 0;\r
1732 }\r
1733 }\r
1734\r
1735 *VariableSize = BufferSize;\r
1736 return Buffer;\r
1737}\r
1738\r
4c5a5e0c 1739/**\r
1740 Create the iSCSI driver data.\r
1741\r
1742 @param[in] Image The handle of the driver image.\r
1743 @param[in] Controller The handle of the controller.\r
1744\r
1745 @return The iSCSI driver data created.\r
1746 @retval NULL Other errors as indicated.\r
1747\r
1748**/\r
1749ISCSI_DRIVER_DATA *\r
1750IScsiCreateDriverData (\r
1751 IN EFI_HANDLE Image,\r
1752 IN EFI_HANDLE Controller\r
1753 )\r
1754{\r
d1050b9d
MK
1755 ISCSI_DRIVER_DATA *Private;\r
1756 EFI_STATUS Status;\r
4c5a5e0c 1757\r
1758 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
1759 if (Private == NULL) {\r
1760 return NULL;\r
1761 }\r
1762\r
1763 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
1764 Private->Image = Image;\r
1765 Private->Controller = Controller;\r
1766 Private->Session = NULL;\r
1767\r
1768 //\r
1769 // Create an event to be signaled when the BS to RT transition is triggerd so\r
1770 // as to abort the iSCSI session.\r
1771 //\r
1772 Status = gBS->CreateEventEx (\r
1773 EVT_NOTIFY_SIGNAL,\r
1774 TPL_CALLBACK,\r
1775 IScsiOnExitBootService,\r
1776 Private,\r
1777 &gEfiEventExitBootServicesGuid,\r
1778 &Private->ExitBootServiceEvent\r
1779 );\r
1780 if (EFI_ERROR (Status)) {\r
1781 FreePool (Private);\r
1782 return NULL;\r
1783 }\r
1784\r
1785 Private->ExtScsiPassThruHandle = NULL;\r
d1050b9d 1786 CopyMem (&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof (EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
4c5a5e0c 1787\r
1788 //\r
1789 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
1790 //\r
1791 Private->ExtScsiPassThruMode.AdapterId = 2;\r
1792 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
1793 Private->ExtScsiPassThruMode.IoAlign = 4;\r
1794 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
1795\r
1796 return Private;\r
1797}\r
1798\r
4c5a5e0c 1799/**\r
1800 Clean the iSCSI driver data.\r
1801\r
e590d29f
ZL
1802 @param[in] Private The iSCSI driver data.\r
1803\r
6d0bab0e 1804 @retval EFI_SUCCESS The clean operation is successful.\r
e590d29f 1805 @retval Others Other errors as indicated.\r
4c5a5e0c 1806\r
1807**/\r
e590d29f 1808EFI_STATUS\r
4c5a5e0c 1809IScsiCleanDriverData (\r
1810 IN ISCSI_DRIVER_DATA *Private\r
1811 )\r
1812{\r
d1050b9d 1813 EFI_STATUS Status;\r
6d0bab0e
ZL
1814\r
1815 Status = EFI_SUCCESS;\r
4c5a5e0c 1816\r
1817 if (Private->DevicePath != NULL) {\r
e590d29f
ZL
1818 Status = gBS->UninstallProtocolInterface (\r
1819 Private->ExtScsiPassThruHandle,\r
1820 &gEfiDevicePathProtocolGuid,\r
1821 Private->DevicePath\r
1822 );\r
1823 if (EFI_ERROR (Status)) {\r
1824 goto EXIT;\r
1825 }\r
4c5a5e0c 1826\r
1827 FreePool (Private->DevicePath);\r
1828 }\r
1829\r
1830 if (Private->ExtScsiPassThruHandle != NULL) {\r
1831 Status = gBS->UninstallProtocolInterface (\r
1832 Private->ExtScsiPassThruHandle,\r
1833 &gEfiExtScsiPassThruProtocolGuid,\r
1834 &Private->IScsiExtScsiPassThru\r
1835 );\r
1836 if (!EFI_ERROR (Status)) {\r
1837 mPrivate->OneSessionEstablished = FALSE;\r
1838 }\r
1839 }\r
1840\r
e590d29f 1841EXIT:\r
a37c60b6 1842 if (Private->ExitBootServiceEvent != NULL) {\r
f75a7f56 1843 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
a37c60b6 1844 }\r
4c5a5e0c 1845\r
3cb5b997
ZL
1846 mCallbackInfo->Current = NULL;\r
1847\r
4c5a5e0c 1848 FreePool (Private);\r
e590d29f 1849 return Status;\r
4c5a5e0c 1850}\r
1851\r
b7cc5bf1
WJ
1852/**\r
1853 Check wheather the Controller handle is configured to use DHCP protocol.\r
1854\r
1855 @param[in] Controller The handle of the controller.\r
1856 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
f75a7f56 1857\r
b7cc5bf1
WJ
1858 @retval TRUE The handle of the controller need the Dhcp protocol.\r
1859 @retval FALSE The handle of the controller does not need the Dhcp protocol.\r
f75a7f56 1860\r
b7cc5bf1
WJ
1861**/\r
1862BOOLEAN\r
1863IScsiDhcpIsConfigured (\r
1864 IN EFI_HANDLE Controller,\r
1865 IN UINT8 IpVersion\r
1866 )\r
1867{\r
d1050b9d
MK
1868 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1869 UINT8 *AttemptConfigOrder;\r
1870 UINTN AttemptConfigOrderSize;\r
1871 UINTN Index;\r
1872 EFI_STATUS Status;\r
1873 EFI_MAC_ADDRESS MacAddr;\r
1874 UINTN HwAddressSize;\r
1875 UINT16 VlanId;\r
1876 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
1877 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
1878 CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];\r
f75a7f56 1879\r
b7cc5bf1
WJ
1880 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1881 L"AttemptOrder",\r
1882 &gIScsiConfigGuid,\r
1883 &AttemptConfigOrderSize\r
1884 );\r
d1050b9d 1885 if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
b7cc5bf1
WJ
1886 return FALSE;\r
1887 }\r
f75a7f56 1888\r
b7cc5bf1
WJ
1889 //\r
1890 // Get MAC address of this network device.\r
1891 //\r
1892 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
d1050b9d 1893 if (EFI_ERROR (Status)) {\r
b7cc5bf1
WJ
1894 return FALSE;\r
1895 }\r
d1050b9d 1896\r
b7cc5bf1
WJ
1897 //\r
1898 // Get VLAN ID of this network device.\r
1899 //\r
1900 VlanId = NetLibGetVlanId (Controller);\r
d1050b9d 1901 IScsiMacAddrToStr (&MacAddr, (UINT32)HwAddressSize, VlanId, MacString);\r
f75a7f56 1902\r
b7cc5bf1
WJ
1903 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1904 UnicodeSPrint (\r
1905 AttemptName,\r
d1050b9d 1906 (UINTN)128,\r
8d1f5e04 1907 L"Attempt %d",\r
d1050b9d 1908 (UINTN)AttemptConfigOrder[Index]\r
b7cc5bf1
WJ
1909 );\r
1910 Status = GetVariable2 (\r
1911 AttemptName,\r
1912 &gEfiIScsiInitiatorNameProtocolGuid,\r
d1050b9d 1913 (VOID **)&AttemptTmp,\r
b7cc5bf1
WJ
1914 NULL\r
1915 );\r
d1050b9d 1916 if ((AttemptTmp == NULL) || EFI_ERROR (Status)) {\r
b7cc5bf1
WJ
1917 continue;\r
1918 }\r
f75a7f56 1919\r
b7cc5bf1
WJ
1920 ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);\r
1921\r
1922 if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
1923 FreePool (AttemptTmp);\r
1924 continue;\r
1925 }\r
1926\r
d1050b9d
MK
1927 if ((AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG) &&\r
1928 (AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)))\r
1929 {\r
b7cc5bf1
WJ
1930 FreePool (AttemptTmp);\r
1931 continue;\r
1932 }\r
8d1f5e04
ZL
1933\r
1934 AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
1935\r
d1050b9d 1936 if ((AttemptTmp->Actived == ISCSI_ACTIVE_DISABLED) || StrCmp (MacString, AttemptMacString)) {\r
8d1f5e04
ZL
1937 continue;\r
1938 }\r
1939\r
d1050b9d
MK
1940 if ((AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) ||\r
1941 (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE) ||\r
1942 (AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE))\r
1943 {\r
b7cc5bf1
WJ
1944 FreePool (AttemptTmp);\r
1945 FreePool (AttemptConfigOrder);\r
1946 return TRUE;\r
1947 }\r
1948\r
1949 FreePool (AttemptTmp);\r
1950 }\r
f75a7f56 1951\r
b7cc5bf1
WJ
1952 FreePool (AttemptConfigOrder);\r
1953 return FALSE;\r
1954}\r
4c5a5e0c 1955\r
eabc6e59 1956/**\r
df077b3e 1957 Check whether the Controller handle is configured to use DNS protocol.\r
eabc6e59
ZL
1958\r
1959 @param[in] Controller The handle of the controller.\r
f75a7f56 1960\r
eabc6e59
ZL
1961 @retval TRUE The handle of the controller need the Dns protocol.\r
1962 @retval FALSE The handle of the controller does not need the Dns protocol.\r
f75a7f56 1963\r
eabc6e59
ZL
1964**/\r
1965BOOLEAN\r
1966IScsiDnsIsConfigured (\r
1967 IN EFI_HANDLE Controller\r
1968 )\r
1969{\r
d1050b9d
MK
1970 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1971 UINT8 *AttemptConfigOrder;\r
1972 UINTN AttemptConfigOrderSize;\r
1973 UINTN Index;\r
1974 EFI_STATUS Status;\r
1975 EFI_MAC_ADDRESS MacAddr;\r
1976 UINTN HwAddressSize;\r
1977 UINT16 VlanId;\r
1978 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
1979 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
1980 CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];\r
f75a7f56 1981\r
eabc6e59
ZL
1982 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1983 L"AttemptOrder",\r
1984 &gIScsiConfigGuid,\r
1985 &AttemptConfigOrderSize\r
1986 );\r
d1050b9d 1987 if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
eabc6e59
ZL
1988 return FALSE;\r
1989 }\r
f75a7f56 1990\r
eabc6e59
ZL
1991 //\r
1992 // Get MAC address of this network device.\r
1993 //\r
1994 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
d1050b9d 1995 if (EFI_ERROR (Status)) {\r
eabc6e59
ZL
1996 return FALSE;\r
1997 }\r
d1050b9d 1998\r
eabc6e59
ZL
1999 //\r
2000 // Get VLAN ID of this network device.\r
2001 //\r
2002 VlanId = NetLibGetVlanId (Controller);\r
d1050b9d 2003 IScsiMacAddrToStr (&MacAddr, (UINT32)HwAddressSize, VlanId, MacString);\r
f75a7f56 2004\r
eabc6e59
ZL
2005 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
2006 UnicodeSPrint (\r
2007 AttemptName,\r
d1050b9d 2008 (UINTN)128,\r
df077b3e 2009 L"Attempt %d",\r
d1050b9d 2010 (UINTN)AttemptConfigOrder[Index]\r
eabc6e59 2011 );\r
df077b3e 2012\r
eabc6e59
ZL
2013 Status = GetVariable2 (\r
2014 AttemptName,\r
2015 &gEfiIScsiInitiatorNameProtocolGuid,\r
d1050b9d 2016 (VOID **)&AttemptTmp,\r
eabc6e59
ZL
2017 NULL\r
2018 );\r
d1050b9d 2019 if ((AttemptTmp == NULL) || EFI_ERROR (Status)) {\r
eabc6e59
ZL
2020 continue;\r
2021 }\r
f75a7f56 2022\r
eabc6e59
ZL
2023 ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);\r
2024\r
df077b3e
ZL
2025 AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
2026\r
d1050b9d 2027 if ((AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) || StrCmp (MacString, AttemptMacString)) {\r
eabc6e59
ZL
2028 FreePool (AttemptTmp);\r
2029 continue;\r
2030 }\r
f75a7f56 2031\r
841d8698 2032 if (AttemptTmp->SessionConfigData.DnsMode || AttemptTmp->SessionConfigData.TargetInfoFromDhcp) {\r
eabc6e59
ZL
2033 FreePool (AttemptTmp);\r
2034 FreePool (AttemptConfigOrder);\r
2035 return TRUE;\r
2036 } else {\r
2037 FreePool (AttemptTmp);\r
2038 continue;\r
2039 }\r
eabc6e59
ZL
2040 }\r
2041\r
2042 FreePool (AttemptConfigOrder);\r
2043 return FALSE;\r
eabc6e59
ZL
2044}\r
2045\r
4c5a5e0c 2046/**\r
2047 Get the various configuration data.\r
2048\r
2049 @param[in] Private The iSCSI driver data.\r
2050\r
2051 @retval EFI_SUCCESS The configuration data is retrieved.\r
2052 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.\r
7c275b3c 2053 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
4c5a5e0c 2054\r
2055**/\r
2056EFI_STATUS\r
2057IScsiGetConfigData (\r
2058 IN ISCSI_DRIVER_DATA *Private\r
2059 )\r
2060{\r
d1050b9d
MK
2061 EFI_STATUS Status;\r
2062 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
2063 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
2064 UINTN Index;\r
2065 ISCSI_NIC_INFO *NicInfo;\r
2066 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2067 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
2068 UINT8 *AttemptConfigOrder;\r
2069 UINTN AttemptConfigOrderSize;\r
2070 CHAR16 IScsiMode[64];\r
2071 CHAR16 IpMode[64];\r
4c5a5e0c 2072\r
2073 //\r
2074 // There should be at least one attempt configured.\r
2075 //\r
2076 AttemptConfigOrder = IScsiGetVariableAndSize (\r
2077 L"AttemptOrder",\r
9bdc6592 2078 &gIScsiConfigGuid,\r
4c5a5e0c 2079 &AttemptConfigOrderSize\r
2080 );\r
d1050b9d 2081 if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {\r
4c5a5e0c 2082 return EFI_NOT_FOUND;\r
2083 }\r
2084\r
2085 //\r
2086 // Get the iSCSI Initiator Name.\r
2087 //\r
d1050b9d
MK
2088 mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
2089 Status = gIScsiInitiatorName.Get (\r
2090 &gIScsiInitiatorName,\r
2091 &mPrivate->InitiatorNameLength,\r
2092 mPrivate->InitiatorName\r
2093 );\r
4c5a5e0c 2094 if (EFI_ERROR (Status)) {\r
2095 return Status;\r
2096 }\r
2097\r
2098 //\r
2099 // Get the normal configuration.\r
2100 //\r
2101 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
4c5a5e0c 2102 //\r
2103 // Check whether the attempt exists in AttemptConfig.\r
2104 //\r
f75a7f56 2105 AttemptTmp = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);\r
d1050b9d 2106 if ((AttemptTmp != NULL) && (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED)) {\r
4c5a5e0c 2107 continue;\r
d1050b9d 2108 } else if ((AttemptTmp != NULL) && (AttemptTmp->SessionConfigData.Enabled != ISCSI_DISABLED)) {\r
4c5a5e0c 2109 //\r
2110 // Check the autoconfig path to see whether it should be retried.\r
2111 //\r
d1050b9d
MK
2112 if ((AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&\r
2113 !AttemptTmp->AutoConfigureSuccess)\r
2114 {\r
4c5a5e0c 2115 if (mPrivate->Ipv6Flag &&\r
d1050b9d
MK
2116 (AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6))\r
2117 {\r
4c5a5e0c 2118 //\r
2119 // Autoconfigure for IP6 already attempted but failed. Do not try again.\r
2120 //\r
2121 continue;\r
2122 } else if (!mPrivate->Ipv6Flag &&\r
d1050b9d
MK
2123 (AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4))\r
2124 {\r
4c5a5e0c 2125 //\r
2126 // Autoconfigure for IP4 already attempted but failed. Do not try again.\r
2127 //\r
2128 continue;\r
2129 } else {\r
2130 //\r
2131 // Try another approach for this autoconfigure path.\r
2132 //\r
2133 AttemptTmp->AutoConfigureMode =\r
d1050b9d 2134 (UINT8)(mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);\r
4c5a5e0c 2135 AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp = TRUE;\r
2136 AttemptTmp->SessionConfigData.TargetInfoFromDhcp = TRUE;\r
2137 AttemptTmp->DhcpSuccess = FALSE;\r
2138\r
2139 //\r
2140 // Get some information from the dhcp server.\r
2141 //\r
2142 if (!mPrivate->Ipv6Flag) {\r
2143 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);\r
2144 if (!EFI_ERROR (Status)) {\r
2145 AttemptTmp->DhcpSuccess = TRUE;\r
2146 }\r
2147 } else {\r
2148 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);\r
2149 if (!EFI_ERROR (Status)) {\r
2150 AttemptTmp->DhcpSuccess = TRUE;\r
2151 }\r
2152 }\r
2153\r
2154 //\r
2155 // Refresh the state of this attempt to NVR.\r
2156 //\r
4c5a5e0c 2157 UnicodeSPrint (\r
2158 mPrivate->PortString,\r
d1050b9d 2159 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2160 L"Attempt %d",\r
d1050b9d 2161 (UINTN)AttemptTmp->AttemptConfigIndex\r
4c5a5e0c 2162 );\r
2163\r
2164 gRT->SetVariable (\r
2165 mPrivate->PortString,\r
2166 &gEfiIScsiInitiatorNameProtocolGuid,\r
2167 ISCSI_CONFIG_VAR_ATTR,\r
2168 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2169 AttemptTmp\r
2170 );\r
2171\r
2172 continue;\r
2173 }\r
f75a7f56
LG
2174 } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp &&\r
2175 !AttemptTmp->ValidPath &&\r
d1050b9d
MK
2176 (AttemptTmp->NicIndex == mPrivate->CurrentNic))\r
2177 {\r
4c5a5e0c 2178 //\r
f75a7f56 2179 // If the attempt associates with the current NIC, we can\r
067ca838 2180 // get DHCP information for already added, but failed, attempt.\r
4c5a5e0c 2181 //\r
2182 AttemptTmp->DhcpSuccess = FALSE;\r
2183 if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) {\r
2184 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);\r
2185 if (!EFI_ERROR (Status)) {\r
2186 AttemptTmp->DhcpSuccess = TRUE;\r
2187 }\r
2188 } else if (mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP6)) {\r
2189 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);\r
2190 if (!EFI_ERROR (Status)) {\r
2191 AttemptTmp->DhcpSuccess = TRUE;\r
2192 }\r
2193 }\r
2194\r
2195 //\r
2196 // Refresh the state of this attempt to NVR.\r
2197 //\r
4c5a5e0c 2198 UnicodeSPrint (\r
2199 mPrivate->PortString,\r
d1050b9d 2200 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2201 L"Attempt %d",\r
d1050b9d 2202 (UINTN)AttemptTmp->AttemptConfigIndex\r
4c5a5e0c 2203 );\r
2204\r
2205 gRT->SetVariable (\r
2206 mPrivate->PortString,\r
2207 &gEfiIScsiInitiatorNameProtocolGuid,\r
2208 ISCSI_CONFIG_VAR_ATTR,\r
2209 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2210 AttemptTmp\r
2211 );\r
2212\r
2213 continue;\r
4c5a5e0c 2214 } else {\r
2215 continue;\r
2216 }\r
2217 }\r
2218\r
2219 //\r
2220 // This attempt does not exist in AttemptConfig. Try to add a new one.\r
2221 //\r
2222\r
2223 NicInfo = IScsiGetNicInfoByIndex (mPrivate->CurrentNic);\r
2224 ASSERT (NicInfo != NULL);\r
2225 IScsiMacAddrToStr (&NicInfo->PermanentAddress, NicInfo->HwAddressSize, NicInfo->VlanId, MacString);\r
2226 UnicodeSPrint (\r
2227 mPrivate->PortString,\r
d1050b9d 2228 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2229 L"Attempt %d",\r
d1050b9d 2230 (UINTN)AttemptConfigOrder[Index]\r
4c5a5e0c 2231 );\r
2232\r
bf4a3dbd 2233 GetVariable2 (\r
a2d59ef2
YT
2234 mPrivate->PortString,\r
2235 &gEfiIScsiInitiatorNameProtocolGuid,\r
d1050b9d 2236 (VOID **)&AttemptConfigData,\r
a2d59ef2
YT
2237 NULL\r
2238 );\r
8d1f5e04 2239 AsciiStrToUnicodeStrS (AttemptConfigData->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
4c5a5e0c 2240\r
d1050b9d
MK
2241 if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_DISABLED) ||\r
2242 StrCmp (MacString, AttemptMacString))\r
2243 {\r
4c5a5e0c 2244 continue;\r
2245 }\r
2246\r
2247 ASSERT (AttemptConfigOrder[Index] == AttemptConfigData->AttemptConfigIndex);\r
2248\r
2249 AttemptConfigData->NicIndex = NicInfo->NicIndex;\r
2250 AttemptConfigData->DhcpSuccess = FALSE;\r
d1050b9d 2251 AttemptConfigData->ValidiBFTPath = (BOOLEAN)(mPrivate->EnableMpio ? TRUE : FALSE);\r
4c5a5e0c 2252 AttemptConfigData->ValidPath = FALSE;\r
2253\r
2254 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {\r
2255 AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp = TRUE;\r
2256 AttemptConfigData->SessionConfigData.TargetInfoFromDhcp = TRUE;\r
2257\r
2258 AttemptConfigData->AutoConfigureMode =\r
d1050b9d 2259 (UINT8)(mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);\r
87ce4210 2260 AttemptConfigData->AutoConfigureSuccess = FALSE;\r
4c5a5e0c 2261 }\r
f75a7f56 2262\r
4c5a5e0c 2263 //\r
2264 // Get some information from dhcp server.\r
2265 //\r
d1050b9d
MK
2266 if ((AttemptConfigData->SessionConfigData.Enabled != ISCSI_DISABLED) &&\r
2267 AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp)\r
2268 {\r
4c5a5e0c 2269 if (!mPrivate->Ipv6Flag &&\r
d1050b9d
MK
2270 ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) ||\r
2271 (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4)))\r
2272 {\r
4c5a5e0c 2273 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptConfigData);\r
2274 if (!EFI_ERROR (Status)) {\r
2275 AttemptConfigData->DhcpSuccess = TRUE;\r
2276 }\r
2277 } else if (mPrivate->Ipv6Flag &&\r
d1050b9d
MK
2278 ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) ||\r
2279 (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6)))\r
2280 {\r
4c5a5e0c 2281 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptConfigData);\r
2282 if (!EFI_ERROR (Status)) {\r
2283 AttemptConfigData->DhcpSuccess = TRUE;\r
2284 }\r
2285 }\r
2286\r
2287 //\r
2288 // Refresh the state of this attempt to NVR.\r
2289 //\r
4c5a5e0c 2290 UnicodeSPrint (\r
2291 mPrivate->PortString,\r
d1050b9d 2292 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2293 L"Attempt %d",\r
d1050b9d 2294 (UINTN)AttemptConfigData->AttemptConfigIndex\r
4c5a5e0c 2295 );\r
2296\r
2297 gRT->SetVariable (\r
2298 mPrivate->PortString,\r
2299 &gEfiIScsiInitiatorNameProtocolGuid,\r
2300 ISCSI_CONFIG_VAR_ATTR,\r
2301 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2302 AttemptConfigData\r
2303 );\r
2304 }\r
2305\r
2306 //\r
2307 // Update Attempt Help Info.\r
2308 //\r
2309\r
2310 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
2311 UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
2312 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2313 UnicodeSPrint (IScsiMode, 64, L"Enabled");\r
2314 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2315 UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");\r
2316 }\r
2317\r
2318 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {\r
2319 UnicodeSPrint (IpMode, 64, L"IP4");\r
2320 } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {\r
2321 UnicodeSPrint (IpMode, 64, L"IP6");\r
2322 } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {\r
2323 UnicodeSPrint (IpMode, 64, L"Autoconfigure");\r
2324 }\r
2325\r
2326 UnicodeSPrint (\r
2327 mPrivate->PortString,\r
d1050b9d 2328 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,\r
4c5a5e0c 2329 L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
2330 MacString,\r
2331 NicInfo->BusNumber,\r
2332 NicInfo->DeviceNumber,\r
2333 NicInfo->FunctionNumber,\r
2334 IScsiMode,\r
2335 IpMode\r
2336 );\r
2337\r
2338 AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
2339 mCallbackInfo->RegisteredHandle,\r
2340 0,\r
2341 mPrivate->PortString,\r
2342 NULL\r
2343 );\r
7c275b3c
ZL
2344 if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
2345 return EFI_OUT_OF_RESOURCES;\r
2346 }\r
4c5a5e0c 2347\r
2348 //\r
2349 // Record the attempt in global link list.\r
2350 //\r
2351 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2352 mPrivate->AttemptCount++;\r
2353\r
2354 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2355 mPrivate->MpioCount++;\r
2356 mPrivate->EnableMpio = TRUE;\r
2357\r
2358 if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {\r
2359 mPrivate->Krb5MpioCount++;\r
2360 }\r
2361 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2362 mPrivate->SinglePathCount++;\r
2363 }\r
2364 }\r
2365\r
2366 //\r
2367 // Reorder the AttemptConfig by the configured order.\r
2368 //\r
2369 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
2370 AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);\r
2371 if (AttemptConfigData == NULL) {\r
2372 continue;\r
2373 }\r
2374\r
2375 RemoveEntryList (&AttemptConfigData->Link);\r
2376 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2377 }\r
2378\r
2379 //\r
2380 // Update the Main Form.\r
2381 //\r
2382 IScsiConfigUpdateAttempt ();\r
2383\r
2384 FreePool (AttemptConfigOrder);\r
2385\r
2386 //\r
2387 // There should be at least one attempt configuration.\r
2388 //\r
2389 if (!mPrivate->EnableMpio) {\r
2390 if (mPrivate->SinglePathCount == 0) {\r
2391 return EFI_NOT_FOUND;\r
2392 }\r
d1050b9d 2393\r
4c5a5e0c 2394 mPrivate->ValidSinglePathCount = mPrivate->SinglePathCount;\r
2395 }\r
2396\r
2397 return EFI_SUCCESS;\r
2398}\r
2399\r
4c5a5e0c 2400/**\r
2401 Get the device path of the iSCSI tcp connection and update it.\r
2402\r
2403 @param Session The iSCSI session.\r
2404\r
2405 @return The updated device path.\r
2406 @retval NULL Other errors as indicated.\r
2407\r
2408**/\r
2409EFI_DEVICE_PATH_PROTOCOL *\r
2410IScsiGetTcpConnDevicePath (\r
d1050b9d 2411 IN ISCSI_SESSION *Session\r
4c5a5e0c 2412 )\r
2413{\r
2414 ISCSI_CONNECTION *Conn;\r
2415 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2416 EFI_STATUS Status;\r
2417 EFI_DEV_PATH *DPathNode;\r
42f0586d 2418 UINTN PathLen;\r
4c5a5e0c 2419\r
2420 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
2421 return NULL;\r
2422 }\r
2423\r
2424 Conn = NET_LIST_USER_STRUCT_S (\r
2425 Session->Conns.ForwardLink,\r
2426 ISCSI_CONNECTION,\r
2427 Link,\r
2428 ISCSI_CONNECTION_SIGNATURE\r
2429 );\r
2430\r
2431 Status = gBS->HandleProtocol (\r
2432 Conn->TcpIo.Handle,\r
2433 &gEfiDevicePathProtocolGuid,\r
d1050b9d 2434 (VOID **)&DevicePath\r
f75a7f56 2435 );\r
4c5a5e0c 2436 if (EFI_ERROR (Status)) {\r
2437 return NULL;\r
2438 }\r
d1050b9d 2439\r
4c5a5e0c 2440 //\r
2441 // Duplicate it.\r
2442 //\r
d1050b9d 2443 DevicePath = DuplicateDevicePath (DevicePath);\r
4c5a5e0c 2444 if (DevicePath == NULL) {\r
2445 return NULL;\r
2446 }\r
2447\r
d1050b9d 2448 DPathNode = (EFI_DEV_PATH *)DevicePath;\r
4c5a5e0c 2449\r
2450 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
2451 if (DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) {\r
d1050b9d
MK
2452 if (!Conn->Ipv6Flag && (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)) {\r
2453 DPathNode->Ipv4.LocalPort = 0;\r
501793fa 2454\r
f75a7f56 2455 DPathNode->Ipv4.StaticIpAddress =\r
d1050b9d 2456 (BOOLEAN)(!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);\r
501793fa 2457\r
42f0586d 2458 //\r
2459 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.\r
2460 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask\r
2461 // do not exist.\r
efb56593 2462 // In new version of IPv4_DEVICE_PATH, structure length is 27.\r
42f0586d 2463 //\r
501793fa 2464\r
42f0586d 2465 PathLen = DevicePathNodeLength (&DPathNode->Ipv4);\r
f75a7f56
LG
2466\r
2467 if (PathLen == IP4_NODE_LEN_NEW_VERSIONS) {\r
42f0586d 2468 IP4_COPY_ADDRESS (\r
2469 &DPathNode->Ipv4.GatewayIpAddress,\r
2470 &Session->ConfigData->SessionConfigData.Gateway\r
2471 );\r
2472\r
2473 IP4_COPY_ADDRESS (\r
2474 &DPathNode->Ipv4.SubnetMask,\r
2475 &Session->ConfigData->SessionConfigData.SubnetMask\r
2476 );\r
2477 }\r
f75a7f56 2478\r
4c5a5e0c 2479 break;\r
d1050b9d
MK
2480 } else if (Conn->Ipv6Flag && (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv6_DP)) {\r
2481 DPathNode->Ipv6.LocalPort = 0;\r
42f0586d 2482\r
2483 //\r
2484 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.\r
2485 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength\r
2486 // and GatewayIpAddress do not exist.\r
f75a7f56 2487 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in\r
42f0586d 2488 // old versions, the length is 43.\r
2489 //\r
2490\r
2491 PathLen = DevicePathNodeLength (&DPathNode->Ipv6);\r
f75a7f56
LG
2492\r
2493 if (PathLen == IP6_NODE_LEN_NEW_VERSIONS ) {\r
42f0586d 2494 DPathNode->Ipv6.IpAddressOrigin = 0;\r
2495 DPathNode->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;\r
2496 ZeroMem (&DPathNode->Ipv6.GatewayIpAddress, sizeof (EFI_IPv6_ADDRESS));\r
d1050b9d 2497 } else if (PathLen == IP6_NODE_LEN_OLD_VERSIONS) {\r
42f0586d 2498 //\r
f75a7f56 2499 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new\r
42f0586d 2500 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.\r
2501 //\r
f75a7f56 2502 *((UINT8 *)(&DPathNode->Ipv6) + IP6_OLD_IPADDRESS_OFFSET) =\r
d1050b9d 2503 (BOOLEAN)(!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);\r
42f0586d 2504 }\r
f75a7f56 2505\r
4c5a5e0c 2506 break;\r
2507 }\r
2508 }\r
2509\r
d1050b9d 2510 DPathNode = (EFI_DEV_PATH *)NextDevicePathNode (&DPathNode->DevPath);\r
4c5a5e0c 2511 }\r
2512\r
2513 return DevicePath;\r
2514}\r
2515\r
4c5a5e0c 2516/**\r
2517 Abort the session when the transition from BS to RT is initiated.\r
2518\r
2519 @param[in] Event The event signaled.\r
2520 @param[in] Context The iSCSI driver data.\r
2521\r
2522**/\r
2523VOID\r
2524EFIAPI\r
2525IScsiOnExitBootService (\r
2526 IN EFI_EVENT Event,\r
2527 IN VOID *Context\r
2528 )\r
2529{\r
d1050b9d 2530 ISCSI_DRIVER_DATA *Private;\r
4c5a5e0c 2531\r
d1050b9d 2532 Private = (ISCSI_DRIVER_DATA *)Context;\r
f75a7f56 2533\r
4c5a5e0c 2534 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
a37c60b6 2535 Private->ExitBootServiceEvent = NULL;\r
f75a7f56 2536\r
4c5a5e0c 2537 if (Private->Session != NULL) {\r
2538 IScsiSessionAbort (Private->Session);\r
2539 }\r
2540}\r
18b24f92
FS
2541\r
2542/**\r
2543 Tests whether a controller handle is being managed by IScsi driver.\r
2544\r
2545 This function tests whether the driver specified by DriverBindingHandle is\r
2546 currently managing the controller specified by ControllerHandle. This test\r
efb56593 2547 is performed by evaluating if the protocol specified by ProtocolGuid is\r
18b24f92 2548 present on ControllerHandle and is was opened by DriverBindingHandle and Nic\r
f75a7f56 2549 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.\r
18b24f92
FS
2550 If ProtocolGuid is NULL, then ASSERT().\r
2551\r
2552 @param ControllerHandle A handle for a controller to test.\r
2553 @param DriverBindingHandle Specifies the driver binding handle for the\r
2554 driver.\r
2555 @param ProtocolGuid Specifies the protocol that the driver specified\r
2556 by DriverBindingHandle opens in its Start()\r
2557 function.\r
2558\r
2559 @retval EFI_SUCCESS ControllerHandle is managed by the driver\r
2560 specified by DriverBindingHandle.\r
2561 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver\r
2562 specified by DriverBindingHandle.\r
2563\r
2564**/\r
2565EFI_STATUS\r
2566EFIAPI\r
2567IScsiTestManagedDevice (\r
d1050b9d
MK
2568 IN EFI_HANDLE ControllerHandle,\r
2569 IN EFI_HANDLE DriverBindingHandle,\r
2570 IN EFI_GUID *ProtocolGuid\r
18b24f92
FS
2571 )\r
2572{\r
d1050b9d
MK
2573 EFI_STATUS Status;\r
2574 VOID *ManagedInterface;\r
2575 EFI_HANDLE NicControllerHandle;\r
18b24f92
FS
2576\r
2577 ASSERT (ProtocolGuid != NULL);\r
2578\r
2579 NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);\r
2580 if (NicControllerHandle == NULL) {\r
2581 return EFI_UNSUPPORTED;\r
2582 }\r
2583\r
2584 Status = gBS->OpenProtocol (\r
2585 ControllerHandle,\r
d1050b9d 2586 (EFI_GUID *)ProtocolGuid,\r
18b24f92
FS
2587 &ManagedInterface,\r
2588 DriverBindingHandle,\r
2589 NicControllerHandle,\r
2590 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2591 );\r
2592 if (!EFI_ERROR (Status)) {\r
2593 gBS->CloseProtocol (\r
2594 ControllerHandle,\r
d1050b9d 2595 (EFI_GUID *)ProtocolGuid,\r
18b24f92
FS
2596 DriverBindingHandle,\r
2597 NicControllerHandle\r
2598 );\r
2599 return EFI_UNSUPPORTED;\r
2600 }\r
2601\r
2602 if (Status != EFI_ALREADY_STARTED) {\r
2603 return EFI_UNSUPPORTED;\r
2604 }\r
2605\r
2606 return EFI_SUCCESS;\r
2607}\r