3 Copyright (c) 2007 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
20 #include "IScsiImpl.h"
22 EFI_GUID mVendorGuid
= ISCSI_CONFIG_GUID
;
23 BOOLEAN mIScsiDeviceListUpdated
= FALSE
;
24 UINTN mNumberOfIScsiDevices
= 0;
26 NET_LIST_ENTRY mIScsiConfigFormList
= {
27 &mIScsiConfigFormList
,
34 IN EFI_IPv4_ADDRESS
*Ip
,
41 Convert the IPv4 address into a dotted string.
45 Ip - The IPv4 address.
46 Str - The dotted IP string.
54 UnicodeSPrint ( Str
, 2 * IP4_STR_MAX_SIZE
, L
"%d.%d.%d.%d", Ip
->Addr
[0], Ip
->Addr
[1], Ip
->Addr
[2], Ip
->Addr
[3]);
65 Pop up an invalid notify which displays the message in Warning.
69 Warning - The warning message.
77 EFI_FORM_BROWSER_PROTOCOL
*FormBrowser
;
82 Status
= gBS
->LocateProtocol (
83 &gEfiFormBrowserProtocolGuid
,
87 if (EFI_ERROR (Status
)) {
91 FormBrowser
->CreatePopUp (1, TRUE
, 10, Buffer
, &Key
, Warning
);
95 IScsiUpdateDeviceList (
102 Update the list of iSCSI devices the iSCSI driver is controlling.
115 ISCSI_DEVICE_LIST
*DeviceList
;
121 UINTN LastDeviceIndex
;
122 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
123 EFI_SIMPLE_NETWORK_MODE
*Mode
;
124 ISCSI_MAC_INFO
*CurMacInfo
;
125 ISCSI_MAC_INFO TempMacInfo
;
126 CHAR16 MacString
[65];
127 UINTN DeviceListSize
;
130 // Dump all the handles the Simple Network Protocol is installed on.
132 Status
= gBS
->LocateHandleBuffer (
134 &gEfiSimpleNetworkProtocolGuid
,
139 if (EFI_ERROR (Status
)) {
144 Status
= gRT
->GetVariable (
151 if (Status
== EFI_BUFFER_TOO_SMALL
) {
152 DeviceList
= (ISCSI_DEVICE_LIST
*) NetAllocatePool (DataSize
);
164 for (HandleIndex
= 0; HandleIndex
< NumHandles
; HandleIndex
++) {
165 gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleNetworkProtocolGuid
, (VOID
**)&Snp
);
169 for (Index
= LastDeviceIndex
; Index
< DeviceList
->NumDevice
; Index
++) {
170 CurMacInfo
= &DeviceList
->MacInfo
[Index
];
171 if ((CurMacInfo
->Len
== Mode
->HwAddressSize
) &&
172 (NET_MAC_EQUAL (&CurMacInfo
->Mac
, &Mode
->PermanentAddress
, Mode
->HwAddressSize
))
175 // The previous configured NIC is still here.
177 if (Index
!= LastDeviceIndex
) {
179 // Swap the current MAC address entry with the one indexed by
182 NetCopyMem (&TempMacInfo
, CurMacInfo
, sizeof (ISCSI_MAC_INFO
));
183 NetCopyMem (CurMacInfo
, &DeviceList
->MacInfo
[LastDeviceIndex
], sizeof (ISCSI_MAC_INFO
));
184 NetCopyMem (&DeviceList
->MacInfo
[LastDeviceIndex
], &TempMacInfo
, sizeof (ISCSI_MAC_INFO
));
191 if (LastDeviceIndex
== DeviceList
->NumDevice
) {
196 for (Index
= LastDeviceIndex
; Index
< DeviceList
->NumDevice
; Index
++) {
198 // delete the variables
200 CurMacInfo
= &DeviceList
->MacInfo
[Index
];
201 IScsiMacAddrToStr (&CurMacInfo
->Mac
, CurMacInfo
->Len
, MacString
);
202 gRT
->SetVariable (MacString
, &gEfiIScsiInitiatorNameProtocolGuid
, 0, 0, NULL
);
203 gRT
->SetVariable (MacString
, &mIScsiCHAPAuthInfoGuid
, 0, 0, NULL
);
206 NetFreePool (DeviceList
);
207 } else if (Status
!= EFI_NOT_FOUND
) {
208 NetFreePool (Handles
);
212 // Construct the new iSCSI device list.
214 DeviceListSize
= sizeof (ISCSI_DEVICE_LIST
) + (NumHandles
- 1) * sizeof (ISCSI_MAC_INFO
);
215 DeviceList
= (ISCSI_DEVICE_LIST
*) NetAllocatePool (DeviceListSize
);
216 DeviceList
->NumDevice
= (UINT8
) NumHandles
;
218 for (Index
= 0; Index
< NumHandles
; Index
++) {
219 gBS
->HandleProtocol (Handles
[Index
], &gEfiSimpleNetworkProtocolGuid
, (VOID
**)&Snp
);
222 CurMacInfo
= &DeviceList
->MacInfo
[Index
];
223 NetCopyMem (&CurMacInfo
->Mac
, &Mode
->PermanentAddress
, Mode
->HwAddressSize
);
224 CurMacInfo
->Len
= (UINT8
) Mode
->HwAddressSize
;
230 ISCSI_CONFIG_VAR_ATTR
,
235 NetFreePool (DeviceList
);
241 ISCSI_CONFIG_FORM_ENTRY
*
242 IScsiGetConfigFormEntryByIndex (
249 Get the iSCSI configuration form entry by the index of the goto opcode actived.
253 Index - The 0-based index of the goto opcode actived.
257 The iSCSI configuration form entry found.
262 NET_LIST_ENTRY
*Entry
;
263 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
266 ConfigFormEntry
= NULL
;
268 NET_LIST_FOR_EACH (Entry
, &mIScsiConfigFormList
) {
269 if (CurrentIndex
== Index
) {
270 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
277 return ConfigFormEntry
;
282 IScsiConvertDeviceConfigDataToIfrNvData (
283 IN ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
,
284 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
290 Convert the iSCSI configuration data into the IFR data.
294 ConfigFormEntry - The iSCSI configuration form entry.
295 IfrNvData - The IFR nv data.
303 ISCSI_SESSION_CONFIG_NVDATA
*SessionConfigData
;
304 ISCSI_CHAP_AUTH_CONFIG_NVDATA
*AuthConfigData
;
307 // Normal session configuration parameters.
309 SessionConfigData
= &ConfigFormEntry
->SessionConfigData
;
310 IfrNvData
->Enabled
= SessionConfigData
->Enabled
;
312 IfrNvData
->InitiatorInfoFromDhcp
= SessionConfigData
->InitiatorInfoFromDhcp
;
313 IfrNvData
->TargetInfoFromDhcp
= SessionConfigData
->TargetInfoFromDhcp
;
314 IfrNvData
->TargetPort
= SessionConfigData
->TargetPort
;
316 IScsiIpToStr (&SessionConfigData
->LocalIp
, IfrNvData
->LocalIp
);
317 IScsiIpToStr (&SessionConfigData
->SubnetMask
, IfrNvData
->SubnetMask
);
318 IScsiIpToStr (&SessionConfigData
->Gateway
, IfrNvData
->Gateway
);
319 IScsiIpToStr (&SessionConfigData
->TargetIp
, IfrNvData
->TargetIp
);
321 IScsiAsciiStrToUnicodeStr (SessionConfigData
->TargetName
, IfrNvData
->TargetName
);
323 IScsiLunToUnicodeStr (SessionConfigData
->BootLun
, IfrNvData
->BootLun
);
326 // CHAP authentication parameters.
328 AuthConfigData
= &ConfigFormEntry
->AuthConfigData
;
330 IfrNvData
->CHAPType
= AuthConfigData
->CHAPType
;
332 IScsiAsciiStrToUnicodeStr (AuthConfigData
->CHAPName
, IfrNvData
->CHAPName
);
333 IScsiAsciiStrToUnicodeStr (AuthConfigData
->CHAPSecret
, IfrNvData
->CHAPSecret
);
334 IScsiAsciiStrToUnicodeStr (AuthConfigData
->ReverseCHAPName
, IfrNvData
->ReverseCHAPName
);
335 IScsiAsciiStrToUnicodeStr (AuthConfigData
->ReverseCHAPSecret
, IfrNvData
->ReverseCHAPSecret
);
341 IN EFI_FORM_CALLBACK_PROTOCOL
* This
,
342 IN CHAR16
*VariableName
,
343 IN EFI_GUID
* VendorGuid
,
344 OUT UINT32
*Attributes OPTIONAL
,
345 IN OUT UINTN
*DataSize
,
352 NV read function for the iSCSI form callback protocol.
356 This - The EFI form callback protocol instance.
357 VariableName - Name of the variable to read.
358 VendorGuid - Guid of the variable to read.
359 Attributes - The storage to get the attributes of the variable.
360 DataSize - The size of the buffer to store the variable.
361 Buffer - The buffer to store the variable to read.
365 EFI_SUCCESS - The variable is read.
366 EFI_BUFFER_TOO_SMALL - The buffer provided is too small to hold the variable.
371 CHAR8 InitiatorName
[ISCSI_NAME_IFR_MAX_SIZE
];
373 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
375 if (!mIScsiDeviceListUpdated
) {
377 // Update the device list.
379 IScsiUpdateDeviceList ();
380 mIScsiDeviceListUpdated
= TRUE
;
383 IfrNvData
= (ISCSI_CONFIG_IFR_NVDATA
*) Buffer
;
384 BufferSize
= ISCSI_NAME_IFR_MAX_SIZE
;
386 Status
= gIScsiInitiatorName
.Get (&gIScsiInitiatorName
, &BufferSize
, InitiatorName
);
387 if (EFI_ERROR (Status
)) {
388 IfrNvData
->InitiatorName
[0] = L
'\0';
390 IScsiAsciiStrToUnicodeStr (InitiatorName
, IfrNvData
->InitiatorName
);
399 IN EFI_FORM_CALLBACK_PROTOCOL
*This
,
401 IN EFI_IFR_DATA_ARRAY
*Data
,
402 OUT EFI_HII_CALLBACK_PACKET
**Packet
408 The form callback function for iSCSI form callback protocol, it processes
409 the events tiggered in the UI and take some operations to update the form,
414 This - The EFI form callback protocol instance.
415 KeyValue - A unique value which is sent to the original exporting driver so that it
416 can identify the type of data to expect. The format of the data tends to
417 vary based on the op-code that geerated the callback.
418 Data - A pointer to the data being sent to the original exporting driver.
422 EFI_SUCCESS - The data is valid and the correspondance operation is done.
423 EFI_INVALID_PARAMETER - The data is invalid.
427 ISCSI_FORM_CALLBACK_INFO
*Private
;
429 CHAR8 IScsiName
[ISCSI_NAME_IFR_MAX_SIZE
];
430 CHAR16 PortString
[128];
431 CHAR8 Ip4String
[IP4_STR_MAX_SIZE
];
432 CHAR8 LunString
[ISCSI_LUN_STR_MAX_LEN
];
434 STRING_REF DeviceFormTitleToken
;
435 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
436 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
437 EFI_IP_ADDRESS HostIp
;
438 EFI_IP_ADDRESS SubnetMask
;
439 EFI_IP_ADDRESS Gateway
;
442 Private
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
443 IfrNvData
= (ISCSI_CONFIG_IFR_NVDATA
*) Data
->NvRamMap
;
444 Status
= EFI_SUCCESS
;
447 case KEY_INITIATOR_NAME
:
448 IScsiUnicodeStrToAsciiStr (IfrNvData
->InitiatorName
, IScsiName
);
449 BufferSize
= AsciiStrLen (IScsiName
) + 1;
451 Status
= gIScsiInitiatorName
.Set (&gIScsiInitiatorName
, &BufferSize
, IScsiName
);
452 if (EFI_ERROR (Status
)) {
453 PopUpInvalidNotify (L
"Invalid iSCSI Name!");
459 IScsiUnicodeStrToAsciiStr (IfrNvData
->LocalIp
, Ip4String
);
460 Status
= IScsiAsciiStrToIp (Ip4String
, &HostIp
.v4
);
461 if (EFI_ERROR (Status
) || !Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
462 PopUpInvalidNotify (L
"Invalid IP address!");
463 Status
= EFI_INVALID_PARAMETER
;
465 NetCopyMem (&Private
->Current
->SessionConfigData
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
470 case KEY_SUBNET_MASK
:
471 IScsiUnicodeStrToAsciiStr (IfrNvData
->SubnetMask
, Ip4String
);
472 Status
= IScsiAsciiStrToIp (Ip4String
, &SubnetMask
.v4
);
473 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
474 PopUpInvalidNotify (L
"Invalid Subnet Mask!");
475 Status
= EFI_INVALID_PARAMETER
;
477 NetCopyMem (&Private
->Current
->SessionConfigData
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
483 IScsiUnicodeStrToAsciiStr (IfrNvData
->Gateway
, Ip4String
);
484 Status
= IScsiAsciiStrToIp (Ip4String
, &Gateway
.v4
);
485 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !Ip4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
486 PopUpInvalidNotify (L
"Invalid Gateway!");
487 Status
= EFI_INVALID_PARAMETER
;
489 NetCopyMem (&Private
->Current
->SessionConfigData
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
495 IScsiUnicodeStrToAsciiStr (IfrNvData
->TargetIp
, Ip4String
);
496 Status
= IScsiAsciiStrToIp (Ip4String
, &HostIp
.v4
);
497 if (EFI_ERROR (Status
) || !Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
498 PopUpInvalidNotify (L
"Invalid IP address!");
499 Status
= EFI_INVALID_PARAMETER
;
501 NetCopyMem (&Private
->Current
->SessionConfigData
.TargetIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
506 case KEY_TARGET_NAME
:
507 IScsiUnicodeStrToAsciiStr (IfrNvData
->TargetName
, IScsiName
);
508 Status
= IScsiNormalizeName (IScsiName
, AsciiStrLen (IScsiName
));
509 if (EFI_ERROR (Status
)) {
510 PopUpInvalidNotify (L
"Invalid iSCSI Name!");
512 AsciiStrCpy (Private
->Current
->SessionConfigData
.TargetName
, IScsiName
);
517 case KEY_DHCP_ENABLE
:
518 if (IfrNvData
->InitiatorInfoFromDhcp
== 0) {
519 IfrNvData
->TargetInfoFromDhcp
= 0;
525 IScsiUnicodeStrToAsciiStr (IfrNvData
->BootLun
, LunString
);
526 Status
= IScsiAsciiStrToLun (LunString
, (UINT8
*) &Lun
);
527 if (EFI_ERROR (Status
)) {
528 PopUpInvalidNotify (L
"Invalid LUN string!");
530 NetCopyMem (Private
->Current
->SessionConfigData
.BootLun
, &Lun
, sizeof (Lun
));
536 IScsiUnicodeStrToAsciiStr (IfrNvData
->CHAPName
, Private
->Current
->AuthConfigData
.CHAPName
);
539 case KEY_CHAP_SECRET
:
540 IScsiUnicodeStrToAsciiStr (IfrNvData
->CHAPSecret
, Private
->Current
->AuthConfigData
.CHAPSecret
);
543 case KEY_REVERSE_CHAP_NAME
:
544 IScsiUnicodeStrToAsciiStr (IfrNvData
->ReverseCHAPName
, Private
->Current
->AuthConfigData
.ReverseCHAPName
);
547 case KEY_REVERSE_CHAP_SECRET
:
548 IScsiUnicodeStrToAsciiStr (IfrNvData
->ReverseCHAPSecret
, Private
->Current
->AuthConfigData
.ReverseCHAPSecret
);
551 case KEY_SAVE_CHANGES
:
553 // First, update those fields which don't have INTERACTIVE set.
555 Private
->Current
->SessionConfigData
.Enabled
= IfrNvData
->Enabled
;
556 Private
->Current
->SessionConfigData
.InitiatorInfoFromDhcp
= IfrNvData
->InitiatorInfoFromDhcp
;
557 Private
->Current
->SessionConfigData
.TargetPort
= IfrNvData
->TargetPort
;
558 if (Private
->Current
->SessionConfigData
.TargetPort
== 0) {
559 Private
->Current
->SessionConfigData
.TargetPort
= ISCSI_WELL_KNOWN_PORT
;
562 Private
->Current
->SessionConfigData
.TargetInfoFromDhcp
= IfrNvData
->TargetInfoFromDhcp
;
563 Private
->Current
->AuthConfigData
.CHAPType
= IfrNvData
->CHAPType
;
566 // Only do full parameter validation if iSCSI is enabled on this device.
568 if (Private
->Current
->SessionConfigData
.Enabled
) {
570 // Validate the address configuration of the Initiator if DHCP isn't
573 if (!Private
->Current
->SessionConfigData
.InitiatorInfoFromDhcp
) {
574 NetCopyMem (&HostIp
.v4
, &Private
->Current
->SessionConfigData
.LocalIp
, sizeof (HostIp
.v4
));
575 NetCopyMem (&SubnetMask
.v4
, &Private
->Current
->SessionConfigData
.SubnetMask
, sizeof (SubnetMask
.v4
));
576 NetCopyMem (&Gateway
.v4
, &Private
->Current
->SessionConfigData
.Gateway
, sizeof (Gateway
.v4
));
578 if ((Gateway
.Addr
[0] != 0)) {
579 if (SubnetMask
.Addr
[0] == 0) {
580 PopUpInvalidNotify (L
"Gateway address is set but subnet mask is zero.");
581 Status
= EFI_INVALID_PARAMETER
;
583 } else if (!IP4_NET_EQUAL (HostIp
.Addr
[0], Gateway
.Addr
[0], SubnetMask
.Addr
[0])) {
584 PopUpInvalidNotify (L
"Local IP and Gateway are not in the same subnet.");
585 Status
= EFI_INVALID_PARAMETER
;
591 // Validate target configuration if DHCP isn't deployed.
593 if (!Private
->Current
->SessionConfigData
.TargetInfoFromDhcp
) {
594 NetCopyMem (&HostIp
.v4
, &Private
->Current
->SessionConfigData
.TargetIp
, sizeof (HostIp
.v4
));
595 if (!Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
596 PopUpInvalidNotify (L
"Target IP is invalid!");
597 Status
= EFI_INVALID_PARAMETER
;
602 if (IfrNvData
->CHAPType
!= ISCSI_CHAP_NONE
) {
603 if ((IfrNvData
->CHAPName
[0] == '\0') || (IfrNvData
->CHAPSecret
[0] == '\0')) {
604 PopUpInvalidNotify (L
"CHAP Name or CHAP Secret is invalid!");
605 Status
= EFI_INVALID_PARAMETER
;
609 if ((IfrNvData
->CHAPType
== ISCSI_CHAP_MUTUAL
) &&
610 ((IfrNvData
->ReverseCHAPName
[0] == '\0') || (IfrNvData
->ReverseCHAPSecret
[0] == '\0'))
612 PopUpInvalidNotify (L
"Reverse CHAP Name or Reverse CHAP Secret is invalid!");
613 Status
= EFI_INVALID_PARAMETER
;
619 BufferSize
= sizeof (Private
->Current
->SessionConfigData
);
621 Private
->Current
->MacString
,
622 &gEfiIScsiInitiatorNameProtocolGuid
,
623 ISCSI_CONFIG_VAR_ATTR
,
625 &Private
->Current
->SessionConfigData
628 BufferSize
= sizeof (Private
->Current
->AuthConfigData
);
630 Private
->Current
->MacString
,
631 &mIScsiCHAPAuthInfoGuid
,
632 ISCSI_CONFIG_VAR_ATTR
,
634 &Private
->Current
->AuthConfigData
640 if ((KeyValue
>= KEY_DEVICE_ENTRY_BASE
) && (KeyValue
< (mNumberOfIScsiDevices
+ KEY_DEVICE_ENTRY_BASE
))) {
642 // In case goto the device configuration form, update the device form title.
644 ConfigFormEntry
= IScsiGetConfigFormEntryByIndex ((UINT32
) (KeyValue
- KEY_DEVICE_ENTRY_BASE
));
645 ASSERT (ConfigFormEntry
!= NULL
);
647 UnicodeSPrint (PortString
, 128, L
"Port %s", ConfigFormEntry
->MacString
);
648 DeviceFormTitleToken
= (STRING_REF
) STR_ISCSI_DEVICE_FORM_TITLE
;
650 Private
->Hii
->NewString (
653 Private
->RegisteredHandle
,
654 &DeviceFormTitleToken
,
658 IScsiConvertDeviceConfigDataToIfrNvData (ConfigFormEntry
, IfrNvData
);
660 Private
->Current
= ConfigFormEntry
;
670 IScsiConfigUpdateForm (
671 IN EFI_HANDLE DriverBindingHandle
,
672 IN EFI_HANDLE Controller
,
679 Updates the iSCSI configuration form to add/delete an entry for the iSCSI
680 device specified by the Controller.
684 DriverBindingHandle - The driverbinding handle.
685 Controller - The controller handle of the iSCSI device.
686 AddForm - Whether to add or delete a form entry.
690 EFI_SUCCESS - The iSCSI configuration form is updated.
691 EFI_OUT_OF_RESOURCES - Failed to allocate memory.
695 NET_LIST_ENTRY
*Entry
;
696 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
697 BOOLEAN EntryExisted
;
698 EFI_HII_UPDATE_DATA
*UpdateData
;
700 EFI_FORM_CALLBACK_PROTOCOL
*Callback
;
701 ISCSI_FORM_CALLBACK_INFO
*CallbackInfo
;
702 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
703 CHAR16 PortString
[128];
708 // Get the EFI_FORM_CALLBACK_PROTOCOL.
710 Status
= gBS
->HandleProtocol (
712 &gEfiFormCallbackProtocolGuid
,
715 if (EFI_ERROR (Status
)) {
719 CallbackInfo
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (Callback
);
721 ConfigFormEntry
= NULL
;
722 EntryExisted
= FALSE
;
724 NET_LIST_FOR_EACH (Entry
, &mIScsiConfigFormList
) {
725 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
727 if (ConfigFormEntry
->Controller
== Controller
) {
740 ConfigFormEntry
= (ISCSI_CONFIG_FORM_ENTRY
*) NetAllocateZeroPool (sizeof (ISCSI_CONFIG_FORM_ENTRY
));
741 if (ConfigFormEntry
== NULL
) {
742 return EFI_OUT_OF_RESOURCES
;
745 NetListInit (&ConfigFormEntry
->Link
);
746 ConfigFormEntry
->Controller
= Controller
;
749 // Get the simple network protocol and convert the MAC address into
750 // the formatted string.
752 Status
= gBS
->HandleProtocol (
754 &gEfiSimpleNetworkProtocolGuid
,
757 ASSERT (Status
== EFI_SUCCESS
);
759 IScsiMacAddrToStr (&Snp
->Mode
->PermanentAddress
, Snp
->Mode
->HwAddressSize
, ConfigFormEntry
->MacString
);
762 // Get the normal session configuration data.
764 BufferSize
= sizeof (ConfigFormEntry
->SessionConfigData
);
765 Status
= gRT
->GetVariable (
766 ConfigFormEntry
->MacString
,
767 &gEfiIScsiInitiatorNameProtocolGuid
,
770 &ConfigFormEntry
->SessionConfigData
772 if (EFI_ERROR (Status
)) {
773 NetZeroMem (&ConfigFormEntry
->SessionConfigData
, sizeof (ConfigFormEntry
->SessionConfigData
));
776 // Get the CHAP authentication configuration data.
778 BufferSize
= sizeof (ConfigFormEntry
->AuthConfigData
);
779 Status
= gRT
->GetVariable (
780 ConfigFormEntry
->MacString
,
781 &mIScsiCHAPAuthInfoGuid
,
784 &ConfigFormEntry
->AuthConfigData
786 if (EFI_ERROR (Status
)) {
787 NetZeroMem (&ConfigFormEntry
->AuthConfigData
, sizeof (ConfigFormEntry
->AuthConfigData
));
790 // Compose the Port string and create a new STRING_REF.
792 UnicodeSPrint (PortString
, 128, L
"Port %s", ConfigFormEntry
->MacString
);
793 CallbackInfo
->Hii
->NewString (
796 CallbackInfo
->RegisteredHandle
,
797 &ConfigFormEntry
->PortTitleToken
,
802 // Compose the help string of this port and create a new STRING_REF.
804 UnicodeSPrint (PortString
, 128, L
"Set the iSCSI parameters on port %s", ConfigFormEntry
->MacString
);
805 CallbackInfo
->Hii
->NewString (
808 CallbackInfo
->RegisteredHandle
,
809 &ConfigFormEntry
->PortTitleHelpToken
,
813 NetListInsertTail (&mIScsiConfigFormList
, &ConfigFormEntry
->Link
);
814 mNumberOfIScsiDevices
++;
817 ASSERT (EntryExisted
);
819 mNumberOfIScsiDevices
--;
820 NetListRemoveEntry (&ConfigFormEntry
->Link
);
821 NetFreePool (ConfigFormEntry
);
824 // Allocate space for creation of Buffer
826 UpdateData
= (EFI_HII_UPDATE_DATA
*) NetAllocatePool (0x1000);
827 NetZeroMem (UpdateData
, 0x1000);
830 // Flag update pending in FormSet
832 UpdateData
->FormSetUpdate
= TRUE
;
835 // Register CallbackHandle data for FormSet
837 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) CallbackInfo
->CallbackHandle
;
838 UpdateData
->FormUpdate
= FALSE
;
839 UpdateData
->FormTitle
= 0;
842 // first of all, remove all the forms.
844 UpdateData
->DataCount
= 0xFF;
846 CallbackInfo
->Hii
->UpdateForm (
848 CallbackInfo
->RegisteredHandle
,
849 (EFI_FORM_LABEL
) DEVICE_ENTRY_LABEL
,
854 UpdateData
->DataCount
= 1;
857 NET_LIST_FOR_EACH (Entry
, &mIScsiConfigFormList
) {
858 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
862 ConfigFormEntry
->PortTitleToken
,
863 ConfigFormEntry
->PortTitleHelpToken
,
864 EFI_IFR_FLAG_INTERACTIVE
,
865 (UINT16
) (KEY_DEVICE_ENTRY_BASE
+ FormIndex
),
869 CallbackInfo
->Hii
->UpdateForm (
871 CallbackInfo
->RegisteredHandle
,
872 (EFI_FORM_LABEL
) DEVICE_ENTRY_LABEL
,
880 NetFreePool (UpdateData
);
886 IScsiConfigFormInit (
887 IN EFI_HANDLE DriverBindingHandle
893 Initialize the iSCSI configuration form.
897 DriverBindingHandle - The iSCSI driverbinding handle.
901 EFI_SUCCESS - The iSCSI configuration form is initialized.
902 EFI_OUT_OF_RESOURCES - Failed to allocate memory.
907 EFI_HII_PROTOCOL
*Hii
;
908 EFI_HII_PACKAGES
*PackageList
;
909 EFI_HII_HANDLE HiiHandle
;
910 EFI_HII_UPDATE_DATA
*UpdateData
;
911 ISCSI_FORM_CALLBACK_INFO
*CallbackInfo
;
912 EFI_GUID StringPackGuid
= ISCSI_CONFIG_GUID
;
914 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**)&Hii
);
915 if (EFI_ERROR (Status
)) {
919 CallbackInfo
= (ISCSI_FORM_CALLBACK_INFO
*) NetAllocatePool (sizeof (ISCSI_FORM_CALLBACK_INFO
));
920 if (CallbackInfo
== NULL
) {
921 return EFI_OUT_OF_RESOURCES
;
924 CallbackInfo
->Signature
= ISCSI_FORM_CALLBACK_INFO_SIGNATURE
;
925 CallbackInfo
->Hii
= Hii
;
926 CallbackInfo
->Current
= NULL
;
928 CallbackInfo
->FormCallback
.NvRead
= IScsiFormNvRead
;
929 CallbackInfo
->FormCallback
.NvWrite
= NULL
;
930 CallbackInfo
->FormCallback
.Callback
= IScsiFormCallback
;
933 // Install protocol interface
935 Status
= gBS
->InstallProtocolInterface (
936 &DriverBindingHandle
,
937 &gEfiFormCallbackProtocolGuid
,
938 EFI_NATIVE_INTERFACE
,
939 &CallbackInfo
->FormCallback
942 ASSERT_EFI_ERROR (Status
);
944 CallbackInfo
->CallbackHandle
= DriverBindingHandle
;
945 PackageList
= PreparePackages (2, &StringPackGuid
, iSCSIStrings
, IScsiConfigDxeBin
);
946 Status
= Hii
->NewPack (Hii
, PackageList
, &HiiHandle
);
947 NetFreePool (PackageList
);
949 CallbackInfo
->RegisteredHandle
= HiiHandle
;
952 // Allocate space for creation of Buffer
954 UpdateData
= (EFI_HII_UPDATE_DATA
*) NetAllocatePool (0x1000);
955 ASSERT (UpdateData
!= NULL
);
956 if (UpdateData
== NULL
) {
957 return EFI_OUT_OF_RESOURCES
;
960 NetZeroMem (UpdateData
, 0x1000);
963 // Flag update pending in FormSet
965 UpdateData
->FormSetUpdate
= TRUE
;
968 // Register CallbackHandle data for FormSet
970 UpdateData
->FormCallbackHandle
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) CallbackInfo
->CallbackHandle
;
971 UpdateData
->FormUpdate
= FALSE
;
972 UpdateData
->FormTitle
= 0;
973 UpdateData
->DataCount
= 0x1;
975 Hii
->UpdateForm (Hii
, HiiHandle
, (EFI_FORM_LABEL
) 0x1000, TRUE
, UpdateData
);
977 NetFreePool (UpdateData
);
983 IScsiConfigFormUnload (
984 IN EFI_HANDLE DriverBindingHandle
990 Unload the iSCSI configuration form, this includes: delete all the iSCSI
991 device configuration entries, uninstall the form callback protocol and
992 free the resources used.
996 DriverBindingHandle - The iSCSI driverbinding handle.
1000 EFI_SUCCESS - The iSCSI configuration form is unloaded.
1001 EFI_OUT_OF_RESOURCES - Failed to allocate memory.
1005 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
1007 EFI_HII_PROTOCOL
*Hii
;
1008 EFI_HII_UPDATE_DATA
*UpdateData
;
1009 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
1010 ISCSI_FORM_CALLBACK_INFO
*CallbackInfo
;
1012 while (!NetListIsEmpty (&mIScsiConfigFormList
)) {
1014 // Uninstall the device forms as the iSCSI driver instance may fail to
1015 // control the controller but still install the device configuration form.
1016 // In such case, upon driver unloading, the driver instance's driverbinding.
1017 // stop () won't be called, so we have to take this chance here to uninstall
1020 ConfigFormEntry
= NET_LIST_USER_STRUCT (mIScsiConfigFormList
.ForwardLink
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
1021 IScsiConfigUpdateForm (DriverBindingHandle
, ConfigFormEntry
->Controller
, FALSE
);
1024 Status
= gBS
->LocateProtocol (&gEfiHiiProtocolGuid
, NULL
, (VOID
**)&Hii
);
1025 if (EFI_ERROR (Status
)) {
1029 Status
= gBS
->HandleProtocol (DriverBindingHandle
, &gEfiFormCallbackProtocolGuid
, (VOID
**)&FormCallback
);
1030 if (EFI_ERROR (Status
)) {
1034 CallbackInfo
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (FormCallback
);
1039 UpdateData
= (EFI_HII_UPDATE_DATA
*) NetAllocatePool (0x1000);
1040 ASSERT (UpdateData
!= NULL
);
1041 if (UpdateData
== NULL
) {
1042 return EFI_OUT_OF_RESOURCES
;
1045 NetZeroMem (UpdateData
, 0x1000);
1047 UpdateData
->FormSetUpdate
= FALSE
;
1048 UpdateData
->FormCallbackHandle
= 0;
1049 UpdateData
->FormUpdate
= FALSE
;
1050 UpdateData
->FormTitle
= 0;
1051 UpdateData
->DataCount
= 0xFF;
1053 Hii
->UpdateForm (Hii
, CallbackInfo
->RegisteredHandle
, (EFI_FORM_LABEL
) 0x1000, FALSE
, UpdateData
);
1055 NetFreePool (UpdateData
);
1058 // Uninstall the EFI_FORM_CALLBACK_PROTOCOL.
1060 gBS
->UninstallProtocolInterface (
1061 DriverBindingHandle
,
1062 &gEfiFormCallbackProtocolGuid
,
1067 // Remove the package.
1069 Hii
->RemovePack (Hii
, CallbackInfo
->RegisteredHandle
);
1071 NetFreePool (CallbackInfo
);