]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
delete redundant **/
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiMisc.c
... / ...
CommitLineData
1/** @file\r
2 Miscellaneous routines for IScsi driver.\r
3\r
4Copyright (c) 2004 - 2008, Intel Corporation.<BR>\r
5All rights reserved. This 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. On return, \r
23 str will hold the trimmed string. \r
24\r
25 @param[in] CharC Character will be trimmed from str.\r
26**/\r
27VOID\r
28StrTrim (\r
29 IN OUT CHAR16 *Str,\r
30 IN CHAR16 CharC\r
31 )\r
32{\r
33 CHAR16 *Pointer1;\r
34 CHAR16 *Pointer2;\r
35 \r
36 if (*Str == 0) {\r
37 return;\r
38 }\r
39 \r
40 //\r
41 // Trim off the leading and trailing characters c\r
42 //\r
43 for (Pointer1 = Str; (*Pointer1 != 0) && (*Pointer1 == CharC); Pointer1++) {\r
44 ;\r
45 }\r
46 \r
47 Pointer2 = Str;\r
48 if (Pointer2 == Pointer1) {\r
49 while (*Pointer1 != 0) {\r
50 Pointer2++;\r
51 Pointer1++;\r
52 }\r
53 } else {\r
54 while (*Pointer1 != 0) { \r
55 *Pointer2 = *Pointer1; \r
56 Pointer1++;\r
57 Pointer2++;\r
58 }\r
59 *Pointer2 = 0;\r
60 }\r
61 \r
62 \r
63 for (Pointer1 = Str + StrLen(Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {\r
64 ;\r
65 }\r
66 if (Pointer1 != Str + StrLen(Str) - 1) { \r
67 *(Pointer1 + 1) = 0;\r
68 }\r
69}\r
70\r
71/**\r
72 Calculate the prefix length of the IPv4 subnet mask.\r
73\r
74 @param[in] SubnetMask The IPv4 subnet mask.\r
75\r
76 @return The prefix length of the subnet mask.\r
77 @return 0 Some unexpected error happened.\r
78**/\r
79UINT8\r
80IScsiGetSubnetMaskPrefixLength (\r
81 IN EFI_IPv4_ADDRESS *SubnetMask\r
82 )\r
83{\r
84 UINT8 Len;\r
85 UINT32 ReverseMask;\r
86\r
87 //\r
88 // The SubnetMask is in network byte order.\r
89 //\r
90 ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);\r
91\r
92 //\r
93 // Reverse it.\r
94 //\r
95 ReverseMask = ~ReverseMask;\r
96\r
97 if ((ReverseMask != 0) & ((ReverseMask + 1) != 0)) {\r
98 return 0;\r
99 }\r
100\r
101 Len = 0;\r
102\r
103 while (ReverseMask != 0) {\r
104 ReverseMask = ReverseMask >> 1;\r
105 Len++;\r
106 }\r
107\r
108 return (UINT8) (32 - Len);\r
109}\r
110\r
111/**\r
112 Convert the hexadecimal encoded LUN string into the 64-bit LUN. \r
113\r
114 @param[in] Str The hexadecimal encoded LUN string.\r
115 @param[out] Lun Storage to return the 64-bit LUN.\r
116\r
117 @retval EFI_SUCCESS The 64-bit LUN is stored in Lun.\r
118 @retval EFI_INVALID_PARAMETER The string is malformatted.\r
119**/\r
120EFI_STATUS\r
121IScsiAsciiStrToLun (\r
122 IN CHAR8 *Str,\r
123 OUT UINT8 *Lun\r
124 )\r
125{\r
126 UINT32 Index;\r
127 CHAR8 *LunUnitStr[4];\r
128 CHAR8 Digit;\r
129 UINTN Temp;\r
130\r
131 ZeroMem (Lun, 8);\r
132 ZeroMem (LunUnitStr, sizeof (LunUnitStr));\r
133\r
134 Index = 0;\r
135 LunUnitStr[0] = Str;\r
136\r
137 if (!IsHexDigit ((UINT8 *) &Digit, *Str)) {\r
138 return EFI_INVALID_PARAMETER;\r
139 }\r
140\r
141 while (*Str != '\0') {\r
142 //\r
143 // Legal representations of LUN:\r
144 // 4752-3A4F-6b7e-2F99,\r
145 // 6734-9-156f-127,\r
146 // 4186-9\r
147 //\r
148 if (*Str == '-') {\r
149 *Str = '\0';\r
150 Index++;\r
151\r
152 if (*(Str + 1) != '\0') {\r
153 if (!IsHexDigit ((UINT8 *) &Digit, *(Str + 1))) {\r
154 return EFI_INVALID_PARAMETER;\r
155 }\r
156\r
157 LunUnitStr[Index] = Str + 1;\r
158 }\r
159 } else if (!IsHexDigit ((UINT8 *) &Digit, *Str)) {\r
160 return EFI_INVALID_PARAMETER;\r
161 }\r
162\r
163 Str++;\r
164 }\r
165\r
166 for (Index = 0; (Index < 4) && (LunUnitStr[Index] != NULL); Index++) {\r
167 if (AsciiStrLen (LunUnitStr[Index]) > 4) {\r
168 return EFI_INVALID_PARAMETER;\r
169 }\r
170\r
171 Temp = AsciiStrHexToUintn (LunUnitStr[Index]);\r
172 *((UINT16 *) &Lun[Index * 2]) = HTONS (Temp);\r
173 }\r
174\r
175 return EFI_SUCCESS;\r
176}\r
177\r
178/**\r
179 Convert the 64-bit LUN into the hexadecimal encoded LUN string.\r
180\r
181 @param[in] Lun The 64-bit LUN.\r
182 @param[out] Str The storage to return the hexadecimal encoded LUN string.\r
183**/\r
184VOID\r
185IScsiLunToUnicodeStr (\r
186 IN UINT8 *Lun,\r
187 OUT CHAR16 *Str\r
188 )\r
189{\r
190 UINTN Index;\r
191 CHAR16 *TempStr;\r
192\r
193 TempStr = Str;\r
194\r
195 for (Index = 0; Index < 4; Index++) {\r
196\r
197 if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {\r
198 StrCpy (TempStr, L"0-");\r
199 } else {\r
200 TempStr[0] = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];\r
201 TempStr[1] = (CHAR16) IScsiHexString[Lun[2 * Index] & 0x0F];\r
202 TempStr[2] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];\r
203 TempStr[3] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0x0F];\r
204 TempStr[4] = L'-';\r
205 TempStr[5] = 0;\r
206\r
207 StrTrim (TempStr, L'0');\r
208 }\r
209\r
210 TempStr += StrLen (TempStr);\r
211 }\r
212\r
213 Str[StrLen (Str) - 1] = 0;\r
214\r
215 for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {\r
216 if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {\r
217 Str[Index - 1] = 0;\r
218 } else {\r
219 break;\r
220 }\r
221 }\r
222}\r
223\r
224/**\r
225 Convert the ASCII string into a UNICODE string.\r
226\r
227 @param[in] Source The ASCII string.\r
228 @param[out] Destination The storage to return the UNICODE string.\r
229\r
230 @return CHAR16 * Pointer to the UNICODE string.\r
231**/\r
232CHAR16 *\r
233IScsiAsciiStrToUnicodeStr (\r
234 IN CHAR8 *Source,\r
235 OUT CHAR16 *Destination\r
236 )\r
237{\r
238 ASSERT (Destination != NULL);\r
239 ASSERT (Source != NULL);\r
240\r
241 while (*Source != '\0') {\r
242 *(Destination++) = (CHAR16) *(Source++);\r
243 }\r
244\r
245 *Destination = '\0';\r
246\r
247 return Destination;\r
248}\r
249\r
250/**\r
251 Convert the UNICODE string into an ASCII string.\r
252\r
253 @param[in] Source The UNICODE string.\r
254 @param[out] Destination The storage to return the ASCII string.\r
255\r
256 @return CHAR8 * Pointer to the ASCII string.\r
257**/\r
258CHAR8 *\r
259IScsiUnicodeStrToAsciiStr (\r
260 IN CHAR16 *Source,\r
261 OUT CHAR8 *Destination\r
262 )\r
263{\r
264 ASSERT (Destination != NULL);\r
265 ASSERT (Source != NULL);\r
266\r
267 while (*Source != '\0') {\r
268 //\r
269 // If any Unicode characters in Source contain\r
270 // non-zero value in the upper 8 bits, then ASSERT().\r
271 //\r
272 ASSERT (*Source < 0x100);\r
273 *(Destination++) = (CHAR8) *(Source++);\r
274 }\r
275\r
276 *Destination = '\0';\r
277\r
278 return Destination;\r
279}\r
280\r
281/**\r
282 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
283\r
284 @param[in] Str The UNICODE string.\r
285 @param[out] Ip The storage to return the ASCII string.\r
286\r
287 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
288 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
289**/\r
290EFI_STATUS\r
291IScsiAsciiStrToIp (\r
292 IN CHAR8 *Str,\r
293 OUT EFI_IPv4_ADDRESS *Ip\r
294 )\r
295{\r
296 UINTN Index;\r
297 UINTN Number;\r
298\r
299 Index = 0;\r
300\r
301 while (*Str) {\r
302\r
303 if (Index > 3) {\r
304 return EFI_INVALID_PARAMETER;\r
305 }\r
306\r
307 Number = 0;\r
308 while (NET_IS_DIGIT (*Str)) {\r
309 Number = Number * 10 + (*Str - '0');\r
310 Str++;\r
311 }\r
312\r
313 if (Number > 0xFF) {\r
314 return EFI_INVALID_PARAMETER;\r
315 }\r
316\r
317 Ip->Addr[Index] = (UINT8) Number;\r
318\r
319 if ((*Str != '\0') && (*Str != '.')) {\r
320 //\r
321 // The current character should be either the NULL terminator or\r
322 // the dot delimiter.\r
323 //\r
324 return EFI_INVALID_PARAMETER;\r
325 }\r
326\r
327 if (*Str == '.') {\r
328 //\r
329 // Skip the delimiter.\r
330 //\r
331 Str++;\r
332 }\r
333\r
334 Index++;\r
335 }\r
336\r
337 if (Index != 4) {\r
338 return EFI_INVALID_PARAMETER;\r
339 }\r
340\r
341 return EFI_SUCCESS;\r
342}\r
343\r
344/**\r
345 Convert the mac address into a hexadecimal encoded "-" seperated string.\r
346\r
347 @param[in] Mac The mac address.\r
348 @param[in] Len Length in bytes of the mac address.\r
349 @param[out] Str The storage to return the mac string.\r
350**/\r
351VOID\r
352IScsiMacAddrToStr (\r
353 IN EFI_MAC_ADDRESS *Mac,\r
354 IN UINT32 Len,\r
355 OUT CHAR16 *Str\r
356 )\r
357{\r
358 UINT32 Index;\r
359\r
360 for (Index = 0; Index < Len; Index++) {\r
361 Str[3 * Index] = (CHAR16) IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];\r
362 Str[3 * Index + 1] = (CHAR16) IScsiHexString[Mac->Addr[Index] & 0x0F];\r
363 Str[3 * Index + 2] = L'-';\r
364 }\r
365\r
366 Str[3 * Index - 1] = L'\0';\r
367}\r
368\r
369/**\r
370 Convert the binary encoded buffer into a hexadecimal encoded string.\r
371\r
372 @param[in] BinBuffer The buffer containing the binary data.\r
373 @param[in] BinLength Length of the binary buffer.\r
374 @param[in, out] HexStr Pointer to the string.\r
375 @param[in, out] HexLength The length of the string.\r
376\r
377 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string \r
378 and the length of the string is updated.\r
379 @retval EFI_BUFFER_TOO_SMALL The string is too small.\r
380 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
381**/\r
382EFI_STATUS\r
383IScsiBinToHex (\r
384 IN UINT8 *BinBuffer,\r
385 IN UINT32 BinLength,\r
386 IN OUT CHAR8 *HexStr,\r
387 IN OUT UINT32 *HexLength\r
388 )\r
389{\r
390 UINTN Index;\r
391\r
392 if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {\r
393 return EFI_INVALID_PARAMETER;\r
394 }\r
395\r
396 if (((*HexLength) - 3) < BinLength * 2) {\r
397 *HexLength = BinLength * 2 + 3;\r
398 return EFI_BUFFER_TOO_SMALL;\r
399 }\r
400\r
401 *HexLength = BinLength * 2 + 3;\r
402 //\r
403 // Prefix for Hex String\r
404 //\r
405 HexStr[0] = '0';\r
406 HexStr[1] = 'x';\r
407\r
408 for (Index = 0; Index < BinLength; Index++) {\r
409 HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];\r
410 HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0x0F];\r
411 }\r
412\r
413 HexStr[Index * 2 + 2] = '\0';\r
414\r
415 return EFI_SUCCESS;\r
416}\r
417\r
418/**\r
419 Convert the hexadecimal string into a binary encoded buffer.\r
420\r
421 @param[in, out] BinBuffer The binary buffer.\r
422 @param[in, out] BinLength Length of the binary buffer.\r
423 @param[in] HexStr The hexadecimal string.\r
424\r
425 @retval EFI_SUCCESS The hexadecimal string is converted into a binary\r
426 encoded buffer.\r
427 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.s\r
428**/\r
429EFI_STATUS\r
430IScsiHexToBin (\r
431 IN OUT UINT8 *BinBuffer,\r
432 IN OUT UINT32 *BinLength,\r
433 IN CHAR8 *HexStr\r
434 )\r
435{\r
436 UINTN Index;\r
437 UINT32 HexCount;\r
438 CHAR8 *HexBuf;\r
439 UINT8 Digit;\r
440 UINT8 Byte;\r
441\r
442 Digit = 0;\r
443\r
444 //\r
445 // Find out how many hex characters the string has.\r
446 //\r
447 HexBuf = HexStr;\r
448 if ((HexBuf[0] == '0') && ((HexBuf[1] == 'x') || (HexBuf[1] == 'X'))) {\r
449 HexBuf += 2;\r
450 }\r
451\r
452 for (Index = 0, HexCount = 0; IsHexDigit (&Digit, HexBuf[Index]); Index++, HexCount++)\r
453 ;\r
454\r
455 if (HexCount == 0) {\r
456 *BinLength = 0;\r
457 return EFI_SUCCESS;\r
458 }\r
459 //\r
460 // Test if buffer is passed enough.\r
461 //\r
462 if (((HexCount + 1) / 2) > *BinLength) {\r
463 *BinLength = (HexCount + 1) / 2;\r
464 return EFI_BUFFER_TOO_SMALL;\r
465 }\r
466\r
467 *BinLength = (HexCount + 1) / 2;\r
468\r
469 for (Index = 0; Index < HexCount; Index++) {\r
470\r
471 IsHexDigit (&Digit, HexBuf[HexCount - 1 - Index]);\r
472\r
473 if ((Index & 1) == 0) {\r
474 Byte = Digit;\r
475 } else {\r
476 Byte = BinBuffer[*BinLength - 1 - Index / 2];\r
477 Byte &= 0x0F;\r
478 Byte = (UINT8) (Byte | (Digit << 4));\r
479 }\r
480\r
481 BinBuffer[*BinLength - 1 - Index / 2] = Byte;\r
482 }\r
483\r
484 return EFI_SUCCESS;\r
485}\r
486\r
487/**\r
488 Generate random numbers.\r
489\r
490 @param[in, out] Rand The buffer to contain random numbers.\r
491 @param[in] RandLength The length of the Rand buffer.\r
492**/\r
493VOID\r
494IScsiGenRandom (\r
495 IN OUT UINT8 *Rand,\r
496 IN UINTN RandLength\r
497 )\r
498{\r
499 UINT32 Random;\r
500\r
501 while (RandLength > 0) {\r
502 Random = NET_RANDOM (NetRandomInitSeed ());\r
503 *Rand++ = (UINT8) (Random);\r
504 RandLength--;\r
505 }\r
506}\r
507\r
508/**\r
509 Create the iSCSI driver data..\r
510\r
511 @param[in] Image The handle of the driver image.\r
512 @param[in] Controller The handle of the controller.\r
513\r
514 @return The iSCSI driver data created.\r
515 @return NULL Some unexpected error happened.\r
516**/\r
517ISCSI_DRIVER_DATA *\r
518IScsiCreateDriverData (\r
519 IN EFI_HANDLE Image,\r
520 IN EFI_HANDLE Controller\r
521 )\r
522{\r
523 ISCSI_DRIVER_DATA *Private;\r
524 EFI_STATUS Status;\r
525\r
526 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
527 if (Private == NULL) {\r
528 return NULL;\r
529 }\r
530\r
531 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
532 Private->Image = Image;\r
533 Private->Controller = Controller;\r
534\r
535 //\r
536 // Create an event to be signal when the BS to RT transition is triggerd so\r
537 // as to abort the iSCSI session.\r
538 //\r
539 Status = gBS->CreateEvent (\r
540 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
541 TPL_CALLBACK,\r
542 IScsiOnExitBootService,\r
543 Private,\r
544 &Private->ExitBootServiceEvent\r
545 );\r
546 if (EFI_ERROR (Status)) {\r
547 gBS->FreePool (Private);\r
548 return NULL;\r
549 }\r
550\r
551 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
552\r
553 //\r
554 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
555 //\r
556 Private->ExtScsiPassThruMode.AdapterId = 2;\r
557 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
558 Private->ExtScsiPassThruMode.IoAlign = 4;\r
559 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
560\r
561 //\r
562 // Install the Ext SCSI PASS THRU protocol.\r
563 //\r
564 Status = gBS->InstallProtocolInterface (\r
565 &Private->ExtScsiPassThruHandle,\r
566 &gEfiExtScsiPassThruProtocolGuid,\r
567 EFI_NATIVE_INTERFACE,\r
568 &Private->IScsiExtScsiPassThru\r
569 );\r
570 if (EFI_ERROR (Status)) {\r
571 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
572 gBS->FreePool (Private);\r
573\r
574 return NULL;\r
575 }\r
576\r
577 IScsiSessionInit (&Private->Session, FALSE);\r
578\r
579 return Private;\r
580}\r
581\r
582/**\r
583 Clean the iSCSI driver data.\r
584\r
585 @param[in] Private The iSCSI driver data.\r
586**/\r
587VOID\r
588IScsiCleanDriverData (\r
589 IN ISCSI_DRIVER_DATA *Private\r
590 )\r
591{\r
592 if (Private->DevicePath != NULL) {\r
593 gBS->UninstallProtocolInterface (\r
594 Private->ExtScsiPassThruHandle,\r
595 &gEfiDevicePathProtocolGuid,\r
596 Private->DevicePath\r
597 );\r
598\r
599 gBS->FreePool (Private->DevicePath);\r
600 }\r
601\r
602 if (Private->ExtScsiPassThruHandle != NULL) {\r
603 gBS->UninstallProtocolInterface (\r
604 Private->ExtScsiPassThruHandle,\r
605 &gEfiExtScsiPassThruProtocolGuid,\r
606 &Private->IScsiExtScsiPassThru\r
607 );\r
608 }\r
609\r
610 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
611\r
612 gBS->FreePool (Private);\r
613}\r
614\r
615/**\r
616 Get the various configuration data of this iSCSI instance.\r
617\r
618 @param[in] Private The iSCSI driver data.\r
619\r
620 @retval EFI_SUCCESS The configuration of this instance is got.\r
621 @retval EFI_ABORTED The operation was aborted.\r
622 @retval Others Some unexpected error happened.\r
623**/\r
624EFI_STATUS\r
625IScsiGetConfigData (\r
626 IN ISCSI_DRIVER_DATA *Private\r
627 )\r
628{\r
629 EFI_STATUS Status;\r
630 ISCSI_SESSION *Session;\r
631 UINTN BufferSize;\r
632 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
633 EFI_SIMPLE_NETWORK_MODE *Mode;\r
634 CHAR16 MacString[65];\r
635\r
636 //\r
637 // get the iSCSI Initiator Name\r
638 //\r
639 Session = &Private->Session;\r
640 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
641 Status = gIScsiInitiatorName.Get (\r
642 &gIScsiInitiatorName,\r
643 &Session->InitiatorNameLength,\r
644 Session->InitiatorName\r
645 );\r
646 if (EFI_ERROR (Status)) {\r
647 return Status;\r
648 }\r
649\r
650 Status = gBS->HandleProtocol (\r
651 Private->Controller,\r
652 &gEfiSimpleNetworkProtocolGuid,\r
653 (VOID **)&Snp\r
654 );\r
655 if (EFI_ERROR (Status)) {\r
656 return Status;\r
657 }\r
658\r
659 Mode = Snp->Mode;\r
660\r
661 //\r
662 // Get the mac string, it's the name of various variable\r
663 //\r
664 IScsiMacAddrToStr (&Mode->PermanentAddress, Mode->HwAddressSize, MacString);\r
665\r
666 //\r
667 // Get the normal configuration.\r
668 //\r
669 BufferSize = sizeof (Session->ConfigData.NvData);\r
670 Status = gRT->GetVariable (\r
671 MacString,\r
672 &gEfiIScsiInitiatorNameProtocolGuid,\r
673 NULL,\r
674 &BufferSize,\r
675 &Session->ConfigData.NvData\r
676 );\r
677 if (EFI_ERROR (Status)) {\r
678 return Status;\r
679 }\r
680\r
681 if (!Session->ConfigData.NvData.Enabled) {\r
682 return EFI_ABORTED;\r
683 }\r
684 //\r
685 // Get the CHAP Auth information.\r
686 //\r
687 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
688 Status = gRT->GetVariable (\r
689 MacString,\r
690 &mIScsiCHAPAuthInfoGuid,\r
691 NULL,\r
692 &BufferSize,\r
693 &Session->AuthData.AuthConfig\r
694 );\r
695\r
696 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
697 //\r
698 // Start dhcp.\r
699 //\r
700 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
701 }\r
702\r
703 return Status;\r
704}\r
705\r
706/**\r
707 Get the device path of the iSCSI tcp connection and update it.\r
708\r
709 @param[in] Private The iSCSI driver data.\r
710\r
711 @return The updated device path.\r
712 @return NULL Some unexpected error happened.\r
713**/\r
714EFI_DEVICE_PATH_PROTOCOL *\r
715IScsiGetTcpConnDevicePath (\r
716 IN ISCSI_DRIVER_DATA *Private\r
717 )\r
718{\r
719 ISCSI_SESSION *Session;\r
720 ISCSI_CONNECTION *Conn;\r
721 TCP4_IO *Tcp4Io;\r
722 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
723 EFI_STATUS Status;\r
724 EFI_DEV_PATH *DPathNode;\r
725\r
726 Session = &Private->Session;\r
727 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
728 return NULL;\r
729 }\r
730\r
731 Conn = NET_LIST_USER_STRUCT_S (\r
732 Session->Conns.ForwardLink,\r
733 ISCSI_CONNECTION,\r
734 Link,\r
735 ISCSI_CONNECTION_SIGNATURE\r
736 );\r
737 Tcp4Io = &Conn->Tcp4Io;\r
738\r
739 Status = gBS->HandleProtocol (\r
740 Tcp4Io->Handle,\r
741 &gEfiDevicePathProtocolGuid,\r
742 (VOID **)&DevicePath\r
743 );\r
744 if (EFI_ERROR (Status)) {\r
745 return NULL;\r
746 }\r
747 //\r
748 // Duplicate it.\r
749 //\r
750 DevicePath = DuplicateDevicePath (DevicePath);\r
751\r
752 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
753\r
754 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
755 if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&\r
756 (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)\r
757 ) {\r
758\r
759 DPathNode->Ipv4.LocalPort = 0;\r
760 DPathNode->Ipv4.StaticIpAddress = (BOOLEAN) (!Session->ConfigData.NvData.InitiatorInfoFromDhcp);\r
761 break;\r
762 }\r
763\r
764 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
765 }\r
766\r
767 return DevicePath;\r
768}\r
769\r
770/**\r
771 Abort the session when the transition from BS to RT is initiated.\r
772\r
773 @param[in] Event The event signaled.\r
774 @param[in] Context The iSCSI driver data.\r
775**/\r
776VOID\r
777EFIAPI\r
778IScsiOnExitBootService (\r
779 IN EFI_EVENT Event,\r
780 IN VOID *Context\r
781 )\r
782{\r
783 ISCSI_DRIVER_DATA *Private;\r
784\r
785 Private = (ISCSI_DRIVER_DATA *) Context;\r
786 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
787\r
788 IScsiSessionAbort (&Private->Session);\r
789}\r