]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
Clean up the private GUID definition in module Level.
[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 - 2011, Intel Corporation. All rights reserved.<BR>\r
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. 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 & (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 UINTN Index, IndexValue, IndexNum, SizeStr;\r
127 CHAR8 TemStr[2];\r
128 UINT8 TemValue;\r
129 UINT16 Value[4];\r
130 \r
131 ZeroMem (Lun, 8);\r
132 ZeroMem (TemStr, 2);\r
133 ZeroMem ((UINT8 *) Value, sizeof (Value));\r
134 SizeStr = AsciiStrLen (Str); \r
135 IndexValue = 0;\r
136 IndexNum = 0;\r
137\r
138 for (Index = 0; Index < SizeStr; Index ++) {\r
139 TemStr[0] = Str[Index];\r
140 TemValue = (UINT8) AsciiStrHexToUint64 (TemStr);\r
141 if (TemValue == 0 && TemStr[0] != '0') {\r
142 if ((TemStr[0] != '-') || (IndexNum == 0)) {\r
143 //\r
144 // Invalid Lun Char\r
145 //\r
146 return EFI_INVALID_PARAMETER;\r
147 }\r
148 }\r
149 \r
150 if ((TemValue == 0) && (TemStr[0] == '-')) {\r
151 //\r
152 // Next Lun value\r
153 //\r
154 if (++IndexValue >= 4) {\r
155 //\r
156 // Max 4 Lun value\r
157 //\r
158 return EFI_INVALID_PARAMETER;\r
159 }\r
160 //\r
161 // Restart str index for the next lun value\r
162 //\r
163 IndexNum = 0;\r
164 continue;\r
165 }\r
166 \r
167 if (++IndexNum > 4) {\r
168 // \r
169 // Each Lun Str can't exceed size 4, because it will be as UINT16 value\r
170 //\r
171 return EFI_INVALID_PARAMETER;\r
172 }\r
173 \r
174 //\r
175 // Combine UINT16 value\r
176 //\r
177 Value[IndexValue] = (UINT16) ((Value[IndexValue] << 4) + TemValue);\r
178 }\r
179 \r
180 for (Index = 0; Index <= IndexValue; Index ++) {\r
181 *((UINT16 *) &Lun[Index * 2]) = HTONS (Value[Index]);\r
182 }\r
183 \r
184 return EFI_SUCCESS;\r
185}\r
186\r
187/**\r
188 Convert the 64-bit LUN into the hexadecimal encoded LUN string.\r
189\r
190 @param[in] Lun The 64-bit LUN.\r
191 @param[out] Str The storage to return the hexadecimal encoded LUN string.\r
192**/\r
193VOID\r
194IScsiLunToUnicodeStr (\r
195 IN UINT8 *Lun,\r
196 OUT CHAR16 *Str\r
197 )\r
198{\r
199 UINTN Index;\r
200 CHAR16 *TempStr;\r
201\r
202 TempStr = Str;\r
203\r
204 for (Index = 0; Index < 4; Index++) {\r
205\r
206 if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {\r
207 StrCpy (TempStr, L"0-");\r
208 } else {\r
209 TempStr[0] = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];\r
210 TempStr[1] = (CHAR16) IScsiHexString[Lun[2 * Index] & 0x0F];\r
211 TempStr[2] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];\r
212 TempStr[3] = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0x0F];\r
213 TempStr[4] = L'-';\r
214 TempStr[5] = 0;\r
215\r
216 StrTrim (TempStr, L'0');\r
217 }\r
218\r
219 TempStr += StrLen (TempStr);\r
220 }\r
221\r
222 Str[StrLen (Str) - 1] = 0;\r
223\r
224 for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {\r
225 if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {\r
226 Str[Index - 1] = 0;\r
227 } else {\r
228 break;\r
229 }\r
230 }\r
231}\r
232\r
233/**\r
234 Convert the ASCII string into a UNICODE string.\r
235\r
236 @param[in] Source The ASCII string.\r
237 @param[out] Destination The storage to return the UNICODE string.\r
238\r
239 @return CHAR16 * Pointer to the UNICODE string.\r
240**/\r
241CHAR16 *\r
242IScsiAsciiStrToUnicodeStr (\r
243 IN CHAR8 *Source,\r
244 OUT CHAR16 *Destination\r
245 )\r
246{\r
247 ASSERT (Destination != NULL);\r
248 ASSERT (Source != NULL);\r
249\r
250 while (*Source != '\0') {\r
251 *(Destination++) = (CHAR16) *(Source++);\r
252 }\r
253\r
254 *Destination = '\0';\r
255\r
256 return Destination;\r
257}\r
258\r
259/**\r
260 Convert the UNICODE string into an ASCII string.\r
261\r
262 @param[in] Source The UNICODE string.\r
263 @param[out] Destination The storage to return the ASCII string.\r
264\r
265 @return CHAR8 * Pointer to the ASCII string.\r
266**/\r
267CHAR8 *\r
268IScsiUnicodeStrToAsciiStr (\r
269 IN CHAR16 *Source,\r
270 OUT CHAR8 *Destination\r
271 )\r
272{\r
273 ASSERT (Destination != NULL);\r
274 ASSERT (Source != NULL);\r
275\r
276 while (*Source != '\0') {\r
277 //\r
278 // If any Unicode characters in Source contain\r
279 // non-zero value in the upper 8 bits, then ASSERT().\r
280 //\r
281 ASSERT (*Source < 0x100);\r
282 *(Destination++) = (CHAR8) *(Source++);\r
283 }\r
284\r
285 *Destination = '\0';\r
286\r
287 return Destination;\r
288}\r
289\r
290/**\r
291 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
292\r
293 @param[in] Str The UNICODE string.\r
294 @param[out] Ip The storage to return the ASCII string.\r
295\r
296 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
297 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
298**/\r
299EFI_STATUS\r
300IScsiAsciiStrToIp (\r
301 IN CHAR8 *Str,\r
302 OUT EFI_IPv4_ADDRESS *Ip\r
303 )\r
304{\r
305 UINTN Index;\r
306 UINTN Number;\r
307\r
308 Index = 0;\r
309\r
310 while (*Str != 0) {\r
311\r
312 if (Index > 3) {\r
313 return EFI_INVALID_PARAMETER;\r
314 }\r
315\r
316 Number = 0;\r
317 while (NET_IS_DIGIT (*Str)) {\r
318 Number = Number * 10 + (*Str - '0');\r
319 Str++;\r
320 }\r
321\r
322 if (Number > 0xFF) {\r
323 return EFI_INVALID_PARAMETER;\r
324 }\r
325\r
326 Ip->Addr[Index] = (UINT8) Number;\r
327\r
328 if ((*Str != '\0') && (*Str != '.')) {\r
329 //\r
330 // The current character should be either the NULL terminator or\r
331 // the dot delimiter.\r
332 //\r
333 return EFI_INVALID_PARAMETER;\r
334 }\r
335\r
336 if (*Str == '.') {\r
337 //\r
338 // Skip the delimiter.\r
339 //\r
340 Str++;\r
341 }\r
342\r
343 Index++;\r
344 }\r
345\r
346 if (Index != 4) {\r
347 return EFI_INVALID_PARAMETER;\r
348 }\r
349\r
350 return EFI_SUCCESS;\r
351}\r
352\r
353/**\r
354 Convert the mac address into a hexadecimal encoded "-" seperated string.\r
355\r
356 @param[in] Mac The mac address.\r
357 @param[in] Len Length in bytes of the mac address.\r
358 @param[in] VlanId VLAN ID of the network device.\r
359 @param[out] Str The storage to return the mac string.\r
360**/\r
361VOID\r
362IScsiMacAddrToStr (\r
363 IN EFI_MAC_ADDRESS *Mac,\r
364 IN UINT32 Len,\r
365 IN UINT16 VlanId,\r
366 OUT CHAR16 *Str\r
367 )\r
368{\r
369 UINT32 Index;\r
370 CHAR16 *String;\r
371\r
372 for (Index = 0; Index < Len; Index++) {\r
373 Str[3 * Index] = (CHAR16) IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];\r
374 Str[3 * Index + 1] = (CHAR16) IScsiHexString[Mac->Addr[Index] & 0x0F];\r
375 Str[3 * Index + 2] = L'-';\r
376 }\r
377\r
378 String = &Str[3 * Index - 1] ;\r
379 if (VlanId != 0) {\r
380 String += UnicodeSPrint (String, 6 * sizeof (CHAR16), L"\\%04x", (UINTN) VlanId);\r
381 }\r
382\r
383 *String = L'\0';\r
384}\r
385\r
386/**\r
387 Convert the binary encoded buffer into a hexadecimal encoded string.\r
388\r
389 @param[in] BinBuffer The buffer containing the binary data.\r
390 @param[in] BinLength Length of the binary buffer.\r
391 @param[in, out] HexStr Pointer to the string.\r
392 @param[in, out] HexLength The length of the string.\r
393\r
394 @retval EFI_SUCCESS The binary data is converted to the hexadecimal string \r
395 and the length of the string is updated.\r
396 @retval EFI_BUFFER_TOO_SMALL The string is too small.\r
397 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
398**/\r
399EFI_STATUS\r
400IScsiBinToHex (\r
401 IN UINT8 *BinBuffer,\r
402 IN UINT32 BinLength,\r
403 IN OUT CHAR8 *HexStr,\r
404 IN OUT UINT32 *HexLength\r
405 )\r
406{\r
407 UINTN Index;\r
408\r
409 if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {\r
410 return EFI_INVALID_PARAMETER;\r
411 }\r
412\r
413 if (((*HexLength) - 3) < BinLength * 2) {\r
414 *HexLength = BinLength * 2 + 3;\r
415 return EFI_BUFFER_TOO_SMALL;\r
416 }\r
417\r
418 *HexLength = BinLength * 2 + 3;\r
419 //\r
420 // Prefix for Hex String\r
421 //\r
422 HexStr[0] = '0';\r
423 HexStr[1] = 'x';\r
424\r
425 for (Index = 0; Index < BinLength; Index++) {\r
426 HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];\r
427 HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0x0F];\r
428 }\r
429\r
430 HexStr[Index * 2 + 2] = '\0';\r
431\r
432 return EFI_SUCCESS;\r
433}\r
434\r
435/**\r
436 Convert the hexadecimal string into a binary encoded buffer.\r
437\r
438 @param[in, out] BinBuffer The binary buffer.\r
439 @param[in, out] BinLength Length of the binary buffer.\r
440 @param[in] HexStr The hexadecimal string.\r
441\r
442 @retval EFI_SUCCESS The hexadecimal string is converted into a binary\r
443 encoded buffer.\r
444 @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.\r
445**/\r
446EFI_STATUS\r
447IScsiHexToBin (\r
448 IN OUT UINT8 *BinBuffer,\r
449 IN OUT UINT32 *BinLength,\r
450 IN CHAR8 *HexStr\r
451 )\r
452{\r
453 UINTN Index;\r
454 UINTN Length;\r
455 UINT8 Digit;\r
456 CHAR8 TemStr[2];\r
457 \r
458 ZeroMem (TemStr, sizeof (TemStr));\r
459\r
460 //\r
461 // Find out how many hex characters the string has.\r
462 //\r
463 if ((HexStr[0] == '0') && ((HexStr[1] == 'x') || (HexStr[1] == 'X'))) {\r
464 HexStr += 2;\r
465 }\r
466 \r
467 Length = AsciiStrLen (HexStr);\r
468\r
469 for (Index = 0; Index < Length; Index ++) {\r
470 TemStr[0] = HexStr[Index];\r
471 Digit = (UINT8) AsciiStrHexToUint64 (TemStr);\r
472 if (Digit == 0 && TemStr[0] != '0') {\r
473 //\r
474 // Invalid Lun Char\r
475 //\r
476 break;\r
477 }\r
478 if ((Index & 1) == 0) {\r
479 BinBuffer [Index/2] = Digit;\r
480 } else {\r
481 BinBuffer [Index/2] = (UINT8) ((BinBuffer [Index/2] << 4) + Digit);\r
482 }\r
483 }\r
484 \r
485 *BinLength = (UINT32) ((Index + 1)/2);\r
486\r
487 return EFI_SUCCESS;\r
488}\r
489\r
490/**\r
491 Generate random numbers.\r
492\r
493 @param[in, out] Rand The buffer to contain random numbers.\r
494 @param[in] RandLength The length of the Rand buffer.\r
495**/\r
496VOID\r
497IScsiGenRandom (\r
498 IN OUT UINT8 *Rand,\r
499 IN UINTN RandLength\r
500 )\r
501{\r
502 UINT32 Random;\r
503\r
504 while (RandLength > 0) {\r
505 Random = NET_RANDOM (NetRandomInitSeed ());\r
506 *Rand++ = (UINT8) (Random);\r
507 RandLength--;\r
508 }\r
509}\r
510\r
511/**\r
512 Create the iSCSI driver data..\r
513\r
514 @param[in] Image The handle of the driver image.\r
515 @param[in] Controller The handle of the controller.\r
516\r
517 @return The iSCSI driver data created.\r
518 @retval NULL Other errors as indicated.\r
519**/\r
520ISCSI_DRIVER_DATA *\r
521IScsiCreateDriverData (\r
522 IN EFI_HANDLE Image,\r
523 IN EFI_HANDLE Controller\r
524 )\r
525{\r
526 ISCSI_DRIVER_DATA *Private;\r
527 EFI_STATUS Status;\r
528\r
529 Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));\r
530 if (Private == NULL) {\r
531 return NULL;\r
532 }\r
533\r
534 Private->Signature = ISCSI_DRIVER_DATA_SIGNATURE;\r
535 Private->Image = Image;\r
536 Private->Controller = Controller;\r
537\r
538 //\r
539 // Create an event to be signal when the BS to RT transition is triggerd so\r
540 // as to abort the iSCSI session.\r
541 //\r
542 Status = gBS->CreateEventEx (\r
543 EVT_NOTIFY_SIGNAL,\r
544 TPL_CALLBACK,\r
545 IScsiOnExitBootService,\r
546 Private,\r
547 &gEfiEventExitBootServicesGuid,\r
548 &Private->ExitBootServiceEvent\r
549 );\r
550 if (EFI_ERROR (Status)) {\r
551 FreePool (Private);\r
552 return NULL;\r
553 }\r
554\r
555 CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));\r
556\r
557 //\r
558 // 0 is designated to the TargetId, so use another value for the AdapterId.\r
559 //\r
560 Private->ExtScsiPassThruMode.AdapterId = 2;\r
561 Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;\r
562 Private->ExtScsiPassThruMode.IoAlign = 4;\r
563 Private->IScsiExtScsiPassThru.Mode = &Private->ExtScsiPassThruMode;\r
564\r
565 //\r
566 // Install the Ext SCSI PASS THRU protocol.\r
567 //\r
568 Status = gBS->InstallProtocolInterface (\r
569 &Private->ExtScsiPassThruHandle,\r
570 &gEfiExtScsiPassThruProtocolGuid,\r
571 EFI_NATIVE_INTERFACE,\r
572 &Private->IScsiExtScsiPassThru\r
573 );\r
574 if (EFI_ERROR (Status)) {\r
575 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
576 FreePool (Private);\r
577\r
578 return NULL;\r
579 }\r
580\r
581 IScsiSessionInit (&Private->Session, FALSE);\r
582\r
583 return Private;\r
584}\r
585\r
586/**\r
587 Clean the iSCSI driver data.\r
588\r
589 @param[in] Private The iSCSI driver data.\r
590**/\r
591VOID\r
592IScsiCleanDriverData (\r
593 IN ISCSI_DRIVER_DATA *Private\r
594 )\r
595{\r
596 if (Private->DevicePath != NULL) {\r
597 gBS->UninstallProtocolInterface (\r
598 Private->ExtScsiPassThruHandle,\r
599 &gEfiDevicePathProtocolGuid,\r
600 Private->DevicePath\r
601 );\r
602\r
603 FreePool (Private->DevicePath);\r
604 }\r
605\r
606 if (Private->ExtScsiPassThruHandle != NULL) {\r
607 gBS->UninstallProtocolInterface (\r
608 Private->ExtScsiPassThruHandle,\r
609 &gEfiExtScsiPassThruProtocolGuid,\r
610 &Private->IScsiExtScsiPassThru\r
611 );\r
612 }\r
613\r
614 gBS->CloseEvent (Private->ExitBootServiceEvent);\r
615\r
616 FreePool (Private);\r
617}\r
618\r
619/**\r
620 Get the various configuration data of this iSCSI instance.\r
621\r
622 @param[in] Private The iSCSI driver data.\r
623\r
624 @retval EFI_SUCCESS The configuration of this instance is got.\r
625 @retval EFI_ABORTED The operation was aborted.\r
626 @retval Others Other errors as indicated.\r
627**/\r
628EFI_STATUS\r
629IScsiGetConfigData (\r
630 IN ISCSI_DRIVER_DATA *Private\r
631 )\r
632{\r
633 EFI_STATUS Status;\r
634 ISCSI_SESSION *Session;\r
635 UINTN BufferSize;\r
636 EFI_MAC_ADDRESS MacAddress;\r
637 UINTN HwAddressSize;\r
638 UINT16 VlanId;\r
639 CHAR16 MacString[70];\r
640\r
641 //\r
642 // get the iSCSI Initiator Name\r
643 //\r
644 Session = &Private->Session;\r
645 Session->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;\r
646 Status = gIScsiInitiatorName.Get (\r
647 &gIScsiInitiatorName,\r
648 &Session->InitiatorNameLength,\r
649 Session->InitiatorName\r
650 );\r
651 if (EFI_ERROR (Status)) {\r
652 return Status;\r
653 }\r
654\r
655 //\r
656 // Get the mac string, it's the name of various variable\r
657 //\r
658 Status = NetLibGetMacAddress (Private->Controller, &MacAddress, &HwAddressSize);\r
659 ASSERT (Status == EFI_SUCCESS);\r
660 VlanId = NetLibGetVlanId (Private->Controller);\r
661 IScsiMacAddrToStr (&MacAddress, (UINT32) HwAddressSize, VlanId, MacString);\r
662\r
663 //\r
664 // Get the normal configuration.\r
665 //\r
666 BufferSize = sizeof (Session->ConfigData.NvData);\r
667 Status = gRT->GetVariable (\r
668 MacString,\r
669 &gEfiIScsiInitiatorNameProtocolGuid,\r
670 NULL,\r
671 &BufferSize,\r
672 &Session->ConfigData.NvData\r
673 );\r
674 if (EFI_ERROR (Status)) {\r
675 return Status;\r
676 }\r
677\r
678 if (!Session->ConfigData.NvData.Enabled) {\r
679 return EFI_ABORTED;\r
680 }\r
681 //\r
682 // Get the CHAP Auth information.\r
683 //\r
684 BufferSize = sizeof (Session->AuthData.AuthConfig);\r
685 Status = gRT->GetVariable (\r
686 MacString,\r
687 &gIScsiCHAPAuthInfoGuid,\r
688 NULL,\r
689 &BufferSize,\r
690 &Session->AuthData.AuthConfig\r
691 );\r
692\r
693 if (!EFI_ERROR (Status) && Session->ConfigData.NvData.InitiatorInfoFromDhcp) {\r
694 //\r
695 // Start dhcp.\r
696 //\r
697 Status = IScsiDoDhcp (Private->Image, Private->Controller, &Session->ConfigData);\r
698 }\r
699\r
700 return Status;\r
701}\r
702\r
703/**\r
704 Get the device path of the iSCSI tcp connection and update it.\r
705\r
706 @param[in] Private The iSCSI driver data.\r
707\r
708 @return The updated device path.\r
709 @retval NULL Other errors as indicated.\r
710**/\r
711EFI_DEVICE_PATH_PROTOCOL *\r
712IScsiGetTcpConnDevicePath (\r
713 IN ISCSI_DRIVER_DATA *Private\r
714 )\r
715{\r
716 ISCSI_SESSION *Session;\r
717 ISCSI_CONNECTION *Conn;\r
718 TCP4_IO *Tcp4Io;\r
719 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
720 EFI_STATUS Status;\r
721 EFI_DEV_PATH *DPathNode;\r
722\r
723 Session = &Private->Session;\r
724 if (Session->State != SESSION_STATE_LOGGED_IN) {\r
725 return NULL;\r
726 }\r
727\r
728 Conn = NET_LIST_USER_STRUCT_S (\r
729 Session->Conns.ForwardLink,\r
730 ISCSI_CONNECTION,\r
731 Link,\r
732 ISCSI_CONNECTION_SIGNATURE\r
733 );\r
734 Tcp4Io = &Conn->Tcp4Io;\r
735\r
736 Status = gBS->HandleProtocol (\r
737 Tcp4Io->Handle,\r
738 &gEfiDevicePathProtocolGuid,\r
739 (VOID **)&DevicePath\r
740 );\r
741 if (EFI_ERROR (Status)) {\r
742 return NULL;\r
743 }\r
744 //\r
745 // Duplicate it.\r
746 //\r
747 DevicePath = DuplicateDevicePath (DevicePath);\r
748 if (DevicePath == NULL) {\r
749 return NULL;\r
750 }\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