]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c
Add UefiHiiServicesLib library instance in every one DSC
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiConfig.c
CommitLineData
12618416 1/** @file\r
55a64ae0 2 Helper functions for configuring or getting the parameters relating to iSCSI.\r
6a690e23 3\r
669314e5 4Copyright (c) 2004 - 2008, Intel Corporation.<BR>\r
7a444476 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 12\r
12618416 13**/\r
6a690e23 14\r
15#include "IScsiImpl.h"\r
16\r
f2a94e25 17EFI_GUID mVendorGuid = ISCSI_CONFIG_GUID;\r
18BOOLEAN mIScsiDeviceListUpdated = FALSE;\r
19UINTN mNumberOfIScsiDevices = 0;\r
20ISCSI_FORM_CALLBACK_INFO *mCallbackInfo = NULL;\r
6a690e23 21\r
e48e37fc 22LIST_ENTRY mIScsiConfigFormList = {\r
6a690e23 23 &mIScsiConfigFormList,\r
24 &mIScsiConfigFormList\r
25};\r
26\r
f6f910dd 27HII_VENDOR_DEVICE_PATH mIScsiHiiVendorDevicePath = {\r
28 {\r
29 {\r
30 HARDWARE_DEVICE_PATH,\r
31 HW_VENDOR_DP,\r
32 {\r
33 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
34 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
35 }\r
36 },\r
37 //\r
38 // {49D7B73E-143D-4716-977B-C45F1CB038CC}\r
39 //\r
40 { 0x49d7b73e, 0x143d, 0x4716, { 0x97, 0x7b, 0xc4, 0x5f, 0x1c, 0xb0, 0x38, 0xcc } }\r
41 },\r
42 {\r
43 END_DEVICE_PATH_TYPE,\r
44 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
45 { \r
46 (UINT8) (END_DEVICE_PATH_LENGTH),\r
47 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
48 }\r
49 }\r
50};\r
51\r
12618416 52/**\r
53 Convert the IPv4 address into a dotted string.\r
54\r
669314e5 55 @param[in] Ip The IPv4 address.\r
56 @param[out] Str The dotted IP string.\r
12618416 57**/\r
6a690e23 58VOID\r
59IScsiIpToStr (\r
60 IN EFI_IPv4_ADDRESS *Ip,\r
61 OUT CHAR16 *Str\r
62 )\r
6a690e23 63{\r
64 UnicodeSPrint ( Str, 2 * IP4_STR_MAX_SIZE, L"%d.%d.%d.%d", Ip->Addr[0], Ip->Addr[1], Ip->Addr[2], Ip->Addr[3]);\r
65}\r
66\r
12618416 67/**\r
6a690e23 68 Update the list of iSCSI devices the iSCSI driver is controlling.\r
669314e5 69 \r
70 @retval EFI_SUCCESS The callback successfully handled the action.\r
963dbb30 71 @retval Others Other errors as indicated. \r
12618416 72**/\r
73EFI_STATUS\r
74IScsiUpdateDeviceList (\r
75 VOID\r
76 )\r
6a690e23 77{\r
78 EFI_STATUS Status;\r
79 ISCSI_DEVICE_LIST *DeviceList;\r
80 UINTN DataSize;\r
81 UINTN NumHandles;\r
82 EFI_HANDLE *Handles;\r
83 UINTN HandleIndex;\r
84 UINTN Index;\r
85 UINTN LastDeviceIndex;\r
86 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
87 EFI_SIMPLE_NETWORK_MODE *Mode;\r
88 ISCSI_MAC_INFO *CurMacInfo;\r
89 ISCSI_MAC_INFO TempMacInfo;\r
90 CHAR16 MacString[65];\r
91 UINTN DeviceListSize;\r
92\r
93 //\r
94 // Dump all the handles the Simple Network Protocol is installed on.\r
95 //\r
96 Status = gBS->LocateHandleBuffer (\r
97 ByProtocol,\r
98 &gEfiSimpleNetworkProtocolGuid,\r
99 NULL,\r
100 &NumHandles,\r
101 &Handles\r
102 );\r
103 if (EFI_ERROR (Status)) {\r
104 return Status;\r
105 }\r
106\r
107 DataSize = 0;\r
108 Status = gRT->GetVariable (\r
109 L"iSCSIDeviceList",\r
110 &mVendorGuid,\r
111 NULL,\r
112 &DataSize,\r
113 NULL\r
114 );\r
115 if (Status == EFI_BUFFER_TOO_SMALL) {\r
e48e37fc 116 DeviceList = (ISCSI_DEVICE_LIST *) AllocatePool (DataSize);\r
6a690e23 117\r
118 gRT->GetVariable (\r
119 L"iSCSIDeviceList",\r
120 &mVendorGuid,\r
121 NULL,\r
122 &DataSize,\r
123 DeviceList\r
124 );\r
125\r
126 LastDeviceIndex = 0;\r
127\r
128 for (HandleIndex = 0; HandleIndex < NumHandles; HandleIndex++) {\r
129 gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp);\r
130\r
131 Mode = Snp->Mode;\r
132\r
133 for (Index = LastDeviceIndex; Index < DeviceList->NumDevice; Index++) {\r
134 CurMacInfo = &DeviceList->MacInfo[Index];\r
135 if ((CurMacInfo->Len == Mode->HwAddressSize) &&\r
136 (NET_MAC_EQUAL (&CurMacInfo->Mac, &Mode->PermanentAddress, Mode->HwAddressSize))\r
137 ) {\r
138 //\r
139 // The previous configured NIC is still here.\r
140 //\r
141 if (Index != LastDeviceIndex) {\r
142 //\r
143 // Swap the current MAC address entry with the one indexed by\r
144 // LastDeviceIndex.\r
145 //\r
e48e37fc 146 CopyMem (&TempMacInfo, CurMacInfo, sizeof (ISCSI_MAC_INFO));\r
147 CopyMem (CurMacInfo, &DeviceList->MacInfo[LastDeviceIndex], sizeof (ISCSI_MAC_INFO));\r
148 CopyMem (&DeviceList->MacInfo[LastDeviceIndex], &TempMacInfo, sizeof (ISCSI_MAC_INFO));\r
6a690e23 149 }\r
150\r
151 LastDeviceIndex++;\r
152 }\r
153 }\r
154\r
155 if (LastDeviceIndex == DeviceList->NumDevice) {\r
156 break;\r
157 }\r
158 }\r
159\r
160 for (Index = LastDeviceIndex; Index < DeviceList->NumDevice; Index++) {\r
161 //\r
162 // delete the variables\r
163 //\r
164 CurMacInfo = &DeviceList->MacInfo[Index];\r
165 IScsiMacAddrToStr (&CurMacInfo->Mac, CurMacInfo->Len, MacString);\r
166 gRT->SetVariable (MacString, &gEfiIScsiInitiatorNameProtocolGuid, 0, 0, NULL);\r
167 gRT->SetVariable (MacString, &mIScsiCHAPAuthInfoGuid, 0, 0, NULL);\r
168 }\r
169\r
e48e37fc 170 gBS->FreePool (DeviceList);\r
6a690e23 171 } else if (Status != EFI_NOT_FOUND) {\r
e48e37fc 172 gBS->FreePool (Handles);\r
6a690e23 173 return Status;\r
174 }\r
175 //\r
176 // Construct the new iSCSI device list.\r
177 //\r
178 DeviceListSize = sizeof (ISCSI_DEVICE_LIST) + (NumHandles - 1) * sizeof (ISCSI_MAC_INFO);\r
e48e37fc 179 DeviceList = (ISCSI_DEVICE_LIST *) AllocatePool (DeviceListSize);\r
6a690e23 180 DeviceList->NumDevice = (UINT8) NumHandles;\r
181\r
182 for (Index = 0; Index < NumHandles; Index++) {\r
183 gBS->HandleProtocol (Handles[Index], &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp);\r
184 Mode = Snp->Mode;\r
185\r
186 CurMacInfo = &DeviceList->MacInfo[Index];\r
e48e37fc 187 CopyMem (&CurMacInfo->Mac, &Mode->PermanentAddress, Mode->HwAddressSize);\r
6a690e23 188 CurMacInfo->Len = (UINT8) Mode->HwAddressSize;\r
189 }\r
190\r
191 gRT->SetVariable (\r
192 L"iSCSIDeviceList",\r
193 &mVendorGuid,\r
194 ISCSI_CONFIG_VAR_ATTR,\r
195 DeviceListSize,\r
196 DeviceList\r
197 );\r
198\r
e48e37fc 199 gBS->FreePool (DeviceList);\r
356e635c 200 gBS->FreePool (Handles);\r
6a690e23 201\r
202 return Status;\r
203}\r
204\r
12618416 205/**\r
206 Get the iSCSI configuration form entry by the index of the goto opcode actived.\r
207\r
669314e5 208 @param[in] Index The 0-based index of the goto opcode actived.\r
12618416 209\r
669314e5 210 @return The iSCSI configuration form entry found.\r
12618416 211**/\r
6a690e23 212ISCSI_CONFIG_FORM_ENTRY *\r
213IScsiGetConfigFormEntryByIndex (\r
214 IN UINT32 Index\r
215 )\r
6a690e23 216{\r
217 UINT32 CurrentIndex;\r
e48e37fc 218 LIST_ENTRY *Entry;\r
6a690e23 219 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
220\r
221 CurrentIndex = 0;\r
222 ConfigFormEntry = NULL;\r
223\r
224 NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) {\r
225 if (CurrentIndex == Index) {\r
226 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link);\r
227 break;\r
228 }\r
229\r
230 CurrentIndex++;\r
231 }\r
232\r
233 return ConfigFormEntry;\r
234}\r
235\r
12618416 236/**\r
237 Convert the iSCSI configuration data into the IFR data.\r
238\r
c5de0d55 239 @param[in] ConfigFormEntry The iSCSI configuration form entry.\r
240 @param[out] IfrNvData The IFR nv data.\r
12618416 241**/\r
6a690e23 242VOID\r
243IScsiConvertDeviceConfigDataToIfrNvData (\r
c5de0d55 244 IN ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry,\r
245 OUT ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
6a690e23 246 )\r
6a690e23 247{\r
248 ISCSI_SESSION_CONFIG_NVDATA *SessionConfigData;\r
249 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfigData;\r
250\r
251 //\r
252 // Normal session configuration parameters.\r
253 //\r
254 SessionConfigData = &ConfigFormEntry->SessionConfigData;\r
255 IfrNvData->Enabled = SessionConfigData->Enabled;\r
256\r
257 IfrNvData->InitiatorInfoFromDhcp = SessionConfigData->InitiatorInfoFromDhcp;\r
258 IfrNvData->TargetInfoFromDhcp = SessionConfigData->TargetInfoFromDhcp;\r
259 IfrNvData->TargetPort = SessionConfigData->TargetPort;\r
260\r
261 IScsiIpToStr (&SessionConfigData->LocalIp, IfrNvData->LocalIp);\r
262 IScsiIpToStr (&SessionConfigData->SubnetMask, IfrNvData->SubnetMask);\r
263 IScsiIpToStr (&SessionConfigData->Gateway, IfrNvData->Gateway);\r
264 IScsiIpToStr (&SessionConfigData->TargetIp, IfrNvData->TargetIp);\r
265\r
266 IScsiAsciiStrToUnicodeStr (SessionConfigData->TargetName, IfrNvData->TargetName);\r
267\r
268 IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->BootLun);\r
269\r
270 //\r
271 // CHAP authentication parameters.\r
272 //\r
273 AuthConfigData = &ConfigFormEntry->AuthConfigData;\r
274\r
275 IfrNvData->CHAPType = AuthConfigData->CHAPType;\r
276\r
277 IScsiAsciiStrToUnicodeStr (AuthConfigData->CHAPName, IfrNvData->CHAPName);\r
278 IScsiAsciiStrToUnicodeStr (AuthConfigData->CHAPSecret, IfrNvData->CHAPSecret);\r
279 IScsiAsciiStrToUnicodeStr (AuthConfigData->ReverseCHAPName, IfrNvData->ReverseCHAPName);\r
280 IScsiAsciiStrToUnicodeStr (AuthConfigData->ReverseCHAPSecret, IfrNvData->ReverseCHAPSecret);\r
281}\r
282\r
12618416 283/**\r
669314e5 284 This function allows the caller to request the current\r
285 configuration for one or more named elements. The resulting\r
286 string is in <ConfigAltResp> format. Any and all alternative\r
287 configuration strings shall also be appended to the end of the\r
288 current configuration string. If they are, they must appear\r
289 after the current configuration. They must contain the same\r
290 routing (GUID, NAME, PATH) as the current configuration string.\r
291 They must have an additional description indicating the type of\r
292 alternative configuration the string represents,\r
293 "ALTCFG=<StringToken>". That <StringToken> (when\r
294 converted from Hex UNICODE to binary) is a reference to a\r
295 string in the associated string pack.\r
296\r
297 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
298 @param[in] Request A null-terminated Unicode string in\r
299 <ConfigRequest> format. Note that this\r
300 includes the routing information as well as\r
301 the configurable name / value pairs. It is\r
302 invalid for this string to be in\r
303 <MultiConfigRequest> format.\r
304 @param[out] Progress On return, points to a character in the\r
305 Request string. Points to the string's null\r
306 terminator if request was successful. Points\r
307 to the most recent "&" before the first\r
308 failing name / value pair (or the beginning\r
309 of the string if the failure is in the first\r
310 name / value pair) if the request was not\r
311 successful.\r
312 @param[out] Results A null-terminated Unicode string in\r
313 <ConfigAltResp> format which has all values\r
314 filled in for the names in the Request string.\r
315 String to be allocated by the called function.\r
316\r
317 @retval EFI_SUCCESS The Results string is filled with the\r
318 values corresponding to all requested\r
319 names.\r
320 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
321 parts of the results that must be\r
322 stored awaiting possible future\r
323 protocols.\r
324 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
325 for the Request parameter\r
326 would result in this type of\r
327 error. In this case, the\r
328 Progress parameter would be\r
329 set to NULL. \r
330 @retval EFI_NOT_FOUND Routing data doesn't match any\r
331 known driver. Progress set to the\r
332 first character in the routing header.\r
333 Note: There is no requirement that the\r
334 driver validate the routing data. It\r
335 must skip the <ConfigHdr> in order to\r
336 process the names.\r
337 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
338 to most recent & before the\r
339 error or the beginning of the\r
340 string.\r
341 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
342 to the & before the name in\r
343 question.Currently not implemented.\r
12618416 344**/\r
6a690e23 345EFI_STATUS\r
346EFIAPI\r
93e3992d 347IScsiFormExtractConfig (\r
348 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
349 IN CONST EFI_STRING Request,\r
350 OUT EFI_STRING *Progress,\r
351 OUT EFI_STRING *Results\r
6a690e23 352 )\r
6a690e23 353{\r
93e3992d 354 EFI_STATUS Status;\r
355 CHAR8 InitiatorName[ISCSI_NAME_IFR_MAX_SIZE];\r
356 UINTN BufferSize;\r
357 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
358 ISCSI_FORM_CALLBACK_INFO *Private;\r
359 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
6a690e23 360\r
8d00a0f1 361 if (Request == NULL) {\r
669314e5 362 return EFI_INVALID_PARAMETER;\r
8d00a0f1 363 }\r
364\r
6a690e23 365 if (!mIScsiDeviceListUpdated) {\r
366 //\r
367 // Update the device list.\r
368 //\r
369 IScsiUpdateDeviceList ();\r
370 mIScsiDeviceListUpdated = TRUE;\r
371 }\r
372\r
93e3992d 373 Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
374 IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
375 ASSERT (IfrNvData != NULL);\r
376 if (Private->Current != NULL) {\r
377 IScsiConvertDeviceConfigDataToIfrNvData (Private->Current, IfrNvData);\r
378 }\r
6a690e23 379\r
93e3992d 380 BufferSize = ISCSI_NAME_IFR_MAX_SIZE;\r
6a690e23 381 Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
382 if (EFI_ERROR (Status)) {\r
383 IfrNvData->InitiatorName[0] = L'\0';\r
384 } else {\r
385 IScsiAsciiStrToUnicodeStr (InitiatorName, IfrNvData->InitiatorName);\r
386 }\r
387\r
93e3992d 388 //\r
389 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
390 //\r
391 HiiConfigRouting = Private->ConfigRouting;\r
392 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
393 Status = HiiConfigRouting->BlockToConfig (\r
394 HiiConfigRouting,\r
395 Request,\r
396 (UINT8 *) IfrNvData,\r
397 BufferSize,\r
398 Results,\r
399 Progress\r
400 );\r
e48e37fc 401 gBS->FreePool (IfrNvData);\r
93e3992d 402 return Status;\r
6a690e23 403}\r
404\r
12618416 405/**\r
669314e5 406 This function applies changes in a driver's configuration.\r
407 Input is a Configuration, which has the routing data for this\r
408 driver followed by name / value configuration pairs. The driver\r
409 must apply those pairs to its configurable storage. If the\r
410 driver's configuration is stored in a linear block of data\r
55a64ae0 411 and the driver's name / value pairs are in <BlockConfig>\r
669314e5 412 format, it may use the ConfigToBlock helper function (above) to\r
413 simplify the job. Currently not implemented.\r
414\r
415 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
416 @param[in] Configuration A null-terminated Unicode string in\r
417 <ConfigString> format. \r
418 @param[out] Progress A pointer to a string filled in with the\r
419 offset of the most recent '&' before the\r
420 first failing name / value pair (or the\r
421 beginn ing of the string if the failure\r
422 is in the first name / value pair) or\r
423 the terminating NULL if all was\r
424 successful.\r
425\r
426 @retval EFI_SUCCESS The results have been distributed or are\r
427 awaiting distribution. \r
428 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
429 parts of the results that must be\r
430 stored awaiting possible future\r
431 protocols.\r
432 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
433 Results parameter would result\r
434 in this type of error.\r
435 @retval EFI_NOT_FOUND Target for the specified routing data\r
436 was not found.\r
12618416 437**/\r
6a690e23 438EFI_STATUS\r
439EFIAPI\r
93e3992d 440IScsiFormRouteConfig (\r
441 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
442 IN CONST EFI_STRING Configuration,\r
443 OUT EFI_STRING *Progress\r
6a690e23 444 )\r
12618416 445{\r
446 return EFI_SUCCESS;\r
447}\r
6a690e23 448\r
12618416 449/**\r
669314e5 450 This function is called to provide results data to the driver.\r
451 This data consists of a unique key that is used to identify\r
452 which data is either being passed back or being asked for.\r
453\r
454 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
455 @param[in] Action Specifies the type of action taken by the browser.\r
456 @param[in] QuestionId A unique value which is sent to the original\r
457 exporting driver so that it can identify the type\r
458 of data to expect. The format of the data tends to \r
459 vary based on the opcode that enerated the callback.\r
460 @param[in] Type The type of value for the question.\r
461 @param[in] Value A pointer to the data being sent to the original\r
462 exporting driver.\r
463 @param[out] ActionRequest On return, points to the action requested by the\r
464 callback function.\r
465\r
466 @retval EFI_SUCCESS The callback successfully handled the action.\r
467 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
468 variable and its data.\r
469 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
470 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
471 callback.Currently not implemented.\r
472 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. \r
963dbb30 473 @retval Others Other errors as indicated. \r
12618416 474**/\r
93e3992d 475EFI_STATUS\r
476EFIAPI\r
477IScsiFormCallback (\r
478 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
f3e1569d 479 IN EFI_BROWSER_ACTION Action,\r
669314e5 480 IN EFI_QUESTION_ID QuestionId,\r
93e3992d 481 IN UINT8 Type,\r
482 IN EFI_IFR_TYPE_VALUE *Value,\r
483 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
484 )\r
6a690e23 485{\r
486 ISCSI_FORM_CALLBACK_INFO *Private;\r
487 UINTN BufferSize;\r
488 CHAR8 IScsiName[ISCSI_NAME_IFR_MAX_SIZE];\r
489 CHAR16 PortString[128];\r
490 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
491 CHAR8 LunString[ISCSI_LUN_STR_MAX_LEN];\r
492 UINT64 Lun;\r
6c7a807a 493 EFI_STRING_ID DeviceFormTitleToken;\r
6a690e23 494 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
495 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
496 EFI_IP_ADDRESS HostIp;\r
497 EFI_IP_ADDRESS SubnetMask;\r
498 EFI_IP_ADDRESS Gateway;\r
499 EFI_STATUS Status;\r
63d55bb9 500 EFI_INPUT_KEY Key;\r
6a690e23 501\r
502 Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
93e3992d 503\r
504 //\r
505 // Retrive uncommitted data from Browser\r
506 //\r
507 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
508 IfrNvData = AllocateZeroPool (BufferSize);\r
509 ASSERT (IfrNvData != NULL);\r
510 Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) IfrNvData);\r
511 if (EFI_ERROR (Status)) {\r
512 gBS->FreePool (IfrNvData);\r
513 return Status;\r
514 }\r
6a690e23 515\r
669314e5 516 switch (QuestionId) {\r
6a690e23 517 case KEY_INITIATOR_NAME:\r
518 IScsiUnicodeStrToAsciiStr (IfrNvData->InitiatorName, IScsiName);\r
519 BufferSize = AsciiStrLen (IScsiName) + 1;\r
520\r
521 Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, IScsiName);\r
522 if (EFI_ERROR (Status)) {\r
63d55bb9 523 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid iSCSI Name!", NULL);\r
6a690e23 524 }\r
525\r
526 break;\r
527\r
528 case KEY_LOCAL_IP:\r
529 IScsiUnicodeStrToAsciiStr (IfrNvData->LocalIp, Ip4String);\r
530 Status = IScsiAsciiStrToIp (Ip4String, &HostIp.v4);\r
531 if (EFI_ERROR (Status) || !Ip4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
63d55bb9 532 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
6a690e23 533 Status = EFI_INVALID_PARAMETER;\r
534 } else {\r
e48e37fc 535 CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
6a690e23 536 }\r
537\r
538 break;\r
539\r
540 case KEY_SUBNET_MASK:\r
541 IScsiUnicodeStrToAsciiStr (IfrNvData->SubnetMask, Ip4String);\r
542 Status = IScsiAsciiStrToIp (Ip4String, &SubnetMask.v4);\r
543 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
63d55bb9 544 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);\r
6a690e23 545 Status = EFI_INVALID_PARAMETER;\r
546 } else {\r
e48e37fc 547 CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
6a690e23 548 }\r
549\r
550 break;\r
551\r
552 case KEY_GATE_WAY:\r
553 IScsiUnicodeStrToAsciiStr (IfrNvData->Gateway, Ip4String);\r
554 Status = IScsiAsciiStrToIp (Ip4String, &Gateway.v4);\r
555 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !Ip4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
63d55bb9 556 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
6a690e23 557 Status = EFI_INVALID_PARAMETER;\r
558 } else {\r
e48e37fc 559 CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
6a690e23 560 }\r
561\r
562 break;\r
563\r
564 case KEY_TARGET_IP:\r
565 IScsiUnicodeStrToAsciiStr (IfrNvData->TargetIp, Ip4String);\r
566 Status = IScsiAsciiStrToIp (Ip4String, &HostIp.v4);\r
567 if (EFI_ERROR (Status) || !Ip4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
63d55bb9 568 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
6a690e23 569 Status = EFI_INVALID_PARAMETER;\r
570 } else {\r
e48e37fc 571 CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp.v4, sizeof (HostIp.v4));\r
6a690e23 572 }\r
573\r
574 break;\r
575\r
576 case KEY_TARGET_NAME:\r
577 IScsiUnicodeStrToAsciiStr (IfrNvData->TargetName, IScsiName);\r
578 Status = IScsiNormalizeName (IScsiName, AsciiStrLen (IScsiName));\r
579 if (EFI_ERROR (Status)) {\r
63d55bb9 580 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid iSCSI Name!", NULL);\r
6a690e23 581 } else {\r
582 AsciiStrCpy (Private->Current->SessionConfigData.TargetName, IScsiName);\r
583 }\r
584\r
585 break;\r
586\r
587 case KEY_DHCP_ENABLE:\r
588 if (IfrNvData->InitiatorInfoFromDhcp == 0) {\r
589 IfrNvData->TargetInfoFromDhcp = 0;\r
590 }\r
591\r
592 break;\r
593\r
594 case KEY_BOOT_LUN:\r
595 IScsiUnicodeStrToAsciiStr (IfrNvData->BootLun, LunString);\r
596 Status = IScsiAsciiStrToLun (LunString, (UINT8 *) &Lun);\r
597 if (EFI_ERROR (Status)) {\r
63d55bb9 598 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid LUN string!", NULL);\r
6a690e23 599 } else {\r
e48e37fc 600 CopyMem (Private->Current->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
6a690e23 601 }\r
602\r
603 break;\r
604\r
605 case KEY_CHAP_NAME:\r
606 IScsiUnicodeStrToAsciiStr (IfrNvData->CHAPName, Private->Current->AuthConfigData.CHAPName);\r
607 break;\r
608\r
609 case KEY_CHAP_SECRET:\r
610 IScsiUnicodeStrToAsciiStr (IfrNvData->CHAPSecret, Private->Current->AuthConfigData.CHAPSecret);\r
611 break;\r
612\r
613 case KEY_REVERSE_CHAP_NAME:\r
614 IScsiUnicodeStrToAsciiStr (IfrNvData->ReverseCHAPName, Private->Current->AuthConfigData.ReverseCHAPName);\r
615 break;\r
616\r
617 case KEY_REVERSE_CHAP_SECRET:\r
618 IScsiUnicodeStrToAsciiStr (IfrNvData->ReverseCHAPSecret, Private->Current->AuthConfigData.ReverseCHAPSecret);\r
619 break;\r
620\r
621 case KEY_SAVE_CHANGES:\r
622 //\r
623 // First, update those fields which don't have INTERACTIVE set.\r
624 //\r
625 Private->Current->SessionConfigData.Enabled = IfrNvData->Enabled;\r
626 Private->Current->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->InitiatorInfoFromDhcp;\r
627 Private->Current->SessionConfigData.TargetPort = IfrNvData->TargetPort;\r
628 if (Private->Current->SessionConfigData.TargetPort == 0) {\r
629 Private->Current->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;\r
630 }\r
631\r
632 Private->Current->SessionConfigData.TargetInfoFromDhcp = IfrNvData->TargetInfoFromDhcp;\r
633 Private->Current->AuthConfigData.CHAPType = IfrNvData->CHAPType;\r
634\r
635 //\r
636 // Only do full parameter validation if iSCSI is enabled on this device.\r
637 //\r
638 if (Private->Current->SessionConfigData.Enabled) {\r
639 //\r
640 // Validate the address configuration of the Initiator if DHCP isn't\r
641 // deployed.\r
642 //\r
643 if (!Private->Current->SessionConfigData.InitiatorInfoFromDhcp) {\r
e48e37fc 644 CopyMem (&HostIp.v4, &Private->Current->SessionConfigData.LocalIp, sizeof (HostIp.v4));\r
645 CopyMem (&SubnetMask.v4, &Private->Current->SessionConfigData.SubnetMask, sizeof (SubnetMask.v4));\r
646 CopyMem (&Gateway.v4, &Private->Current->SessionConfigData.Gateway, sizeof (Gateway.v4));\r
6a690e23 647\r
648 if ((Gateway.Addr[0] != 0)) {\r
649 if (SubnetMask.Addr[0] == 0) {\r
63d55bb9 650 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
6a690e23 651 Status = EFI_INVALID_PARAMETER;\r
652 break;\r
653 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
63d55bb9 654 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
6a690e23 655 Status = EFI_INVALID_PARAMETER;\r
656 break;\r
657 }\r
658 }\r
659 }\r
660 //\r
661 // Validate target configuration if DHCP isn't deployed.\r
662 //\r
663 if (!Private->Current->SessionConfigData.TargetInfoFromDhcp) {\r
e48e37fc 664 CopyMem (&HostIp.v4, &Private->Current->SessionConfigData.TargetIp, sizeof (HostIp.v4));\r
6a690e23 665 if (!Ip4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
63d55bb9 666 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Target IP is invalid!", NULL);\r
6a690e23 667 Status = EFI_INVALID_PARAMETER;\r
668 break;\r
669 }\r
670 }\r
671\r
672 if (IfrNvData->CHAPType != ISCSI_CHAP_NONE) {\r
673 if ((IfrNvData->CHAPName[0] == '\0') || (IfrNvData->CHAPSecret[0] == '\0')) {\r
63d55bb9 674 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"CHAP Name or CHAP Secret is invalid!", NULL);\r
6a690e23 675 Status = EFI_INVALID_PARAMETER;\r
676 break;\r
677 }\r
678\r
679 if ((IfrNvData->CHAPType == ISCSI_CHAP_MUTUAL) &&\r
680 ((IfrNvData->ReverseCHAPName[0] == '\0') || (IfrNvData->ReverseCHAPSecret[0] == '\0'))\r
681 ) {\r
63d55bb9 682 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Reverse CHAP Name or Reverse CHAP Secret is invalid!", NULL);\r
6a690e23 683 Status = EFI_INVALID_PARAMETER;\r
684 break;\r
685 }\r
686 }\r
687 }\r
688\r
689 BufferSize = sizeof (Private->Current->SessionConfigData);\r
690 gRT->SetVariable (\r
691 Private->Current->MacString,\r
692 &gEfiIScsiInitiatorNameProtocolGuid,\r
693 ISCSI_CONFIG_VAR_ATTR,\r
694 BufferSize,\r
695 &Private->Current->SessionConfigData\r
696 );\r
697\r
698 BufferSize = sizeof (Private->Current->AuthConfigData);\r
699 gRT->SetVariable (\r
700 Private->Current->MacString,\r
701 &mIScsiCHAPAuthInfoGuid,\r
702 ISCSI_CONFIG_VAR_ATTR,\r
703 BufferSize,\r
704 &Private->Current->AuthConfigData\r
705 );\r
93e3992d 706 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
6a690e23 707 break;\r
708\r
709 default:\r
669314e5 710 if ((QuestionId >= KEY_DEVICE_ENTRY_BASE) && (QuestionId < (mNumberOfIScsiDevices + KEY_DEVICE_ENTRY_BASE))) {\r
6a690e23 711 //\r
712 // In case goto the device configuration form, update the device form title.\r
713 //\r
669314e5 714 ConfigFormEntry = IScsiGetConfigFormEntryByIndex ((UINT32) (QuestionId - KEY_DEVICE_ENTRY_BASE));\r
6a690e23 715 ASSERT (ConfigFormEntry != NULL);\r
716\r
93e3992d 717 UnicodeSPrint (PortString, (UINTN) 128, L"Port %s", ConfigFormEntry->MacString);\r
6c7a807a 718 DeviceFormTitleToken = (EFI_STRING_ID) STR_ISCSI_DEVICE_FORM_TITLE;\r
9226efe5 719 HiiLibSetString (Private->RegisteredHandle, DeviceFormTitleToken, PortString);\r
6a690e23 720\r
721 IScsiConvertDeviceConfigDataToIfrNvData (ConfigFormEntry, IfrNvData);\r
722\r
723 Private->Current = ConfigFormEntry;\r
724 }\r
725\r
726 break;\r
727 }\r
728\r
93e3992d 729 if (!EFI_ERROR (Status)) {\r
730 //\r
731 // Pass changed uncommitted data back to Form Browser\r
732 //\r
733 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
734 Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);\r
735 }\r
736\r
e48e37fc 737 gBS->FreePool (IfrNvData);\r
6a690e23 738 return Status;\r
739}\r
740\r
12618416 741/**\r
6a690e23 742 Updates the iSCSI configuration form to add/delete an entry for the iSCSI\r
743 device specified by the Controller.\r
744\r
669314e5 745 @param[in] DriverBindingHandle The driverbinding handle.\r
746 @param[in] Controller The controller handle of the iSCSI device.\r
747 @param[in] AddForm Whether to add or delete a form entry.\r
6a690e23 748\r
12618416 749 @retval EFI_SUCCESS The iSCSI configuration form is updated.\r
12618416 750 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
963dbb30 751 @retval Others Other errors as indicated.\r
12618416 752**/\r
753EFI_STATUS\r
754IScsiConfigUpdateForm (\r
755 IN EFI_HANDLE DriverBindingHandle,\r
756 IN EFI_HANDLE Controller,\r
757 IN BOOLEAN AddForm\r
758 )\r
6a690e23 759{\r
e48e37fc 760 LIST_ENTRY *Entry;\r
6a690e23 761 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
762 BOOLEAN EntryExisted;\r
6a690e23 763 EFI_STATUS Status;\r
93e3992d 764 EFI_HII_UPDATE_DATA UpdateData;\r
6a690e23 765 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
766 CHAR16 PortString[128];\r
767 UINT16 FormIndex;\r
768 UINTN BufferSize;\r
769\r
6a690e23 770\r
771 ConfigFormEntry = NULL;\r
772 EntryExisted = FALSE;\r
773\r
774 NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) {\r
775 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link);\r
776\r
777 if (ConfigFormEntry->Controller == Controller) {\r
778 EntryExisted = TRUE;\r
779 break;\r
780 }\r
781 }\r
782\r
783 if (AddForm) {\r
784 if (EntryExisted) {\r
785 return EFI_SUCCESS;\r
786 } else {\r
787 //\r
788 // Add a new form.\r
789 //\r
e48e37fc 790 ConfigFormEntry = (ISCSI_CONFIG_FORM_ENTRY *) AllocateZeroPool (sizeof (ISCSI_CONFIG_FORM_ENTRY));\r
6a690e23 791 if (ConfigFormEntry == NULL) {\r
792 return EFI_OUT_OF_RESOURCES;\r
793 }\r
794\r
e48e37fc 795 InitializeListHead (&ConfigFormEntry->Link);\r
6a690e23 796 ConfigFormEntry->Controller = Controller;\r
797\r
798 //\r
799 // Get the simple network protocol and convert the MAC address into\r
800 // the formatted string.\r
801 //\r
802 Status = gBS->HandleProtocol (\r
803 Controller,\r
804 &gEfiSimpleNetworkProtocolGuid,\r
805 (VOID **)&Snp\r
806 );\r
807 ASSERT (Status == EFI_SUCCESS);\r
808\r
809 IScsiMacAddrToStr (&Snp->Mode->PermanentAddress, Snp->Mode->HwAddressSize, ConfigFormEntry->MacString);\r
810\r
811 //\r
812 // Get the normal session configuration data.\r
813 //\r
814 BufferSize = sizeof (ConfigFormEntry->SessionConfigData);\r
815 Status = gRT->GetVariable (\r
816 ConfigFormEntry->MacString,\r
817 &gEfiIScsiInitiatorNameProtocolGuid,\r
818 NULL,\r
819 &BufferSize,\r
820 &ConfigFormEntry->SessionConfigData\r
821 );\r
822 if (EFI_ERROR (Status)) {\r
e48e37fc 823 ZeroMem (&ConfigFormEntry->SessionConfigData, sizeof (ConfigFormEntry->SessionConfigData));\r
6a690e23 824 }\r
825 //\r
826 // Get the CHAP authentication configuration data.\r
827 //\r
828 BufferSize = sizeof (ConfigFormEntry->AuthConfigData);\r
829 Status = gRT->GetVariable (\r
830 ConfigFormEntry->MacString,\r
831 &mIScsiCHAPAuthInfoGuid,\r
832 NULL,\r
833 &BufferSize,\r
834 &ConfigFormEntry->AuthConfigData\r
835 );\r
836 if (EFI_ERROR (Status)) {\r
e48e37fc 837 ZeroMem (&ConfigFormEntry->AuthConfigData, sizeof (ConfigFormEntry->AuthConfigData));\r
6a690e23 838 }\r
839 //\r
6c7a807a 840 // Compose the Port string and create a new EFI_STRING_ID.\r
6a690e23 841 //\r
842 UnicodeSPrint (PortString, 128, L"Port %s", ConfigFormEntry->MacString);\r
9226efe5 843 HiiLibNewString (mCallbackInfo->RegisteredHandle, &ConfigFormEntry->PortTitleToken, PortString);\r
6a690e23 844\r
845 //\r
6c7a807a 846 // Compose the help string of this port and create a new EFI_STRING_ID.\r
6a690e23 847 //\r
848 UnicodeSPrint (PortString, 128, L"Set the iSCSI parameters on port %s", ConfigFormEntry->MacString);\r
9226efe5 849 HiiLibNewString (mCallbackInfo->RegisteredHandle, &ConfigFormEntry->PortTitleHelpToken, PortString);\r
6a690e23 850\r
e48e37fc 851 InsertTailList (&mIScsiConfigFormList, &ConfigFormEntry->Link);\r
6a690e23 852 mNumberOfIScsiDevices++;\r
853 }\r
854 } else {\r
855 ASSERT (EntryExisted);\r
856\r
857 mNumberOfIScsiDevices--;\r
e48e37fc 858 RemoveEntryList (&ConfigFormEntry->Link);\r
859 gBS->FreePool (ConfigFormEntry);\r
6a690e23 860 }\r
861 //\r
862 // Allocate space for creation of Buffer\r
863 //\r
93e3992d 864 UpdateData.BufferSize = 0x1000;\r
e48e37fc 865 UpdateData.Data = AllocateZeroPool (0x1000);\r
93e3992d 866 UpdateData.Offset = 0;\r
6a690e23 867\r
93e3992d 868 FormIndex = 0;\r
6a690e23 869 NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) {\r
870 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link);\r
871\r
872 CreateGotoOpCode (\r
873 FORMID_DEVICE_FORM,\r
874 ConfigFormEntry->PortTitleToken,\r
875 ConfigFormEntry->PortTitleHelpToken,\r
93e3992d 876 EFI_IFR_FLAG_CALLBACK,\r
69b0882d 877 (UINT16)(KEY_DEVICE_ENTRY_BASE + FormIndex),\r
93e3992d 878 &UpdateData\r
6a690e23 879 );\r
880\r
6a690e23 881 FormIndex++;\r
882 }\r
883\r
93e3992d 884 IfrLibUpdateForm (\r
885 mCallbackInfo->RegisteredHandle,\r
886 &mVendorGuid,\r
887 FORMID_MAIN_FORM,\r
888 DEVICE_ENTRY_LABEL,\r
889 FALSE,\r
890 &UpdateData\r
891 );\r
892\r
e48e37fc 893 gBS->FreePool (UpdateData.Data);\r
6a690e23 894\r
895 return EFI_SUCCESS;\r
896}\r
897\r
12618416 898/**\r
6a690e23 899 Initialize the iSCSI configuration form.\r
900\r
669314e5 901 @param[in] DriverBindingHandle The iSCSI driverbinding handle.\r
6a690e23 902\r
669314e5 903 @retval EFI_SUCCESS The iSCSI configuration form is initialized.\r
904 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
963dbb30 905 @retval Others Other errors as indicated.\r
12618416 906**/\r
907EFI_STATUS\r
908IScsiConfigFormInit (\r
963dbb30 909 VOID\r
12618416 910 )\r
6a690e23 911{\r
93e3992d 912 EFI_STATUS Status;\r
913 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
914 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
915 ISCSI_FORM_CALLBACK_INFO *CallbackInfo;\r
916\r
69b0882d 917 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);\r
6a690e23 918 if (EFI_ERROR (Status)) {\r
93e3992d 919 return Status;\r
6a690e23 920 }\r
921\r
f6f910dd 922 CallbackInfo = (ISCSI_FORM_CALLBACK_INFO *) AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO));\r
6a690e23 923 if (CallbackInfo == NULL) {\r
924 return EFI_OUT_OF_RESOURCES;\r
925 }\r
926\r
f2a94e25 927 CallbackInfo->Signature = ISCSI_FORM_CALLBACK_INFO_SIGNATURE;\r
93e3992d 928 CallbackInfo->HiiDatabase = HiiDatabase;\r
f2a94e25 929 CallbackInfo->Current = NULL;\r
6a690e23 930\r
93e3992d 931 CallbackInfo->ConfigAccess.ExtractConfig = IScsiFormExtractConfig;\r
932 CallbackInfo->ConfigAccess.RouteConfig = IScsiFormRouteConfig;\r
933 CallbackInfo->ConfigAccess.Callback = IScsiFormCallback;\r
6a690e23 934\r
69b0882d 935 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&CallbackInfo->ConfigRouting);\r
93e3992d 936 if (EFI_ERROR (Status)) {\r
f2a94e25 937 FreePool(CallbackInfo);\r
93e3992d 938 return Status;\r
939 }\r
940\r
941 //\r
f6f910dd 942 // Install Device Path Protocol and Config Access protocol to driver handle\r
93e3992d 943 //\r
f6f910dd 944 Status = gBS->InstallMultipleProtocolInterfaces (\r
93e3992d 945 &CallbackInfo->DriverHandle,\r
f6f910dd 946 &gEfiDevicePathProtocolGuid,\r
947 &mIScsiHiiVendorDevicePath,\r
93e3992d 948 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 949 &CallbackInfo->ConfigAccess,\r
950 NULL\r
6a690e23 951 );\r
6a690e23 952 ASSERT_EFI_ERROR (Status);\r
93e3992d 953 \r
6a690e23 954 //\r
93e3992d 955 // Publish our HII data\r
6a690e23 956 //\r
9226efe5 957 PackageList = HiiLibPreparePackageList (2, &mVendorGuid, IScsiDxeStrings, IScsiConfigDxeBin);\r
93e3992d 958 ASSERT (PackageList != NULL);\r
959 \r
960 Status = HiiDatabase->NewPackageList (\r
961 HiiDatabase,\r
962 PackageList,\r
963 CallbackInfo->DriverHandle,\r
964 &CallbackInfo->RegisteredHandle\r
965 );\r
f2a94e25 966 FreePool (PackageList);\r
93e3992d 967 if (EFI_ERROR (Status)) {\r
f2a94e25 968 FreePool(CallbackInfo);\r
93e3992d 969 return Status;\r
6a690e23 970 }\r
971\r
93e3992d 972 mCallbackInfo = CallbackInfo;\r
6a690e23 973\r
974 return Status;\r
975}\r
976\r
12618416 977/**\r
6a690e23 978 Unload the iSCSI configuration form, this includes: delete all the iSCSI\r
979 device configuration entries, uninstall the form callback protocol and\r
980 free the resources used.\r
981\r
669314e5 982 @param[in] DriverBindingHandle The iSCSI driverbinding handle.\r
983 \r
12618416 984 @retval EFI_SUCCESS The iSCSI configuration form is unloaded.\r
12618416 985 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
12618416 986**/\r
987EFI_STATUS\r
988IScsiConfigFormUnload (\r
989 IN EFI_HANDLE DriverBindingHandle\r
990 )\r
6a690e23 991{\r
992 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
6a690e23 993\r
e48e37fc 994 while (!IsListEmpty (&mIScsiConfigFormList)) {\r
6a690e23 995 //\r
996 // Uninstall the device forms as the iSCSI driver instance may fail to\r
997 // control the controller but still install the device configuration form.\r
998 // In such case, upon driver unloading, the driver instance's driverbinding.\r
999 // stop () won't be called, so we have to take this chance here to uninstall\r
1000 // the device form.\r
1001 //\r
1002 ConfigFormEntry = NET_LIST_USER_STRUCT (mIScsiConfigFormList.ForwardLink, ISCSI_CONFIG_FORM_ENTRY, Link);\r
1003 IScsiConfigUpdateForm (DriverBindingHandle, ConfigFormEntry->Controller, FALSE);\r
1004 }\r
1005\r
6a690e23 1006 //\r
93e3992d 1007 // Remove HII package list\r
6a690e23 1008 //\r
93e3992d 1009 mCallbackInfo->HiiDatabase->RemovePackageList (\r
1010 mCallbackInfo->HiiDatabase,\r
1011 mCallbackInfo->RegisteredHandle\r
1012 );\r
6a690e23 1013\r
1014 //\r
93e3992d 1015 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
6a690e23 1016 //\r
f6f910dd 1017 gBS->UninstallMultipleProtocolInterfaces (\r
1018 mCallbackInfo->DriverHandle,\r
1019 &gEfiDevicePathProtocolGuid,\r
1020 &mIScsiHiiVendorDevicePath,\r
1021 &gEfiHiiConfigAccessProtocolGuid,\r
1022 &mCallbackInfo->ConfigAccess,\r
1023 NULL\r
1024 );\r
e48e37fc 1025 gBS->FreePool (mCallbackInfo);\r
6a690e23 1026\r
1027 return EFI_SUCCESS;\r
1028}\r