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