]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
Move Crc32GuidedSectionExtraction from Protocol to Guid directory
[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 @retval 0 Other errors as indicated.\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 != 0) {\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.\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 @retval NULL Other errors as indicated.\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->CreateEventEx (\r
540 EVT_NOTIFY_SIGNAL,\r
541 TPL_CALLBACK,\r
542 IScsiOnExitBootService,\r
543 Private,\r
544 &gEfiEventExitBootServicesGuid,\r
545 &Private->ExitBootServiceEvent\r
546 );\r
547 if (EFI_ERROR (Status)) {\r
548 gBS->FreePool (Private);\r
549 return NULL;\r
550 }\r
551\r
552 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
553\r
554 //\r
555 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
556 //\r
557 Private->ExtScsiPassThruMode.AdapterId = 2;\r
558 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
559 Private->ExtScsiPassThruMode.IoAlign = 4;\r
560 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
561\r
562 //\r
563 // Install the Ext SCSI PASS THRU protocol.\r
564 //\r
565 Status = gBS->InstallProtocolInterface (\r
566 &Private->ExtScsiPassThruHandle,\r
567 &gEfiExtScsiPassThruProtocolGuid,\r
568 EFI_NATIVE_INTERFACE,\r
569 &Private->IScsiExtScsiPassThru\r
570 );\r
571 if (EFI_ERROR (Status)) {\r
572 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
573 gBS->FreePool (Private);\r
574\r
575 return NULL;\r
576 }\r
577\r
578 IScsiSessionInit (&Private->Session, FALSE);\r
579\r
580 return Private;\r
581}\r
582\r
583/**\r
584 Clean the iSCSI driver data.\r
585\r
586 @param[in] Private The iSCSI driver data.\r
587**/\r
588VOID\r
589IScsiCleanDriverData (\r
590 IN ISCSI_DRIVER_DATA *Private\r
591 )\r
592{\r
593 if (Private->DevicePath != NULL) {\r
594 gBS->UninstallProtocolInterface (\r
595 Private->ExtScsiPassThruHandle,\r
596 &gEfiDevicePathProtocolGuid,\r
597 Private->DevicePath\r
598 );\r
599\r
600 gBS->FreePool (Private->DevicePath);\r
601 }\r
602\r
603 if (Private->ExtScsiPassThruHandle != NULL) {\r
604 gBS->UninstallProtocolInterface (\r
605 Private->ExtScsiPassThruHandle,\r
606 &gEfiExtScsiPassThruProtocolGuid,\r
607 &Private->IScsiExtScsiPassThru\r
608 );\r
609 }\r
610\r
611 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
612\r
613 gBS->FreePool (Private);\r
614}\r
615\r
616/**\r
617 Get the various configuration data of this iSCSI instance.\r
618\r
619 @param[in] Private The iSCSI driver data.\r
620\r
621 @retval EFI_SUCCESS The configuration of this instance is got.\r
622 @retval EFI_ABORTED The operation was aborted.\r
623 @retval Others Other errors as indicated.\r
624**/\r
625EFI_STATUS\r
626IScsiGetConfigData (\r
627 IN ISCSI_DRIVER_DATA *Private\r
628 )\r
629{\r
630 EFI_STATUS Status;\r
631 ISCSI_SESSION *Session;\r
632 UINTN BufferSize;\r
633 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
634 EFI_SIMPLE_NETWORK_MODE *Mode;\r
635 CHAR16 MacString[65];\r
636\r
637 //\r
638 // get the iSCSI Initiator Name\r
639 //\r
640 Session = &Private->Session;\r
641 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
642 Status = gIScsiInitiatorName.Get (\r
643 &gIScsiInitiatorName,\r
644 &Session->InitiatorNameLength,\r
645 Session->InitiatorName\r
646 );\r
647 if (EFI_ERROR (Status)) {\r
648 return Status;\r
649 }\r
650\r
651 Status = gBS->HandleProtocol (\r
652 Private->Controller,\r
653 &gEfiSimpleNetworkProtocolGuid,\r
654 (VOID **)&Snp\r
655 );\r
656 if (EFI_ERROR (Status)) {\r
657 return Status;\r
658 }\r
659\r
660 Mode = Snp->Mode;\r
661\r
662 //\r
663 // Get the mac string, it's the name of various variable\r
664 //\r
665 IScsiMacAddrToStr (&Mode->PermanentAddress, Mode->HwAddressSize, MacString);\r
666\r
667 //\r
668 // Get the normal configuration.\r
669 //\r
670 BufferSize = sizeof (Session->ConfigData.NvData);\r
671 Status = gRT->GetVariable (\r
672 MacString,\r
673 &gEfiIScsiInitiatorNameProtocolGuid,\r
674 NULL,\r
675 &BufferSize,\r
676 &Session->ConfigData.NvData\r
677 );\r
678 if (EFI_ERROR (Status)) {\r
679 return Status;\r
680 }\r
681\r
682 if (!Session->ConfigData.NvData.Enabled) {\r
683 return EFI_ABORTED;\r
684 }\r
685 //\r
686 // Get the CHAP Auth information.\r
687 //\r
688 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
689 Status = gRT->GetVariable (\r
690 MacString,\r
691 &mIScsiCHAPAuthInfoGuid,\r
692 NULL,\r
693 &BufferSize,\r
694 &Session->AuthData.AuthConfig\r
695 );\r
696\r
697 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
698 //\r
699 // Start dhcp.\r
700 //\r
701 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
702 }\r
703\r
704 return Status;\r
705}\r
706\r
707/**\r
708 Get the device path of the iSCSI tcp connection and update it.\r
709\r
710 @param[in] Private The iSCSI driver data.\r
711\r
712 @return The updated device path.\r
713 @retval NULL Other errors as indicated.\r
714**/\r
715EFI_DEVICE_PATH_PROTOCOL *\r
716IScsiGetTcpConnDevicePath (\r
717 IN ISCSI_DRIVER_DATA *Private\r
718 )\r
719{\r
720 ISCSI_SESSION *Session;\r
721 ISCSI_CONNECTION *Conn;\r
722 TCP4_IO *Tcp4Io;\r
723 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
724 EFI_STATUS Status;\r
725 EFI_DEV_PATH *DPathNode;\r
726\r
727 Session = &Private->Session;\r
728 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
729 return NULL;\r
730 }\r
731\r
732 Conn = NET_LIST_USER_STRUCT_S (\r
733 Session->Conns.ForwardLink,\r
734 ISCSI_CONNECTION,\r
735 Link,\r
736 ISCSI_CONNECTION_SIGNATURE\r
737 );\r
738 Tcp4Io = &Conn->Tcp4Io;\r
739\r
740 Status = gBS->HandleProtocol (\r
741 Tcp4Io->Handle,\r
742 &gEfiDevicePathProtocolGuid,\r
743 (VOID **)&DevicePath\r
744 );\r
745 if (EFI_ERROR (Status)) {\r
746 return NULL;\r
747 }\r
748 //\r
749 // Duplicate it.\r
750 //\r
751 DevicePath = DuplicateDevicePath (DevicePath);\r
752\r
753 DPathNode = (EFI_DEV_PATH *) DevicePath;\r
754\r
755 while (!IsDevicePathEnd (&DPathNode->DevPath)) {\r
756 if ((DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) &&\r
757 (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)\r
758 ) {\r
759\r
760 DPathNode->Ipv4.LocalPort = 0;\r
761 DPathNode->Ipv4.StaticIpAddress = (BOOLEAN) (!Session->ConfigData.NvData.InitiatorInfoFromDhcp);\r
762 break;\r
763 }\r
764\r
765 DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);\r
766 }\r
767\r
768 return DevicePath;\r
769}\r
770\r
771/**\r
772 Abort the session when the transition from BS to RT is initiated.\r
773\r
774 @param[in] Event The event signaled.\r
775 @param[in] Context The iSCSI driver data.\r
776**/\r
777VOID\r
778EFIAPI\r
779IScsiOnExitBootService (\r
780 IN EFI_EVENT Event,\r
781 IN VOID *Context\r
782 )\r
783{\r
784 ISCSI_DRIVER_DATA *Private;\r
785\r
786 Private = (ISCSI_DRIVER_DATA *) Context;\r
787 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
788\r
789 IScsiSessionAbort (&Private->Session);\r
790}\r