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