]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IScsiDxe/IScsiMisc.c
MdeModulePkg/IScsiDxe: Set ExitBootServiceEvent to NULL after close it.
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiMisc.c
CommitLineData
4c5a5e0c 1/** @file\r
2 Miscellaneous routines for iSCSI driver.\r
3\r
eabc6e59 4Copyright (c) 2004 - 2017, 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
23 On return, Str will hold the trimmed string. \r
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
36 \r
37 if (*Str == 0) {\r
38 return ;\r
39 }\r
40 \r
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
47 \r
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
55 while (*Pointer1 != 0) { \r
56 *Pointer2 = *Pointer1; \r
57 Pointer1++;\r
58 Pointer2++;\r
59 }\r
60 *Pointer2 = 0;\r
61 }\r
62 \r
63 \r
64 for (Pointer1 = Str + StrLen(Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {\r
65 ;\r
66 }\r
67 if (Pointer1 != Str + StrLen(Str) - 1) { \r
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
134 \r
135 ZeroMem (Lun, 8);\r
136 ZeroMem (TemStr, 2);\r
137 ZeroMem ((UINT8 *) Value, sizeof (Value));\r
138 SizeStr = AsciiStrLen (Str); \r
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
153 \r
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
170 \r
171 if (++IndexNum > 4) {\r
172 // \r
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
177 \r
178 //\r
179 // Combine UINT16 value.\r
180 //\r
181 Value[IndexValue] = (UINT16) ((Value[IndexValue] << 4) + TemValue);\r
182 }\r
183 \r
184 for (Index = 0; Index <= IndexValue; Index ++) {\r
185 *((UINT16 *) &Lun[Index * 2]) = HTONS (Value[Index]);\r
186 }\r
187 \r
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
322 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string \r
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
388 \r
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
397 \r
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
415 \r
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
495 \r
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
518 // \r
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
564 } \r
565\r
566 *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support;\r
567 FreePool (InfoBlock);\r
568 \r
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
6b08dd6e
JW
618 \r
619 //\r
620 // Set IPv6 available flag.\r
621 // \r
622 Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);\r
623 if (EFI_ERROR (Status)) {\r
624 //\r
625 // Fail to get the data whether UNDI supports IPv6. \r
626 // Set default value to TRUE.\r
627 //\r
628 NicInfo->Ipv6Available = TRUE;\r
629 }\r
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
6b08dd6e
JW
652 \r
653 //\r
654 // Set IPv6 available flag.\r
655 // \r
656 Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);\r
657 if (EFI_ERROR (Status)) {\r
658 //\r
659 // Fail to get the data whether UNDI supports IPv6. \r
660 // Set default value to TRUE.\r
661 //\r
662 NicInfo->Ipv6Available = TRUE;\r
663 }\r
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
ZL
1800EXIT:\r
1801\r
4c5a5e0c 1802 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
1803\r
3cb5b997
ZL
1804 mCallbackInfo->Current = NULL;\r
1805\r
4c5a5e0c 1806 FreePool (Private);\r
e590d29f 1807 return Status;\r
4c5a5e0c 1808}\r
1809\r
b7cc5bf1
WJ
1810/**\r
1811 Check wheather the Controller handle is configured to use DHCP protocol.\r
1812\r
1813 @param[in] Controller The handle of the controller.\r
1814 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
1815 \r
1816 @retval TRUE The handle of the controller need the Dhcp protocol.\r
1817 @retval FALSE The handle of the controller does not need the Dhcp protocol.\r
1818 \r
1819**/\r
1820BOOLEAN\r
1821IScsiDhcpIsConfigured (\r
1822 IN EFI_HANDLE Controller,\r
1823 IN UINT8 IpVersion\r
1824 )\r
1825{\r
1826 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1827 UINT8 *AttemptConfigOrder;\r
1828 UINTN AttemptConfigOrderSize;\r
1829 UINTN Index;\r
1830 EFI_STATUS Status;\r
1831 EFI_MAC_ADDRESS MacAddr;\r
1832 UINTN HwAddressSize;\r
1833 UINT16 VlanId;\r
1834 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
8d1f5e04 1835 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
b7cc5bf1
WJ
1836 CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];\r
1837 \r
1838 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1839 L"AttemptOrder",\r
1840 &gIScsiConfigGuid,\r
1841 &AttemptConfigOrderSize\r
1842 );\r
1843 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
1844 return FALSE;\r
1845 }\r
1846 \r
1847 //\r
1848 // Get MAC address of this network device.\r
1849 //\r
1850 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
1851 if(EFI_ERROR (Status)) {\r
1852 return FALSE;\r
1853 }\r
1854 //\r
1855 // Get VLAN ID of this network device.\r
1856 //\r
1857 VlanId = NetLibGetVlanId (Controller);\r
1858 IScsiMacAddrToStr (&MacAddr, (UINT32) HwAddressSize, VlanId, MacString);\r
1859 \r
1860 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1861 UnicodeSPrint (\r
1862 AttemptName,\r
1863 (UINTN) 128,\r
8d1f5e04 1864 L"Attempt %d",\r
b7cc5bf1
WJ
1865 (UINTN) AttemptConfigOrder[Index]\r
1866 );\r
1867 Status = GetVariable2 (\r
1868 AttemptName,\r
1869 &gEfiIScsiInitiatorNameProtocolGuid,\r
1870 (VOID**)&AttemptTmp,\r
1871 NULL\r
1872 );\r
107e3d7a 1873 if(AttemptTmp == NULL || EFI_ERROR (Status)) {\r
b7cc5bf1
WJ
1874 continue;\r
1875 }\r
107e3d7a 1876 \r
b7cc5bf1
WJ
1877 ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);\r
1878\r
1879 if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
1880 FreePool (AttemptTmp);\r
1881 continue;\r
1882 }\r
1883\r
1884 if (AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG && \r
1885 AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)) {\r
1886 FreePool (AttemptTmp);\r
1887 continue;\r
1888 }\r
8d1f5e04
ZL
1889\r
1890 AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
1891\r
1892 if (AttemptTmp->Actived == ISCSI_ACTIVE_DISABLED || StrCmp (MacString, AttemptMacString)) {\r
1893 continue;\r
1894 }\r
1895\r
b7cc5bf1
WJ
1896 if(AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG ||\r
1897 AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE ||\r
1898 AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE) { \r
1899 FreePool (AttemptTmp);\r
1900 FreePool (AttemptConfigOrder);\r
1901 return TRUE;\r
1902 }\r
1903\r
1904 FreePool (AttemptTmp);\r
1905 }\r
1906 \r
1907 FreePool (AttemptConfigOrder);\r
1908 return FALSE;\r
1909}\r
4c5a5e0c 1910\r
eabc6e59 1911/**\r
df077b3e 1912 Check whether the Controller handle is configured to use DNS protocol.\r
eabc6e59
ZL
1913\r
1914 @param[in] Controller The handle of the controller.\r
1915 \r
1916 @retval TRUE The handle of the controller need the Dns protocol.\r
1917 @retval FALSE The handle of the controller does not need the Dns protocol.\r
1918 \r
1919**/\r
1920BOOLEAN\r
1921IScsiDnsIsConfigured (\r
1922 IN EFI_HANDLE Controller\r
1923 )\r
1924{\r
1925 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1926 UINT8 *AttemptConfigOrder;\r
1927 UINTN AttemptConfigOrderSize;\r
1928 UINTN Index;\r
1929 EFI_STATUS Status;\r
1930 EFI_MAC_ADDRESS MacAddr;\r
1931 UINTN HwAddressSize;\r
1932 UINT16 VlanId;\r
df077b3e 1933 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
eabc6e59
ZL
1934 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
1935 CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];\r
1936 \r
1937 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1938 L"AttemptOrder",\r
1939 &gIScsiConfigGuid,\r
1940 &AttemptConfigOrderSize\r
1941 );\r
1942 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
1943 return FALSE;\r
1944 }\r
1945 \r
1946 //\r
1947 // Get MAC address of this network device.\r
1948 //\r
1949 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
1950 if(EFI_ERROR (Status)) {\r
1951 return FALSE;\r
1952 }\r
1953 //\r
1954 // Get VLAN ID of this network device.\r
1955 //\r
1956 VlanId = NetLibGetVlanId (Controller);\r
1957 IScsiMacAddrToStr (&MacAddr, (UINT32) HwAddressSize, VlanId, MacString);\r
1958 \r
1959 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1960 UnicodeSPrint (\r
1961 AttemptName,\r
1962 (UINTN) 128,\r
df077b3e 1963 L"Attempt %d",\r
eabc6e59
ZL
1964 (UINTN) AttemptConfigOrder[Index]\r
1965 );\r
df077b3e 1966\r
eabc6e59
ZL
1967 Status = GetVariable2 (\r
1968 AttemptName,\r
1969 &gEfiIScsiInitiatorNameProtocolGuid,\r
1970 (VOID**)&AttemptTmp,\r
1971 NULL\r
1972 );\r
1973 if(AttemptTmp == NULL || EFI_ERROR (Status)) {\r
1974 continue;\r
1975 }\r
1976 \r
1977 ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);\r
1978\r
df077b3e
ZL
1979 AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
1980\r
1981 if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED || StrCmp (MacString, AttemptMacString)) {\r
eabc6e59
ZL
1982 FreePool (AttemptTmp);\r
1983 continue;\r
1984 }\r
1985 \r
1986 if (AttemptTmp->SessionConfigData.DnsMode) {\r
1987 FreePool (AttemptTmp);\r
1988 FreePool (AttemptConfigOrder);\r
1989 return TRUE;\r
1990 } else {\r
1991 FreePool (AttemptTmp);\r
1992 continue;\r
1993 }\r
1994\r
1995 }\r
1996\r
1997 FreePool (AttemptConfigOrder);\r
1998 return FALSE;\r
1999\r
2000}\r
2001\r
4c5a5e0c 2002/**\r
2003 Get the various configuration data.\r
2004\r
2005 @param[in] Private The iSCSI driver data.\r
2006\r
2007 @retval EFI_SUCCESS The configuration data is retrieved.\r
2008 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.\r
7c275b3c 2009 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
4c5a5e0c 2010\r
2011**/\r
2012EFI_STATUS\r
2013IScsiGetConfigData (\r
2014 IN ISCSI_DRIVER_DATA *Private\r
2015 )\r
2016{\r
2017 EFI_STATUS Status;\r
2018 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
8d1f5e04 2019 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
4c5a5e0c 2020 UINTN Index;\r
2021 ISCSI_NIC_INFO *NicInfo;\r
2022 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
2023 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
2024 UINT8 *AttemptConfigOrder;\r
2025 UINTN AttemptConfigOrderSize;\r
2026 CHAR16 IScsiMode[64];\r
2027 CHAR16 IpMode[64];\r
2028\r
2029 //\r
2030 // There should be at least one attempt configured.\r
2031 //\r
2032 AttemptConfigOrder = IScsiGetVariableAndSize (\r
2033 L"AttemptOrder",\r
9bdc6592 2034 &gIScsiConfigGuid,\r
4c5a5e0c 2035 &AttemptConfigOrderSize\r
2036 );\r
2037 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
2038 return EFI_NOT_FOUND;\r
2039 }\r
2040\r
2041 //\r
2042 // Get the iSCSI Initiator Name.\r
2043 //\r
2044 mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
2045 Status = gIScsiInitiatorName.Get (\r
2046 &gIScsiInitiatorName,\r
2047 &mPrivate->InitiatorNameLength,\r
2048 mPrivate->InitiatorName\r
2049 );\r
2050 if (EFI_ERROR (Status)) {\r
2051 return Status;\r
2052 }\r
2053\r
2054 //\r
2055 // Get the normal configuration.\r
2056 //\r
2057 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
2058\r
2059 //\r
2060 // Check whether the attempt exists in AttemptConfig.\r
2061 //\r
2062 AttemptTmp = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]); \r
2063 if (AttemptTmp != NULL && AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
2064 continue;\r
2065 } else if (AttemptTmp != NULL && AttemptTmp->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
2066 //\r
2067 // Check the autoconfig path to see whether it should be retried.\r
2068 //\r
2069 if (AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG &&\r
87ce4210 2070 !AttemptTmp->AutoConfigureSuccess) {\r
4c5a5e0c 2071 if (mPrivate->Ipv6Flag &&\r
2072 AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6) {\r
2073 //\r
2074 // Autoconfigure for IP6 already attempted but failed. Do not try again.\r
2075 //\r
2076 continue;\r
2077 } else if (!mPrivate->Ipv6Flag &&\r
2078 AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4) {\r
2079 //\r
2080 // Autoconfigure for IP4 already attempted but failed. Do not try again.\r
2081 //\r
2082 continue;\r
2083 } else {\r
2084 //\r
2085 // Try another approach for this autoconfigure path.\r
2086 //\r
2087 AttemptTmp->AutoConfigureMode =\r
2088 (UINT8) (mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);\r
2089 AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp = TRUE;\r
2090 AttemptTmp->SessionConfigData.TargetInfoFromDhcp = TRUE;\r
2091 AttemptTmp->DhcpSuccess = FALSE;\r
2092\r
2093 //\r
2094 // Get some information from the dhcp server.\r
2095 //\r
2096 if (!mPrivate->Ipv6Flag) {\r
2097 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);\r
2098 if (!EFI_ERROR (Status)) {\r
2099 AttemptTmp->DhcpSuccess = TRUE;\r
2100 }\r
2101 } else {\r
2102 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);\r
2103 if (!EFI_ERROR (Status)) {\r
2104 AttemptTmp->DhcpSuccess = TRUE;\r
2105 }\r
2106 }\r
2107\r
2108 //\r
2109 // Refresh the state of this attempt to NVR.\r
2110 //\r
4c5a5e0c 2111 UnicodeSPrint (\r
2112 mPrivate->PortString,\r
2113 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2114 L"Attempt %d",\r
4c5a5e0c 2115 (UINTN) AttemptTmp->AttemptConfigIndex\r
2116 );\r
2117\r
2118 gRT->SetVariable (\r
2119 mPrivate->PortString,\r
2120 &gEfiIScsiInitiatorNameProtocolGuid,\r
2121 ISCSI_CONFIG_VAR_ATTR,\r
2122 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2123 AttemptTmp\r
2124 );\r
2125\r
2126 continue;\r
2127 }\r
067ca838
JW
2128 } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp && \r
2129 !AttemptTmp->ValidPath && \r
2130 AttemptTmp->NicIndex == mPrivate->CurrentNic) {\r
4c5a5e0c 2131 //\r
067ca838
JW
2132 // If the attempt associates with the current NIC, we can \r
2133 // get DHCP information for already added, but failed, attempt.\r
4c5a5e0c 2134 //\r
2135 AttemptTmp->DhcpSuccess = FALSE;\r
2136 if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) {\r
2137 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);\r
2138 if (!EFI_ERROR (Status)) {\r
2139 AttemptTmp->DhcpSuccess = TRUE;\r
2140 }\r
2141 } else if (mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP6)) {\r
2142 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);\r
2143 if (!EFI_ERROR (Status)) {\r
2144 AttemptTmp->DhcpSuccess = TRUE;\r
2145 }\r
2146 }\r
2147\r
2148 //\r
2149 // Refresh the state of this attempt to NVR.\r
2150 //\r
4c5a5e0c 2151 UnicodeSPrint (\r
2152 mPrivate->PortString,\r
2153 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2154 L"Attempt %d",\r
4c5a5e0c 2155 (UINTN) AttemptTmp->AttemptConfigIndex\r
2156 );\r
2157\r
2158 gRT->SetVariable (\r
2159 mPrivate->PortString,\r
2160 &gEfiIScsiInitiatorNameProtocolGuid,\r
2161 ISCSI_CONFIG_VAR_ATTR,\r
2162 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2163 AttemptTmp\r
2164 );\r
2165\r
2166 continue;\r
2167\r
2168 } else {\r
2169 continue;\r
2170 }\r
2171 }\r
2172\r
2173 //\r
2174 // This attempt does not exist in AttemptConfig. Try to add a new one.\r
2175 //\r
2176\r
2177 NicInfo = IScsiGetNicInfoByIndex (mPrivate->CurrentNic);\r
2178 ASSERT (NicInfo != NULL);\r
2179 IScsiMacAddrToStr (&NicInfo->PermanentAddress, NicInfo->HwAddressSize, NicInfo->VlanId, MacString);\r
2180 UnicodeSPrint (\r
2181 mPrivate->PortString,\r
8d1f5e04
ZL
2182 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
2183 L"Attempt %d",\r
4c5a5e0c 2184 (UINTN) AttemptConfigOrder[Index]\r
2185 );\r
2186\r
bf4a3dbd 2187 GetVariable2 (\r
a2d59ef2
YT
2188 mPrivate->PortString,\r
2189 &gEfiIScsiInitiatorNameProtocolGuid,\r
2190 (VOID**)&AttemptConfigData,\r
2191 NULL\r
2192 );\r
8d1f5e04 2193 AsciiStrToUnicodeStrS (AttemptConfigData->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
4c5a5e0c 2194\r
8d1f5e04
ZL
2195 if (AttemptConfigData == NULL || AttemptConfigData->Actived == ISCSI_ACTIVE_DISABLED ||\r
2196 StrCmp (MacString, AttemptMacString)) {\r
4c5a5e0c 2197 continue;\r
2198 }\r
2199\r
2200 ASSERT (AttemptConfigOrder[Index] == AttemptConfigData->AttemptConfigIndex);\r
2201\r
2202 AttemptConfigData->NicIndex = NicInfo->NicIndex;\r
2203 AttemptConfigData->DhcpSuccess = FALSE;\r
2204 AttemptConfigData->ValidiBFTPath = (BOOLEAN) (mPrivate->EnableMpio ? TRUE : FALSE);\r
2205 AttemptConfigData->ValidPath = FALSE;\r
2206\r
2207 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {\r
2208 AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp = TRUE;\r
2209 AttemptConfigData->SessionConfigData.TargetInfoFromDhcp = TRUE;\r
2210\r
2211 AttemptConfigData->AutoConfigureMode =\r
2212 (UINT8) (mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);\r
87ce4210 2213 AttemptConfigData->AutoConfigureSuccess = FALSE;\r
4c5a5e0c 2214 }\r
2215 \r
2216 //\r
2217 // Get some information from dhcp server.\r
2218 //\r
2219 if (AttemptConfigData->SessionConfigData.Enabled != ISCSI_DISABLED &&\r
2220 AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp) {\r
2221\r
2222 if (!mPrivate->Ipv6Flag &&\r
2223 (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4 ||\r
2224 AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4)) {\r
2225 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptConfigData);\r
2226 if (!EFI_ERROR (Status)) {\r
2227 AttemptConfigData->DhcpSuccess = TRUE;\r
2228 }\r
2229 } else if (mPrivate->Ipv6Flag &&\r
2230 (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6 ||\r
2231 AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6)) {\r
2232 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptConfigData);\r
2233 if (!EFI_ERROR (Status)) {\r
2234 AttemptConfigData->DhcpSuccess = TRUE;\r
2235 }\r
2236 }\r
2237\r
2238 //\r
2239 // Refresh the state of this attempt to NVR.\r
2240 //\r
4c5a5e0c 2241 UnicodeSPrint (\r
2242 mPrivate->PortString,\r
2243 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2244 L"Attempt %d",\r
4c5a5e0c 2245 (UINTN) AttemptConfigData->AttemptConfigIndex\r
2246 );\r
2247\r
2248 gRT->SetVariable (\r
2249 mPrivate->PortString,\r
2250 &gEfiIScsiInitiatorNameProtocolGuid,\r
2251 ISCSI_CONFIG_VAR_ATTR,\r
2252 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2253 AttemptConfigData\r
2254 );\r
2255 }\r
2256\r
2257 //\r
2258 // Update Attempt Help Info.\r
2259 //\r
2260\r
2261 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
2262 UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
2263 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2264 UnicodeSPrint (IScsiMode, 64, L"Enabled");\r
2265 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2266 UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");\r
2267 }\r
2268\r
2269 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {\r
2270 UnicodeSPrint (IpMode, 64, L"IP4");\r
2271 } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {\r
2272 UnicodeSPrint (IpMode, 64, L"IP6");\r
2273 } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {\r
2274 UnicodeSPrint (IpMode, 64, L"Autoconfigure");\r
2275 }\r
2276\r
2277 UnicodeSPrint (\r
2278 mPrivate->PortString,\r
2279 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
2280 L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
2281 MacString,\r
2282 NicInfo->BusNumber,\r
2283 NicInfo->DeviceNumber,\r
2284 NicInfo->FunctionNumber,\r
2285 IScsiMode,\r
2286 IpMode\r
2287 );\r
2288\r
2289 AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
2290 mCallbackInfo->RegisteredHandle,\r
2291 0,\r
2292 mPrivate->PortString,\r
2293 NULL\r
2294 );\r
7c275b3c
ZL
2295 if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
2296 return EFI_OUT_OF_RESOURCES;\r
2297 }\r
4c5a5e0c 2298\r
2299 //\r
2300 // Record the attempt in global link list.\r
2301 //\r
2302 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2303 mPrivate->AttemptCount++;\r
2304\r
2305 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2306 mPrivate->MpioCount++;\r
2307 mPrivate->EnableMpio = TRUE;\r
2308\r
2309 if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {\r
2310 mPrivate->Krb5MpioCount++;\r
2311 }\r
2312 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2313 mPrivate->SinglePathCount++;\r
2314 }\r
2315 }\r
2316\r
2317 //\r
2318 // Reorder the AttemptConfig by the configured order.\r
2319 //\r
2320 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
2321 AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);\r
2322 if (AttemptConfigData == NULL) {\r
2323 continue;\r
2324 }\r
2325\r
2326 RemoveEntryList (&AttemptConfigData->Link);\r
2327 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2328 }\r
2329\r
2330 //\r
2331 // Update the Main Form.\r
2332 //\r
2333 IScsiConfigUpdateAttempt ();\r
2334\r
2335 FreePool (AttemptConfigOrder);\r
2336\r
2337 //\r
2338 // There should be at least one attempt configuration.\r
2339 //\r
2340 if (!mPrivate->EnableMpio) {\r
2341 if (mPrivate->SinglePathCount == 0) {\r
2342 return EFI_NOT_FOUND;\r
2343 }\r
2344 mPrivate->ValidSinglePathCount = mPrivate->SinglePathCount;\r
2345 }\r
2346\r
2347 return EFI_SUCCESS;\r
2348}\r
2349\r
2350\r
2351/**\r
2352 Get the device path of the iSCSI tcp connection and update it.\r
2353\r
2354 @param Session The iSCSI session.\r
2355\r
2356 @return The updated device path.\r
2357 @retval NULL Other errors as indicated.\r
2358\r
2359**/\r
2360EFI_DEVICE_PATH_PROTOCOL *\r
2361IScsiGetTcpConnDevicePath (\r
2362 IN ISCSI_SESSION *Session\r
2363 )\r
2364{\r
2365 ISCSI_CONNECTION *Conn;\r
2366 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2367 EFI_STATUS Status;\r
2368 EFI_DEV_PATH *DPathNode;\r
42f0586d 2369 UINTN PathLen;\r
4c5a5e0c 2370\r
2371 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
2372 return NULL;\r
2373 }\r
2374\r
2375 Conn = NET_LIST_USER_STRUCT_S (\r
2376 Session->Conns.ForwardLink,\r
2377 ISCSI_CONNECTION,\r
2378 Link,\r
2379 ISCSI_CONNECTION_SIGNATURE\r
2380 );\r
2381\r
2382 Status = gBS->HandleProtocol (\r
2383 Conn->TcpIo.Handle,\r
2384 &gEfiDevicePathProtocolGuid,\r
2385 (VOID **) &DevicePath\r
2386 ); \r
2387 if (EFI_ERROR (Status)) {\r
2388 return NULL;\r
2389 }\r
2390 //\r
2391 // Duplicate it.\r
2392 //\r
2393 DevicePath = DuplicateDevicePath (DevicePath);\r
2394 if (DevicePath == NULL) {\r
2395 return NULL;\r
2396 }\r
2397\r
2398 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
2399\r
2400 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
2401 if (DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) {\r
2402 if (!Conn->Ipv6Flag && DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP) {\r
2403 DPathNode->Ipv4.LocalPort = 0;\r
501793fa
RN
2404\r
2405 DPathNode->Ipv4.StaticIpAddress = \r
2406 (BOOLEAN) (!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);\r
2407\r
42f0586d 2408 //\r
2409 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.\r
2410 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask\r
2411 // do not exist.\r
2412 // In new version of IPv4_DEVICE_PATH, structcure length is 27.\r
2413 //\r
501793fa 2414\r
42f0586d 2415 PathLen = DevicePathNodeLength (&DPathNode->Ipv4);\r
2416 \r
5ae7578a 2417 if (PathLen == IP4_NODE_LEN_NEW_VERSIONS) { \r
42f0586d 2418 \r
2419 IP4_COPY_ADDRESS (\r
2420 &DPathNode->Ipv4.GatewayIpAddress,\r
2421 &Session->ConfigData->SessionConfigData.Gateway\r
2422 );\r
2423\r
2424 IP4_COPY_ADDRESS (\r
2425 &DPathNode->Ipv4.SubnetMask,\r
2426 &Session->ConfigData->SessionConfigData.SubnetMask\r
2427 );\r
2428 }\r
2429 \r
4c5a5e0c 2430 break;\r
2431 } else if (Conn->Ipv6Flag && DevicePathSubType (&DPathNode->DevPath) == MSG_IPv6_DP) {\r
2432 DPathNode->Ipv6.LocalPort = 0;\r
42f0586d 2433\r
2434 //\r
2435 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.\r
2436 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength\r
2437 // and GatewayIpAddress do not exist.\r
2438 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in \r
2439 // old versions, the length is 43.\r
2440 //\r
2441\r
2442 PathLen = DevicePathNodeLength (&DPathNode->Ipv6);\r
2443 \r
5ae7578a 2444 if (PathLen == IP6_NODE_LEN_NEW_VERSIONS ) { \r
42f0586d 2445\r
2446 DPathNode->Ipv6.IpAddressOrigin = 0;\r
2447 DPathNode->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;\r
2448 ZeroMem (&DPathNode->Ipv6.GatewayIpAddress, sizeof (EFI_IPv6_ADDRESS));\r
2449 }\r
5ae7578a 2450 else if (PathLen == IP6_NODE_LEN_OLD_VERSIONS) { \r
42f0586d 2451\r
2452 //\r
2453 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new \r
2454 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.\r
2455 //\r
5ae7578a 2456 *((UINT8 *)(&DPathNode->Ipv6) + IP6_OLD_IPADDRESS_OFFSET) = \r
42f0586d 2457 (BOOLEAN) (!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);\r
2458 }\r
2459 \r
4c5a5e0c 2460 break;\r
2461 }\r
2462 }\r
2463\r
2464 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
2465 }\r
2466\r
2467 return DevicePath;\r
2468}\r
2469\r
2470\r
2471/**\r
2472 Abort the session when the transition from BS to RT is initiated.\r
2473\r
2474 @param[in] Event The event signaled.\r
2475 @param[in] Context The iSCSI driver data.\r
2476\r
2477**/\r
2478VOID\r
2479EFIAPI\r
2480IScsiOnExitBootService (\r
2481 IN EFI_EVENT Event,\r
2482 IN VOID *Context\r
2483 )\r
2484{\r
2485 ISCSI_DRIVER_DATA *Private;\r
2486\r
2487 Private = (ISCSI_DRIVER_DATA *) Context;\r
2488 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
2489\r
2490 if (Private->Session != NULL) {\r
2491 IScsiSessionAbort (Private->Session);\r
2492 }\r
2493}\r
18b24f92
FS
2494\r
2495/**\r
2496 Tests whether a controller handle is being managed by IScsi driver.\r
2497\r
2498 This function tests whether the driver specified by DriverBindingHandle is\r
2499 currently managing the controller specified by ControllerHandle. This test\r
2500 is performed by evaluating if the the protocol specified by ProtocolGuid is\r
2501 present on ControllerHandle and is was opened by DriverBindingHandle and Nic\r
2502 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER. \r
2503 If ProtocolGuid is NULL, then ASSERT().\r
2504\r
2505 @param ControllerHandle A handle for a controller to test.\r
2506 @param DriverBindingHandle Specifies the driver binding handle for the\r
2507 driver.\r
2508 @param ProtocolGuid Specifies the protocol that the driver specified\r
2509 by DriverBindingHandle opens in its Start()\r
2510 function.\r
2511\r
2512 @retval EFI_SUCCESS ControllerHandle is managed by the driver\r
2513 specified by DriverBindingHandle.\r
2514 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver\r
2515 specified by DriverBindingHandle.\r
2516\r
2517**/\r
2518EFI_STATUS\r
2519EFIAPI\r
2520IScsiTestManagedDevice (\r
2521 IN EFI_HANDLE ControllerHandle,\r
2522 IN EFI_HANDLE DriverBindingHandle,\r
2523 IN EFI_GUID *ProtocolGuid\r
2524 )\r
2525{\r
2526 EFI_STATUS Status;\r
2527 VOID *ManagedInterface;\r
2528 EFI_HANDLE NicControllerHandle;\r
2529\r
2530 ASSERT (ProtocolGuid != NULL);\r
2531\r
2532 NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);\r
2533 if (NicControllerHandle == NULL) {\r
2534 return EFI_UNSUPPORTED;\r
2535 }\r
2536\r
2537 Status = gBS->OpenProtocol (\r
2538 ControllerHandle,\r
2539 (EFI_GUID *) ProtocolGuid,\r
2540 &ManagedInterface,\r
2541 DriverBindingHandle,\r
2542 NicControllerHandle,\r
2543 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2544 );\r
2545 if (!EFI_ERROR (Status)) {\r
2546 gBS->CloseProtocol (\r
2547 ControllerHandle,\r
2548 (EFI_GUID *) ProtocolGuid,\r
2549 DriverBindingHandle,\r
2550 NicControllerHandle\r
2551 );\r
2552 return EFI_UNSUPPORTED;\r
2553 }\r
2554\r
2555 if (Status != EFI_ALREADY_STARTED) {\r
2556 return EFI_UNSUPPORTED;\r
2557 }\r
2558\r
2559 return EFI_SUCCESS;\r
2560}\r