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