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