]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c
Clean up the private GUID definition in module Level.
[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
312e3bdf 4Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
7a444476 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
7e3bcccb 17CHAR16 mVendorStorageName[] = L"ISCSI_CONFIG_IFR_NVDATA";\r
f2a94e25 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
c8ad2d7a 37 IP4_ISCSI_CONFIG_GUID\r
f6f910dd 38 },\r
39 {\r
40 END_DEVICE_PATH_TYPE,\r
41 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
42 { \r
43 (UINT8) (END_DEVICE_PATH_LENGTH),\r
44 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
45 }\r
46 }\r
47};\r
48\r
12618416 49/**\r
50 Convert the IPv4 address into a dotted string.\r
51\r
669314e5 52 @param[in] Ip The IPv4 address.\r
53 @param[out] Str The dotted IP string.\r
12618416 54**/\r
6a690e23 55VOID\r
56IScsiIpToStr (\r
57 IN EFI_IPv4_ADDRESS *Ip,\r
58 OUT CHAR16 *Str\r
59 )\r
6a690e23 60{\r
61 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
62}\r
63\r
312e3bdf 64\r
65/**\r
66 Parse IsId in string format and convert it to binary.\r
67\r
68 @param[in] String The buffer of the string to be parsed.\r
69 @param[in, out] IsId The buffer to store IsId.\r
70\r
71 @retval EFI_SUCCESS The operation finished successfully.\r
72 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
73\r
74**/\r
75EFI_STATUS\r
76IScsiParseIsIdFromString (\r
77 IN CONST CHAR16 *String,\r
78 IN OUT UINT8 *IsId\r
79 )\r
80{\r
81 UINT8 Index;\r
82 CHAR16 *IsIdStr;\r
83 CHAR16 TempStr[3];\r
84 UINTN NodeVal;\r
85 CHAR16 PortString[ISCSI_NAME_IFR_MAX_SIZE];\r
86 EFI_INPUT_KEY Key;\r
87\r
88 if ((String == NULL) || (IsId == NULL)) {\r
89 return EFI_INVALID_PARAMETER;\r
90 }\r
91\r
92 IsIdStr = (CHAR16 *) String;\r
93\r
94 if (StrLen (IsIdStr) != 6) {\r
95 UnicodeSPrint (\r
96 PortString,\r
97 (UINTN) ISCSI_NAME_IFR_MAX_SIZE,\r
98 L"Error! Input is incorrect, please input 6 hex numbers!\n"\r
99 );\r
100\r
101 CreatePopUp (\r
102 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
103 &Key,\r
104 PortString,\r
105 NULL\r
106 );\r
107\r
108 return EFI_INVALID_PARAMETER;\r
109 }\r
110\r
111 for (Index = 3; Index < 6; Index++) {\r
112 CopyMem (TempStr, IsIdStr, sizeof (TempStr));\r
113 TempStr[2] = L'\0';\r
114\r
115 //\r
116 // Convert the string to IsId. StrHexToUintn stops at the first character\r
117 // that is not a valid hex character, '\0' here.\r
118 //\r
119 NodeVal = StrHexToUintn (TempStr);\r
120\r
121 IsId[Index] = (UINT8) NodeVal;\r
122\r
123 IsIdStr = IsIdStr + 2;\r
124 }\r
125\r
126 return EFI_SUCCESS;\r
127}\r
128\r
129/**\r
130 Convert IsId from binary to string format.\r
131\r
132 @param[out] String The buffer to store the converted string.\r
133 @param[in] IsId The buffer to store IsId.\r
134\r
135 @retval EFI_SUCCESS The string converted successfully.\r
136 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
137\r
138**/\r
139EFI_STATUS\r
140IScsiConvertIsIdToString (\r
141 OUT CHAR16 *String,\r
142 IN UINT8 *IsId\r
143 )\r
144{\r
145 UINT8 Index;\r
146 UINTN Number;\r
147\r
148 if ((String == NULL) || (IsId == NULL)) {\r
149 return EFI_INVALID_PARAMETER;\r
150 }\r
151\r
152 for (Index = 0; Index < 6; Index++) {\r
153 if (IsId[Index] <= 0xF) {\r
154 Number = UnicodeSPrint (\r
155 String,\r
156 2 * ISID_CONFIGURABLE_STORAGE,\r
157 L"0%X",\r
158 (UINTN) IsId[Index]\r
159 );\r
160 } else {\r
161 Number = UnicodeSPrint (\r
162 String,\r
163 2 * ISID_CONFIGURABLE_STORAGE,\r
164 L"%X",\r
165 (UINTN) IsId[Index]\r
166 );\r
167\r
168 }\r
169\r
170 String = String + Number;\r
171 }\r
172\r
173 *String = L'\0';\r
174\r
175 return EFI_SUCCESS;\r
176}\r
177\r
178\r
12618416 179/**\r
6a690e23 180 Update the list of iSCSI devices the iSCSI driver is controlling.\r
779ae357 181\r
669314e5 182 @retval EFI_SUCCESS The callback successfully handled the action.\r
963dbb30 183 @retval Others Other errors as indicated. \r
12618416 184**/\r
185EFI_STATUS\r
186IScsiUpdateDeviceList (\r
187 VOID\r
188 )\r
6a690e23 189{\r
190 EFI_STATUS Status;\r
191 ISCSI_DEVICE_LIST *DeviceList;\r
192 UINTN DataSize;\r
193 UINTN NumHandles;\r
194 EFI_HANDLE *Handles;\r
195 UINTN HandleIndex;\r
196 UINTN Index;\r
197 UINTN LastDeviceIndex;\r
779ae357 198 EFI_MAC_ADDRESS MacAddress;\r
199 UINTN HwAddressSize;\r
200 UINT16 VlanId;\r
6a690e23 201 ISCSI_MAC_INFO *CurMacInfo;\r
202 ISCSI_MAC_INFO TempMacInfo;\r
779ae357 203 CHAR16 MacString[70];\r
6a690e23 204 UINTN DeviceListSize;\r
205\r
206 //\r
779ae357 207 // Dump all the handles the Managed Network Service Binding Protocol is installed on.\r
6a690e23 208 //\r
209 Status = gBS->LocateHandleBuffer (\r
210 ByProtocol,\r
779ae357 211 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
6a690e23 212 NULL,\r
213 &NumHandles,\r
214 &Handles\r
215 );\r
216 if (EFI_ERROR (Status)) {\r
217 return Status;\r
218 }\r
219\r
220 DataSize = 0;\r
221 Status = gRT->GetVariable (\r
222 L"iSCSIDeviceList",\r
c8ad2d7a 223 &gIp4IScsiConfigGuid,\r
6a690e23 224 NULL,\r
225 &DataSize,\r
226 NULL\r
227 );\r
228 if (Status == EFI_BUFFER_TOO_SMALL) {\r
e48e37fc 229 DeviceList = (ISCSI_DEVICE_LIST *) AllocatePool (DataSize);\r
6a690e23 230\r
231 gRT->GetVariable (\r
232 L"iSCSIDeviceList",\r
c8ad2d7a 233 &gIp4IScsiConfigGuid,\r
6a690e23 234 NULL,\r
235 &DataSize,\r
236 DeviceList\r
237 );\r
238\r
239 LastDeviceIndex = 0;\r
240\r
241 for (HandleIndex = 0; HandleIndex < NumHandles; HandleIndex++) {\r
779ae357 242 Status = NetLibGetMacAddress (Handles[HandleIndex], &MacAddress, &HwAddressSize);\r
243 ASSERT (Status == EFI_SUCCESS);\r
244 VlanId = NetLibGetVlanId (Handles[HandleIndex]);\r
6a690e23 245\r
246 for (Index = LastDeviceIndex; Index < DeviceList->NumDevice; Index++) {\r
247 CurMacInfo = &DeviceList->MacInfo[Index];\r
779ae357 248 if ((CurMacInfo->Len == HwAddressSize) &&\r
249 (CurMacInfo->VlanId == VlanId) &&\r
250 (NET_MAC_EQUAL (&CurMacInfo->Mac, MacAddress.Addr, HwAddressSize))\r
6a690e23 251 ) {\r
252 //\r
253 // The previous configured NIC is still here.\r
254 //\r
255 if (Index != LastDeviceIndex) {\r
256 //\r
257 // Swap the current MAC address entry with the one indexed by\r
258 // LastDeviceIndex.\r
259 //\r
e48e37fc 260 CopyMem (&TempMacInfo, CurMacInfo, sizeof (ISCSI_MAC_INFO));\r
261 CopyMem (CurMacInfo, &DeviceList->MacInfo[LastDeviceIndex], sizeof (ISCSI_MAC_INFO));\r
262 CopyMem (&DeviceList->MacInfo[LastDeviceIndex], &TempMacInfo, sizeof (ISCSI_MAC_INFO));\r
6a690e23 263 }\r
264\r
265 LastDeviceIndex++;\r
266 }\r
267 }\r
268\r
269 if (LastDeviceIndex == DeviceList->NumDevice) {\r
270 break;\r
271 }\r
272 }\r
273\r
274 for (Index = LastDeviceIndex; Index < DeviceList->NumDevice; Index++) {\r
275 //\r
276 // delete the variables\r
277 //\r
278 CurMacInfo = &DeviceList->MacInfo[Index];\r
779ae357 279 IScsiMacAddrToStr (&CurMacInfo->Mac, CurMacInfo->Len, CurMacInfo->VlanId, MacString);\r
6a690e23 280 gRT->SetVariable (MacString, &gEfiIScsiInitiatorNameProtocolGuid, 0, 0, NULL);\r
c8ad2d7a 281 gRT->SetVariable (MacString, &gIScsiCHAPAuthInfoGuid, 0, 0, NULL);\r
6a690e23 282 }\r
283\r
766c7483 284 FreePool (DeviceList);\r
6a690e23 285 } else if (Status != EFI_NOT_FOUND) {\r
766c7483 286 FreePool (Handles);\r
6a690e23 287 return Status;\r
288 }\r
289 //\r
290 // Construct the new iSCSI device list.\r
291 //\r
292 DeviceListSize = sizeof (ISCSI_DEVICE_LIST) + (NumHandles - 1) * sizeof (ISCSI_MAC_INFO);\r
e48e37fc 293 DeviceList = (ISCSI_DEVICE_LIST *) AllocatePool (DeviceListSize);\r
6a690e23 294 DeviceList->NumDevice = (UINT8) NumHandles;\r
295\r
296 for (Index = 0; Index < NumHandles; Index++) {\r
779ae357 297 NetLibGetMacAddress (Handles[Index], &MacAddress, &HwAddressSize);\r
6a690e23 298\r
299 CurMacInfo = &DeviceList->MacInfo[Index];\r
779ae357 300 CopyMem (&CurMacInfo->Mac, MacAddress.Addr, HwAddressSize);\r
301 CurMacInfo->Len = (UINT8) HwAddressSize;\r
302 CurMacInfo->VlanId = NetLibGetVlanId (Handles[Index]);\r
6a690e23 303 }\r
304\r
305 gRT->SetVariable (\r
306 L"iSCSIDeviceList",\r
c8ad2d7a 307 &gIp4IScsiConfigGuid,\r
6a690e23 308 ISCSI_CONFIG_VAR_ATTR,\r
309 DeviceListSize,\r
310 DeviceList\r
311 );\r
312\r
766c7483 313 FreePool (DeviceList);\r
314 FreePool (Handles);\r
6a690e23 315\r
316 return Status;\r
317}\r
318\r
12618416 319/**\r
320 Get the iSCSI configuration form entry by the index of the goto opcode actived.\r
321\r
669314e5 322 @param[in] Index The 0-based index of the goto opcode actived.\r
12618416 323\r
669314e5 324 @return The iSCSI configuration form entry found.\r
12618416 325**/\r
6a690e23 326ISCSI_CONFIG_FORM_ENTRY *\r
327IScsiGetConfigFormEntryByIndex (\r
328 IN UINT32 Index\r
329 )\r
6a690e23 330{\r
331 UINT32 CurrentIndex;\r
e48e37fc 332 LIST_ENTRY *Entry;\r
6a690e23 333 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
334\r
335 CurrentIndex = 0;\r
336 ConfigFormEntry = NULL;\r
337\r
338 NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) {\r
339 if (CurrentIndex == Index) {\r
340 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link);\r
341 break;\r
342 }\r
343\r
344 CurrentIndex++;\r
345 }\r
346\r
347 return ConfigFormEntry;\r
348}\r
349\r
12618416 350/**\r
351 Convert the iSCSI configuration data into the IFR data.\r
352\r
c5de0d55 353 @param[in] ConfigFormEntry The iSCSI configuration form entry.\r
354 @param[out] IfrNvData The IFR nv data.\r
312e3bdf 355\r
12618416 356**/\r
6a690e23 357VOID\r
358IScsiConvertDeviceConfigDataToIfrNvData (\r
c5de0d55 359 IN ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry,\r
360 OUT ISCSI_CONFIG_IFR_NVDATA *IfrNvData\r
6a690e23 361 )\r
6a690e23 362{\r
363 ISCSI_SESSION_CONFIG_NVDATA *SessionConfigData;\r
364 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfigData;\r
365\r
366 //\r
367 // Normal session configuration parameters.\r
368 //\r
369 SessionConfigData = &ConfigFormEntry->SessionConfigData;\r
370 IfrNvData->Enabled = SessionConfigData->Enabled;\r
371\r
372 IfrNvData->InitiatorInfoFromDhcp = SessionConfigData->InitiatorInfoFromDhcp;\r
373 IfrNvData->TargetInfoFromDhcp = SessionConfigData->TargetInfoFromDhcp;\r
374 IfrNvData->TargetPort = SessionConfigData->TargetPort;\r
375\r
376 IScsiIpToStr (&SessionConfigData->LocalIp, IfrNvData->LocalIp);\r
377 IScsiIpToStr (&SessionConfigData->SubnetMask, IfrNvData->SubnetMask);\r
378 IScsiIpToStr (&SessionConfigData->Gateway, IfrNvData->Gateway);\r
379 IScsiIpToStr (&SessionConfigData->TargetIp, IfrNvData->TargetIp);\r
380\r
381 IScsiAsciiStrToUnicodeStr (SessionConfigData->TargetName, IfrNvData->TargetName);\r
382\r
383 IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->BootLun);\r
384\r
312e3bdf 385 IScsiConvertIsIdToString (IfrNvData->IsId, SessionConfigData->IsId);\r
386\r
6a690e23 387 //\r
388 // CHAP authentication parameters.\r
389 //\r
390 AuthConfigData = &ConfigFormEntry->AuthConfigData;\r
391\r
392 IfrNvData->CHAPType = AuthConfigData->CHAPType;\r
393\r
394 IScsiAsciiStrToUnicodeStr (AuthConfigData->CHAPName, IfrNvData->CHAPName);\r
395 IScsiAsciiStrToUnicodeStr (AuthConfigData->CHAPSecret, IfrNvData->CHAPSecret);\r
396 IScsiAsciiStrToUnicodeStr (AuthConfigData->ReverseCHAPName, IfrNvData->ReverseCHAPName);\r
397 IScsiAsciiStrToUnicodeStr (AuthConfigData->ReverseCHAPSecret, IfrNvData->ReverseCHAPSecret);\r
398}\r
399\r
12618416 400/**\r
669314e5 401 This function allows the caller to request the current\r
402 configuration for one or more named elements. The resulting\r
403 string is in <ConfigAltResp> format. Any and all alternative\r
404 configuration strings shall also be appended to the end of the\r
405 current configuration string. If they are, they must appear\r
406 after the current configuration. They must contain the same\r
407 routing (GUID, NAME, PATH) as the current configuration string.\r
408 They must have an additional description indicating the type of\r
409 alternative configuration the string represents,\r
410 "ALTCFG=<StringToken>". That <StringToken> (when\r
411 converted from Hex UNICODE to binary) is a reference to a\r
412 string in the associated string pack.\r
413\r
414 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
415 @param[in] Request A null-terminated Unicode string in\r
416 <ConfigRequest> format. Note that this\r
417 includes the routing information as well as\r
418 the configurable name / value pairs. It is\r
419 invalid for this string to be in\r
420 <MultiConfigRequest> format.\r
421 @param[out] Progress On return, points to a character in the\r
422 Request string. Points to the string's null\r
423 terminator if request was successful. Points\r
424 to the most recent "&" before the first\r
425 failing name / value pair (or the beginning\r
426 of the string if the failure is in the first\r
427 name / value pair) if the request was not\r
428 successful.\r
429 @param[out] Results A null-terminated Unicode string in\r
430 <ConfigAltResp> format which has all values\r
431 filled in for the names in the Request string.\r
432 String to be allocated by the called function.\r
433\r
434 @retval EFI_SUCCESS The Results string is filled with the\r
435 values corresponding to all requested\r
436 names.\r
437 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
438 parts of the results that must be\r
439 stored awaiting possible future\r
440 protocols.\r
441 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
442 for the Request parameter\r
443 would result in this type of\r
444 error. In this case, the\r
445 Progress parameter would be\r
446 set to NULL. \r
447 @retval EFI_NOT_FOUND Routing data doesn't match any\r
448 known driver. Progress set to the\r
449 first character in the routing header.\r
450 Note: There is no requirement that the\r
451 driver validate the routing data. It\r
452 must skip the <ConfigHdr> in order to\r
453 process the names.\r
454 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
455 to most recent & before the\r
456 error or the beginning of the\r
457 string.\r
458 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
459 to the & before the name in\r
460 question.Currently not implemented.\r
12618416 461**/\r
6a690e23 462EFI_STATUS\r
463EFIAPI\r
93e3992d 464IScsiFormExtractConfig (\r
465 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
466 IN CONST EFI_STRING Request,\r
467 OUT EFI_STRING *Progress,\r
468 OUT EFI_STRING *Results\r
6a690e23 469 )\r
6a690e23 470{\r
93e3992d 471 EFI_STATUS Status;\r
4da9ccc9 472 CHAR8 InitiatorName[ISCSI_NAME_MAX_SIZE];\r
93e3992d 473 UINTN BufferSize;\r
474 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
475 ISCSI_FORM_CALLBACK_INFO *Private;\r
476 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
59aefb7e
LG
477 EFI_STRING ConfigRequestHdr;\r
478 EFI_STRING ConfigRequest;\r
479 BOOLEAN AllocatedRequest;\r
480 UINTN Size;\r
6a690e23 481\r
59aefb7e 482 if (Progress == NULL || Results == NULL) {\r
669314e5 483 return EFI_INVALID_PARAMETER;\r
8d00a0f1 484 }\r
59aefb7e 485\r
ae79d2f9 486 *Progress = Request;\r
c8ad2d7a 487 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gIp4IScsiConfigGuid, mVendorStorageName)) {\r
59aefb7e
LG
488 return EFI_NOT_FOUND;\r
489 }\r
490\r
491 ConfigRequestHdr = NULL;\r
492 ConfigRequest = NULL;\r
493 AllocatedRequest = FALSE;\r
494 Size = 0;\r
8d00a0f1 495\r
6a690e23 496 if (!mIScsiDeviceListUpdated) {\r
497 //\r
498 // Update the device list.\r
499 //\r
500 IScsiUpdateDeviceList ();\r
501 mIScsiDeviceListUpdated = TRUE;\r
502 }\r
503\r
93e3992d 504 Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
505 IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
506 ASSERT (IfrNvData != NULL);\r
507 if (Private->Current != NULL) {\r
508 IScsiConvertDeviceConfigDataToIfrNvData (Private->Current, IfrNvData);\r
509 }\r
6a690e23 510\r
4da9ccc9 511 BufferSize = ISCSI_NAME_MAX_SIZE;\r
6a690e23 512 Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);\r
513 if (EFI_ERROR (Status)) {\r
514 IfrNvData->InitiatorName[0] = L'\0';\r
515 } else {\r
516 IScsiAsciiStrToUnicodeStr (InitiatorName, IfrNvData->InitiatorName);\r
517 }\r
518\r
93e3992d 519 //\r
520 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
521 //\r
522 HiiConfigRouting = Private->ConfigRouting;\r
523 BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);\r
59aefb7e
LG
524 ConfigRequest = Request;\r
525 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
526 //\r
527 // Request has no request element, construct full request string.\r
528 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
529 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
530 //\r
c8ad2d7a 531 ConfigRequestHdr = HiiConstructConfigHdr (&gIp4IScsiConfigGuid, mVendorStorageName, Private->DriverHandle);\r
59aefb7e
LG
532 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
533 ConfigRequest = AllocateZeroPool (Size);\r
534 ASSERT (ConfigRequest != NULL);\r
535 AllocatedRequest = TRUE;\r
536 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
537 FreePool (ConfigRequestHdr);\r
538 }\r
93e3992d 539 Status = HiiConfigRouting->BlockToConfig (\r
540 HiiConfigRouting,\r
59aefb7e 541 ConfigRequest,\r
93e3992d 542 (UINT8 *) IfrNvData,\r
543 BufferSize,\r
544 Results,\r
545 Progress\r
546 );\r
766c7483 547 FreePool (IfrNvData);\r
59aefb7e
LG
548 //\r
549 // Free the allocated config request string.\r
550 //\r
551 if (AllocatedRequest) {\r
552 FreePool (ConfigRequest);\r
553 ConfigRequest = NULL;\r
554 }\r
555\r
556 //\r
557 // Set Progress string to the original request string.\r
558 //\r
559 if (Request == NULL) {\r
560 *Progress = NULL;\r
561 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
562 *Progress = Request + StrLen (Request);\r
563 }\r
564\r
93e3992d 565 return Status;\r
6a690e23 566}\r
567\r
12618416 568/**\r
669314e5 569 This function applies changes in a driver's configuration.\r
570 Input is a Configuration, which has the routing data for this\r
571 driver followed by name / value configuration pairs. The driver\r
572 must apply those pairs to its configurable storage. If the\r
573 driver's configuration is stored in a linear block of data\r
55a64ae0 574 and the driver's name / value pairs are in <BlockConfig>\r
669314e5 575 format, it may use the ConfigToBlock helper function (above) to\r
576 simplify the job. Currently not implemented.\r
577\r
578 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
579 @param[in] Configuration A null-terminated Unicode string in\r
580 <ConfigString> format. \r
581 @param[out] Progress A pointer to a string filled in with the\r
582 offset of the most recent '&' before the\r
583 first failing name / value pair (or the\r
584 beginn ing of the string if the failure\r
585 is in the first name / value pair) or\r
586 the terminating NULL if all was\r
587 successful.\r
588\r
589 @retval EFI_SUCCESS The results have been distributed or are\r
590 awaiting distribution. \r
e1f1fb16 591 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
669314e5 592 parts of the results that must be\r
593 stored awaiting possible future\r
594 protocols.\r
595 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
596 Results parameter would result\r
597 in this type of error.\r
598 @retval EFI_NOT_FOUND Target for the specified routing data\r
599 was not found.\r
12618416 600**/\r
6a690e23 601EFI_STATUS\r
602EFIAPI\r
93e3992d 603IScsiFormRouteConfig (\r
604 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
605 IN CONST EFI_STRING Configuration,\r
606 OUT EFI_STRING *Progress\r
6a690e23 607 )\r
12618416 608{\r
ae79d2f9
LG
609 if (Configuration == NULL || Progress == NULL) {\r
610 return EFI_INVALID_PARAMETER;\r
611 }\r
612\r
613 //\r
614 // Check routing data in <ConfigHdr>.\r
615 // Note: if only one Storage is used, then this checking could be skipped.\r
616 //\r
c8ad2d7a 617 if (!HiiIsConfigHdrMatch (Configuration, &gIp4IScsiConfigGuid, mVendorStorageName)) {\r
ae79d2f9
LG
618 *Progress = Configuration;\r
619 return EFI_NOT_FOUND;\r
620 }\r
621\r
622 *Progress = Configuration + StrLen (Configuration);\r
12618416 623 return EFI_SUCCESS;\r
624}\r
6a690e23 625\r
12618416 626/**\r
669314e5 627 This function is called to provide results data to the driver.\r
628 This data consists of a unique key that is used to identify\r
629 which data is either being passed back or being asked for.\r
630\r
631 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
632 @param[in] Action Specifies the type of action taken by the browser.\r
633 @param[in] QuestionId A unique value which is sent to the original\r
634 exporting driver so that it can identify the type\r
635 of data to expect. The format of the data tends to \r
636 vary based on the opcode that enerated the callback.\r
637 @param[in] Type The type of value for the question.\r
638 @param[in] Value A pointer to the data being sent to the original\r
639 exporting driver.\r
640 @param[out] ActionRequest On return, points to the action requested by the\r
641 callback function.\r
642\r
643 @retval EFI_SUCCESS The callback successfully handled the action.\r
644 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
645 variable and its data.\r
646 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
647 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
648 callback.Currently not implemented.\r
649 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter. \r
963dbb30 650 @retval Others Other errors as indicated. \r
12618416 651**/\r
93e3992d 652EFI_STATUS\r
653EFIAPI\r
654IScsiFormCallback (\r
655 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
f3e1569d 656 IN EFI_BROWSER_ACTION Action,\r
669314e5 657 IN EFI_QUESTION_ID QuestionId,\r
93e3992d 658 IN UINT8 Type,\r
659 IN EFI_IFR_TYPE_VALUE *Value,\r
660 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
661 )\r
6a690e23 662{\r
663 ISCSI_FORM_CALLBACK_INFO *Private;\r
664 UINTN BufferSize;\r
4da9ccc9 665 CHAR8 IScsiName[ISCSI_NAME_MAX_SIZE];\r
6a690e23 666 CHAR16 PortString[128];\r
667 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
668 CHAR8 LunString[ISCSI_LUN_STR_MAX_LEN];\r
669 UINT64 Lun;\r
6c7a807a 670 EFI_STRING_ID DeviceFormTitleToken;\r
6a690e23 671 ISCSI_CONFIG_IFR_NVDATA *IfrNvData;\r
672 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
673 EFI_IP_ADDRESS HostIp;\r
674 EFI_IP_ADDRESS SubnetMask;\r
675 EFI_IP_ADDRESS Gateway;\r
676 EFI_STATUS Status;\r
63d55bb9 677 EFI_INPUT_KEY Key;\r
6a690e23 678\r
083f7c69
ED
679 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
680 Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
5adb8db7 681 //\r
083f7c69 682 // Retrive uncommitted data from Browser\r
5adb8db7 683 //\r
083f7c69
ED
684 IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));\r
685 ASSERT (IfrNvData != NULL);\r
c8ad2d7a 686 if (!HiiGetBrowserData (&gIp4IScsiConfigGuid, mVendorStorageName, sizeof (ISCSI_CONFIG_IFR_NVDATA), (UINT8 *) IfrNvData)) {\r
083f7c69
ED
687 FreePool (IfrNvData);\r
688 return EFI_NOT_FOUND;\r
689 }\r
690 Status = EFI_SUCCESS;\r
6a690e23 691\r
083f7c69
ED
692 switch (QuestionId) {\r
693 case KEY_INITIATOR_NAME:\r
694 IScsiUnicodeStrToAsciiStr (IfrNvData->InitiatorName, IScsiName);\r
695 BufferSize = AsciiStrSize (IScsiName);\r
6a690e23 696\r
083f7c69
ED
697 Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, IScsiName);\r
698 if (EFI_ERROR (Status)) {\r
699 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid iSCSI Name!", NULL);\r
700 }\r
6a690e23 701\r
083f7c69 702 break;\r
6a690e23 703\r
083f7c69
ED
704 case KEY_LOCAL_IP:\r
705 IScsiUnicodeStrToAsciiStr (IfrNvData->LocalIp, Ip4String);\r
706 Status = IScsiAsciiStrToIp (Ip4String, &HostIp.v4);\r
707 if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
708 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
709 Status = EFI_INVALID_PARAMETER;\r
710 } else {\r
711 CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
712 }\r
6a690e23 713\r
083f7c69 714 break;\r
6a690e23 715\r
083f7c69
ED
716 case KEY_SUBNET_MASK:\r
717 IScsiUnicodeStrToAsciiStr (IfrNvData->SubnetMask, Ip4String);\r
718 Status = IScsiAsciiStrToIp (Ip4String, &SubnetMask.v4);\r
719 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
720 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);\r
721 Status = EFI_INVALID_PARAMETER;\r
722 } else {\r
723 CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
724 }\r
6a690e23 725\r
083f7c69 726 break;\r
6a690e23 727\r
083f7c69
ED
728 case KEY_GATE_WAY:\r
729 IScsiUnicodeStrToAsciiStr (IfrNvData->Gateway, Ip4String);\r
730 Status = IScsiAsciiStrToIp (Ip4String, &Gateway.v4);\r
731 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
732 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
733 Status = EFI_INVALID_PARAMETER;\r
734 } else {\r
735 CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
736 }\r
6a690e23 737\r
083f7c69 738 break;\r
6a690e23 739\r
083f7c69
ED
740 case KEY_TARGET_IP:\r
741 IScsiUnicodeStrToAsciiStr (IfrNvData->TargetIp, Ip4String);\r
742 Status = IScsiAsciiStrToIp (Ip4String, &HostIp.v4);\r
743 if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
744 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
745 Status = EFI_INVALID_PARAMETER;\r
746 } else {\r
747 CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp.v4, sizeof (HostIp.v4));\r
748 }\r
6a690e23 749\r
083f7c69 750 break;\r
6a690e23 751\r
083f7c69
ED
752 case KEY_TARGET_NAME:\r
753 IScsiUnicodeStrToAsciiStr (IfrNvData->TargetName, IScsiName);\r
754 Status = IScsiNormalizeName (IScsiName, AsciiStrLen (IScsiName));\r
755 if (EFI_ERROR (Status)) {\r
756 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid iSCSI Name!", NULL);\r
757 } else {\r
758 AsciiStrCpy (Private->Current->SessionConfigData.TargetName, IScsiName);\r
759 }\r
6a690e23 760\r
083f7c69 761 break;\r
6a690e23 762\r
083f7c69
ED
763 case KEY_DHCP_ENABLE:\r
764 if (IfrNvData->InitiatorInfoFromDhcp == 0) {\r
765 IfrNvData->TargetInfoFromDhcp = 0;\r
766 }\r
6a690e23 767\r
083f7c69 768 break;\r
6a690e23 769\r
083f7c69
ED
770 case KEY_BOOT_LUN:\r
771 IScsiUnicodeStrToAsciiStr (IfrNvData->BootLun, LunString);\r
772 Status = IScsiAsciiStrToLun (LunString, (UINT8 *) &Lun);\r
773 if (EFI_ERROR (Status)) {\r
774 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid LUN string!", NULL);\r
775 } else {\r
776 CopyMem (Private->Current->SessionConfigData.BootLun, &Lun, sizeof (Lun));\r
777 }\r
6a690e23 778\r
083f7c69 779 break;\r
6a690e23 780\r
083f7c69
ED
781 case KEY_CHAP_NAME:\r
782 IScsiUnicodeStrToAsciiStr (IfrNvData->CHAPName, Private->Current->AuthConfigData.CHAPName);\r
783 break;\r
6a690e23 784\r
083f7c69
ED
785 case KEY_CHAP_SECRET:\r
786 IScsiUnicodeStrToAsciiStr (IfrNvData->CHAPSecret, Private->Current->AuthConfigData.CHAPSecret);\r
787 break;\r
6a690e23 788\r
083f7c69
ED
789 case KEY_REVERSE_CHAP_NAME:\r
790 IScsiUnicodeStrToAsciiStr (IfrNvData->ReverseCHAPName, Private->Current->AuthConfigData.ReverseCHAPName);\r
791 break;\r
6a690e23 792\r
083f7c69
ED
793 case KEY_REVERSE_CHAP_SECRET:\r
794 IScsiUnicodeStrToAsciiStr (IfrNvData->ReverseCHAPSecret, Private->Current->AuthConfigData.ReverseCHAPSecret);\r
795 break;\r
6a690e23 796\r
083f7c69
ED
797 case KEY_CONFIG_ISID:\r
798 IScsiParseIsIdFromString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
799 IScsiConvertIsIdToString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);\r
312e3bdf 800\r
083f7c69 801 break;\r
312e3bdf 802\r
083f7c69
ED
803 case KEY_SAVE_CHANGES:\r
804 //\r
805 // First, update those fields which don't have INTERACTIVE set.\r
806 //\r
807 Private->Current->SessionConfigData.Enabled = IfrNvData->Enabled;\r
808 Private->Current->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->InitiatorInfoFromDhcp;\r
809 Private->Current->SessionConfigData.TargetPort = IfrNvData->TargetPort;\r
810 if (Private->Current->SessionConfigData.TargetPort == 0) {\r
811 Private->Current->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;\r
812 }\r
6a690e23 813\r
083f7c69
ED
814 Private->Current->SessionConfigData.TargetInfoFromDhcp = IfrNvData->TargetInfoFromDhcp;\r
815 Private->Current->AuthConfigData.CHAPType = IfrNvData->CHAPType;\r
6a690e23 816\r
6a690e23 817 //\r
083f7c69 818 // Only do full parameter validation if iSCSI is enabled on this device.\r
6a690e23 819 //\r
083f7c69
ED
820 if (Private->Current->SessionConfigData.Enabled) {\r
821 //\r
822 // Validate the address configuration of the Initiator if DHCP isn't\r
823 // deployed.\r
824 //\r
825 if (!Private->Current->SessionConfigData.InitiatorInfoFromDhcp) {\r
826 CopyMem (&HostIp.v4, &Private->Current->SessionConfigData.LocalIp, sizeof (HostIp.v4));\r
827 CopyMem (&SubnetMask.v4, &Private->Current->SessionConfigData.SubnetMask, sizeof (SubnetMask.v4));\r
828 CopyMem (&Gateway.v4, &Private->Current->SessionConfigData.Gateway, sizeof (Gateway.v4));\r
829\r
830 if ((Gateway.Addr[0] != 0)) {\r
831 if (SubnetMask.Addr[0] == 0) {\r
832 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
833 Status = EFI_INVALID_PARAMETER;\r
834 break;\r
835 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
836 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
837 Status = EFI_INVALID_PARAMETER;\r
838 break;\r
839 }\r
840 }\r
841 }\r
842 //\r
843 // Validate target configuration if DHCP isn't deployed.\r
844 //\r
845 if (!Private->Current->SessionConfigData.TargetInfoFromDhcp) {\r
846 CopyMem (&HostIp.v4, &Private->Current->SessionConfigData.TargetIp, sizeof (HostIp.v4));\r
847 if (!NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
848 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Target IP is invalid!", NULL);\r
6a690e23 849 Status = EFI_INVALID_PARAMETER;\r
850 break;\r
851 }\r
852 }\r
6a690e23 853\r
083f7c69
ED
854 if (IfrNvData->CHAPType != ISCSI_CHAP_NONE) {\r
855 if ((IfrNvData->CHAPName[0] == '\0') || (IfrNvData->CHAPSecret[0] == '\0')) {\r
856 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"CHAP Name or CHAP Secret is invalid!", NULL);\r
857 Status = EFI_INVALID_PARAMETER;\r
858 break;\r
859 }\r
6a690e23 860\r
083f7c69
ED
861 if ((IfrNvData->CHAPType == ISCSI_CHAP_MUTUAL) &&\r
862 ((IfrNvData->ReverseCHAPName[0] == '\0') || (IfrNvData->ReverseCHAPSecret[0] == '\0'))\r
863 ) {\r
864 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Reverse CHAP Name or Reverse CHAP Secret is invalid!", NULL);\r
865 Status = EFI_INVALID_PARAMETER;\r
866 break;\r
867 }\r
6a690e23 868 }\r
869 }\r
6a690e23 870\r
083f7c69
ED
871 BufferSize = sizeof (Private->Current->SessionConfigData);\r
872 gRT->SetVariable (\r
873 Private->Current->MacString,\r
874 &gEfiIScsiInitiatorNameProtocolGuid,\r
875 ISCSI_CONFIG_VAR_ATTR,\r
876 BufferSize,\r
877 &Private->Current->SessionConfigData\r
878 );\r
879\r
880 BufferSize = sizeof (Private->Current->AuthConfigData);\r
881 gRT->SetVariable (\r
882 Private->Current->MacString,\r
c8ad2d7a 883 &gIScsiCHAPAuthInfoGuid,\r
083f7c69
ED
884 ISCSI_CONFIG_VAR_ATTR,\r
885 BufferSize,\r
886 &Private->Current->AuthConfigData\r
887 );\r
e7fe4028 888 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
083f7c69 889 break;\r
6a690e23 890\r
083f7c69
ED
891 default:\r
892 if ((QuestionId >= KEY_DEVICE_ENTRY_BASE) && (QuestionId < (mNumberOfIScsiDevices + KEY_DEVICE_ENTRY_BASE))) {\r
893 //\r
894 // In case goto the device configuration form, update the device form title.\r
895 //\r
896 ConfigFormEntry = IScsiGetConfigFormEntryByIndex ((UINT32) (QuestionId - KEY_DEVICE_ENTRY_BASE));\r
897 ASSERT (ConfigFormEntry != NULL);\r
6a690e23 898\r
083f7c69
ED
899 UnicodeSPrint (PortString, (UINTN) 128, L"Port %s", ConfigFormEntry->MacString);\r
900 DeviceFormTitleToken = (EFI_STRING_ID) STR_ISCSI_DEVICE_FORM_TITLE;\r
901 HiiSetString (Private->RegisteredHandle, DeviceFormTitleToken, PortString, NULL);\r
6a690e23 902\r
083f7c69 903 IScsiConvertDeviceConfigDataToIfrNvData (ConfigFormEntry, IfrNvData);\r
6a690e23 904\r
083f7c69
ED
905 Private->Current = ConfigFormEntry;\r
906 }\r
6a690e23 907\r
083f7c69 908 break;\r
6a690e23 909 }\r
910\r
083f7c69
ED
911 if (!EFI_ERROR (Status)) {\r
912 //\r
913 // Pass changed uncommitted data back to Form Browser\r
914 //\r
c8ad2d7a 915 HiiSetBrowserData (&gIp4IScsiConfigGuid, mVendorStorageName, sizeof (ISCSI_CONFIG_IFR_NVDATA), (UINT8 *) IfrNvData, NULL);\r
083f7c69
ED
916 }\r
917 \r
918 FreePool (IfrNvData);\r
6a690e23 919\r
083f7c69 920 return Status;\r
93e3992d 921 }\r
922\r
083f7c69
ED
923 //\r
924 // All other action return unsupported.\r
925 //\r
926 return EFI_UNSUPPORTED;\r
6a690e23 927}\r
928\r
12618416 929/**\r
6a690e23 930 Updates the iSCSI configuration form to add/delete an entry for the iSCSI\r
931 device specified by the Controller.\r
932\r
669314e5 933 @param[in] DriverBindingHandle The driverbinding handle.\r
934 @param[in] Controller The controller handle of the iSCSI device.\r
935 @param[in] AddForm Whether to add or delete a form entry.\r
6a690e23 936\r
12618416 937 @retval EFI_SUCCESS The iSCSI configuration form is updated.\r
12618416 938 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
963dbb30 939 @retval Others Other errors as indicated.\r
12618416 940**/\r
941EFI_STATUS\r
942IScsiConfigUpdateForm (\r
943 IN EFI_HANDLE DriverBindingHandle,\r
944 IN EFI_HANDLE Controller,\r
945 IN BOOLEAN AddForm\r
946 )\r
6a690e23 947{\r
e48e37fc 948 LIST_ENTRY *Entry;\r
6a690e23 949 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
950 BOOLEAN EntryExisted;\r
6a690e23 951 EFI_STATUS Status;\r
779ae357 952 EFI_MAC_ADDRESS MacAddress;\r
953 UINTN HwAddressSize;\r
954 UINT16 VlanId;\r
6a690e23 955 CHAR16 PortString[128];\r
956 UINT16 FormIndex;\r
957 UINTN BufferSize;\r
7e3bcccb
LG
958 VOID *StartOpCodeHandle;\r
959 VOID *EndOpCodeHandle;\r
960 EFI_IFR_GUID_LABEL *StartLabel;\r
961 EFI_IFR_GUID_LABEL *EndLabel;\r
6a690e23 962\r
963 ConfigFormEntry = NULL;\r
964 EntryExisted = FALSE;\r
965\r
966 NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) {\r
967 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link);\r
968\r
969 if (ConfigFormEntry->Controller == Controller) {\r
970 EntryExisted = TRUE;\r
971 break;\r
972 }\r
973 }\r
974\r
975 if (AddForm) {\r
976 if (EntryExisted) {\r
977 return EFI_SUCCESS;\r
978 } else {\r
979 //\r
980 // Add a new form.\r
981 //\r
e48e37fc 982 ConfigFormEntry = (ISCSI_CONFIG_FORM_ENTRY *) AllocateZeroPool (sizeof (ISCSI_CONFIG_FORM_ENTRY));\r
6a690e23 983 if (ConfigFormEntry == NULL) {\r
984 return EFI_OUT_OF_RESOURCES;\r
985 }\r
986\r
e48e37fc 987 InitializeListHead (&ConfigFormEntry->Link);\r
6a690e23 988 ConfigFormEntry->Controller = Controller;\r
989\r
990 //\r
779ae357 991 // Get the MAC address and convert it into the formatted string.\r
6a690e23 992 //\r
779ae357 993 Status = NetLibGetMacAddress (Controller, &MacAddress, &HwAddressSize);\r
6a690e23 994 ASSERT (Status == EFI_SUCCESS);\r
779ae357 995 VlanId = NetLibGetVlanId (Controller);\r
6a690e23 996\r
779ae357 997 IScsiMacAddrToStr (&MacAddress, (UINT32) HwAddressSize, VlanId, ConfigFormEntry->MacString);\r
6a690e23 998\r
999 //\r
1000 // Get the normal session configuration data.\r
1001 //\r
1002 BufferSize = sizeof (ConfigFormEntry->SessionConfigData);\r
1003 Status = gRT->GetVariable (\r
1004 ConfigFormEntry->MacString,\r
1005 &gEfiIScsiInitiatorNameProtocolGuid,\r
1006 NULL,\r
1007 &BufferSize,\r
1008 &ConfigFormEntry->SessionConfigData\r
1009 );\r
1010 if (EFI_ERROR (Status)) {\r
e48e37fc 1011 ZeroMem (&ConfigFormEntry->SessionConfigData, sizeof (ConfigFormEntry->SessionConfigData));\r
312e3bdf 1012 \r
1013 //\r
1014 // Generate OUI-format ISID based on MAC address.\r
1015 //\r
1016 CopyMem (ConfigFormEntry->SessionConfigData.IsId, &MacAddress, 6);\r
1017 ConfigFormEntry->SessionConfigData.IsId[0] = \r
b97a8d35 1018 (UINT8) (ConfigFormEntry->SessionConfigData.IsId[0] & 0x3F);\r
6a690e23 1019 }\r
1020 //\r
1021 // Get the CHAP authentication configuration data.\r
1022 //\r
1023 BufferSize = sizeof (ConfigFormEntry->AuthConfigData);\r
1024 Status = gRT->GetVariable (\r
1025 ConfigFormEntry->MacString,\r
c8ad2d7a 1026 &gIScsiCHAPAuthInfoGuid,\r
6a690e23 1027 NULL,\r
1028 &BufferSize,\r
1029 &ConfigFormEntry->AuthConfigData\r
1030 );\r
1031 if (EFI_ERROR (Status)) {\r
e48e37fc 1032 ZeroMem (&ConfigFormEntry->AuthConfigData, sizeof (ConfigFormEntry->AuthConfigData));\r
6a690e23 1033 }\r
1034 //\r
6c7a807a 1035 // Compose the Port string and create a new EFI_STRING_ID.\r
6a690e23 1036 //\r
1037 UnicodeSPrint (PortString, 128, L"Port %s", ConfigFormEntry->MacString);\r
cb7d01c0 1038 ConfigFormEntry->PortTitleToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, PortString, NULL);\r
6a690e23 1039\r
1040 //\r
6c7a807a 1041 // Compose the help string of this port and create a new EFI_STRING_ID.\r
6a690e23 1042 //\r
1043 UnicodeSPrint (PortString, 128, L"Set the iSCSI parameters on port %s", ConfigFormEntry->MacString);\r
cb7d01c0 1044 ConfigFormEntry->PortTitleHelpToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, PortString, NULL);\r
6a690e23 1045\r
e48e37fc 1046 InsertTailList (&mIScsiConfigFormList, &ConfigFormEntry->Link);\r
6a690e23 1047 mNumberOfIScsiDevices++;\r
1048 }\r
1049 } else {\r
1050 ASSERT (EntryExisted);\r
1051\r
1052 mNumberOfIScsiDevices--;\r
e48e37fc 1053 RemoveEntryList (&ConfigFormEntry->Link);\r
766c7483 1054 FreePool (ConfigFormEntry);\r
6a690e23 1055 }\r
1056 //\r
1057 // Allocate space for creation of Buffer\r
1058 //\r
7e3bcccb
LG
1059\r
1060 //\r
1061 // Init OpCode Handle\r
1062 //\r
1063 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1064 ASSERT (StartOpCodeHandle != NULL);\r
1065\r
1066 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1067 ASSERT (EndOpCodeHandle != NULL);\r
1068\r
1069 //\r
1070 // Create Hii Extend Label OpCode as the start opcode\r
1071 //\r
1072 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1073 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1074 StartLabel->Number = DEVICE_ENTRY_LABEL;\r
1075\r
1076 //\r
1077 // Create Hii Extend Label OpCode as the end opcode\r
1078 //\r
1079 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1080 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1081 EndLabel->Number = LABEL_END;\r
6a690e23 1082\r
93e3992d 1083 FormIndex = 0;\r
6a690e23 1084 NET_LIST_FOR_EACH (Entry, &mIScsiConfigFormList) {\r
1085 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, ISCSI_CONFIG_FORM_ENTRY, Link);\r
1086\r
7e3bcccb
LG
1087 HiiCreateGotoOpCode (\r
1088 StartOpCodeHandle, // Container for dynamic created opcodes\r
1089 FORMID_DEVICE_FORM, // Target Form ID\r
1090 ConfigFormEntry->PortTitleToken, // Prompt text\r
1091 ConfigFormEntry->PortTitleHelpToken, // Help text\r
1092 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1093 (UINT16)(KEY_DEVICE_ENTRY_BASE + FormIndex) // Question ID\r
6a690e23 1094 );\r
1095\r
6a690e23 1096 FormIndex++;\r
1097 }\r
1098\r
7e3bcccb 1099 HiiUpdateForm (\r
93e3992d 1100 mCallbackInfo->RegisteredHandle,\r
c8ad2d7a 1101 &gIp4IScsiConfigGuid,\r
93e3992d 1102 FORMID_MAIN_FORM,\r
7e3bcccb
LG
1103 StartOpCodeHandle, // Label DEVICE_ENTRY_LABEL\r
1104 EndOpCodeHandle // LABEL_END\r
93e3992d 1105 );\r
1106\r
7e3bcccb
LG
1107 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1108 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
6a690e23 1109\r
1110 return EFI_SUCCESS;\r
1111}\r
1112\r
12618416 1113/**\r
6a690e23 1114 Initialize the iSCSI configuration form.\r
1115\r
669314e5 1116 @param[in] DriverBindingHandle The iSCSI driverbinding handle.\r
6a690e23 1117\r
669314e5 1118 @retval EFI_SUCCESS The iSCSI configuration form is initialized.\r
1119 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
963dbb30 1120 @retval Others Other errors as indicated.\r
12618416 1121**/\r
1122EFI_STATUS\r
1123IScsiConfigFormInit (\r
963dbb30 1124 VOID\r
12618416 1125 )\r
6a690e23 1126{\r
93e3992d 1127 EFI_STATUS Status;\r
1128 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
93e3992d 1129 ISCSI_FORM_CALLBACK_INFO *CallbackInfo;\r
1130\r
69b0882d 1131 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);\r
6a690e23 1132 if (EFI_ERROR (Status)) {\r
93e3992d 1133 return Status;\r
6a690e23 1134 }\r
1135\r
f6f910dd 1136 CallbackInfo = (ISCSI_FORM_CALLBACK_INFO *) AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO));\r
6a690e23 1137 if (CallbackInfo == NULL) {\r
1138 return EFI_OUT_OF_RESOURCES;\r
1139 }\r
1140\r
f2a94e25 1141 CallbackInfo->Signature = ISCSI_FORM_CALLBACK_INFO_SIGNATURE;\r
93e3992d 1142 CallbackInfo->HiiDatabase = HiiDatabase;\r
f2a94e25 1143 CallbackInfo->Current = NULL;\r
6a690e23 1144\r
93e3992d 1145 CallbackInfo->ConfigAccess.ExtractConfig = IScsiFormExtractConfig;\r
1146 CallbackInfo->ConfigAccess.RouteConfig = IScsiFormRouteConfig;\r
1147 CallbackInfo->ConfigAccess.Callback = IScsiFormCallback;\r
6a690e23 1148\r
69b0882d 1149 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&CallbackInfo->ConfigRouting);\r
93e3992d 1150 if (EFI_ERROR (Status)) {\r
f2a94e25 1151 FreePool(CallbackInfo);\r
93e3992d 1152 return Status;\r
1153 }\r
1154\r
1155 //\r
f6f910dd 1156 // Install Device Path Protocol and Config Access protocol to driver handle\r
93e3992d 1157 //\r
f6f910dd 1158 Status = gBS->InstallMultipleProtocolInterfaces (\r
93e3992d 1159 &CallbackInfo->DriverHandle,\r
f6f910dd 1160 &gEfiDevicePathProtocolGuid,\r
1161 &mIScsiHiiVendorDevicePath,\r
93e3992d 1162 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 1163 &CallbackInfo->ConfigAccess,\r
1164 NULL\r
6a690e23 1165 );\r
6a690e23 1166 ASSERT_EFI_ERROR (Status);\r
93e3992d 1167 \r
6a690e23 1168 //\r
93e3992d 1169 // Publish our HII data\r
6a690e23 1170 //\r
cb7d01c0 1171 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
c8ad2d7a 1172 &gIp4IScsiConfigGuid,\r
cb7d01c0 1173 CallbackInfo->DriverHandle,\r
1174 IScsiDxeStrings,\r
1175 IScsiConfigDxeBin,\r
1176 NULL\r
1177 );\r
1178 if (CallbackInfo->RegisteredHandle == NULL) {\r
f2a94e25 1179 FreePool(CallbackInfo);\r
cb7d01c0 1180 return EFI_OUT_OF_RESOURCES;\r
6a690e23 1181 }\r
1182\r
93e3992d 1183 mCallbackInfo = CallbackInfo;\r
6a690e23 1184\r
1185 return Status;\r
1186}\r
1187\r
12618416 1188/**\r
6a690e23 1189 Unload the iSCSI configuration form, this includes: delete all the iSCSI\r
1190 device configuration entries, uninstall the form callback protocol and\r
1191 free the resources used.\r
1192\r
669314e5 1193 @param[in] DriverBindingHandle The iSCSI driverbinding handle.\r
1194 \r
12618416 1195 @retval EFI_SUCCESS The iSCSI configuration form is unloaded.\r
12618416 1196 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
12618416 1197**/\r
1198EFI_STATUS\r
1199IScsiConfigFormUnload (\r
1200 IN EFI_HANDLE DriverBindingHandle\r
1201 )\r
6a690e23 1202{\r
1203 ISCSI_CONFIG_FORM_ENTRY *ConfigFormEntry;\r
6a690e23 1204\r
e48e37fc 1205 while (!IsListEmpty (&mIScsiConfigFormList)) {\r
6a690e23 1206 //\r
1207 // Uninstall the device forms as the iSCSI driver instance may fail to\r
1208 // control the controller but still install the device configuration form.\r
1209 // In such case, upon driver unloading, the driver instance's driverbinding.\r
1210 // stop () won't be called, so we have to take this chance here to uninstall\r
1211 // the device form.\r
1212 //\r
1213 ConfigFormEntry = NET_LIST_USER_STRUCT (mIScsiConfigFormList.ForwardLink, ISCSI_CONFIG_FORM_ENTRY, Link);\r
1214 IScsiConfigUpdateForm (DriverBindingHandle, ConfigFormEntry->Controller, FALSE);\r
1215 }\r
1216\r
6a690e23 1217 //\r
93e3992d 1218 // Remove HII package list\r
6a690e23 1219 //\r
93e3992d 1220 mCallbackInfo->HiiDatabase->RemovePackageList (\r
1221 mCallbackInfo->HiiDatabase,\r
1222 mCallbackInfo->RegisteredHandle\r
1223 );\r
6a690e23 1224\r
1225 //\r
93e3992d 1226 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
6a690e23 1227 //\r
f6f910dd 1228 gBS->UninstallMultipleProtocolInterfaces (\r
1229 mCallbackInfo->DriverHandle,\r
1230 &gEfiDevicePathProtocolGuid,\r
1231 &mIScsiHiiVendorDevicePath,\r
1232 &gEfiHiiConfigAccessProtocolGuid,\r
1233 &mCallbackInfo->ConfigAccess,\r
1234 NULL\r
1235 );\r
766c7483 1236 FreePool (mCallbackInfo);\r
6a690e23 1237\r
1238 return EFI_SUCCESS;\r
1239}\r