]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IScsiDxe/IScsiMisc.c
MdePkg/UefiDevicePathLib: Fix the wrong MAC address length
[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
468/**\r
469 Record the NIC info in global structure.\r
470\r
471 @param[in] Controller The handle of the controller.\r
472\r
473 @retval EFI_SUCCESS The operation is completed.\r
474 @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this\r
475 operation.\r
476\r
477**/\r
478EFI_STATUS\r
479IScsiAddNic (\r
480 IN EFI_HANDLE Controller\r
481 )\r
482{\r
483 EFI_STATUS Status;\r
484 ISCSI_NIC_INFO *NicInfo;\r
485 LIST_ENTRY *Entry;\r
486 EFI_MAC_ADDRESS MacAddr;\r
487 UINTN HwAddressSize;\r
488 UINT16 VlanId;\r
489\r
490 //\r
491 // Get MAC address of this network device.\r
492 //\r
493 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
494 if (EFI_ERROR (Status)) {\r
495 return Status;\r
496 }\r
497\r
498 //\r
499 // Get VLAN ID of this network device.\r
500 //\r
501 VlanId = NetLibGetVlanId (Controller);\r
502\r
503 //\r
504 // Check whether the NIC info already exists. Return directly if so.\r
505 //\r
506 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
507 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
508 if (NicInfo->HwAddressSize == HwAddressSize &&\r
509 CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&\r
510 NicInfo->VlanId == VlanId) {\r
511 mPrivate->CurrentNic = NicInfo->NicIndex;\r
512 return EFI_SUCCESS;\r
513 }\r
514\r
515 if (mPrivate->MaxNic < NicInfo->NicIndex) {\r
516 mPrivate->MaxNic = NicInfo->NicIndex;\r
517 }\r
518 }\r
519\r
520 //\r
521 // Record the NIC info in private structure.\r
522 //\r
523 NicInfo = AllocateZeroPool (sizeof (ISCSI_NIC_INFO));\r
524 if (NicInfo == NULL) {\r
525 return EFI_OUT_OF_RESOURCES;\r
526 }\r
527\r
528 CopyMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize);\r
529 NicInfo->HwAddressSize = (UINT32) HwAddressSize;\r
530 NicInfo->VlanId = VlanId;\r
531 NicInfo->NicIndex = (UINT8) (mPrivate->MaxNic + 1);\r
532 mPrivate->MaxNic = NicInfo->NicIndex;\r
533\r
534 //\r
535 // Get the PCI location.\r
536 //\r
537 IScsiGetNICPciLocation (\r
538 Controller,\r
539 &NicInfo->BusNumber,\r
540 &NicInfo->DeviceNumber,\r
541 &NicInfo->FunctionNumber\r
542 );\r
543\r
544 InsertTailList (&mPrivate->NicInfoList, &NicInfo->Link);\r
545 mPrivate->NicCount++;\r
546\r
547 mPrivate->CurrentNic = NicInfo->NicIndex;\r
548 return EFI_SUCCESS;\r
549}\r
550\r
551\r
552/**\r
553 Delete the recorded NIC info from global structure. Also delete corresponding\r
554 attempts.\r
555\r
556 @param[in] Controller The handle of the controller.\r
557\r
558 @retval EFI_SUCCESS The operation is completed.\r
559 @retval EFI_NOT_FOUND The NIC info to be deleted is not recorded.\r
560\r
561**/\r
562EFI_STATUS\r
563IScsiRemoveNic (\r
564 IN EFI_HANDLE Controller\r
565 )\r
566{\r
567 EFI_STATUS Status;\r
568 ISCSI_NIC_INFO *NicInfo;\r
569 LIST_ENTRY *Entry;\r
570 LIST_ENTRY *NextEntry;\r
571 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
572 ISCSI_NIC_INFO *ThisNic;\r
573 EFI_MAC_ADDRESS MacAddr;\r
574 UINTN HwAddressSize;\r
575 UINT16 VlanId;\r
576\r
577 //\r
578 // Get MAC address of this network device.\r
579 //\r
580 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
581 if (EFI_ERROR (Status)) {\r
582 return Status;\r
583 }\r
584\r
585 //\r
586 // Get VLAN ID of this network device.\r
587 //\r
588 VlanId = NetLibGetVlanId (Controller);\r
589\r
590 //\r
591 // Check whether the NIC information exists.\r
592 //\r
593 ThisNic = NULL;\r
594\r
595 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
596 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
597 if (NicInfo->HwAddressSize == HwAddressSize &&\r
598 CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&\r
599 NicInfo->VlanId == VlanId) {\r
600\r
601 ThisNic = NicInfo;\r
602 break;\r
603 }\r
604 }\r
605\r
606 if (ThisNic == NULL) {\r
607 return EFI_NOT_FOUND;\r
608 }\r
609\r
610 mPrivate->CurrentNic = ThisNic->NicIndex;\r
611\r
612 RemoveEntryList (&ThisNic->Link);\r
613 FreePool (ThisNic);\r
614 mPrivate->NicCount--;\r
615\r
616 //\r
617 // Remove all attempts related to this NIC.\r
618 //\r
619 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {\r
620 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);\r
621 if (AttemptConfigData->NicIndex == mPrivate->CurrentNic) {\r
622 RemoveEntryList (&AttemptConfigData->Link);\r
623 mPrivate->AttemptCount--;\r
624\r
625 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO && mPrivate->MpioCount > 0) {\r
626 if (--mPrivate->MpioCount == 0) {\r
627 mPrivate->EnableMpio = FALSE;\r
628 }\r
629\r
630 if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB && mPrivate->Krb5MpioCount > 0) {\r
631 mPrivate->Krb5MpioCount--;\r
632 }\r
633\r
634 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED && mPrivate->SinglePathCount > 0) {\r
635 mPrivate->SinglePathCount--;\r
636\r
637 if (mPrivate->ValidSinglePathCount > 0) {\r
638 mPrivate->ValidSinglePathCount--;\r
639 }\r
640 }\r
641\r
642 FreePool (AttemptConfigData);\r
643 }\r
644 }\r
645\r
8d1f5e04
ZL
646 return EFI_SUCCESS;\r
647}\r
648\r
649/**\r
650 Create and initialize the Attempts.\r
651\r
652 @param[in] AttemptNum The number of Attempts will be created.\r
653\r
654 @retval EFI_SUCCESS The Attempts have been created successfully.\r
655 @retval Others Failed to create the Attempt.\r
656\r
657**/\r
658EFI_STATUS\r
659IScsiCreateAttempts (\r
660 IN UINTN AttemptNum\r
661)\r
662{\r
663 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
664 ISCSI_SESSION_CONFIG_NVDATA *ConfigData;\r
665 UINT8 *AttemptConfigOrder;\r
666 UINTN AttemptConfigOrderSize;\r
667 UINT8 *AttemptOrderTmp;\r
668 UINTN TotalNumber;\r
669 UINT8 Index;\r
670 EFI_STATUS Status;\r
671\r
672 for (Index = 1; Index <= AttemptNum; Index ++) {\r
673 //\r
674 // Get the initialized attempt order. This is used to essure creating attempts by order.\r
675 //\r
676 AttemptConfigOrder = IScsiGetVariableAndSize (\r
677 L"InitialAttemptOrder",\r
678 &gIScsiConfigGuid,\r
679 &AttemptConfigOrderSize\r
680 );\r
681 TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);\r
682 if (TotalNumber == AttemptNum) {\r
683 Status = EFI_SUCCESS;\r
684 break;\r
685 }\r
686 TotalNumber++;\r
687\r
688 //\r
689 // Append the new created attempt to the end.\r
690 //\r
691 AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));\r
692 if (AttemptOrderTmp == NULL) {\r
693 if (AttemptConfigOrder != NULL) {\r
694 FreePool (AttemptConfigOrder);\r
695 }\r
696 return EFI_OUT_OF_RESOURCES;\r
697 }\r
698\r
699 if (AttemptConfigOrder != NULL) {\r
700 CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);\r
701 FreePool (AttemptConfigOrder);\r
702 }\r
703\r
704 AttemptOrderTmp[TotalNumber - 1] = Index;\r
705 AttemptConfigOrder = AttemptOrderTmp;\r
706 AttemptConfigOrderSize = TotalNumber * sizeof (UINT8);\r
707\r
708 Status = gRT->SetVariable (\r
709 L"InitialAttemptOrder",\r
710 &gIScsiConfigGuid,\r
711 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
712 AttemptConfigOrderSize,\r
713 AttemptConfigOrder\r
714 );\r
715 FreePool (AttemptConfigOrder);\r
716 if (EFI_ERROR (Status)) {\r
717 return Status;\r
718 }\r
719\r
720 //\r
721 // Create new Attempt\r
722 //\r
723 AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));\r
724 if (AttemptConfigData == NULL) {\r
725 return EFI_OUT_OF_RESOURCES;\r
726 }\r
727 ConfigData = &AttemptConfigData->SessionConfigData;\r
728 ConfigData->TargetPort = ISCSI_WELL_KNOWN_PORT;\r
729 ConfigData->ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;\r
730 ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;\r
731\r
732 AttemptConfigData->AuthenticationType = ISCSI_AUTH_TYPE_CHAP;\r
733 AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;\r
734 //\r
735 // Configure the Attempt index and set variable.\r
736 //\r
737 AttemptConfigData->AttemptConfigIndex = Index;\r
738\r
739 //\r
740 // Set the attempt name according to the order.\r
741 //\r
742 UnicodeSPrint (\r
743 mPrivate->PortString,\r
744 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
745 L"Attempt %d",\r
746 (UINTN) AttemptConfigData->AttemptConfigIndex\r
747 );\r
748 UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);\r
749\r
750 Status = gRT->SetVariable (\r
751 mPrivate->PortString,\r
752 &gEfiIScsiInitiatorNameProtocolGuid,\r
753 ISCSI_CONFIG_VAR_ATTR,\r
754 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
755 AttemptConfigData\r
756 );\r
757 FreePool (AttemptConfigData);\r
758 if (EFI_ERROR (Status)) {\r
759 return Status;\r
760 }\r
c0d494b5 761 }\r
762\r
4c5a5e0c 763 return EFI_SUCCESS;\r
764}\r
765\r
8d1f5e04
ZL
766/**\r
767 Create the iSCSI configuration Keywords for each attempt. You can find the keywords\r
768 defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).\r
769\r
770 @param[in] KeywordNum The number Sets of Keywords will be created.\r
771\r
772 @retval EFI_SUCCESS The operation is completed.\r
773 @retval Others Failed to create the Keywords.\r
774\r
775**/\r
776EFI_STATUS\r
777IScsiCreateKeywords (\r
778 IN UINTN KeywordNum\r
779)\r
780{\r
781 VOID *StartOpCodeHandle;\r
782 EFI_IFR_GUID_LABEL *StartLabel;\r
783 VOID *EndOpCodeHandle;\r
784 EFI_IFR_GUID_LABEL *EndLabel;\r
785 UINTN Index;\r
786 EFI_STRING_ID StringToken;\r
787 CHAR16 StringId[64];\r
788 CHAR16 KeywordId[32];\r
789 EFI_STATUS Status;\r
790\r
791 Status = IScsiCreateOpCode (\r
792 KEYWORD_ENTRY_LABEL,\r
793 &StartOpCodeHandle,\r
794 &StartLabel,\r
795 &EndOpCodeHandle,\r
796 &EndLabel\r
797 );\r
798 if (EFI_ERROR (Status)) {\r
799 return EFI_OUT_OF_RESOURCES;\r
800 }\r
801\r
802 for (Index = 1; Index <= KeywordNum; Index ++) {\r
803 //\r
804 // Create iSCSIAttemptName Keyword.\r
805 //\r
806 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index);\r
807 StringToken = HiiSetString (\r
808 mCallbackInfo->RegisteredHandle,\r
809 0,\r
810 StringId,\r
811 NULL\r
812 );\r
813 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAttemptName:%d", Index);\r
814 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
815 HiiCreateStringOpCode (\r
816 StartOpCodeHandle,\r
817 (EFI_QUESTION_ID) (ATTEMPT_ATTEMPT_NAME_QUESTION_ID + (Index - 1)),\r
818 CONFIGURATION_VARSTORE_ID,\r
819 (UINT16) (ATTEMPT_ATTEMPT_NAME_VAR_OFFSET + ATTEMPT_NAME_SIZE * (Index - 1) * sizeof (CHAR16)),\r
820 StringToken,\r
821 StringToken,\r
822 EFI_IFR_FLAG_READ_ONLY,\r
823 0,\r
824 0,\r
825 ATTEMPT_NAME_SIZE,\r
826 NULL\r
827 );\r
828\r
829 //\r
830 // Create iSCSIBootEnable Keyword.\r
831 //\r
832 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_MODE_PROMPT%d", Index);\r
833 StringToken = HiiSetString (\r
834 mCallbackInfo->RegisteredHandle,\r
835 0,\r
836 StringId,\r
837 NULL\r
838 );\r
839 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIBootEnable:%d", Index);\r
840 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
841 HiiCreateNumericOpCode (\r
842 StartOpCodeHandle,\r
843 (EFI_QUESTION_ID) (ATTEMPT_BOOTENABLE_QUESTION_ID + (Index - 1)),\r
844 CONFIGURATION_VARSTORE_ID,\r
845 (UINT16) (ATTEMPT_BOOTENABLE_VAR_OFFSET + (Index - 1)),\r
846 StringToken,\r
847 StringToken,\r
848 0,\r
849 EFI_IFR_NUMERIC_SIZE_1,\r
850 0,\r
851 2,\r
852 0,\r
853 NULL\r
854 );\r
855\r
856 //\r
857 // Create iSCSIIpAddressType Keyword.\r
858 //\r
859 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_IP_MODE_PROMPT%d", Index);\r
860 StringToken = HiiSetString (\r
861 mCallbackInfo->RegisteredHandle,\r
862 0,\r
863 StringId,\r
864 NULL\r
865 );\r
866 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIIpAddressType:%d", Index);\r
867 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
868 HiiCreateNumericOpCode (\r
869 StartOpCodeHandle,\r
870 (EFI_QUESTION_ID) (ATTEMPT_ADDRESS_TYPE_QUESTION_ID + (Index - 1)),\r
871 CONFIGURATION_VARSTORE_ID,\r
872 (UINT16) (ATTEMPT_ADDRESS_TYPE_VAR_OFFSET + (Index - 1)),\r
873 StringToken,\r
874 StringToken,\r
875 0,\r
876 EFI_IFR_NUMERIC_SIZE_1,\r
877 0,\r
878 2,\r
879 0,\r
880 NULL\r
881 );\r
882\r
883 //\r
884 // Create iSCSIConnectRetry Keyword.\r
885 //\r
886 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index);\r
887 StringToken = HiiSetString (\r
888 mCallbackInfo->RegisteredHandle,\r
889 0,\r
890 StringId,\r
891 NULL\r
892 );\r
893 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectRetry:%d", Index);\r
894 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
895 HiiCreateNumericOpCode (\r
896 StartOpCodeHandle,\r
897 (EFI_QUESTION_ID) (ATTEMPT_CONNECT_RETRY_QUESTION_ID + (Index - 1)),\r
898 CONFIGURATION_VARSTORE_ID,\r
899 (UINT16) (ATTEMPT_CONNECT_RETRY_VAR_OFFSET + (Index - 1)),\r
900 StringToken,\r
901 StringToken,\r
902 0,\r
903 EFI_IFR_NUMERIC_SIZE_1,\r
904 0,\r
905 16,\r
906 0,\r
907 NULL\r
908 );\r
909\r
910 //\r
911 // Create iSCSIConnectTimeout Keyword.\r
912 //\r
913 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index);\r
914 StringToken = HiiSetString (\r
915 mCallbackInfo->RegisteredHandle,\r
916 0,\r
917 StringId,\r
918 NULL\r
919 );\r
920 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectTimeout:%d", Index);\r
921 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
922 HiiCreateNumericOpCode (\r
923 StartOpCodeHandle,\r
924 (EFI_QUESTION_ID) (ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID + (Index - 1)),\r
925 CONFIGURATION_VARSTORE_ID,\r
926 (UINT16) (ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET + 2 * (Index - 1)),\r
927 StringToken,\r
928 StringToken,\r
929 0,\r
930 EFI_IFR_NUMERIC_SIZE_2,\r
931 CONNECT_MIN_TIMEOUT,\r
932 CONNECT_MAX_TIMEOUT,\r
933 0,\r
934 NULL\r
935 );\r
936\r
937 //\r
938 // Create ISID Keyword.\r
939 //\r
940 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ISID_PROMPT%d", Index);\r
941 StringToken = HiiSetString (\r
942 mCallbackInfo->RegisteredHandle,\r
943 0,\r
944 StringId,\r
945 NULL\r
946 );\r
947 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIISID:%d", Index);\r
948 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
949 HiiCreateStringOpCode (\r
950 StartOpCodeHandle,\r
951 (EFI_QUESTION_ID) (ATTEMPT_ISID_QUESTION_ID + (Index - 1)),\r
952 CONFIGURATION_VARSTORE_ID,\r
953 (UINT16) (ATTEMPT_ISID_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
954 StringToken,\r
955 StringToken,\r
956 0,\r
957 0,\r
958 ISID_CONFIGURABLE_MIN_LEN,\r
959 ISID_CONFIGURABLE_STORAGE,\r
960 NULL\r
961 );\r
962\r
963 //\r
964 // Create iSCSIInitiatorInfoViaDHCP Keyword.\r
965 //\r
966 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index);\r
967 StringToken = HiiSetString (\r
968 mCallbackInfo->RegisteredHandle,\r
969 0,\r
970 StringId,\r
971 NULL\r
972 );\r
973 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorInfoViaDHCP:%d", Index);\r
974 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
975 HiiCreateNumericOpCode (\r
976 StartOpCodeHandle,\r
977 (EFI_QUESTION_ID) (ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID + (Index - 1)),\r
978 CONFIGURATION_VARSTORE_ID,\r
979 (UINT16) (ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET + (Index - 1)),\r
980 StringToken,\r
981 StringToken,\r
982 0,\r
983 0,\r
984 0,\r
985 1,\r
986 0,\r
987 NULL\r
988 );\r
989\r
990 //\r
991 // Create iSCSIInitiatorIpAddress Keyword.\r
992 //\r
993 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index);\r
994 StringToken = HiiSetString (\r
995 mCallbackInfo->RegisteredHandle,\r
996 0,\r
997 StringId,\r
998 NULL\r
999 );\r
1000 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorIpAddress:%d", Index);\r
1001 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1002 HiiCreateStringOpCode (\r
1003 StartOpCodeHandle,\r
1004 (EFI_QUESTION_ID) (ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID + (Index - 1)),\r
1005 CONFIGURATION_VARSTORE_ID,\r
1006 (UINT16) (ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1007 StringToken,\r
1008 StringToken,\r
1009 0,\r
1010 0,\r
1011 IP4_MIN_SIZE,\r
1012 IP4_MAX_SIZE,\r
1013 NULL\r
1014 );\r
1015\r
1016 //\r
1017 // Create iSCSIInitiatorNetmask Keyword.\r
1018 //\r
1019 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_NET_MASK_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"iSCSIInitiatorNetmask:%d", Index);\r
1027 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1028 HiiCreateStringOpCode (\r
1029 StartOpCodeHandle,\r
1030 (EFI_QUESTION_ID) (ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID + (Index - 1)),\r
1031 CONFIGURATION_VARSTORE_ID,\r
1032 (UINT16) (ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1033 StringToken,\r
1034 StringToken,\r
1035 0,\r
1036 0,\r
1037 IP4_MIN_SIZE,\r
1038 IP4_MAX_SIZE,\r
1039 NULL\r
1040 );\r
1041\r
1042 //\r
1043 // Create iSCSIInitiatorGateway Keyword.\r
1044 //\r
1045 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index);\r
1046 StringToken = HiiSetString (\r
1047 mCallbackInfo->RegisteredHandle,\r
1048 0,\r
1049 StringId,\r
1050 NULL\r
1051 );\r
1052 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorGateway:%d", Index);\r
1053 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1054 HiiCreateStringOpCode (\r
1055 StartOpCodeHandle,\r
1056 (EFI_QUESTION_ID) (ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID + (Index - 1)),\r
1057 CONFIGURATION_VARSTORE_ID,\r
1058 (UINT16) (ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1059 StringToken,\r
1060 StringToken,\r
1061 0,\r
1062 0,\r
1063 IP4_MIN_SIZE,\r
1064 IP4_MAX_SIZE,\r
1065 NULL\r
1066 );\r
1067\r
1068 //\r
1069 // Create iSCSITargetInfoViaDHCP Keyword.\r
1070 //\r
1071 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_VIA_DHCP_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"iSCSITargetInfoViaDHCP:%d", Index);\r
1079 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1080 HiiCreateNumericOpCode (\r
1081 StartOpCodeHandle,\r
1082 (EFI_QUESTION_ID) (ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID + (Index - 1)),\r
1083 CONFIGURATION_VARSTORE_ID,\r
1084 (UINT16) (ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET + (Index - 1)),\r
1085 StringToken,\r
1086 StringToken,\r
1087 0,\r
1088 0,\r
1089 0,\r
1090 1,\r
1091 0,\r
1092 NULL\r
1093 );\r
1094\r
1095 //\r
1096 // Create iSCSITargetTcpPort Keyword.\r
1097 //\r
1098 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index);\r
1099 StringToken = HiiSetString (\r
1100 mCallbackInfo->RegisteredHandle,\r
1101 0,\r
1102 StringId,\r
1103 NULL\r
1104 );\r
1105 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetTcpPort:%d", Index);\r
1106 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1107 HiiCreateNumericOpCode (\r
1108 StartOpCodeHandle,\r
1109 (EFI_QUESTION_ID) (ATTEMPT_TARGET_TCP_PORT_QUESTION_ID + (Index - 1)),\r
1110 CONFIGURATION_VARSTORE_ID,\r
1111 (UINT16) (ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET + 2 * (Index - 1)),\r
1112 StringToken,\r
1113 StringToken,\r
1114 0,\r
1115 EFI_IFR_NUMERIC_SIZE_2,\r
1116 TARGET_PORT_MIN_NUM,\r
1117 TARGET_PORT_MAX_NUM,\r
1118 0,\r
1119 NULL\r
1120 );\r
1121\r
1122 //\r
1123 // Create iSCSITargetName Keyword.\r
1124 //\r
1125 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_NAME_PROMPT%d", Index);\r
1126 StringToken = HiiSetString (\r
1127 mCallbackInfo->RegisteredHandle,\r
1128 0,\r
1129 StringId,\r
1130 NULL\r
1131 );\r
1132 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetName:%d", Index);\r
1133 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1134 HiiCreateStringOpCode (\r
1135 StartOpCodeHandle,\r
1136 (EFI_QUESTION_ID) (ATTEMPT_TARGET_NAME_QUESTION_ID + (Index - 1)),\r
1137 CONFIGURATION_VARSTORE_ID,\r
1138 (UINT16) (ATTEMPT_TARGET_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1139 StringToken,\r
1140 StringToken,\r
1141 0,\r
1142 0,\r
1143 ISCSI_NAME_IFR_MIN_SIZE,\r
1144 ISCSI_NAME_IFR_MAX_SIZE,\r
1145 NULL\r
1146 );\r
1147\r
1148 //\r
1149 // Create iSCSITargetIpAddress Keyword.\r
1150 //\r
1151 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index);\r
1152 StringToken = HiiSetString (\r
1153 mCallbackInfo->RegisteredHandle,\r
1154 0,\r
1155 StringId,\r
1156 NULL\r
1157 );\r
1158 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetIpAddress:%d", Index);\r
1159 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1160 HiiCreateStringOpCode (\r
1161 StartOpCodeHandle,\r
1162 (EFI_QUESTION_ID) (ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID + (Index - 1)),\r
1163 CONFIGURATION_VARSTORE_ID,\r
1164 (UINT16) (ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1165 StringToken,\r
1166 StringToken,\r
1167 0,\r
1168 0,\r
1169 IP_MIN_SIZE,\r
1170 IP_MAX_SIZE,\r
1171 NULL\r
1172 );\r
1173\r
1174 //\r
1175 // Create iSCSILUN Keyword.\r
1176 //\r
1177 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_LUN_PROMPT%d", Index);\r
1178 StringToken = HiiSetString (\r
1179 mCallbackInfo->RegisteredHandle,\r
1180 0,\r
1181 StringId,\r
1182 NULL\r
1183 );\r
1184 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSILUN:%d", Index);\r
1185 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1186 HiiCreateStringOpCode (\r
1187 StartOpCodeHandle,\r
1188 (EFI_QUESTION_ID) (ATTEMPT_LUN_QUESTION_ID + (Index - 1)),\r
1189 CONFIGURATION_VARSTORE_ID,\r
1190 (UINT16) (ATTEMPT_LUN_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1191 StringToken,\r
1192 StringToken,\r
1193 0,\r
1194 0,\r
1195 LUN_MIN_SIZE,\r
1196 LUN_MAX_SIZE,\r
1197 NULL\r
1198 );\r
1199\r
1200 //\r
1201 // Create iSCSIAuthenticationMethod Keyword.\r
1202 //\r
1203 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index);\r
1204 StringToken = HiiSetString (\r
1205 mCallbackInfo->RegisteredHandle,\r
1206 0,\r
1207 StringId,\r
1208 NULL\r
1209 );\r
1210 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAuthenticationMethod:%d", Index);\r
1211 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1212 HiiCreateNumericOpCode (\r
1213 StartOpCodeHandle,\r
1214 (EFI_QUESTION_ID) (ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID + (Index - 1)),\r
1215 CONFIGURATION_VARSTORE_ID,\r
1216 (UINT16) (ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET + (Index - 1)),\r
1217 StringToken,\r
1218 StringToken,\r
1219 0,\r
1220 0,\r
1221 0,\r
1222 1,\r
1223 0,\r
1224 NULL\r
1225 );\r
1226\r
1227 //\r
1228 // Create iSCSIChapType Keyword.\r
1229 //\r
1230 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHARTYPE_PROMPT%d", Index);\r
1231 StringToken = HiiSetString (\r
1232 mCallbackInfo->RegisteredHandle,\r
1233 0,\r
1234 StringId,\r
1235 NULL\r
1236 );\r
1237 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapType:%d", Index);\r
1238 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1239 HiiCreateNumericOpCode (\r
1240 StartOpCodeHandle,\r
1241 (EFI_QUESTION_ID) (ATTEMPT_CHARTYPE_QUESTION_ID + (Index - 1)),\r
1242 CONFIGURATION_VARSTORE_ID,\r
1243 (UINT16) (ATTEMPT_CHARTYPE_VAR_OFFSET + (Index - 1)),\r
1244 StringToken,\r
1245 StringToken,\r
1246 0,\r
1247 0,\r
1248 0,\r
1249 1,\r
1250 0,\r
1251 NULL\r
1252 );\r
1253\r
1254 //\r
1255 // Create iSCSIChapUsername Keyword.\r
1256 //\r
1257 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index);\r
1258 StringToken = HiiSetString (\r
1259 mCallbackInfo->RegisteredHandle,\r
1260 0,\r
1261 StringId,\r
1262 NULL\r
1263 );\r
1264 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapUsername:%d", Index);\r
1265 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1266 HiiCreateStringOpCode (\r
1267 StartOpCodeHandle,\r
1268 (EFI_QUESTION_ID) (ATTEMPT_CHAR_USER_NAME_QUESTION_ID + (Index - 1)),\r
1269 CONFIGURATION_VARSTORE_ID,\r
1270 (UINT16) (ATTEMPT_CHAR_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1271 StringToken,\r
1272 StringToken,\r
1273 0,\r
1274 0,\r
1275 0,\r
1276 ISCSI_CHAP_NAME_MAX_LEN,\r
1277 NULL\r
1278 );\r
1279\r
1280 //\r
1281 // Create iSCSIChapSecret Keyword.\r
1282 //\r
1283 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index);\r
1284 StringToken = HiiSetString (\r
1285 mCallbackInfo->RegisteredHandle,\r
1286 0,\r
1287 StringId,\r
1288 NULL\r
1289 );\r
1290 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapSecret:%d", Index);\r
1291 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1292 HiiCreateStringOpCode (\r
1293 StartOpCodeHandle,\r
1294 (EFI_QUESTION_ID) (ATTEMPT_CHAR_SECRET_QUESTION_ID + (Index - 1)),\r
1295 CONFIGURATION_VARSTORE_ID,\r
1296 (UINT16) (ATTEMPT_CHAR_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1297 StringToken,\r
1298 StringToken,\r
1299 0,\r
1300 0,\r
1301 ISCSI_CHAP_SECRET_MIN_LEN,\r
1302 ISCSI_CHAP_SECRET_MAX_LEN,\r
1303 NULL\r
1304 );\r
1305\r
1306 //\r
1307 // Create iSCSIReverseChapUsername Keyword.\r
1308 //\r
1309 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index);\r
1310 StringToken = HiiSetString (\r
1311 mCallbackInfo->RegisteredHandle,\r
1312 0,\r
1313 StringId,\r
1314 NULL\r
1315 );\r
1316 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapUsername:%d", Index);\r
1317 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1318 HiiCreateStringOpCode (\r
1319 StartOpCodeHandle,\r
1320 (EFI_QUESTION_ID) (ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID + (Index - 1)),\r
1321 CONFIGURATION_VARSTORE_ID,\r
1322 (UINT16) (ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1323 StringToken,\r
1324 StringToken,\r
1325 0,\r
1326 0,\r
1327 0,\r
1328 ISCSI_CHAP_NAME_MAX_LEN,\r
1329 NULL\r
1330 );\r
1331\r
1332 //\r
1333 // Create iSCSIReverseChapSecret Keyword.\r
1334 //\r
1335 UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index);\r
1336 StringToken = HiiSetString (\r
1337 mCallbackInfo->RegisteredHandle,\r
1338 0,\r
1339 StringId,\r
1340 NULL\r
1341 );\r
1342 UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapSecret:%d", Index);\r
1343 HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");\r
1344 HiiCreateStringOpCode (\r
1345 StartOpCodeHandle,\r
1346 (EFI_QUESTION_ID) (ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID + (Index - 1)),\r
1347 CONFIGURATION_VARSTORE_ID,\r
1348 (UINT16) (ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),\r
1349 StringToken,\r
1350 StringToken,\r
1351 0,\r
1352 0,\r
1353 ISCSI_CHAP_SECRET_MIN_LEN,\r
1354 ISCSI_CHAP_SECRET_MAX_LEN,\r
1355 NULL\r
1356 );\r
1357 }\r
1358\r
1359 Status = HiiUpdateForm (\r
1360 mCallbackInfo->RegisteredHandle, // HII handle\r
1361 &gIScsiConfigGuid, // Formset GUID\r
1362 FORMID_ATTEMPT_FORM, // Form ID\r
1363 StartOpCodeHandle, // Label for where to insert opcodes\r
1364 EndOpCodeHandle // Replace data\r
1365 );\r
1366\r
1367 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1368 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1369\r
1370 return Status;\r
1371}\r
1372\r
1373/**\r
1374\r
1375 Free the attempt configure data variable.\r
1376\r
1377**/\r
1378VOID\r
1379IScsiCleanAttemptVariable (\r
1380 IN VOID\r
1381)\r
1382{\r
1383 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
1384 UINT8 *AttemptConfigOrder;\r
1385 UINTN AttemptConfigOrderSize;\r
1386 UINTN Index;\r
1387\r
1388 //\r
1389 // Get the initialized attempt order.\r
1390 //\r
1391 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1392 L"InitialAttemptOrder",\r
1393 &gIScsiConfigGuid,\r
1394 &AttemptConfigOrderSize\r
1395 );\r
1396 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
1397 return;\r
1398 }\r
1399\r
1400 for (Index = 1; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1401 UnicodeSPrint (\r
1402 mPrivate->PortString,\r
1403 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
1404 L"Attempt %d",\r
1405 Index\r
1406 );\r
1407\r
1408 GetVariable2 (\r
1409 mPrivate->PortString,\r
1410 &gEfiIScsiInitiatorNameProtocolGuid,\r
1411 (VOID**)&AttemptConfigData,\r
1412 NULL\r
1413 );\r
1414\r
1415 if (AttemptConfigData != NULL) {\r
1416 gRT->SetVariable (\r
1417 mPrivate->PortString,\r
1418 &gEfiIScsiInitiatorNameProtocolGuid,\r
1419 0,\r
1420 0,\r
1421 NULL\r
1422 );\r
1423 }\r
1424 }\r
1425 return;\r
1426}\r
4c5a5e0c 1427\r
1428/**\r
1429 Get the recorded NIC info from global structure by the Index.\r
1430\r
1431 @param[in] NicIndex The index indicates the position of NIC info.\r
1432\r
1433 @return Pointer to the NIC info, or NULL if not found.\r
1434\r
1435**/\r
1436ISCSI_NIC_INFO *\r
1437IScsiGetNicInfoByIndex (\r
1438 IN UINT8 NicIndex\r
1439 )\r
1440{\r
1441 LIST_ENTRY *Entry;\r
1442 ISCSI_NIC_INFO *NicInfo;\r
1443\r
1444 NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {\r
1445 NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);\r
1446 if (NicInfo->NicIndex == NicIndex) {\r
1447 return NicInfo;\r
1448 }\r
1449 }\r
1450\r
1451 return NULL;\r
1452}\r
1453\r
1454\r
1455/**\r
59c0c1cb 1456 Get the NIC's PCI location and return it according to the composited\r
4c5a5e0c 1457 format defined in iSCSI Boot Firmware Table.\r
1458\r
1459 @param[in] Controller The handle of the controller.\r
1460 @param[out] Bus The bus number.\r
1461 @param[out] Device The device number.\r
1462 @param[out] Function The function number.\r
1463\r
1464 @return The composited representation of the NIC PCI location.\r
1465\r
1466**/\r
1467UINT16\r
1468IScsiGetNICPciLocation (\r
1469 IN EFI_HANDLE Controller,\r
1470 OUT UINTN *Bus,\r
1471 OUT UINTN *Device,\r
1472 OUT UINTN *Function\r
1473 )\r
1474{\r
1475 EFI_STATUS Status;\r
1476 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1477 EFI_HANDLE PciIoHandle;\r
1478 EFI_PCI_IO_PROTOCOL *PciIo;\r
1479 UINTN Segment;\r
1480\r
1481 Status = gBS->HandleProtocol (\r
1482 Controller,\r
1483 &gEfiDevicePathProtocolGuid,\r
1484 (VOID **) &DevicePath\r
1485 );\r
1486 if (EFI_ERROR (Status)) {\r
1487 return 0;\r
1488 }\r
1489\r
1490 Status = gBS->LocateDevicePath (\r
1491 &gEfiPciIoProtocolGuid,\r
1492 &DevicePath,\r
1493 &PciIoHandle\r
1494 );\r
1495 if (EFI_ERROR (Status)) {\r
1496 return 0;\r
1497 }\r
1498\r
1499 Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **) &PciIo);\r
1500 if (EFI_ERROR (Status)) {\r
1501 return 0;\r
1502 }\r
1503\r
1504 Status = PciIo->GetLocation (PciIo, &Segment, Bus, Device, Function);\r
1505 if (EFI_ERROR (Status)) {\r
1506 return 0;\r
1507 }\r
1508\r
1509 return (UINT16) ((*Bus << 8) | (*Device << 3) | *Function);\r
1510}\r
1511\r
1512\r
1513/**\r
1514 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
1515 buffer, and the size of the buffer. If failure, return NULL.\r
1516\r
1517 @param[in] Name String part of EFI variable name.\r
1518 @param[in] VendorGuid GUID part of EFI variable name.\r
1519 @param[out] VariableSize Returns the size of the EFI variable that was read.\r
1520\r
1521 @return Dynamically allocated memory that contains a copy of the EFI variable.\r
1522 @return Caller is responsible freeing the buffer.\r
1523 @retval NULL Variable was not read.\r
1524\r
1525**/\r
1526VOID *\r
1527IScsiGetVariableAndSize (\r
1528 IN CHAR16 *Name,\r
1529 IN EFI_GUID *VendorGuid,\r
1530 OUT UINTN *VariableSize\r
1531 )\r
1532{\r
1533 EFI_STATUS Status;\r
1534 UINTN BufferSize;\r
1535 VOID *Buffer;\r
1536\r
1537 Buffer = NULL;\r
1538\r
1539 //\r
1540 // Pass in a zero size buffer to find the required buffer size.\r
1541 //\r
1542 BufferSize = 0;\r
1543 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1544 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1545 //\r
1546 // Allocate the buffer to return\r
1547 //\r
1548 Buffer = AllocateZeroPool (BufferSize);\r
1549 if (Buffer == NULL) {\r
1550 return NULL;\r
1551 }\r
1552 //\r
1553 // Read variable into the allocated buffer.\r
1554 //\r
1555 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1556 if (EFI_ERROR (Status)) {\r
1557 BufferSize = 0;\r
1558 }\r
1559 }\r
1560\r
1561 *VariableSize = BufferSize;\r
1562 return Buffer;\r
1563}\r
1564\r
1565\r
1566/**\r
1567 Create the iSCSI driver data.\r
1568\r
1569 @param[in] Image The handle of the driver image.\r
1570 @param[in] Controller The handle of the controller.\r
1571\r
1572 @return The iSCSI driver data created.\r
1573 @retval NULL Other errors as indicated.\r
1574\r
1575**/\r
1576ISCSI_DRIVER_DATA *\r
1577IScsiCreateDriverData (\r
1578 IN EFI_HANDLE Image,\r
1579 IN EFI_HANDLE Controller\r
1580 )\r
1581{\r
1582 ISCSI_DRIVER_DATA *Private;\r
1583 EFI_STATUS Status;\r
1584\r
1585 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
1586 if (Private == NULL) {\r
1587 return NULL;\r
1588 }\r
1589\r
1590 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
1591 Private->Image = Image;\r
1592 Private->Controller = Controller;\r
1593 Private->Session = NULL;\r
1594\r
1595 //\r
1596 // Create an event to be signaled when the BS to RT transition is triggerd so\r
1597 // as to abort the iSCSI session.\r
1598 //\r
1599 Status = gBS->CreateEventEx (\r
1600 EVT_NOTIFY_SIGNAL,\r
1601 TPL_CALLBACK,\r
1602 IScsiOnExitBootService,\r
1603 Private,\r
1604 &gEfiEventExitBootServicesGuid,\r
1605 &Private->ExitBootServiceEvent\r
1606 );\r
1607 if (EFI_ERROR (Status)) {\r
1608 FreePool (Private);\r
1609 return NULL;\r
1610 }\r
1611\r
1612 Private->ExtScsiPassThruHandle = NULL;\r
1613 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
1614\r
1615 //\r
1616 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
1617 //\r
1618 Private->ExtScsiPassThruMode.AdapterId = 2;\r
1619 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
1620 Private->ExtScsiPassThruMode.IoAlign = 4;\r
1621 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
1622\r
1623 return Private;\r
1624}\r
1625\r
1626\r
1627/**\r
1628 Clean the iSCSI driver data.\r
1629\r
e590d29f
ZL
1630 @param[in] Private The iSCSI driver data.\r
1631\r
6d0bab0e 1632 @retval EFI_SUCCESS The clean operation is successful.\r
e590d29f 1633 @retval Others Other errors as indicated.\r
4c5a5e0c 1634\r
1635**/\r
e590d29f 1636EFI_STATUS\r
4c5a5e0c 1637IScsiCleanDriverData (\r
1638 IN ISCSI_DRIVER_DATA *Private\r
1639 )\r
1640{\r
1641 EFI_STATUS Status;\r
6d0bab0e
ZL
1642\r
1643 Status = EFI_SUCCESS;\r
4c5a5e0c 1644\r
1645 if (Private->DevicePath != NULL) {\r
e590d29f
ZL
1646 Status = gBS->UninstallProtocolInterface (\r
1647 Private->ExtScsiPassThruHandle,\r
1648 &gEfiDevicePathProtocolGuid,\r
1649 Private->DevicePath\r
1650 );\r
1651 if (EFI_ERROR (Status)) {\r
1652 goto EXIT;\r
1653 }\r
4c5a5e0c 1654\r
1655 FreePool (Private->DevicePath);\r
1656 }\r
1657\r
1658 if (Private->ExtScsiPassThruHandle != NULL) {\r
1659 Status = gBS->UninstallProtocolInterface (\r
1660 Private->ExtScsiPassThruHandle,\r
1661 &gEfiExtScsiPassThruProtocolGuid,\r
1662 &Private->IScsiExtScsiPassThru\r
1663 );\r
1664 if (!EFI_ERROR (Status)) {\r
1665 mPrivate->OneSessionEstablished = FALSE;\r
1666 }\r
1667 }\r
1668\r
e590d29f
ZL
1669EXIT:\r
1670\r
4c5a5e0c 1671 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
1672\r
3cb5b997
ZL
1673 mCallbackInfo->Current = NULL;\r
1674\r
4c5a5e0c 1675 FreePool (Private);\r
e590d29f 1676 return Status;\r
4c5a5e0c 1677}\r
1678\r
b7cc5bf1
WJ
1679/**\r
1680 Check wheather the Controller handle is configured to use DHCP protocol.\r
1681\r
1682 @param[in] Controller The handle of the controller.\r
1683 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
1684 \r
1685 @retval TRUE The handle of the controller need the Dhcp protocol.\r
1686 @retval FALSE The handle of the controller does not need the Dhcp protocol.\r
1687 \r
1688**/\r
1689BOOLEAN\r
1690IScsiDhcpIsConfigured (\r
1691 IN EFI_HANDLE Controller,\r
1692 IN UINT8 IpVersion\r
1693 )\r
1694{\r
1695 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1696 UINT8 *AttemptConfigOrder;\r
1697 UINTN AttemptConfigOrderSize;\r
1698 UINTN Index;\r
1699 EFI_STATUS Status;\r
1700 EFI_MAC_ADDRESS MacAddr;\r
1701 UINTN HwAddressSize;\r
1702 UINT16 VlanId;\r
1703 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
8d1f5e04 1704 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
b7cc5bf1
WJ
1705 CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];\r
1706 \r
1707 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1708 L"AttemptOrder",\r
1709 &gIScsiConfigGuid,\r
1710 &AttemptConfigOrderSize\r
1711 );\r
1712 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
1713 return FALSE;\r
1714 }\r
1715 \r
1716 //\r
1717 // Get MAC address of this network device.\r
1718 //\r
1719 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
1720 if(EFI_ERROR (Status)) {\r
1721 return FALSE;\r
1722 }\r
1723 //\r
1724 // Get VLAN ID of this network device.\r
1725 //\r
1726 VlanId = NetLibGetVlanId (Controller);\r
1727 IScsiMacAddrToStr (&MacAddr, (UINT32) HwAddressSize, VlanId, MacString);\r
1728 \r
1729 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1730 UnicodeSPrint (\r
1731 AttemptName,\r
1732 (UINTN) 128,\r
8d1f5e04 1733 L"Attempt %d",\r
b7cc5bf1
WJ
1734 (UINTN) AttemptConfigOrder[Index]\r
1735 );\r
1736 Status = GetVariable2 (\r
1737 AttemptName,\r
1738 &gEfiIScsiInitiatorNameProtocolGuid,\r
1739 (VOID**)&AttemptTmp,\r
1740 NULL\r
1741 );\r
107e3d7a 1742 if(AttemptTmp == NULL || EFI_ERROR (Status)) {\r
b7cc5bf1
WJ
1743 continue;\r
1744 }\r
107e3d7a 1745 \r
b7cc5bf1
WJ
1746 ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);\r
1747\r
1748 if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
1749 FreePool (AttemptTmp);\r
1750 continue;\r
1751 }\r
1752\r
1753 if (AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG && \r
1754 AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)) {\r
1755 FreePool (AttemptTmp);\r
1756 continue;\r
1757 }\r
8d1f5e04
ZL
1758\r
1759 AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
1760\r
1761 if (AttemptTmp->Actived == ISCSI_ACTIVE_DISABLED || StrCmp (MacString, AttemptMacString)) {\r
1762 continue;\r
1763 }\r
1764\r
b7cc5bf1
WJ
1765 if(AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG ||\r
1766 AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE ||\r
1767 AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE) { \r
1768 FreePool (AttemptTmp);\r
1769 FreePool (AttemptConfigOrder);\r
1770 return TRUE;\r
1771 }\r
1772\r
1773 FreePool (AttemptTmp);\r
1774 }\r
1775 \r
1776 FreePool (AttemptConfigOrder);\r
1777 return FALSE;\r
1778}\r
4c5a5e0c 1779\r
eabc6e59
ZL
1780/**\r
1781 Check wheather the Controller handle is configured to use DNS protocol.\r
1782\r
1783 @param[in] Controller The handle of the controller.\r
1784 \r
1785 @retval TRUE The handle of the controller need the Dns protocol.\r
1786 @retval FALSE The handle of the controller does not need the Dns protocol.\r
1787 \r
1788**/\r
1789BOOLEAN\r
1790IScsiDnsIsConfigured (\r
1791 IN EFI_HANDLE Controller\r
1792 )\r
1793{\r
1794 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1795 UINT8 *AttemptConfigOrder;\r
1796 UINTN AttemptConfigOrderSize;\r
1797 UINTN Index;\r
1798 EFI_STATUS Status;\r
1799 EFI_MAC_ADDRESS MacAddr;\r
1800 UINTN HwAddressSize;\r
1801 UINT16 VlanId;\r
1802 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
1803 CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];\r
1804 \r
1805 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1806 L"AttemptOrder",\r
1807 &gIScsiConfigGuid,\r
1808 &AttemptConfigOrderSize\r
1809 );\r
1810 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
1811 return FALSE;\r
1812 }\r
1813 \r
1814 //\r
1815 // Get MAC address of this network device.\r
1816 //\r
1817 Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);\r
1818 if(EFI_ERROR (Status)) {\r
1819 return FALSE;\r
1820 }\r
1821 //\r
1822 // Get VLAN ID of this network device.\r
1823 //\r
1824 VlanId = NetLibGetVlanId (Controller);\r
1825 IScsiMacAddrToStr (&MacAddr, (UINT32) HwAddressSize, VlanId, MacString);\r
1826 \r
1827 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1828 UnicodeSPrint (\r
1829 AttemptName,\r
1830 (UINTN) 128,\r
1831 L"%s%d",\r
1832 MacString,\r
1833 (UINTN) AttemptConfigOrder[Index]\r
1834 );\r
1835 Status = GetVariable2 (\r
1836 AttemptName,\r
1837 &gEfiIScsiInitiatorNameProtocolGuid,\r
1838 (VOID**)&AttemptTmp,\r
1839 NULL\r
1840 );\r
1841 if(AttemptTmp == NULL || EFI_ERROR (Status)) {\r
1842 continue;\r
1843 }\r
1844 \r
1845 ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);\r
1846\r
1847 if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
1848 FreePool (AttemptTmp);\r
1849 continue;\r
1850 }\r
1851 \r
1852 if (AttemptTmp->SessionConfigData.DnsMode) {\r
1853 FreePool (AttemptTmp);\r
1854 FreePool (AttemptConfigOrder);\r
1855 return TRUE;\r
1856 } else {\r
1857 FreePool (AttemptTmp);\r
1858 continue;\r
1859 }\r
1860\r
1861 }\r
1862\r
1863 FreePool (AttemptConfigOrder);\r
1864 return FALSE;\r
1865\r
1866}\r
1867\r
4c5a5e0c 1868/**\r
1869 Get the various configuration data.\r
1870\r
1871 @param[in] Private The iSCSI driver data.\r
1872\r
1873 @retval EFI_SUCCESS The configuration data is retrieved.\r
1874 @retval EFI_NOT_FOUND This iSCSI driver is not configured yet.\r
7c275b3c 1875 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
4c5a5e0c 1876\r
1877**/\r
1878EFI_STATUS\r
1879IScsiGetConfigData (\r
1880 IN ISCSI_DRIVER_DATA *Private\r
1881 )\r
1882{\r
1883 EFI_STATUS Status;\r
1884 CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];\r
8d1f5e04 1885 CHAR16 AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];\r
4c5a5e0c 1886 UINTN Index;\r
1887 ISCSI_NIC_INFO *NicInfo;\r
1888 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;\r
1889 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;\r
1890 UINT8 *AttemptConfigOrder;\r
1891 UINTN AttemptConfigOrderSize;\r
1892 CHAR16 IScsiMode[64];\r
1893 CHAR16 IpMode[64];\r
1894\r
1895 //\r
1896 // There should be at least one attempt configured.\r
1897 //\r
1898 AttemptConfigOrder = IScsiGetVariableAndSize (\r
1899 L"AttemptOrder",\r
9bdc6592 1900 &gIScsiConfigGuid,\r
4c5a5e0c 1901 &AttemptConfigOrderSize\r
1902 );\r
1903 if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {\r
1904 return EFI_NOT_FOUND;\r
1905 }\r
1906\r
1907 //\r
1908 // Get the iSCSI Initiator Name.\r
1909 //\r
1910 mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
1911 Status = gIScsiInitiatorName.Get (\r
1912 &gIScsiInitiatorName,\r
1913 &mPrivate->InitiatorNameLength,\r
1914 mPrivate->InitiatorName\r
1915 );\r
1916 if (EFI_ERROR (Status)) {\r
1917 return Status;\r
1918 }\r
1919\r
1920 //\r
1921 // Get the normal configuration.\r
1922 //\r
1923 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
1924\r
1925 //\r
1926 // Check whether the attempt exists in AttemptConfig.\r
1927 //\r
1928 AttemptTmp = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]); \r
1929 if (AttemptTmp != NULL && AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
1930 continue;\r
1931 } else if (AttemptTmp != NULL && AttemptTmp->SessionConfigData.Enabled != ISCSI_DISABLED) {\r
1932 //\r
1933 // Check the autoconfig path to see whether it should be retried.\r
1934 //\r
1935 if (AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG &&\r
87ce4210 1936 !AttemptTmp->AutoConfigureSuccess) {\r
4c5a5e0c 1937 if (mPrivate->Ipv6Flag &&\r
1938 AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6) {\r
1939 //\r
1940 // Autoconfigure for IP6 already attempted but failed. Do not try again.\r
1941 //\r
1942 continue;\r
1943 } else if (!mPrivate->Ipv6Flag &&\r
1944 AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4) {\r
1945 //\r
1946 // Autoconfigure for IP4 already attempted but failed. Do not try again.\r
1947 //\r
1948 continue;\r
1949 } else {\r
1950 //\r
1951 // Try another approach for this autoconfigure path.\r
1952 //\r
1953 AttemptTmp->AutoConfigureMode =\r
1954 (UINT8) (mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);\r
1955 AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp = TRUE;\r
1956 AttemptTmp->SessionConfigData.TargetInfoFromDhcp = TRUE;\r
1957 AttemptTmp->DhcpSuccess = FALSE;\r
1958\r
1959 //\r
1960 // Get some information from the dhcp server.\r
1961 //\r
1962 if (!mPrivate->Ipv6Flag) {\r
1963 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);\r
1964 if (!EFI_ERROR (Status)) {\r
1965 AttemptTmp->DhcpSuccess = TRUE;\r
1966 }\r
1967 } else {\r
1968 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);\r
1969 if (!EFI_ERROR (Status)) {\r
1970 AttemptTmp->DhcpSuccess = TRUE;\r
1971 }\r
1972 }\r
1973\r
1974 //\r
1975 // Refresh the state of this attempt to NVR.\r
1976 //\r
4c5a5e0c 1977 UnicodeSPrint (\r
1978 mPrivate->PortString,\r
1979 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 1980 L"Attempt %d",\r
4c5a5e0c 1981 (UINTN) AttemptTmp->AttemptConfigIndex\r
1982 );\r
1983\r
1984 gRT->SetVariable (\r
1985 mPrivate->PortString,\r
1986 &gEfiIScsiInitiatorNameProtocolGuid,\r
1987 ISCSI_CONFIG_VAR_ATTR,\r
1988 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
1989 AttemptTmp\r
1990 );\r
1991\r
1992 continue;\r
1993 }\r
1994 } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp && !AttemptTmp->ValidPath) {\r
1995 //\r
1996 // Get DHCP information for already added, but failed, attempt.\r
1997 //\r
1998 AttemptTmp->DhcpSuccess = FALSE;\r
1999 if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) {\r
2000 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);\r
2001 if (!EFI_ERROR (Status)) {\r
2002 AttemptTmp->DhcpSuccess = TRUE;\r
2003 }\r
2004 } else if (mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP6)) {\r
2005 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);\r
2006 if (!EFI_ERROR (Status)) {\r
2007 AttemptTmp->DhcpSuccess = TRUE;\r
2008 }\r
2009 }\r
2010\r
2011 //\r
2012 // Refresh the state of this attempt to NVR.\r
2013 //\r
4c5a5e0c 2014 UnicodeSPrint (\r
2015 mPrivate->PortString,\r
2016 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2017 L"Attempt %d",\r
4c5a5e0c 2018 (UINTN) AttemptTmp->AttemptConfigIndex\r
2019 );\r
2020\r
2021 gRT->SetVariable (\r
2022 mPrivate->PortString,\r
2023 &gEfiIScsiInitiatorNameProtocolGuid,\r
2024 ISCSI_CONFIG_VAR_ATTR,\r
2025 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2026 AttemptTmp\r
2027 );\r
2028\r
2029 continue;\r
2030\r
2031 } else {\r
2032 continue;\r
2033 }\r
2034 }\r
2035\r
2036 //\r
2037 // This attempt does not exist in AttemptConfig. Try to add a new one.\r
2038 //\r
2039\r
2040 NicInfo = IScsiGetNicInfoByIndex (mPrivate->CurrentNic);\r
2041 ASSERT (NicInfo != NULL);\r
2042 IScsiMacAddrToStr (&NicInfo->PermanentAddress, NicInfo->HwAddressSize, NicInfo->VlanId, MacString);\r
2043 UnicodeSPrint (\r
2044 mPrivate->PortString,\r
8d1f5e04
ZL
2045 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
2046 L"Attempt %d",\r
4c5a5e0c 2047 (UINTN) AttemptConfigOrder[Index]\r
2048 );\r
2049\r
bf4a3dbd 2050 GetVariable2 (\r
a2d59ef2
YT
2051 mPrivate->PortString,\r
2052 &gEfiIScsiInitiatorNameProtocolGuid,\r
2053 (VOID**)&AttemptConfigData,\r
2054 NULL\r
2055 );\r
8d1f5e04 2056 AsciiStrToUnicodeStrS (AttemptConfigData->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));\r
4c5a5e0c 2057\r
8d1f5e04
ZL
2058 if (AttemptConfigData == NULL || AttemptConfigData->Actived == ISCSI_ACTIVE_DISABLED ||\r
2059 StrCmp (MacString, AttemptMacString)) {\r
4c5a5e0c 2060 continue;\r
2061 }\r
2062\r
2063 ASSERT (AttemptConfigOrder[Index] == AttemptConfigData->AttemptConfigIndex);\r
2064\r
2065 AttemptConfigData->NicIndex = NicInfo->NicIndex;\r
2066 AttemptConfigData->DhcpSuccess = FALSE;\r
2067 AttemptConfigData->ValidiBFTPath = (BOOLEAN) (mPrivate->EnableMpio ? TRUE : FALSE);\r
2068 AttemptConfigData->ValidPath = FALSE;\r
2069\r
2070 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {\r
2071 AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp = TRUE;\r
2072 AttemptConfigData->SessionConfigData.TargetInfoFromDhcp = TRUE;\r
2073\r
2074 AttemptConfigData->AutoConfigureMode =\r
2075 (UINT8) (mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);\r
87ce4210 2076 AttemptConfigData->AutoConfigureSuccess = FALSE;\r
4c5a5e0c 2077 }\r
2078 \r
2079 //\r
2080 // Get some information from dhcp server.\r
2081 //\r
2082 if (AttemptConfigData->SessionConfigData.Enabled != ISCSI_DISABLED &&\r
2083 AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp) {\r
2084\r
2085 if (!mPrivate->Ipv6Flag &&\r
2086 (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4 ||\r
2087 AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4)) {\r
2088 Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptConfigData);\r
2089 if (!EFI_ERROR (Status)) {\r
2090 AttemptConfigData->DhcpSuccess = TRUE;\r
2091 }\r
2092 } else if (mPrivate->Ipv6Flag &&\r
2093 (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6 ||\r
2094 AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6)) {\r
2095 Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptConfigData);\r
2096 if (!EFI_ERROR (Status)) {\r
2097 AttemptConfigData->DhcpSuccess = TRUE;\r
2098 }\r
2099 }\r
2100\r
2101 //\r
2102 // Refresh the state of this attempt to NVR.\r
2103 //\r
4c5a5e0c 2104 UnicodeSPrint (\r
2105 mPrivate->PortString,\r
2106 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
8d1f5e04 2107 L"Attempt %d",\r
4c5a5e0c 2108 (UINTN) AttemptConfigData->AttemptConfigIndex\r
2109 );\r
2110\r
2111 gRT->SetVariable (\r
2112 mPrivate->PortString,\r
2113 &gEfiIScsiInitiatorNameProtocolGuid,\r
2114 ISCSI_CONFIG_VAR_ATTR,\r
2115 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),\r
2116 AttemptConfigData\r
2117 );\r
2118 }\r
2119\r
2120 //\r
2121 // Update Attempt Help Info.\r
2122 //\r
2123\r
2124 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) {\r
2125 UnicodeSPrint (IScsiMode, 64, L"Disabled");\r
2126 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2127 UnicodeSPrint (IScsiMode, 64, L"Enabled");\r
2128 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2129 UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");\r
2130 }\r
2131\r
2132 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {\r
2133 UnicodeSPrint (IpMode, 64, L"IP4");\r
2134 } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {\r
2135 UnicodeSPrint (IpMode, 64, L"IP6");\r
2136 } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {\r
2137 UnicodeSPrint (IpMode, 64, L"Autoconfigure");\r
2138 }\r
2139\r
2140 UnicodeSPrint (\r
2141 mPrivate->PortString,\r
2142 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
2143 L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",\r
2144 MacString,\r
2145 NicInfo->BusNumber,\r
2146 NicInfo->DeviceNumber,\r
2147 NicInfo->FunctionNumber,\r
2148 IScsiMode,\r
2149 IpMode\r
2150 );\r
2151\r
2152 AttemptConfigData->AttemptTitleHelpToken = HiiSetString (\r
2153 mCallbackInfo->RegisteredHandle,\r
2154 0,\r
2155 mPrivate->PortString,\r
2156 NULL\r
2157 );\r
7c275b3c
ZL
2158 if (AttemptConfigData->AttemptTitleHelpToken == 0) {\r
2159 return EFI_OUT_OF_RESOURCES;\r
2160 }\r
4c5a5e0c 2161\r
2162 //\r
2163 // Record the attempt in global link list.\r
2164 //\r
2165 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2166 mPrivate->AttemptCount++;\r
2167\r
2168 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {\r
2169 mPrivate->MpioCount++;\r
2170 mPrivate->EnableMpio = TRUE;\r
2171\r
2172 if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {\r
2173 mPrivate->Krb5MpioCount++;\r
2174 }\r
2175 } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {\r
2176 mPrivate->SinglePathCount++;\r
2177 }\r
2178 }\r
2179\r
2180 //\r
2181 // Reorder the AttemptConfig by the configured order.\r
2182 //\r
2183 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {\r
2184 AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);\r
2185 if (AttemptConfigData == NULL) {\r
2186 continue;\r
2187 }\r
2188\r
2189 RemoveEntryList (&AttemptConfigData->Link);\r
2190 InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);\r
2191 }\r
2192\r
2193 //\r
2194 // Update the Main Form.\r
2195 //\r
2196 IScsiConfigUpdateAttempt ();\r
2197\r
2198 FreePool (AttemptConfigOrder);\r
2199\r
2200 //\r
2201 // There should be at least one attempt configuration.\r
2202 //\r
2203 if (!mPrivate->EnableMpio) {\r
2204 if (mPrivate->SinglePathCount == 0) {\r
2205 return EFI_NOT_FOUND;\r
2206 }\r
2207 mPrivate->ValidSinglePathCount = mPrivate->SinglePathCount;\r
2208 }\r
2209\r
2210 return EFI_SUCCESS;\r
2211}\r
2212\r
2213\r
2214/**\r
2215 Get the device path of the iSCSI tcp connection and update it.\r
2216\r
2217 @param Session The iSCSI session.\r
2218\r
2219 @return The updated device path.\r
2220 @retval NULL Other errors as indicated.\r
2221\r
2222**/\r
2223EFI_DEVICE_PATH_PROTOCOL *\r
2224IScsiGetTcpConnDevicePath (\r
2225 IN ISCSI_SESSION *Session\r
2226 )\r
2227{\r
2228 ISCSI_CONNECTION *Conn;\r
2229 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
2230 EFI_STATUS Status;\r
2231 EFI_DEV_PATH *DPathNode;\r
42f0586d 2232 UINTN PathLen;\r
4c5a5e0c 2233\r
2234 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
2235 return NULL;\r
2236 }\r
2237\r
2238 Conn = NET_LIST_USER_STRUCT_S (\r
2239 Session->Conns.ForwardLink,\r
2240 ISCSI_CONNECTION,\r
2241 Link,\r
2242 ISCSI_CONNECTION_SIGNATURE\r
2243 );\r
2244\r
2245 Status = gBS->HandleProtocol (\r
2246 Conn->TcpIo.Handle,\r
2247 &gEfiDevicePathProtocolGuid,\r
2248 (VOID **) &DevicePath\r
2249 ); \r
2250 if (EFI_ERROR (Status)) {\r
2251 return NULL;\r
2252 }\r
2253 //\r
2254 // Duplicate it.\r
2255 //\r
2256 DevicePath = DuplicateDevicePath (DevicePath);\r
2257 if (DevicePath == NULL) {\r
2258 return NULL;\r
2259 }\r
2260\r
2261 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
2262\r
2263 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
2264 if (DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) {\r
2265 if (!Conn->Ipv6Flag && DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP) {\r
2266 DPathNode->Ipv4.LocalPort = 0;\r
501793fa
RN
2267\r
2268 DPathNode->Ipv4.StaticIpAddress = \r
2269 (BOOLEAN) (!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);\r
2270\r
42f0586d 2271 //\r
2272 // Add a judgement here to support previous versions of IPv4_DEVICE_PATH.\r
2273 // In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask\r
2274 // do not exist.\r
2275 // In new version of IPv4_DEVICE_PATH, structcure length is 27.\r
2276 //\r
501793fa 2277\r
42f0586d 2278 PathLen = DevicePathNodeLength (&DPathNode->Ipv4);\r
2279 \r
5ae7578a 2280 if (PathLen == IP4_NODE_LEN_NEW_VERSIONS) { \r
42f0586d 2281 \r
2282 IP4_COPY_ADDRESS (\r
2283 &DPathNode->Ipv4.GatewayIpAddress,\r
2284 &Session->ConfigData->SessionConfigData.Gateway\r
2285 );\r
2286\r
2287 IP4_COPY_ADDRESS (\r
2288 &DPathNode->Ipv4.SubnetMask,\r
2289 &Session->ConfigData->SessionConfigData.SubnetMask\r
2290 );\r
2291 }\r
2292 \r
4c5a5e0c 2293 break;\r
2294 } else if (Conn->Ipv6Flag && DevicePathSubType (&DPathNode->DevPath) == MSG_IPv6_DP) {\r
2295 DPathNode->Ipv6.LocalPort = 0;\r
42f0586d 2296\r
2297 //\r
2298 // Add a judgement here to support previous versions of IPv6_DEVICE_PATH.\r
2299 // In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength\r
2300 // and GatewayIpAddress do not exist.\r
2301 // In new version of IPv6_DEVICE_PATH, structure length is 60, while in \r
2302 // old versions, the length is 43.\r
2303 //\r
2304\r
2305 PathLen = DevicePathNodeLength (&DPathNode->Ipv6);\r
2306 \r
5ae7578a 2307 if (PathLen == IP6_NODE_LEN_NEW_VERSIONS ) { \r
42f0586d 2308\r
2309 DPathNode->Ipv6.IpAddressOrigin = 0;\r
2310 DPathNode->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;\r
2311 ZeroMem (&DPathNode->Ipv6.GatewayIpAddress, sizeof (EFI_IPv6_ADDRESS));\r
2312 }\r
5ae7578a 2313 else if (PathLen == IP6_NODE_LEN_OLD_VERSIONS) { \r
42f0586d 2314\r
2315 //\r
2316 // StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new \r
2317 // version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.\r
2318 //\r
5ae7578a 2319 *((UINT8 *)(&DPathNode->Ipv6) + IP6_OLD_IPADDRESS_OFFSET) = \r
42f0586d 2320 (BOOLEAN) (!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);\r
2321 }\r
2322 \r
4c5a5e0c 2323 break;\r
2324 }\r
2325 }\r
2326\r
2327 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
2328 }\r
2329\r
2330 return DevicePath;\r
2331}\r
2332\r
2333\r
2334/**\r
2335 Abort the session when the transition from BS to RT is initiated.\r
2336\r
2337 @param[in] Event The event signaled.\r
2338 @param[in] Context The iSCSI driver data.\r
2339\r
2340**/\r
2341VOID\r
2342EFIAPI\r
2343IScsiOnExitBootService (\r
2344 IN EFI_EVENT Event,\r
2345 IN VOID *Context\r
2346 )\r
2347{\r
2348 ISCSI_DRIVER_DATA *Private;\r
2349\r
2350 Private = (ISCSI_DRIVER_DATA *) Context;\r
2351 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
2352\r
2353 if (Private->Session != NULL) {\r
2354 IScsiSessionAbort (Private->Session);\r
2355 }\r
2356}\r
18b24f92
FS
2357\r
2358/**\r
2359 Tests whether a controller handle is being managed by IScsi driver.\r
2360\r
2361 This function tests whether the driver specified by DriverBindingHandle is\r
2362 currently managing the controller specified by ControllerHandle. This test\r
2363 is performed by evaluating if the the protocol specified by ProtocolGuid is\r
2364 present on ControllerHandle and is was opened by DriverBindingHandle and Nic\r
2365 Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER. \r
2366 If ProtocolGuid is NULL, then ASSERT().\r
2367\r
2368 @param ControllerHandle A handle for a controller to test.\r
2369 @param DriverBindingHandle Specifies the driver binding handle for the\r
2370 driver.\r
2371 @param ProtocolGuid Specifies the protocol that the driver specified\r
2372 by DriverBindingHandle opens in its Start()\r
2373 function.\r
2374\r
2375 @retval EFI_SUCCESS ControllerHandle is managed by the driver\r
2376 specified by DriverBindingHandle.\r
2377 @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver\r
2378 specified by DriverBindingHandle.\r
2379\r
2380**/\r
2381EFI_STATUS\r
2382EFIAPI\r
2383IScsiTestManagedDevice (\r
2384 IN EFI_HANDLE ControllerHandle,\r
2385 IN EFI_HANDLE DriverBindingHandle,\r
2386 IN EFI_GUID *ProtocolGuid\r
2387 )\r
2388{\r
2389 EFI_STATUS Status;\r
2390 VOID *ManagedInterface;\r
2391 EFI_HANDLE NicControllerHandle;\r
2392\r
2393 ASSERT (ProtocolGuid != NULL);\r
2394\r
2395 NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);\r
2396 if (NicControllerHandle == NULL) {\r
2397 return EFI_UNSUPPORTED;\r
2398 }\r
2399\r
2400 Status = gBS->OpenProtocol (\r
2401 ControllerHandle,\r
2402 (EFI_GUID *) ProtocolGuid,\r
2403 &ManagedInterface,\r
2404 DriverBindingHandle,\r
2405 NicControllerHandle,\r
2406 EFI_OPEN_PROTOCOL_BY_DRIVER\r
2407 );\r
2408 if (!EFI_ERROR (Status)) {\r
2409 gBS->CloseProtocol (\r
2410 ControllerHandle,\r
2411 (EFI_GUID *) ProtocolGuid,\r
2412 DriverBindingHandle,\r
2413 NicControllerHandle\r
2414 );\r
2415 return EFI_UNSUPPORTED;\r
2416 }\r
2417\r
2418 if (Status != EFI_ALREADY_STARTED) {\r
2419 return EFI_UNSUPPORTED;\r
2420 }\r
2421\r
2422 return EFI_SUCCESS;\r
2423}\r