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