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;
25 ISCSI_FORM_CALLBACK_INFO
*mCallbackInfo
;
27 NET_LIST_ENTRY mIScsiConfigFormList
= {
28 &mIScsiConfigFormList
,
35 IN EFI_IPv4_ADDRESS
*Ip
,
42 Convert the IPv4 address into a dotted string.
46 Ip - The IPv4 address.
47 Str - The dotted IP string.
55 UnicodeSPrint ( Str
, 2 * IP4_STR_MAX_SIZE
, L
"%d.%d.%d.%d", Ip
->Addr
[0], Ip
->Addr
[1], Ip
->Addr
[2], Ip
->Addr
[3]);
66 Pop up an invalid notify which displays the message in Warning.
70 Warning - The warning message.
80 IfrLibCreatePopUp (1, &Key
, Warning
);
84 IScsiUpdateDeviceList (
91 Update the list of iSCSI devices the iSCSI driver is controlling.
104 ISCSI_DEVICE_LIST
*DeviceList
;
110 UINTN LastDeviceIndex
;
111 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
112 EFI_SIMPLE_NETWORK_MODE
*Mode
;
113 ISCSI_MAC_INFO
*CurMacInfo
;
114 ISCSI_MAC_INFO TempMacInfo
;
115 CHAR16 MacString
[65];
116 UINTN DeviceListSize
;
119 // Dump all the handles the Simple Network Protocol is installed on.
121 Status
= gBS
->LocateHandleBuffer (
123 &gEfiSimpleNetworkProtocolGuid
,
128 if (EFI_ERROR (Status
)) {
133 Status
= gRT
->GetVariable (
140 if (Status
== EFI_BUFFER_TOO_SMALL
) {
141 DeviceList
= (ISCSI_DEVICE_LIST
*) NetAllocatePool (DataSize
);
153 for (HandleIndex
= 0; HandleIndex
< NumHandles
; HandleIndex
++) {
154 gBS
->HandleProtocol (Handles
[HandleIndex
], &gEfiSimpleNetworkProtocolGuid
, (VOID
**)&Snp
);
158 for (Index
= LastDeviceIndex
; Index
< DeviceList
->NumDevice
; Index
++) {
159 CurMacInfo
= &DeviceList
->MacInfo
[Index
];
160 if ((CurMacInfo
->Len
== Mode
->HwAddressSize
) &&
161 (NET_MAC_EQUAL (&CurMacInfo
->Mac
, &Mode
->PermanentAddress
, Mode
->HwAddressSize
))
164 // The previous configured NIC is still here.
166 if (Index
!= LastDeviceIndex
) {
168 // Swap the current MAC address entry with the one indexed by
171 NetCopyMem (&TempMacInfo
, CurMacInfo
, sizeof (ISCSI_MAC_INFO
));
172 NetCopyMem (CurMacInfo
, &DeviceList
->MacInfo
[LastDeviceIndex
], sizeof (ISCSI_MAC_INFO
));
173 NetCopyMem (&DeviceList
->MacInfo
[LastDeviceIndex
], &TempMacInfo
, sizeof (ISCSI_MAC_INFO
));
180 if (LastDeviceIndex
== DeviceList
->NumDevice
) {
185 for (Index
= LastDeviceIndex
; Index
< DeviceList
->NumDevice
; Index
++) {
187 // delete the variables
189 CurMacInfo
= &DeviceList
->MacInfo
[Index
];
190 IScsiMacAddrToStr (&CurMacInfo
->Mac
, CurMacInfo
->Len
, MacString
);
191 gRT
->SetVariable (MacString
, &gEfiIScsiInitiatorNameProtocolGuid
, 0, 0, NULL
);
192 gRT
->SetVariable (MacString
, &mIScsiCHAPAuthInfoGuid
, 0, 0, NULL
);
195 NetFreePool (DeviceList
);
196 } else if (Status
!= EFI_NOT_FOUND
) {
197 NetFreePool (Handles
);
201 // Construct the new iSCSI device list.
203 DeviceListSize
= sizeof (ISCSI_DEVICE_LIST
) + (NumHandles
- 1) * sizeof (ISCSI_MAC_INFO
);
204 DeviceList
= (ISCSI_DEVICE_LIST
*) NetAllocatePool (DeviceListSize
);
205 DeviceList
->NumDevice
= (UINT8
) NumHandles
;
207 for (Index
= 0; Index
< NumHandles
; Index
++) {
208 gBS
->HandleProtocol (Handles
[Index
], &gEfiSimpleNetworkProtocolGuid
, (VOID
**)&Snp
);
211 CurMacInfo
= &DeviceList
->MacInfo
[Index
];
212 NetCopyMem (&CurMacInfo
->Mac
, &Mode
->PermanentAddress
, Mode
->HwAddressSize
);
213 CurMacInfo
->Len
= (UINT8
) Mode
->HwAddressSize
;
219 ISCSI_CONFIG_VAR_ATTR
,
224 NetFreePool (DeviceList
);
230 ISCSI_CONFIG_FORM_ENTRY
*
231 IScsiGetConfigFormEntryByIndex (
238 Get the iSCSI configuration form entry by the index of the goto opcode actived.
242 Index - The 0-based index of the goto opcode actived.
246 The iSCSI configuration form entry found.
251 NET_LIST_ENTRY
*Entry
;
252 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
255 ConfigFormEntry
= NULL
;
257 NET_LIST_FOR_EACH (Entry
, &mIScsiConfigFormList
) {
258 if (CurrentIndex
== Index
) {
259 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
266 return ConfigFormEntry
;
271 IScsiConvertDeviceConfigDataToIfrNvData (
272 IN ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
,
273 IN ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
279 Convert the iSCSI configuration data into the IFR data.
283 ConfigFormEntry - The iSCSI configuration form entry.
284 IfrNvData - The IFR nv data.
292 ISCSI_SESSION_CONFIG_NVDATA
*SessionConfigData
;
293 ISCSI_CHAP_AUTH_CONFIG_NVDATA
*AuthConfigData
;
296 // Normal session configuration parameters.
298 SessionConfigData
= &ConfigFormEntry
->SessionConfigData
;
299 IfrNvData
->Enabled
= SessionConfigData
->Enabled
;
301 IfrNvData
->InitiatorInfoFromDhcp
= SessionConfigData
->InitiatorInfoFromDhcp
;
302 IfrNvData
->TargetInfoFromDhcp
= SessionConfigData
->TargetInfoFromDhcp
;
303 IfrNvData
->TargetPort
= SessionConfigData
->TargetPort
;
305 IScsiIpToStr (&SessionConfigData
->LocalIp
, IfrNvData
->LocalIp
);
306 IScsiIpToStr (&SessionConfigData
->SubnetMask
, IfrNvData
->SubnetMask
);
307 IScsiIpToStr (&SessionConfigData
->Gateway
, IfrNvData
->Gateway
);
308 IScsiIpToStr (&SessionConfigData
->TargetIp
, IfrNvData
->TargetIp
);
310 IScsiAsciiStrToUnicodeStr (SessionConfigData
->TargetName
, IfrNvData
->TargetName
);
312 IScsiLunToUnicodeStr (SessionConfigData
->BootLun
, IfrNvData
->BootLun
);
315 // CHAP authentication parameters.
317 AuthConfigData
= &ConfigFormEntry
->AuthConfigData
;
319 IfrNvData
->CHAPType
= AuthConfigData
->CHAPType
;
321 IScsiAsciiStrToUnicodeStr (AuthConfigData
->CHAPName
, IfrNvData
->CHAPName
);
322 IScsiAsciiStrToUnicodeStr (AuthConfigData
->CHAPSecret
, IfrNvData
->CHAPSecret
);
323 IScsiAsciiStrToUnicodeStr (AuthConfigData
->ReverseCHAPName
, IfrNvData
->ReverseCHAPName
);
324 IScsiAsciiStrToUnicodeStr (AuthConfigData
->ReverseCHAPSecret
, IfrNvData
->ReverseCHAPSecret
);
330 IScsiFormExtractConfig (
331 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
332 IN CONST EFI_STRING Request
,
333 OUT EFI_STRING
*Progress
,
334 OUT EFI_STRING
*Results
339 This function allows a caller to extract the current configuration for one
340 or more named elements from the target driver.
343 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
344 Request - A null-terminated Unicode string in <ConfigRequest> format.
345 Progress - On return, points to a character in the Request string.
346 Points to the string's null terminator if request was successful.
347 Points to the most recent '&' before the first failing name/value
348 pair (or the beginning of the string if the failure is in the
349 first name/value pair) if the request was not successful.
350 Results - A null-terminated Unicode string in <ConfigAltResp> format which
351 has all values filled in for the names in the Request string.
352 String to be allocated by the called function.
355 EFI_SUCCESS - The Results is filled with the requested values.
356 EFI_OUT_OF_RESOURCES - Not enough memory to store the results.
357 EFI_INVALID_PARAMETER - Request is NULL, illegal syntax, or unknown name.
358 EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.
363 CHAR8 InitiatorName
[ISCSI_NAME_IFR_MAX_SIZE
];
365 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
366 ISCSI_FORM_CALLBACK_INFO
*Private
;
367 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
369 if (!mIScsiDeviceListUpdated
) {
371 // Update the device list.
373 IScsiUpdateDeviceList ();
374 mIScsiDeviceListUpdated
= TRUE
;
377 Private
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
378 IfrNvData
= AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA
));
379 ASSERT (IfrNvData
!= NULL
);
380 if (Private
->Current
!= NULL
) {
381 IScsiConvertDeviceConfigDataToIfrNvData (Private
->Current
, IfrNvData
);
384 BufferSize
= ISCSI_NAME_IFR_MAX_SIZE
;
385 Status
= gIScsiInitiatorName
.Get (&gIScsiInitiatorName
, &BufferSize
, InitiatorName
);
386 if (EFI_ERROR (Status
)) {
387 IfrNvData
->InitiatorName
[0] = L
'\0';
389 IScsiAsciiStrToUnicodeStr (InitiatorName
, IfrNvData
->InitiatorName
);
393 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
395 HiiConfigRouting
= Private
->ConfigRouting
;
396 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
397 Status
= HiiConfigRouting
->BlockToConfig (
405 NetFreePool (IfrNvData
);
411 IScsiFormRouteConfig (
412 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
413 IN CONST EFI_STRING Configuration
,
414 OUT EFI_STRING
*Progress
419 This function processes the results of changes in configuration.
422 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
423 Configuration - A null-terminated Unicode string in <ConfigResp> format.
424 Progress - A pointer to a string filled in with the offset of the most
425 recent '&' before the first failing name/value pair (or the
426 beginning of the string if the failure is in the first
427 name/value pair) or the terminating NULL if all was successful.
430 EFI_SUCCESS - The Results is processed successfully.
431 EFI_INVALID_PARAMETER - Configuration is NULL.
432 EFI_NOT_FOUND - Routing data doesn't match any storage in this driver.
442 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
443 IN EFI_BROWSER_ACTION Action
,
444 IN EFI_QUESTION_ID KeyValue
,
446 IN EFI_IFR_TYPE_VALUE
*Value
,
447 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
452 This function processes the results of changes in configuration.
455 This - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
456 Action - Specifies the type of action taken by the browser.
457 QuestionId - A unique value which is sent to the original exporting driver
458 so that it can identify the type of data to expect.
459 Type - The type of value for the question.
460 Value - A pointer to the data being sent to the original exporting driver.
461 ActionRequest - On return, points to the action requested by the callback function.
464 EFI_SUCCESS - The callback successfully handled the action.
465 EFI_OUT_OF_RESOURCES - Not enough storage is available to hold the variable and its data.
466 EFI_DEVICE_ERROR - The variable could not be saved.
467 EFI_UNSUPPORTED - The specified Action is not supported by the callback.
471 ISCSI_FORM_CALLBACK_INFO
*Private
;
473 CHAR8 IScsiName
[ISCSI_NAME_IFR_MAX_SIZE
];
474 CHAR16 PortString
[128];
475 CHAR8 Ip4String
[IP4_STR_MAX_SIZE
];
476 CHAR8 LunString
[ISCSI_LUN_STR_MAX_LEN
];
478 STRING_REF DeviceFormTitleToken
;
479 ISCSI_CONFIG_IFR_NVDATA
*IfrNvData
;
480 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
481 EFI_IP_ADDRESS HostIp
;
482 EFI_IP_ADDRESS SubnetMask
;
483 EFI_IP_ADDRESS Gateway
;
486 Private
= ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This
);
489 // Retrive uncommitted data from Browser
491 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
492 IfrNvData
= AllocateZeroPool (BufferSize
);
493 ASSERT (IfrNvData
!= NULL
);
494 Status
= GetBrowserData (NULL
, NULL
, &BufferSize
, (UINT8
*) IfrNvData
);
495 if (EFI_ERROR (Status
)) {
496 gBS
->FreePool (IfrNvData
);
501 case KEY_INITIATOR_NAME
:
502 IScsiUnicodeStrToAsciiStr (IfrNvData
->InitiatorName
, IScsiName
);
503 BufferSize
= AsciiStrLen (IScsiName
) + 1;
505 Status
= gIScsiInitiatorName
.Set (&gIScsiInitiatorName
, &BufferSize
, IScsiName
);
506 if (EFI_ERROR (Status
)) {
507 PopUpInvalidNotify (L
"Invalid iSCSI Name!");
513 IScsiUnicodeStrToAsciiStr (IfrNvData
->LocalIp
, Ip4String
);
514 Status
= IScsiAsciiStrToIp (Ip4String
, &HostIp
.v4
);
515 if (EFI_ERROR (Status
) || !Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
516 PopUpInvalidNotify (L
"Invalid IP address!");
517 Status
= EFI_INVALID_PARAMETER
;
519 NetCopyMem (&Private
->Current
->SessionConfigData
.LocalIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
524 case KEY_SUBNET_MASK
:
525 IScsiUnicodeStrToAsciiStr (IfrNvData
->SubnetMask
, Ip4String
);
526 Status
= IScsiAsciiStrToIp (Ip4String
, &SubnetMask
.v4
);
527 if (EFI_ERROR (Status
) || ((SubnetMask
.Addr
[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask
.v4
) == 0))) {
528 PopUpInvalidNotify (L
"Invalid Subnet Mask!");
529 Status
= EFI_INVALID_PARAMETER
;
531 NetCopyMem (&Private
->Current
->SessionConfigData
.SubnetMask
, &SubnetMask
.v4
, sizeof (SubnetMask
.v4
));
537 IScsiUnicodeStrToAsciiStr (IfrNvData
->Gateway
, Ip4String
);
538 Status
= IScsiAsciiStrToIp (Ip4String
, &Gateway
.v4
);
539 if (EFI_ERROR (Status
) || ((Gateway
.Addr
[0] != 0) && !Ip4IsUnicast (NTOHL (Gateway
.Addr
[0]), 0))) {
540 PopUpInvalidNotify (L
"Invalid Gateway!");
541 Status
= EFI_INVALID_PARAMETER
;
543 NetCopyMem (&Private
->Current
->SessionConfigData
.Gateway
, &Gateway
.v4
, sizeof (Gateway
.v4
));
549 IScsiUnicodeStrToAsciiStr (IfrNvData
->TargetIp
, Ip4String
);
550 Status
= IScsiAsciiStrToIp (Ip4String
, &HostIp
.v4
);
551 if (EFI_ERROR (Status
) || !Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
552 PopUpInvalidNotify (L
"Invalid IP address!");
553 Status
= EFI_INVALID_PARAMETER
;
555 NetCopyMem (&Private
->Current
->SessionConfigData
.TargetIp
, &HostIp
.v4
, sizeof (HostIp
.v4
));
560 case KEY_TARGET_NAME
:
561 IScsiUnicodeStrToAsciiStr (IfrNvData
->TargetName
, IScsiName
);
562 Status
= IScsiNormalizeName (IScsiName
, AsciiStrLen (IScsiName
));
563 if (EFI_ERROR (Status
)) {
564 PopUpInvalidNotify (L
"Invalid iSCSI Name!");
566 AsciiStrCpy (Private
->Current
->SessionConfigData
.TargetName
, IScsiName
);
571 case KEY_DHCP_ENABLE
:
572 if (IfrNvData
->InitiatorInfoFromDhcp
== 0) {
573 IfrNvData
->TargetInfoFromDhcp
= 0;
579 IScsiUnicodeStrToAsciiStr (IfrNvData
->BootLun
, LunString
);
580 Status
= IScsiAsciiStrToLun (LunString
, (UINT8
*) &Lun
);
581 if (EFI_ERROR (Status
)) {
582 PopUpInvalidNotify (L
"Invalid LUN string!");
584 NetCopyMem (Private
->Current
->SessionConfigData
.BootLun
, &Lun
, sizeof (Lun
));
590 IScsiUnicodeStrToAsciiStr (IfrNvData
->CHAPName
, Private
->Current
->AuthConfigData
.CHAPName
);
593 case KEY_CHAP_SECRET
:
594 IScsiUnicodeStrToAsciiStr (IfrNvData
->CHAPSecret
, Private
->Current
->AuthConfigData
.CHAPSecret
);
597 case KEY_REVERSE_CHAP_NAME
:
598 IScsiUnicodeStrToAsciiStr (IfrNvData
->ReverseCHAPName
, Private
->Current
->AuthConfigData
.ReverseCHAPName
);
601 case KEY_REVERSE_CHAP_SECRET
:
602 IScsiUnicodeStrToAsciiStr (IfrNvData
->ReverseCHAPSecret
, Private
->Current
->AuthConfigData
.ReverseCHAPSecret
);
605 case KEY_SAVE_CHANGES
:
607 // First, update those fields which don't have INTERACTIVE set.
609 Private
->Current
->SessionConfigData
.Enabled
= IfrNvData
->Enabled
;
610 Private
->Current
->SessionConfigData
.InitiatorInfoFromDhcp
= IfrNvData
->InitiatorInfoFromDhcp
;
611 Private
->Current
->SessionConfigData
.TargetPort
= IfrNvData
->TargetPort
;
612 if (Private
->Current
->SessionConfigData
.TargetPort
== 0) {
613 Private
->Current
->SessionConfigData
.TargetPort
= ISCSI_WELL_KNOWN_PORT
;
616 Private
->Current
->SessionConfigData
.TargetInfoFromDhcp
= IfrNvData
->TargetInfoFromDhcp
;
617 Private
->Current
->AuthConfigData
.CHAPType
= IfrNvData
->CHAPType
;
620 // Only do full parameter validation if iSCSI is enabled on this device.
622 if (Private
->Current
->SessionConfigData
.Enabled
) {
624 // Validate the address configuration of the Initiator if DHCP isn't
627 if (!Private
->Current
->SessionConfigData
.InitiatorInfoFromDhcp
) {
628 NetCopyMem (&HostIp
.v4
, &Private
->Current
->SessionConfigData
.LocalIp
, sizeof (HostIp
.v4
));
629 NetCopyMem (&SubnetMask
.v4
, &Private
->Current
->SessionConfigData
.SubnetMask
, sizeof (SubnetMask
.v4
));
630 NetCopyMem (&Gateway
.v4
, &Private
->Current
->SessionConfigData
.Gateway
, sizeof (Gateway
.v4
));
632 if ((Gateway
.Addr
[0] != 0)) {
633 if (SubnetMask
.Addr
[0] == 0) {
634 PopUpInvalidNotify (L
"Gateway address is set but subnet mask is zero.");
635 Status
= EFI_INVALID_PARAMETER
;
637 } else if (!IP4_NET_EQUAL (HostIp
.Addr
[0], Gateway
.Addr
[0], SubnetMask
.Addr
[0])) {
638 PopUpInvalidNotify (L
"Local IP and Gateway are not in the same subnet.");
639 Status
= EFI_INVALID_PARAMETER
;
645 // Validate target configuration if DHCP isn't deployed.
647 if (!Private
->Current
->SessionConfigData
.TargetInfoFromDhcp
) {
648 NetCopyMem (&HostIp
.v4
, &Private
->Current
->SessionConfigData
.TargetIp
, sizeof (HostIp
.v4
));
649 if (!Ip4IsUnicast (NTOHL (HostIp
.Addr
[0]), 0)) {
650 PopUpInvalidNotify (L
"Target IP is invalid!");
651 Status
= EFI_INVALID_PARAMETER
;
656 if (IfrNvData
->CHAPType
!= ISCSI_CHAP_NONE
) {
657 if ((IfrNvData
->CHAPName
[0] == '\0') || (IfrNvData
->CHAPSecret
[0] == '\0')) {
658 PopUpInvalidNotify (L
"CHAP Name or CHAP Secret is invalid!");
659 Status
= EFI_INVALID_PARAMETER
;
663 if ((IfrNvData
->CHAPType
== ISCSI_CHAP_MUTUAL
) &&
664 ((IfrNvData
->ReverseCHAPName
[0] == '\0') || (IfrNvData
->ReverseCHAPSecret
[0] == '\0'))
666 PopUpInvalidNotify (L
"Reverse CHAP Name or Reverse CHAP Secret is invalid!");
667 Status
= EFI_INVALID_PARAMETER
;
673 BufferSize
= sizeof (Private
->Current
->SessionConfigData
);
675 Private
->Current
->MacString
,
676 &gEfiIScsiInitiatorNameProtocolGuid
,
677 ISCSI_CONFIG_VAR_ATTR
,
679 &Private
->Current
->SessionConfigData
682 BufferSize
= sizeof (Private
->Current
->AuthConfigData
);
684 Private
->Current
->MacString
,
685 &mIScsiCHAPAuthInfoGuid
,
686 ISCSI_CONFIG_VAR_ATTR
,
688 &Private
->Current
->AuthConfigData
690 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
694 if ((KeyValue
>= KEY_DEVICE_ENTRY_BASE
) && (KeyValue
< (mNumberOfIScsiDevices
+ KEY_DEVICE_ENTRY_BASE
))) {
696 // In case goto the device configuration form, update the device form title.
698 ConfigFormEntry
= IScsiGetConfigFormEntryByIndex ((UINT32
) (KeyValue
- KEY_DEVICE_ENTRY_BASE
));
699 ASSERT (ConfigFormEntry
!= NULL
);
701 UnicodeSPrint (PortString
, (UINTN
) 128, L
"Port %s", ConfigFormEntry
->MacString
);
702 DeviceFormTitleToken
= (STRING_REF
) STR_ISCSI_DEVICE_FORM_TITLE
;
703 IfrLibSetString (Private
->RegisteredHandle
, DeviceFormTitleToken
, PortString
);
705 IScsiConvertDeviceConfigDataToIfrNvData (ConfigFormEntry
, IfrNvData
);
707 Private
->Current
= ConfigFormEntry
;
713 if (!EFI_ERROR (Status
)) {
715 // Pass changed uncommitted data back to Form Browser
717 BufferSize
= sizeof (ISCSI_CONFIG_IFR_NVDATA
);
718 Status
= SetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
721 NetFreePool (IfrNvData
);
727 IScsiConfigUpdateForm (
728 IN EFI_HANDLE DriverBindingHandle
,
729 IN EFI_HANDLE Controller
,
736 Updates the iSCSI configuration form to add/delete an entry for the iSCSI
737 device specified by the Controller.
741 DriverBindingHandle - The driverbinding handle.
742 Controller - The controller handle of the iSCSI device.
743 AddForm - Whether to add or delete a form entry.
747 EFI_SUCCESS - The iSCSI configuration form is updated.
748 EFI_OUT_OF_RESOURCES - Failed to allocate memory.
752 NET_LIST_ENTRY
*Entry
;
753 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
754 BOOLEAN EntryExisted
;
756 EFI_HII_UPDATE_DATA UpdateData
;
757 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
758 CHAR16 PortString
[128];
763 ConfigFormEntry
= NULL
;
764 EntryExisted
= FALSE
;
766 NET_LIST_FOR_EACH (Entry
, &mIScsiConfigFormList
) {
767 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
769 if (ConfigFormEntry
->Controller
== Controller
) {
782 ConfigFormEntry
= (ISCSI_CONFIG_FORM_ENTRY
*) NetAllocateZeroPool (sizeof (ISCSI_CONFIG_FORM_ENTRY
));
783 if (ConfigFormEntry
== NULL
) {
784 return EFI_OUT_OF_RESOURCES
;
787 NetListInit (&ConfigFormEntry
->Link
);
788 ConfigFormEntry
->Controller
= Controller
;
791 // Get the simple network protocol and convert the MAC address into
792 // the formatted string.
794 Status
= gBS
->HandleProtocol (
796 &gEfiSimpleNetworkProtocolGuid
,
799 ASSERT (Status
== EFI_SUCCESS
);
801 IScsiMacAddrToStr (&Snp
->Mode
->PermanentAddress
, Snp
->Mode
->HwAddressSize
, ConfigFormEntry
->MacString
);
804 // Get the normal session configuration data.
806 BufferSize
= sizeof (ConfigFormEntry
->SessionConfigData
);
807 Status
= gRT
->GetVariable (
808 ConfigFormEntry
->MacString
,
809 &gEfiIScsiInitiatorNameProtocolGuid
,
812 &ConfigFormEntry
->SessionConfigData
814 if (EFI_ERROR (Status
)) {
815 NetZeroMem (&ConfigFormEntry
->SessionConfigData
, sizeof (ConfigFormEntry
->SessionConfigData
));
818 // Get the CHAP authentication configuration data.
820 BufferSize
= sizeof (ConfigFormEntry
->AuthConfigData
);
821 Status
= gRT
->GetVariable (
822 ConfigFormEntry
->MacString
,
823 &mIScsiCHAPAuthInfoGuid
,
826 &ConfigFormEntry
->AuthConfigData
828 if (EFI_ERROR (Status
)) {
829 NetZeroMem (&ConfigFormEntry
->AuthConfigData
, sizeof (ConfigFormEntry
->AuthConfigData
));
832 // Compose the Port string and create a new STRING_REF.
834 UnicodeSPrint (PortString
, 128, L
"Port %s", ConfigFormEntry
->MacString
);
835 IfrLibNewString (mCallbackInfo
->RegisteredHandle
, &ConfigFormEntry
->PortTitleToken
, PortString
);
838 // Compose the help string of this port and create a new STRING_REF.
840 UnicodeSPrint (PortString
, 128, L
"Set the iSCSI parameters on port %s", ConfigFormEntry
->MacString
);
841 IfrLibNewString (mCallbackInfo
->RegisteredHandle
, &ConfigFormEntry
->PortTitleHelpToken
, PortString
);
843 NetListInsertTail (&mIScsiConfigFormList
, &ConfigFormEntry
->Link
);
844 mNumberOfIScsiDevices
++;
847 ASSERT (EntryExisted
);
849 mNumberOfIScsiDevices
--;
850 NetListRemoveEntry (&ConfigFormEntry
->Link
);
851 NetFreePool (ConfigFormEntry
);
854 // Allocate space for creation of Buffer
856 UpdateData
.BufferSize
= 0x1000;
857 UpdateData
.Data
= NetAllocateZeroPool (0x1000);
858 UpdateData
.Offset
= 0;
861 NET_LIST_FOR_EACH (Entry
, &mIScsiConfigFormList
) {
862 ConfigFormEntry
= NET_LIST_USER_STRUCT (Entry
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
866 ConfigFormEntry
->PortTitleToken
,
867 ConfigFormEntry
->PortTitleHelpToken
,
868 EFI_IFR_FLAG_CALLBACK
,
869 KEY_DEVICE_ENTRY_BASE
+ FormIndex
,
877 mCallbackInfo
->RegisteredHandle
,
885 NetFreePool (UpdateData
.Data
);
891 IScsiConfigFormInit (
892 IN EFI_HANDLE DriverBindingHandle
898 Initialize the iSCSI configuration form.
902 DriverBindingHandle - The iSCSI driverbinding handle.
906 EFI_SUCCESS - The iSCSI configuration form is initialized.
907 EFI_OUT_OF_RESOURCES - Failed to allocate memory.
912 EFI_HII_DATABASE_PROTOCOL
*HiiDatabase
;
913 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
914 ISCSI_FORM_CALLBACK_INFO
*CallbackInfo
;
916 Status
= gBS
->LocateProtocol (&gEfiHiiDatabaseProtocolGuid
, NULL
, &HiiDatabase
);
917 if (EFI_ERROR (Status
)) {
921 CallbackInfo
= (ISCSI_FORM_CALLBACK_INFO
*) NetAllocatePool (sizeof (ISCSI_FORM_CALLBACK_INFO
));
922 if (CallbackInfo
== NULL
) {
923 return EFI_OUT_OF_RESOURCES
;
926 CallbackInfo
->Signature
= ISCSI_FORM_CALLBACK_INFO_SIGNATURE
;
927 CallbackInfo
->HiiDatabase
= HiiDatabase
;
928 CallbackInfo
->Current
= NULL
;
930 CallbackInfo
->ConfigAccess
.ExtractConfig
= IScsiFormExtractConfig
;
931 CallbackInfo
->ConfigAccess
.RouteConfig
= IScsiFormRouteConfig
;
932 CallbackInfo
->ConfigAccess
.Callback
= IScsiFormCallback
;
934 Status
= gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, &CallbackInfo
->ConfigRouting
);
935 if (EFI_ERROR (Status
)) {
940 // Create driver handle used by HII database
942 Status
= HiiLibCreateHiiDriverHandle (&CallbackInfo
->DriverHandle
);
943 if (EFI_ERROR (Status
)) {
948 // Install Config Access protocol to driver handle
950 Status
= gBS
->InstallProtocolInterface (
951 &CallbackInfo
->DriverHandle
,
952 &gEfiHiiConfigAccessProtocolGuid
,
953 EFI_NATIVE_INTERFACE
,
954 &CallbackInfo
->ConfigAccess
956 ASSERT_EFI_ERROR (Status
);
959 // Publish our HII data
961 PackageList
= PreparePackageList (2, &mVendorGuid
, iSCSIStrings
, IScsiConfigDxeBin
);
962 ASSERT (PackageList
!= NULL
);
964 Status
= HiiDatabase
->NewPackageList (
967 CallbackInfo
->DriverHandle
,
968 &CallbackInfo
->RegisteredHandle
970 NetFreePool (PackageList
);
971 if (EFI_ERROR (Status
)) {
975 mCallbackInfo
= CallbackInfo
;
981 IScsiConfigFormUnload (
982 IN EFI_HANDLE DriverBindingHandle
988 Unload the iSCSI configuration form, this includes: delete all the iSCSI
989 device configuration entries, uninstall the form callback protocol and
990 free the resources used.
994 DriverBindingHandle - The iSCSI driverbinding handle.
998 EFI_SUCCESS - The iSCSI configuration form is unloaded.
999 EFI_OUT_OF_RESOURCES - Failed to allocate memory.
1003 ISCSI_CONFIG_FORM_ENTRY
*ConfigFormEntry
;
1005 while (!NetListIsEmpty (&mIScsiConfigFormList
)) {
1007 // Uninstall the device forms as the iSCSI driver instance may fail to
1008 // control the controller but still install the device configuration form.
1009 // In such case, upon driver unloading, the driver instance's driverbinding.
1010 // stop () won't be called, so we have to take this chance here to uninstall
1013 ConfigFormEntry
= NET_LIST_USER_STRUCT (mIScsiConfigFormList
.ForwardLink
, ISCSI_CONFIG_FORM_ENTRY
, Link
);
1014 IScsiConfigUpdateForm (DriverBindingHandle
, ConfigFormEntry
->Controller
, FALSE
);
1018 // Remove HII package list
1020 mCallbackInfo
->HiiDatabase
->RemovePackageList (
1021 mCallbackInfo
->HiiDatabase
,
1022 mCallbackInfo
->RegisteredHandle
1026 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
1028 gBS
->UninstallProtocolInterface (
1029 mCallbackInfo
->DriverHandle
,
1030 &gEfiHiiConfigAccessProtocolGuid
,
1031 &mCallbackInfo
->ConfigAccess
1033 HiiLibDestroyHiiDriverHandle (mCallbackInfo
->DriverHandle
);
1035 NetFreePool (mCallbackInfo
);