TianoCore EDK2 master
Loading...
Searching...
No Matches
IScsiDriver.c
Go to the documentation of this file.
1
12#include "IScsiImpl.h"
13
14EFI_DRIVER_BINDING_PROTOCOL gIScsiIp4DriverBinding = {
18 0xa,
19 NULL,
20 NULL
21};
22
23EFI_DRIVER_BINDING_PROTOCOL gIScsiIp6DriverBinding = {
27 0xa,
28 NULL,
29 NULL
30};
31
32EFI_GUID gIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;
33EFI_GUID gIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;
34ISCSI_PRIVATE_DATA *mPrivate = NULL;
35
53 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
54 )
55{
56 EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
57
58 CurrentDevicePath = RemainingDevicePath;
59 if (CurrentDevicePath != NULL) {
60 while (!IsDevicePathEnd (CurrentDevicePath)) {
61 if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
62 return EFI_SUCCESS;
63 }
64
65 CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
66 }
67
68 return EFI_UNSUPPORTED;
69 }
70
71 return EFI_SUCCESS;
72}
73
85 VOID
86 )
87{
88 UINTN AipHandleCount;
89 EFI_HANDLE *AipHandleBuffer;
90 UINTN AipIndex;
92 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiPassThru;
93 EFI_GUID *InfoTypesBuffer;
94 UINTN InfoTypeBufferCount;
95 UINTN TypeIndex;
96 VOID *InfoBlock;
97 UINTN InfoBlockSize;
98 BOOLEAN Supported;
100 EFI_STATUS Status;
101 UINT8 NetworkBootPolicy;
102
103 //
104 // Check any AIP instances exist in system.
105 //
106 AipHandleCount = 0;
107 AipHandleBuffer = NULL;
108 Status = gBS->LocateHandleBuffer (
110 &gEfiAdapterInformationProtocolGuid,
111 NULL,
112 &AipHandleCount,
113 &AipHandleBuffer
114 );
115 if (EFI_ERROR (Status) || (AipHandleCount == 0)) {
116 return EFI_NOT_FOUND;
117 }
118
119 ASSERT (AipHandleBuffer != NULL);
120
121 InfoBlock = NULL;
122
123 for (AipIndex = 0; AipIndex < AipHandleCount; AipIndex++) {
124 Status = gBS->HandleProtocol (
125 AipHandleBuffer[AipIndex],
126 &gEfiAdapterInformationProtocolGuid,
127 (VOID *)&Aip
128 );
129 ASSERT_EFI_ERROR (Status);
130 ASSERT (Aip != NULL);
131
132 Status = gBS->HandleProtocol (
133 AipHandleBuffer[AipIndex],
134 &gEfiExtScsiPassThruProtocolGuid,
135 (VOID *)&ExtScsiPassThru
136 );
137 if (EFI_ERROR (Status) || (ExtScsiPassThru == NULL)) {
138 continue;
139 }
140
141 InfoTypesBuffer = NULL;
142 InfoTypeBufferCount = 0;
143 Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
144 if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {
145 continue;
146 }
147
148 //
149 // Check whether the AIP instance has Network boot information block.
150 //
151 Supported = FALSE;
152 for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
153 if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoNetworkBootGuid)) {
154 Supported = TRUE;
155 break;
156 }
157 }
158
159 FreePool (InfoTypesBuffer);
160 if (!Supported) {
161 continue;
162 }
163
164 //
165 // We now have network boot information block.
166 //
167 InfoBlock = NULL;
168 InfoBlockSize = 0;
169 Status = Aip->GetInformation (Aip, &gEfiAdapterInfoNetworkBootGuid, &InfoBlock, &InfoBlockSize);
170 if (EFI_ERROR (Status) || (InfoBlock == NULL)) {
171 continue;
172 }
173
174 //
175 // Check whether the network boot policy matches.
176 //
177 NetworkBoot = (EFI_ADAPTER_INFO_NETWORK_BOOT *)InfoBlock;
178 NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy);
179
180 if (NetworkBootPolicy == STOP_UEFI_ISCSI_IF_HBA_INSTALL_AIP) {
181 Status = EFI_SUCCESS;
182 goto Exit;
183 }
184
185 if ((((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP4) != 0) &&
186 !NetworkBoot->iScsiIpv4BootCapablity) ||
187 (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP6) != 0) &&
188 !NetworkBoot->iScsiIpv6BootCapablity) ||
189 (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_OFFLOAD) != 0) &&
190 !NetworkBoot->OffloadCapability) ||
191 (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_MPIO) != 0) &&
192 !NetworkBoot->iScsiMpioCapability) ||
193 (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP4) != 0) &&
194 !NetworkBoot->iScsiIpv4Boot) ||
195 (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP6) != 0) &&
196 !NetworkBoot->iScsiIpv6Boot))
197 {
198 FreePool (InfoBlock);
199 continue;
200 }
201
202 Status = EFI_SUCCESS;
203 goto Exit;
204 }
205
206 Status = EFI_NOT_FOUND;
207
208Exit:
209 if (InfoBlock != NULL) {
210 FreePool (InfoBlock);
211 }
212
213 if (AipHandleBuffer != NULL) {
214 FreePool (AipHandleBuffer);
215 }
216
217 return Status;
218}
219
246EFIAPI
249 IN EFI_HANDLE ControllerHandle,
250 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
251 IN UINT8 IpVersion
252 )
253{
254 EFI_STATUS Status;
255 EFI_GUID *IScsiServiceBindingGuid;
256 EFI_GUID *TcpServiceBindingGuid;
257 EFI_GUID *DhcpServiceBindingGuid;
258 EFI_GUID *DnsServiceBindingGuid;
259
260 if (IpVersion == IP_VERSION_4) {
261 IScsiServiceBindingGuid = &gIScsiV4PrivateGuid;
262 TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
263 DhcpServiceBindingGuid = &gEfiDhcp4ServiceBindingProtocolGuid;
264 DnsServiceBindingGuid = &gEfiDns4ServiceBindingProtocolGuid;
265 } else {
266 IScsiServiceBindingGuid = &gIScsiV6PrivateGuid;
267 TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
268 DhcpServiceBindingGuid = &gEfiDhcp6ServiceBindingProtocolGuid;
269 DnsServiceBindingGuid = &gEfiDns6ServiceBindingProtocolGuid;
270 }
271
272 Status = gBS->OpenProtocol (
273 ControllerHandle,
274 IScsiServiceBindingGuid,
275 NULL,
276 This->DriverBindingHandle,
277 ControllerHandle,
278 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
279 );
280 if (!EFI_ERROR (Status)) {
281 return EFI_ALREADY_STARTED;
282 }
283
284 Status = gBS->OpenProtocol (
285 ControllerHandle,
286 TcpServiceBindingGuid,
287 NULL,
288 This->DriverBindingHandle,
289 ControllerHandle,
290 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
291 );
292 if (EFI_ERROR (Status)) {
293 return EFI_UNSUPPORTED;
294 }
295
296 Status = IScsiIsDevicePathSupported (RemainingDevicePath);
297 if (EFI_ERROR (Status)) {
298 return EFI_UNSUPPORTED;
299 }
300
301 if (IScsiDhcpIsConfigured (ControllerHandle, IpVersion)) {
302 Status = gBS->OpenProtocol (
303 ControllerHandle,
304 DhcpServiceBindingGuid,
305 NULL,
306 This->DriverBindingHandle,
307 ControllerHandle,
308 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
309 );
310 if (EFI_ERROR (Status)) {
311 return EFI_UNSUPPORTED;
312 }
313 }
314
315 if (IScsiDnsIsConfigured (ControllerHandle)) {
316 Status = gBS->OpenProtocol (
317 ControllerHandle,
318 DnsServiceBindingGuid,
319 NULL,
320 This->DriverBindingHandle,
321 ControllerHandle,
322 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
323 );
324 if (EFI_ERROR (Status)) {
325 return EFI_UNSUPPORTED;
326 }
327 }
328
329 return EFI_SUCCESS;
330}
331
353 IN EFI_HANDLE Image,
354 IN EFI_HANDLE ControllerHandle,
355 IN UINT8 IpVersion
356 )
357{
358 EFI_STATUS Status;
359 ISCSI_DRIVER_DATA *Private;
360 LIST_ENTRY *Entry;
361 LIST_ENTRY *NextEntry;
362 ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
363 ISCSI_SESSION *Session;
364 UINT8 Index;
365 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExistIScsiExtScsiPassThru;
366 ISCSI_DRIVER_DATA *ExistPrivate;
367 UINT8 *AttemptConfigOrder;
368 UINTN AttemptConfigOrderSize;
369 UINT8 BootSelected;
370 EFI_HANDLE *HandleBuffer;
371 UINTN NumberOfHandles;
372 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
373 EFI_GUID *IScsiPrivateGuid;
374 EFI_GUID *TcpServiceBindingGuid;
375 BOOLEAN NeedUpdate;
376 VOID *Interface;
377 EFI_GUID *ProtocolGuid;
378 UINT8 NetworkBootPolicy;
380
381 //
382 // Test to see if iSCSI driver supports the given controller.
383 //
384
385 if (IpVersion == IP_VERSION_4) {
386 IScsiPrivateGuid = &gIScsiV4PrivateGuid;
387 TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
388 ProtocolGuid = &gEfiTcp4ProtocolGuid;
389 } else if (IpVersion == IP_VERSION_6) {
390 IScsiPrivateGuid = &gIScsiV6PrivateGuid;
391 TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
392 ProtocolGuid = &gEfiTcp6ProtocolGuid;
393 } else {
394 return EFI_INVALID_PARAMETER;
395 }
396
397 Status = gBS->OpenProtocol (
398 ControllerHandle,
399 IScsiPrivateGuid,
400 NULL,
401 Image,
402 ControllerHandle,
403 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
404 );
405 if (!EFI_ERROR (Status)) {
406 return EFI_ALREADY_STARTED;
407 }
408
409 Status = gBS->OpenProtocol (
410 ControllerHandle,
411 TcpServiceBindingGuid,
412 NULL,
413 Image,
414 ControllerHandle,
415 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
416 );
417 if (EFI_ERROR (Status)) {
418 return EFI_UNSUPPORTED;
419 }
420
421 NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy);
422 if (NetworkBootPolicy == ALWAYS_USE_ISCSI_HBA_AND_IGNORE_UEFI_ISCSI) {
423 return EFI_ABORTED;
424 }
425
426 if (NetworkBootPolicy != ALWAYS_USE_UEFI_ISCSI_AND_IGNORE_ISCSI_HBA) {
427 //
428 // Check existing iSCSI AIP.
429 //
430 Status = IScsiCheckAip ();
431 if (!EFI_ERROR (Status)) {
432 //
433 // Find iSCSI AIP with specified network boot policy. return EFI_ABORTED.
434 //
435 return EFI_ABORTED;
436 }
437 }
438
439 //
440 // Record the incoming NIC info.
441 //
442 Status = IScsiAddNic (ControllerHandle, Image);
443 if (EFI_ERROR (Status)) {
444 return Status;
445 }
446
447 //
448 // Create the instance private data.
449 //
450 Private = IScsiCreateDriverData (Image, ControllerHandle);
451 if (Private == NULL) {
452 return EFI_OUT_OF_RESOURCES;
453 }
454
455 //
456 // Create a underlayer child instance, but not need to configure it. Just open ChildHandle
457 // via BY_DRIVER. That is, establishing the relationship between ControllerHandle and ChildHandle.
458 // Therefore, when DisconnectController(), especially VLAN virtual controller handle,
459 // IScsiDriverBindingStop() will be called.
460 //
461 Status = NetLibCreateServiceChild (
462 ControllerHandle,
463 Image,
464 TcpServiceBindingGuid,
465 &Private->ChildHandle
466 );
467
468 if (EFI_ERROR (Status)) {
469 goto ON_ERROR;
470 }
471
472 Status = gBS->OpenProtocol (
473 Private->ChildHandle,
474 ProtocolGuid,
475 &Interface,
476 Image,
477 ControllerHandle,
478 EFI_OPEN_PROTOCOL_BY_DRIVER
479 );
480
481 if (EFI_ERROR (Status)) {
482 goto ON_ERROR;
483 }
484
485 //
486 // Always install private protocol no matter what happens later. We need to
487 // keep the relationship between ControllerHandle and ChildHandle.
488 //
489 Status = gBS->InstallProtocolInterface (
490 &ControllerHandle,
491 IScsiPrivateGuid,
493 &Private->IScsiIdentifier
494 );
495 if (EFI_ERROR (Status)) {
496 goto ON_ERROR;
497 }
498
499 if (IpVersion == IP_VERSION_4) {
500 mPrivate->Ipv6Flag = FALSE;
501 } else {
502 mPrivate->Ipv6Flag = TRUE;
503 }
504
505 //
506 // Get the current iSCSI configuration data.
507 //
508 Status = IScsiGetConfigData (Private);
509 if (EFI_ERROR (Status)) {
510 goto ON_ERROR;
511 }
512
513 //
514 // If there is already a successul attempt, check whether this attempt is the
515 // first "enabled for MPIO" attempt. If not, still try the first attempt.
516 // In single path mode, try all attempts.
517 //
518 ExistPrivate = NULL;
519 Status = EFI_NOT_FOUND;
520
521 if (mPrivate->OneSessionEstablished && mPrivate->EnableMpio) {
522 AttemptConfigData = NULL;
523 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
524 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
525 if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
526 break;
527 }
528 }
529
530 if (AttemptConfigData == NULL) {
531 goto ON_ERROR;
532 }
533
534 if (AttemptConfigData->AttemptConfigIndex == mPrivate->BootSelectedIndex) {
535 goto ON_EXIT;
536 }
537
538 //
539 // Uninstall the original ExtScsiPassThru first.
540 //
541
542 //
543 // Locate all ExtScsiPassThru protocol instances.
544 //
545 Status = gBS->LocateHandleBuffer (
547 &gEfiExtScsiPassThruProtocolGuid,
548 NULL,
549 &NumberOfHandles,
550 &HandleBuffer
551 );
552 if (EFI_ERROR (Status)) {
553 goto ON_ERROR;
554 }
555
556 //
557 // Find ExtScsiPassThru protocol instance produced by this driver.
558 //
559 ExistIScsiExtScsiPassThru = NULL;
560 for (Index = 0; Index < NumberOfHandles && ExistIScsiExtScsiPassThru == NULL; Index++) {
561 Status = gBS->HandleProtocol (
562 HandleBuffer[Index],
563 &gEfiDevicePathProtocolGuid,
564 (VOID **)&DevicePath
565 );
566 if (EFI_ERROR (Status)) {
567 continue;
568 }
569
570 while (!IsDevicePathEnd (DevicePath)) {
571 if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_MAC_ADDR_DP)) {
572 //
573 // Get the ExtScsiPassThru protocol instance.
574 //
575 Status = gBS->HandleProtocol (
576 HandleBuffer[Index],
577 &gEfiExtScsiPassThruProtocolGuid,
578 (VOID **)&ExistIScsiExtScsiPassThru
579 );
580 ASSERT_EFI_ERROR (Status);
581 break;
582 }
583
584 DevicePath = NextDevicePathNode (DevicePath);
585 }
586 }
587
588 FreePool (HandleBuffer);
589
590 if (ExistIScsiExtScsiPassThru == NULL) {
591 Status = EFI_NOT_FOUND;
592 goto ON_ERROR;
593 }
594
595 ExistPrivate = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (ExistIScsiExtScsiPassThru);
596
597 Status = gBS->UninstallProtocolInterface (
598 ExistPrivate->ExtScsiPassThruHandle,
599 &gEfiExtScsiPassThruProtocolGuid,
600 &ExistPrivate->IScsiExtScsiPassThru
601 );
602 if (EFI_ERROR (Status)) {
603 goto ON_ERROR;
604 }
605 }
606
607 //
608 // Install the Ext SCSI PASS THRU protocol.
609 //
610 Status = gBS->InstallProtocolInterface (
611 &Private->ExtScsiPassThruHandle,
612 &gEfiExtScsiPassThruProtocolGuid,
614 &Private->IScsiExtScsiPassThru
615 );
616 if (EFI_ERROR (Status)) {
617 goto ON_ERROR;
618 }
619
620 BootSelected = 0;
621
622 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
623 AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
624 //
625 // Don't process the attempt that does not associate with the current NIC or
626 // this attempt is disabled or established.
627 //
628 if ((AttemptConfigData->NicIndex != mPrivate->CurrentNic) ||
629 (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) ||
630 AttemptConfigData->ValidPath)
631 {
632 continue;
633 }
634
635 //
636 // In multipath mode, don't process attempts configured for single path.
637 // In default single path mode, don't process attempts configured for multipath.
638 //
639 if ((mPrivate->EnableMpio &&
640 (AttemptConfigData->SessionConfigData.Enabled != ISCSI_ENABLED_FOR_MPIO)) ||
641 (!mPrivate->EnableMpio &&
642 (AttemptConfigData->SessionConfigData.Enabled != ISCSI_ENABLED)))
643 {
644 continue;
645 }
646
647 //
648 // Don't process the attempt that fails to get the init/target information from DHCP.
649 //
650 if (AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp &&
651 !AttemptConfigData->DhcpSuccess)
652 {
653 if (!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount > 0)) {
654 mPrivate->ValidSinglePathCount--;
655 }
656
657 continue;
658 }
659
660 //
661 // Don't process the autoconfigure path if it is already established.
662 //
663 if ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
664 AttemptConfigData->AutoConfigureSuccess)
665 {
666 continue;
667 }
668
669 //
670 // Don't process the attempt if its IP mode is not in the current IP version.
671 //
672 if (!mPrivate->Ipv6Flag) {
673 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {
674 continue;
675 }
676
677 if ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
678 (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6))
679 {
680 continue;
681 }
682 } else {
683 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {
684 continue;
685 }
686
687 if ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
688 (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4))
689 {
690 continue;
691 }
692 }
693
694 //
695 // Fill in the Session and init it.
696 //
697 Session = (ISCSI_SESSION *)AllocateZeroPool (sizeof (ISCSI_SESSION));
698 if (Session == NULL) {
699 Status = EFI_OUT_OF_RESOURCES;
700 goto ON_ERROR;
701 }
702
703 Session->Private = Private;
704 Session->ConfigData = AttemptConfigData;
705 Session->AuthType = AttemptConfigData->AuthenticationType;
706
708 mPrivate->PortString,
709 (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
710 L"Attempt %d",
711 (UINTN)AttemptConfigData->AttemptConfigIndex
712 );
713
714 if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {
715 Session->AuthData.CHAP.AuthConfig = &AttemptConfigData->AuthConfigData.CHAP;
716 }
717
718 IScsiSessionInit (Session, FALSE);
719
720 //
721 // Try to login and create an iSCSI session according to the configuration.
722 //
723 Status = IScsiSessionLogin (Session);
724 if (Status == EFI_MEDIA_CHANGED) {
725 //
726 // The specified target is not available, and the redirection information is
727 // received. Login the session again with the updated target address.
728 //
729 Status = IScsiSessionLogin (Session);
730 } else if (Status == EFI_NOT_READY) {
731 Status = IScsiSessionReLogin (Session);
732 }
733
734 //
735 // Restore the original user setting which specifies the proxy/virtual iSCSI target to NV region.
736 //
737 NvData = &AttemptConfigData->SessionConfigData;
738 if (NvData->RedirectFlag) {
739 NvData->TargetPort = NvData->OriginalTargetPort;
740 CopyMem (&NvData->TargetIp, &NvData->OriginalTargetIp, sizeof (EFI_IP_ADDRESS));
741 NvData->RedirectFlag = FALSE;
742
743 gRT->SetVariable (
744 mPrivate->PortString,
745 &gEfiIScsiInitiatorNameProtocolGuid,
746 ISCSI_CONFIG_VAR_ATTR,
748 AttemptConfigData
749 );
750 }
751
752 if (EFI_ERROR (Status)) {
753 //
754 // In Single path mode, only the successful attempt will be recorded in iBFT;
755 // in multi-path mode, all the attempt entries in MPIO will be recorded in iBFT.
756 //
757 if (!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount > 0)) {
758 mPrivate->ValidSinglePathCount--;
759 }
760
761 FreePool (Session);
762 } else {
763 AttemptConfigData->ValidPath = TRUE;
764
765 //
766 // Do not record the attempt in iBFT if it login with KRB5.
767 // TODO: record KRB5 attempt information in the iSCSI device path.
768 //
769 if (Session->AuthType == ISCSI_AUTH_TYPE_KRB) {
770 if (!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount > 0)) {
771 mPrivate->ValidSinglePathCount--;
772 }
773
774 AttemptConfigData->ValidiBFTPath = FALSE;
775 } else {
776 AttemptConfigData->ValidiBFTPath = TRUE;
777 }
778
779 //
780 // IScsi session success. Update the attempt state to NVR.
781 //
782 if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
783 AttemptConfigData->AutoConfigureSuccess = TRUE;
784 }
785
786 gRT->SetVariable (
787 mPrivate->PortString,
788 &gEfiIScsiInitiatorNameProtocolGuid,
789 ISCSI_CONFIG_VAR_ATTR,
791 AttemptConfigData
792 );
793
794 //
795 // Select the first login session. Abort others.
796 //
797 if (Private->Session == NULL) {
798 Private->Session = Session;
799 BootSelected = AttemptConfigData->AttemptConfigIndex;
800 //
801 // Don't validate other attempt in multipath mode if one is success.
802 //
803 if (mPrivate->EnableMpio) {
804 break;
805 }
806 } else {
807 IScsiSessionAbort (Session);
808 FreePool (Session);
809 }
810 }
811 }
812
813 //
814 // All attempts configured for this driver instance are not valid.
815 //
816 if (Private->Session == NULL) {
817 Status = gBS->UninstallProtocolInterface (
818 Private->ExtScsiPassThruHandle,
819 &gEfiExtScsiPassThruProtocolGuid,
820 &Private->IScsiExtScsiPassThru
821 );
822 ASSERT_EFI_ERROR (Status);
823 Private->ExtScsiPassThruHandle = NULL;
824
825 //
826 // Reinstall the original ExtScsiPassThru back.
827 //
828 if (mPrivate->OneSessionEstablished && (ExistPrivate != NULL)) {
829 Status = gBS->InstallProtocolInterface (
830 &ExistPrivate->ExtScsiPassThruHandle,
831 &gEfiExtScsiPassThruProtocolGuid,
833 &ExistPrivate->IScsiExtScsiPassThru
834 );
835 if (EFI_ERROR (Status)) {
836 goto ON_ERROR;
837 }
838
839 goto ON_EXIT;
840 }
841
842 Status = EFI_NOT_FOUND;
843
844 goto ON_ERROR;
845 }
846
847 NeedUpdate = TRUE;
848 //
849 // More than one attempt successes.
850 //
851 if ((Private->Session != NULL) && mPrivate->OneSessionEstablished) {
852 AttemptConfigOrder = IScsiGetVariableAndSize (
853 L"AttemptOrder",
854 &gIScsiConfigGuid,
855 &AttemptConfigOrderSize
856 );
857 if (AttemptConfigOrder == NULL) {
858 goto ON_ERROR;
859 }
860
861 for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
862 if ((AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex) ||
863 (AttemptConfigOrder[Index] == BootSelected))
864 {
865 break;
866 }
867 }
868
869 if (mPrivate->EnableMpio) {
870 //
871 // Use the attempt in earlier order. Abort the later one in MPIO.
872 //
873 if (AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex) {
874 IScsiSessionAbort (Private->Session);
875 FreePool (Private->Session);
876 Private->Session = NULL;
877 gBS->UninstallProtocolInterface (
878 Private->ExtScsiPassThruHandle,
879 &gEfiExtScsiPassThruProtocolGuid,
880 &Private->IScsiExtScsiPassThru
881 );
882 Private->ExtScsiPassThruHandle = NULL;
883
884 //
885 // Reinstall the original ExtScsiPassThru back.
886 //
887 Status = gBS->InstallProtocolInterface (
888 &ExistPrivate->ExtScsiPassThruHandle,
889 &gEfiExtScsiPassThruProtocolGuid,
891 &ExistPrivate->IScsiExtScsiPassThru
892 );
893 if (EFI_ERROR (Status)) {
894 goto ON_ERROR;
895 }
896
897 goto ON_EXIT;
898 } else {
899 if (AttemptConfigOrder[Index] != BootSelected) {
900 goto ON_ERROR;
901 }
902
903 mPrivate->BootSelectedIndex = BootSelected;
904 //
905 // Clear the resource in ExistPrivate.
906 //
907 gBS->UninstallProtocolInterface (
908 ExistPrivate->Controller,
909 IScsiPrivateGuid,
910 &ExistPrivate->IScsiIdentifier
911 );
912
913 IScsiRemoveNic (ExistPrivate->Controller);
914 if (ExistPrivate->Session != NULL) {
915 IScsiSessionAbort (ExistPrivate->Session);
916 }
917
918 if (ExistPrivate->DevicePath != NULL) {
919 Status = gBS->UninstallProtocolInterface (
920 ExistPrivate->ExtScsiPassThruHandle,
921 &gEfiDevicePathProtocolGuid,
922 ExistPrivate->DevicePath
923 );
924 if (EFI_ERROR (Status)) {
925 goto ON_ERROR;
926 }
927
928 FreePool (ExistPrivate->DevicePath);
929 }
930
931 gBS->CloseEvent (ExistPrivate->ExitBootServiceEvent);
932 FreePool (ExistPrivate);
933 }
934 } else {
935 //
936 // Use the attempt in earlier order as boot selected in single path mode.
937 //
938 if (AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex) {
939 NeedUpdate = FALSE;
940 }
941 }
942 }
943
944 if (NeedUpdate) {
945 mPrivate->OneSessionEstablished = TRUE;
946 mPrivate->BootSelectedIndex = BootSelected;
947 }
948
949 //
950 // Duplicate the Session's tcp connection device path. The source port field
951 // will be set to zero as one iSCSI session is comprised of several iSCSI
952 // connections.
953 //
954 Private->DevicePath = IScsiGetTcpConnDevicePath (Private->Session);
955 if (Private->DevicePath == NULL) {
956 Status = EFI_DEVICE_ERROR;
957 goto ON_ERROR;
958 }
959
960 //
961 // Install the updated device path onto the ExtScsiPassThruHandle.
962 //
963 Status = gBS->InstallProtocolInterface (
964 &Private->ExtScsiPassThruHandle,
965 &gEfiDevicePathProtocolGuid,
967 Private->DevicePath
968 );
969 if (EFI_ERROR (Status)) {
970 goto ON_ERROR;
971 }
972
973 //
974 // ISCSI children should share the default Tcp child, just open the default Tcp child via BY_CHILD_CONTROLLER.
975 //
976 Status = gBS->OpenProtocol (
977 Private->ChildHandle,
978 ProtocolGuid,
979 &Interface,
980 Image,
981 Private->ExtScsiPassThruHandle,
982 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
983 );
984 if (EFI_ERROR (Status)) {
985 gBS->UninstallMultipleProtocolInterfaces (
986 Private->ExtScsiPassThruHandle,
987 &gEfiExtScsiPassThruProtocolGuid,
988 &Private->IScsiExtScsiPassThru,
989 &gEfiDevicePathProtocolGuid,
990 Private->DevicePath,
991 NULL
992 );
993
994 goto ON_ERROR;
995 }
996
997ON_EXIT:
998
999 //
1000 // Update/Publish the iSCSI Boot Firmware Table.
1001 //
1002 if (mPrivate->BootSelectedIndex != 0) {
1004 }
1005
1006 return EFI_SUCCESS;
1007
1008ON_ERROR:
1009
1010 if (Private->Session != NULL) {
1011 IScsiSessionAbort (Private->Session);
1012 }
1013
1014 return Status;
1015}
1016
1038EFIAPI
1041 IN EFI_HANDLE ControllerHandle,
1042 IN UINTN NumberOfChildren,
1043 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL,
1044 IN UINT8 IpVersion
1045 )
1046{
1047 EFI_HANDLE IScsiController;
1048 EFI_STATUS Status;
1049 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;
1050 ISCSI_DRIVER_DATA *Private;
1052 ISCSI_CONNECTION *Conn;
1053 EFI_GUID *ProtocolGuid;
1054 EFI_GUID *TcpServiceBindingGuid;
1055 EFI_GUID *TcpProtocolGuid;
1056
1057 if (NumberOfChildren != 0) {
1058 //
1059 // We should have only one child.
1060 //
1061 Status = gBS->OpenProtocol (
1062 ChildHandleBuffer[0],
1063 &gEfiExtScsiPassThruProtocolGuid,
1064 (VOID **)&PassThru,
1065 This->DriverBindingHandle,
1066 ControllerHandle,
1067 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1068 );
1069 if (EFI_ERROR (Status)) {
1070 return EFI_DEVICE_ERROR;
1071 }
1072
1073 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);
1074 Conn = NET_LIST_HEAD (&Private->Session->Conns, ISCSI_CONNECTION, Link);
1075
1076 //
1077 // Previously the TCP protocol is opened BY_CHILD_CONTROLLER. Just close
1078 // the protocol here, but do not uninstall the device path protocol and
1079 // EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.
1080 //
1081 if (IpVersion == IP_VERSION_4) {
1082 ProtocolGuid = &gEfiTcp4ProtocolGuid;
1083 } else {
1084 ProtocolGuid = &gEfiTcp6ProtocolGuid;
1085 }
1086
1087 gBS->CloseProtocol (
1088 Private->ChildHandle,
1089 ProtocolGuid,
1090 Private->Image,
1091 Private->ExtScsiPassThruHandle
1092 );
1093
1094 gBS->CloseProtocol (
1095 Conn->TcpIo.Handle,
1096 ProtocolGuid,
1097 Private->Image,
1098 Private->ExtScsiPassThruHandle
1099 );
1100
1101 return EFI_SUCCESS;
1102 }
1103
1104 //
1105 // Get the handle of the controller we are controlling.
1106 //
1107 if (IpVersion == IP_VERSION_4) {
1108 ProtocolGuid = &gIScsiV4PrivateGuid;
1109 TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
1110 TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
1111 } else {
1112 ProtocolGuid = &gIScsiV6PrivateGuid;
1113 TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
1114 TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
1115 }
1116
1117 IScsiController = NetLibGetNicHandle (ControllerHandle, TcpProtocolGuid);
1118 if (IScsiController == NULL) {
1119 return EFI_SUCCESS;
1120 }
1121
1122 Status = gBS->OpenProtocol (
1123 IScsiController,
1124 ProtocolGuid,
1125 (VOID **)&IScsiIdentifier,
1126 This->DriverBindingHandle,
1127 ControllerHandle,
1128 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1129 );
1130 if (EFI_ERROR (Status)) {
1131 return EFI_DEVICE_ERROR;
1132 }
1133
1134 Private = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);
1135 ASSERT (Private != NULL);
1136
1137 if (Private->ChildHandle != NULL) {
1138 Status = gBS->CloseProtocol (
1139 Private->ChildHandle,
1140 TcpProtocolGuid,
1141 This->DriverBindingHandle,
1142 IScsiController
1143 );
1144
1145 ASSERT (!EFI_ERROR (Status));
1146
1147 Status = NetLibDestroyServiceChild (
1148 IScsiController,
1149 This->DriverBindingHandle,
1150 TcpServiceBindingGuid,
1151 Private->ChildHandle
1152 );
1153
1154 ASSERT (!EFI_ERROR (Status));
1155 }
1156
1157 gBS->UninstallProtocolInterface (
1158 IScsiController,
1159 ProtocolGuid,
1160 &Private->IScsiIdentifier
1161 );
1162
1163 //
1164 // Remove this NIC.
1165 //
1166 IScsiRemoveNic (IScsiController);
1167
1168 //
1169 // Update the iSCSI Boot Firmware Table.
1170 //
1172
1173 if (Private->Session != NULL) {
1174 IScsiSessionAbort (Private->Session);
1175 }
1176
1177 Status = IScsiCleanDriverData (Private);
1178
1179 if (EFI_ERROR (Status)) {
1180 return Status;
1181 }
1182
1183 return EFI_SUCCESS;
1184}
1185
1229EFIAPI
1232 IN EFI_HANDLE ControllerHandle,
1233 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1234 )
1235{
1236 return IScsiSupported (
1237 This,
1238 ControllerHandle,
1239 RemainingDevicePath,
1240 IP_VERSION_4
1241 );
1242}
1243
1280EFIAPI
1283 IN EFI_HANDLE ControllerHandle,
1284 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1285 )
1286{
1287 EFI_STATUS Status;
1288
1289 Status = IScsiStart (This->DriverBindingHandle, ControllerHandle, IP_VERSION_4);
1290 if (Status == EFI_ALREADY_STARTED) {
1291 Status = EFI_SUCCESS;
1292 }
1293
1294 return Status;
1295}
1296
1324EFIAPI
1327 IN EFI_HANDLE ControllerHandle,
1328 IN UINTN NumberOfChildren,
1329 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
1330 )
1331{
1332 return IScsiStop (
1333 This,
1334 ControllerHandle,
1335 NumberOfChildren,
1336 ChildHandleBuffer,
1337 IP_VERSION_4
1338 );
1339}
1340
1384EFIAPI
1387 IN EFI_HANDLE ControllerHandle,
1388 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1389 )
1390{
1391 return IScsiSupported (
1392 This,
1393 ControllerHandle,
1394 RemainingDevicePath,
1395 IP_VERSION_6
1396 );
1397}
1398
1435EFIAPI
1438 IN EFI_HANDLE ControllerHandle,
1439 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
1440 )
1441{
1442 EFI_STATUS Status;
1443
1444 Status = IScsiStart (This->DriverBindingHandle, ControllerHandle, IP_VERSION_6);
1445 if (Status == EFI_ALREADY_STARTED) {
1446 Status = EFI_SUCCESS;
1447 }
1448
1449 return Status;
1450}
1451
1479EFIAPI
1482 IN EFI_HANDLE ControllerHandle,
1483 IN UINTN NumberOfChildren,
1484 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
1485 )
1486{
1487 return IScsiStop (
1488 This,
1489 ControllerHandle,
1490 NumberOfChildren,
1491 ChildHandleBuffer,
1492 IP_VERSION_6
1493 );
1494}
1495
1506EFIAPI
1508 IN EFI_HANDLE ImageHandle
1509 )
1510{
1511 EFI_STATUS Status;
1512 UINTN DeviceHandleCount;
1513 EFI_HANDLE *DeviceHandleBuffer;
1514 UINTN Index;
1515 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
1516 EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
1517
1518 //
1519 // Try to disconnect the driver from the devices it's controlling.
1520 //
1521 Status = gBS->LocateHandleBuffer (
1522 AllHandles,
1523 NULL,
1524 NULL,
1525 &DeviceHandleCount,
1526 &DeviceHandleBuffer
1527 );
1528 if (EFI_ERROR (Status)) {
1529 return Status;
1530 }
1531
1532 //
1533 // Disconnect the iSCSI4 driver from the controlled device.
1534 //
1535 for (Index = 0; Index < DeviceHandleCount; Index++) {
1536 Status = IScsiTestManagedDevice (
1537 DeviceHandleBuffer[Index],
1538 gIScsiIp4DriverBinding.DriverBindingHandle,
1539 &gEfiTcp4ProtocolGuid
1540 )
1541 ;
1542 if (EFI_ERROR (Status)) {
1543 continue;
1544 }
1545
1546 Status = gBS->DisconnectController (
1547 DeviceHandleBuffer[Index],
1548 gIScsiIp4DriverBinding.DriverBindingHandle,
1549 NULL
1550 );
1551 if (EFI_ERROR (Status)) {
1552 goto ON_EXIT;
1553 }
1554 }
1555
1556 //
1557 // Disconnect the iSCSI6 driver from the controlled device.
1558 //
1559 for (Index = 0; Index < DeviceHandleCount; Index++) {
1560 Status = IScsiTestManagedDevice (
1561 DeviceHandleBuffer[Index],
1562 gIScsiIp6DriverBinding.DriverBindingHandle,
1563 &gEfiTcp6ProtocolGuid
1564 );
1565 if (EFI_ERROR (Status)) {
1566 continue;
1567 }
1568
1569 Status = gBS->DisconnectController (
1570 DeviceHandleBuffer[Index],
1571 gIScsiIp6DriverBinding.DriverBindingHandle,
1572 NULL
1573 );
1574 if (EFI_ERROR (Status)) {
1575 goto ON_EXIT;
1576 }
1577 }
1578
1579 //
1580 // Unload the iSCSI configuration form.
1581 //
1582 Status = IScsiConfigFormUnload (gIScsiIp4DriverBinding.DriverBindingHandle);
1583 if (EFI_ERROR (Status)) {
1584 goto ON_EXIT;
1585 }
1586
1587 //
1588 // Uninstall the protocols installed by iSCSI driver.
1589 //
1590 Status = gBS->UninstallMultipleProtocolInterfaces (
1591 ImageHandle,
1592 &gEfiAuthenticationInfoProtocolGuid,
1593 &gIScsiAuthenticationInfo,
1594 NULL
1595 );
1596 if (EFI_ERROR (Status)) {
1597 goto ON_EXIT;
1598 }
1599
1600 if (gIScsiControllerNameTable != NULL) {
1601 Status = FreeUnicodeStringTable (gIScsiControllerNameTable);
1602 if (EFI_ERROR (Status)) {
1603 goto ON_EXIT;
1604 }
1605
1606 gIScsiControllerNameTable = NULL;
1607 }
1608
1609 //
1610 // Uninstall the ComponentName and ComponentName2 protocol from iSCSI4 driver binding handle
1611 // if it has been installed.
1612 //
1613 Status = gBS->HandleProtocol (
1614 gIScsiIp4DriverBinding.DriverBindingHandle,
1615 &gEfiComponentNameProtocolGuid,
1616 (VOID **)&ComponentName
1617 );
1618 if (!EFI_ERROR (Status)) {
1619 Status = gBS->UninstallMultipleProtocolInterfaces (
1620 gIScsiIp4DriverBinding.DriverBindingHandle,
1621 &gEfiComponentNameProtocolGuid,
1622 ComponentName,
1623 NULL
1624 );
1625 if (EFI_ERROR (Status)) {
1626 goto ON_EXIT;
1627 }
1628 }
1629
1630 Status = gBS->HandleProtocol (
1631 gIScsiIp4DriverBinding.DriverBindingHandle,
1632 &gEfiComponentName2ProtocolGuid,
1633 (VOID **)&ComponentName2
1634 );
1635 if (!EFI_ERROR (Status)) {
1636 gBS->UninstallMultipleProtocolInterfaces (
1637 gIScsiIp4DriverBinding.DriverBindingHandle,
1638 &gEfiComponentName2ProtocolGuid,
1639 ComponentName2,
1640 NULL
1641 );
1642 if (EFI_ERROR (Status)) {
1643 goto ON_EXIT;
1644 }
1645 }
1646
1647 //
1648 // Uninstall the ComponentName and ComponentName2 protocol from iSCSI6 driver binding handle
1649 // if it has been installed.
1650 //
1651 Status = gBS->HandleProtocol (
1652 gIScsiIp6DriverBinding.DriverBindingHandle,
1653 &gEfiComponentNameProtocolGuid,
1654 (VOID **)&ComponentName
1655 );
1656 if (!EFI_ERROR (Status)) {
1657 Status = gBS->UninstallMultipleProtocolInterfaces (
1658 gIScsiIp6DriverBinding.DriverBindingHandle,
1659 &gEfiComponentNameProtocolGuid,
1660 ComponentName,
1661 NULL
1662 );
1663 if (EFI_ERROR (Status)) {
1664 goto ON_EXIT;
1665 }
1666 }
1667
1668 Status = gBS->HandleProtocol (
1669 gIScsiIp6DriverBinding.DriverBindingHandle,
1670 &gEfiComponentName2ProtocolGuid,
1671 (VOID **)&ComponentName2
1672 );
1673 if (!EFI_ERROR (Status)) {
1674 gBS->UninstallMultipleProtocolInterfaces (
1675 gIScsiIp6DriverBinding.DriverBindingHandle,
1676 &gEfiComponentName2ProtocolGuid,
1677 ComponentName2,
1678 NULL
1679 );
1680 if (EFI_ERROR (Status)) {
1681 goto ON_EXIT;
1682 }
1683 }
1684
1685 //
1686 // Uninstall the IScsiInitiatorNameProtocol and all the driver binding protocols.
1687 //
1688 Status = gBS->UninstallMultipleProtocolInterfaces (
1689 gIScsiIp4DriverBinding.DriverBindingHandle,
1690 &gEfiDriverBindingProtocolGuid,
1691 &gIScsiIp4DriverBinding,
1692 &gEfiIScsiInitiatorNameProtocolGuid,
1693 &gIScsiInitiatorName,
1694 NULL
1695 );
1696 if (EFI_ERROR (Status)) {
1697 goto ON_EXIT;
1698 }
1699
1700 Status = gBS->UninstallMultipleProtocolInterfaces (
1701 gIScsiIp6DriverBinding.DriverBindingHandle,
1702 &gEfiDriverBindingProtocolGuid,
1703 &gIScsiIp6DriverBinding,
1704 NULL
1705 );
1706
1707ON_EXIT:
1708
1709 if (DeviceHandleBuffer != NULL) {
1710 FreePool (DeviceHandleBuffer);
1711 }
1712
1713 return Status;
1714}
1715
1733EFIAPI
1735 IN EFI_HANDLE ImageHandle,
1736 IN EFI_SYSTEM_TABLE *SystemTable
1737 )
1738{
1739 EFI_STATUS Status;
1740 EFI_ISCSI_INITIATOR_NAME_PROTOCOL *IScsiInitiatorName;
1741 EFI_AUTHENTICATION_INFO_PROTOCOL *AuthenticationInfo;
1742
1743 //
1744 // There should be only one EFI_ISCSI_INITIATOR_NAME_PROTOCOL.
1745 //
1746 Status = gBS->LocateProtocol (
1747 &gEfiIScsiInitiatorNameProtocolGuid,
1748 NULL,
1749 (VOID **)&IScsiInitiatorName
1750 );
1751 if (!EFI_ERROR (Status)) {
1752 return EFI_ACCESS_DENIED;
1753 }
1754
1755 //
1756 // Initialize the EFI Driver Library.
1757 //
1759 ImageHandle,
1760 SystemTable,
1761 &gIScsiIp4DriverBinding,
1762 ImageHandle,
1763 &gIScsiComponentName,
1764 &gIScsiComponentName2
1765 );
1766 if (EFI_ERROR (Status)) {
1767 return Status;
1768 }
1769
1771 ImageHandle,
1772 SystemTable,
1773 &gIScsiIp6DriverBinding,
1774 NULL,
1775 &gIScsiComponentName,
1776 &gIScsiComponentName2
1777 );
1778 if (EFI_ERROR (Status)) {
1779 goto Error1;
1780 }
1781
1782 //
1783 // Install the iSCSI Initiator Name Protocol.
1784 //
1785 Status = gBS->InstallProtocolInterface (
1786 &ImageHandle,
1787 &gEfiIScsiInitiatorNameProtocolGuid,
1789 &gIScsiInitiatorName
1790 );
1791 if (EFI_ERROR (Status)) {
1792 goto Error2;
1793 }
1794
1795 //
1796 // Create the private data structures.
1797 //
1799
1800 mPrivate = AllocateZeroPool (sizeof (ISCSI_PRIVATE_DATA));
1801 if (mPrivate == NULL) {
1802 Status = EFI_OUT_OF_RESOURCES;
1803 goto Error3;
1804 }
1805
1806 InitializeListHead (&mPrivate->NicInfoList);
1807 InitializeListHead (&mPrivate->AttemptConfigs);
1808
1809 //
1810 // Initialize the configuration form of iSCSI.
1811 //
1812 Status = IScsiConfigFormInit (gIScsiIp4DriverBinding.DriverBindingHandle);
1813 if (EFI_ERROR (Status)) {
1814 goto Error4;
1815 }
1816
1817 //
1818 // Create the Maximum Attempts.
1819 //
1820 Status = IScsiCreateAttempts (PcdGet8 (PcdMaxIScsiAttemptNumber));
1821 if (EFI_ERROR (Status)) {
1822 goto Error5;
1823 }
1824
1825 //
1826 // Create Keywords for all the Attempts.
1827 //
1828 Status = IScsiCreateKeywords (PcdGet8 (PcdMaxIScsiAttemptNumber));
1829 if (EFI_ERROR (Status)) {
1830 goto Error6;
1831 }
1832
1833 //
1834 // There should be only one EFI_AUTHENTICATION_INFO_PROTOCOL. If already exists,
1835 // do not produce the protocol instance.
1836 //
1837 Status = gBS->LocateProtocol (
1838 &gEfiAuthenticationInfoProtocolGuid,
1839 NULL,
1840 (VOID **)&AuthenticationInfo
1841 );
1842 if (Status == EFI_NOT_FOUND) {
1843 Status = gBS->InstallProtocolInterface (
1844 &ImageHandle,
1845 &gEfiAuthenticationInfoProtocolGuid,
1847 &gIScsiAuthenticationInfo
1848 );
1849 if (EFI_ERROR (Status)) {
1850 goto Error6;
1851 }
1852 }
1853
1854 return EFI_SUCCESS;
1855
1856Error6:
1858
1859Error5:
1860 IScsiConfigFormUnload (gIScsiIp4DriverBinding.DriverBindingHandle);
1861
1862Error4:
1863 if (mPrivate != NULL) {
1864 FreePool (mPrivate);
1865 mPrivate = NULL;
1866 }
1867
1868Error3:
1869 gBS->UninstallMultipleProtocolInterfaces (
1870 ImageHandle,
1871 &gEfiIScsiInitiatorNameProtocolGuid,
1872 &gIScsiInitiatorName,
1873 NULL
1874 );
1875
1876Error2:
1878 &gIScsiIp6DriverBinding,
1879 &gIScsiComponentName,
1880 &gIScsiComponentName2
1881 );
1882
1883Error1:
1885 &gIScsiIp4DriverBinding,
1886 &gIScsiComponentName,
1887 &gIScsiComponentName2
1888 );
1889
1890 return Status;
1891}
UINT64 UINTN
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
#define MSG_ISCSI_DP
Definition: DevicePath.h:925
#define MSG_MAC_ADDR_DP
Definition: DevicePath.h:550
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID IScsiCHAPInitHashList(VOID)
Definition: IScsiCHAP.c:635
EFI_STATUS IScsiConfigFormUnload(IN EFI_HANDLE DriverBindingHandle)
Definition: IScsiConfig.c:3878
EFI_STATUS IScsiConfigFormInit(IN EFI_HANDLE DriverBindingHandle)
Definition: IScsiConfig.c:3806
EFI_STATUS EFIAPI IScsiSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN UINT8 IpVersion)
Definition: IScsiDriver.c:247
EFI_STATUS EFIAPI IScsiIp4DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: IScsiDriver.c:1281
EFI_STATUS IScsiStart(IN EFI_HANDLE Image, IN EFI_HANDLE ControllerHandle, IN UINT8 IpVersion)
Definition: IScsiDriver.c:352
EFI_STATUS EFIAPI IScsiDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: IScsiDriver.c:1734
EFI_STATUS EFIAPI IScsiStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL, IN UINT8 IpVersion)
Definition: IScsiDriver.c:1039
EFI_STATUS EFIAPI IScsiIp6DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: IScsiDriver.c:1385
EFI_STATUS EFIAPI IScsiIp4DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: IScsiDriver.c:1325
EFI_STATUS IScsiCheckAip(VOID)
Definition: IScsiDriver.c:84
EFI_STATUS EFIAPI IScsiIp6DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: IScsiDriver.c:1436
EFI_STATUS EFIAPI IScsiUnload(IN EFI_HANDLE ImageHandle)
Definition: IScsiDriver.c:1507
EFI_STATUS EFIAPI IScsiIp6DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: IScsiDriver.c:1480
EFI_STATUS IScsiIsDevicePathSupported(IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: IScsiDriver.c:52
EFI_STATUS EFIAPI IScsiIp4DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: IScsiDriver.c:1230
VOID IScsiPublishIbft(IN VOID)
Definition: IScsiIbft.c:434
VOID * IScsiGetVariableAndSize(IN CHAR16 *Name, IN EFI_GUID *VendorGuid, OUT UINTN *VariableSize)
Definition: IScsiMisc.c:1698
ISCSI_DRIVER_DATA * IScsiCreateDriverData(IN EFI_HANDLE Image, IN EFI_HANDLE Controller)
Definition: IScsiMisc.c:1748
EFI_STATUS IScsiCreateKeywords(IN UINTN KeywordNum)
Definition: IScsiMisc.c:949
EFI_STATUS EFIAPI IScsiTestManagedDevice(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverBindingHandle, IN EFI_GUID *ProtocolGuid)
Definition: IScsiMisc.c:2565
EFI_STATUS IScsiCleanDriverData(IN ISCSI_DRIVER_DATA *Private)
Definition: IScsiMisc.c:1807
EFI_STATUS IScsiRemoveNic(IN EFI_HANDLE Controller)
Definition: IScsiMisc.c:717
VOID IScsiCleanAttemptVariable(IN VOID)
Definition: IScsiMisc.c:1551
EFI_STATUS IScsiAddNic(IN EFI_HANDLE Controller, IN EFI_HANDLE Image)
Definition: IScsiMisc.c:607
EFI_STATUS IScsiCreateAttempts(IN UINTN AttemptNum)
Definition: IScsiMisc.c:812
EFI_DEVICE_PATH_PROTOCOL * IScsiGetTcpConnDevicePath(IN ISCSI_SESSION *Session)
Definition: IScsiMisc.c:2408
EFI_STATUS IScsiGetConfigData(IN ISCSI_DRIVER_DATA *Private)
Definition: IScsiMisc.c:2055
BOOLEAN IScsiDnsIsConfigured(IN EFI_HANDLE Controller)
Definition: IScsiMisc.c:1964
BOOLEAN IScsiDhcpIsConfigured(IN EFI_HANDLE Controller, IN UINT8 IpVersion)
Definition: IScsiMisc.c:1861
VOID IScsiSessionAbort(IN OUT ISCSI_SESSION *Session)
Definition: IScsiProto.c:3166
EFI_STATUS IScsiSessionLogin(IN ISCSI_SESSION *Session)
Definition: IScsiProto.c:452
EFI_STATUS IScsiSessionReLogin(IN ISCSI_SESSION *Session)
Definition: IScsiProto.c:547
VOID IScsiSessionInit(IN OUT ISCSI_SESSION *Session, IN BOOLEAN Recovery)
Definition: IScsiProto.c:3125
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
EFI_HANDLE EFIAPI NetLibGetNicHandle(IN EFI_HANDLE Controller, IN EFI_GUID *ProtocolGuid)
Definition: DxeNetLib.c:3019
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibUninstallDriverBindingComponentName2(IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
@ AllHandles
Definition: UefiSpec.h:1509
Definition: Base.h:213