]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / VlanConfigDxe / VlanConfigImpl.c
1 /** @file
2 HII Config Access protocol implementation of VLAN configuration module.
3
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The full
8 text of the license may be found at<BR>
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "VlanConfigImpl.h"
17
18 CHAR16 mVlanStorageName[] = L"VlanNvData";
19 EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting = NULL;
20
21 VLAN_CONFIG_PRIVATE_DATA mVlanConfigPrivateDateTemplate = {
22 VLAN_CONFIG_PRIVATE_DATA_SIGNATURE,
23 {
24 VlanExtractConfig,
25 VlanRouteConfig,
26 VlanCallback
27 }
28 };
29
30 VENDOR_DEVICE_PATH mHiiVendorDevicePathNode = {
31 {
32 HARDWARE_DEVICE_PATH,
33 HW_VENDOR_DP,
34 {
35 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
36 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
37 }
38 },
39 VLAN_CONFIG_FORM_SET_GUID
40 };
41
42 /**
43 This function allows a caller to extract the current configuration for one
44 or more named elements from the target driver.
45
46 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
47 @param[in] Request A null-terminated Unicode string in
48 <ConfigRequest> format.
49 @param[out] Progress On return, points to a character in the Request
50 string. Points to the string's null terminator if
51 request was successful. Points to the most recent
52 '&' before the first failing name/value pair (or
53 the beginning of the string if the failure is in
54 the first name/value pair) if the request was not
55 successful.
56 @param[out] Results A null-terminated Unicode string in
57 <ConfigAltResp> format which has all values filled
58 in for the names in the Request string. String to
59 be allocated by the called function.
60
61 @retval EFI_SUCCESS The Results is filled with the requested values.
62 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
63 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
64 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
65 driver.
66
67 **/
68 EFI_STATUS
69 EFIAPI
70 VlanExtractConfig (
71 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
72 IN CONST EFI_STRING Request,
73 OUT EFI_STRING *Progress,
74 OUT EFI_STRING *Results
75 )
76 {
77 EFI_STATUS Status;
78 UINTN BufferSize;
79 VLAN_CONFIGURATION Configuration;
80 VLAN_CONFIG_PRIVATE_DATA *PrivateData;
81 EFI_STRING ConfigRequestHdr;
82 EFI_STRING ConfigRequest;
83 BOOLEAN AllocatedRequest;
84 UINTN Size;
85
86 if (Progress == NULL || Results == NULL) {
87 return EFI_INVALID_PARAMETER;
88 }
89
90 *Progress = Request;
91 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gVlanConfigFormSetGuid, mVlanStorageName)) {
92 return EFI_NOT_FOUND;
93 }
94
95 ConfigRequestHdr = NULL;
96 ConfigRequest = NULL;
97 AllocatedRequest = FALSE;
98 Size = 0;
99
100 //
101 // Retrieve the pointer to the UEFI HII Config Routing Protocol
102 //
103 if (mHiiConfigRouting == NULL) {
104 gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mHiiConfigRouting);
105 }
106 ASSERT (mHiiConfigRouting != NULL);
107
108 //
109 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
110 //
111 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
112 ZeroMem (&Configuration, sizeof (VLAN_CONFIGURATION));
113 BufferSize = sizeof (Configuration);
114 ConfigRequest = Request;
115 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
116 //
117 // Request has no request element, construct full request string.
118 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
119 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
120 //
121 ConfigRequestHdr = HiiConstructConfigHdr (&gVlanConfigFormSetGuid, mVlanStorageName, PrivateData->DriverHandle);
122 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
123 ConfigRequest = AllocateZeroPool (Size);
124 ASSERT (ConfigRequest != NULL);
125 AllocatedRequest = TRUE;
126 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
127 FreePool (ConfigRequestHdr);
128 }
129
130 Status = mHiiConfigRouting->BlockToConfig (
131 mHiiConfigRouting,
132 ConfigRequest,
133 (UINT8 *) &Configuration,
134 BufferSize,
135 Results,
136 Progress
137 );
138 //
139 // Free the allocated config request string.
140 //
141 if (AllocatedRequest) {
142 FreePool (ConfigRequest);
143 ConfigRequest = NULL;
144 }
145 //
146 // Set Progress string to the original request string.
147 //
148 if (Request == NULL) {
149 *Progress = NULL;
150 } else if (StrStr (Request, L"OFFSET") == NULL) {
151 *Progress = Request + StrLen (Request);
152 }
153
154 return Status;
155 }
156
157
158 /**
159 This function processes the results of changes in configuration.
160
161 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
162 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
163 format.
164 @param[out] Progress A pointer to a string filled in with the offset of
165 the most recent '&' before the first failing
166 name/value pair (or the beginning of the string if
167 the failure is in the first name/value pair) or
168 the terminating NULL if all was successful.
169
170 @retval EFI_SUCCESS The Results is processed successfully.
171 @retval EFI_INVALID_PARAMETER Configuration is NULL.
172 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
173 driver.
174
175 **/
176 EFI_STATUS
177 EFIAPI
178 VlanRouteConfig (
179 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
180 IN CONST EFI_STRING Configuration,
181 OUT EFI_STRING *Progress
182 )
183 {
184 if (Configuration == NULL || Progress == NULL) {
185 return EFI_INVALID_PARAMETER;
186 }
187
188 *Progress = Configuration;
189 if (!HiiIsConfigHdrMatch (Configuration, &gVlanConfigFormSetGuid, mVlanStorageName)) {
190 return EFI_NOT_FOUND;
191 }
192
193 *Progress = Configuration + StrLen (Configuration);
194 return EFI_SUCCESS;
195 }
196
197 /**
198 This function processes the results of changes in configuration.
199
200 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
201 @param[in] Action Specifies the type of action taken by the browser.
202 @param[in] QuestionId A unique value which is sent to the original
203 exporting driver so that it can identify the type
204 of data to expect.
205 @param[in] Type The type of value for the question.
206 @param[in] Value A pointer to the data being sent to the original
207 exporting driver.
208 @param[out] ActionRequest On return, points to the action requested by the
209 callback function.
210
211 @retval EFI_SUCCESS The callback successfully handled the action.
212 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
213 variable and its data.
214 @retval EFI_DEVICE_ERROR The variable could not be saved.
215 @retval EFI_UNSUPPORTED The specified Action is not supported by the
216 callback.
217
218 **/
219 EFI_STATUS
220 EFIAPI
221 VlanCallback (
222 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
223 IN EFI_BROWSER_ACTION Action,
224 IN EFI_QUESTION_ID QuestionId,
225 IN UINT8 Type,
226 IN EFI_IFR_TYPE_VALUE *Value,
227 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
228 )
229 {
230 VLAN_CONFIG_PRIVATE_DATA *PrivateData;
231 VLAN_CONFIGURATION *Configuration;
232 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
233 UINTN Index;
234 EFI_HANDLE VlanHandle;
235
236 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
237
238 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
239 return EFI_SUCCESS;
240 }
241
242 if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING)) {
243 //
244 // All other action return unsupported.
245 //
246 return EFI_UNSUPPORTED;
247 }
248
249 //
250 // Get Browser data
251 //
252 Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION));
253 ASSERT (Configuration != NULL);
254 HiiGetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration);
255
256 VlanConfig = PrivateData->VlanConfig;
257
258 if (Action == EFI_BROWSER_ACTION_CHANGED) {
259 switch (QuestionId) {
260 case VLAN_ADD_QUESTION_ID:
261 //
262 // Add a VLAN
263 //
264 VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority);
265 VlanUpdateForm (PrivateData);
266
267 //
268 // Connect the newly created VLAN device
269 //
270 VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId);
271 if (VlanHandle == NULL) {
272 //
273 // There may be no child handle created for VLAN ID 0, connect the parent handle
274 //
275 VlanHandle = PrivateData->ControllerHandle;
276 }
277 gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);
278
279 //
280 // Clear UI data
281 //
282 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
283 Configuration->VlanId = 0;
284 Configuration->Priority = 0;
285 break;
286
287 case VLAN_REMOVE_QUESTION_ID:
288 //
289 // Remove VLAN
290 //
291 ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER);
292 for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) {
293 if (Configuration->VlanList[Index] != 0) {
294 //
295 // Checkbox is selected, need remove this VLAN
296 //
297 VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]);
298 }
299 }
300
301 VlanUpdateForm (PrivateData);
302 if (PrivateData->NumberOfVlan == 0) {
303 //
304 // No VLAN device now, connect the physical NIC handle.
305 // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()
306 //
307 gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE);
308 }
309
310 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
311 ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER);
312 break;
313
314 default:
315 break;
316 }
317 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
318 switch (QuestionId) {
319 case VLAN_UPDATE_QUESTION_ID:
320 //
321 // Update current VLAN list into Form.
322 //
323 VlanUpdateForm (PrivateData);
324 break;
325
326 default:
327 break;
328 }
329 }
330
331 HiiSetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration, NULL);
332 FreePool (Configuration);
333 return EFI_SUCCESS;
334 }
335
336
337 /**
338 This function update VLAN list in the VLAN configuration Form.
339
340 @param[in, out] PrivateData Points to VLAN configuration private data.
341
342 **/
343 VOID
344 VlanUpdateForm (
345 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
346 )
347 {
348 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
349 UINT16 NumberOfVlan;
350 UINTN Index;
351 EFI_VLAN_FIND_DATA *VlanData;
352 VOID *StartOpCodeHandle;
353 EFI_IFR_GUID_LABEL *StartLabel;
354 VOID *EndOpCodeHandle;
355 EFI_IFR_GUID_LABEL *EndLabel;
356 CHAR16 *String;
357 CHAR16 VlanStr[30];
358 CHAR16 VlanIdStr[6];
359 UINTN DigitalCount;
360 EFI_STRING_ID StringId;
361
362 //
363 // Find current VLAN configuration
364 //
365 VlanData = NULL;
366 NumberOfVlan = 0;
367 VlanConfig = PrivateData->VlanConfig;
368 VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
369
370 //
371 // Update VLAN configuration in PrivateData
372 //
373 if (NumberOfVlan > MAX_VLAN_NUMBER) {
374 NumberOfVlan = MAX_VLAN_NUMBER;
375 }
376 PrivateData->NumberOfVlan = NumberOfVlan;
377
378 //
379 // Init OpCode Handle
380 //
381 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
382 ASSERT (StartOpCodeHandle != NULL);
383
384 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
385 ASSERT (EndOpCodeHandle != NULL);
386
387 //
388 // Create Hii Extend Label OpCode as the start opcode
389 //
390 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
391 StartOpCodeHandle,
392 &gEfiIfrTianoGuid,
393 NULL,
394 sizeof (EFI_IFR_GUID_LABEL)
395 );
396 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
397 StartLabel->Number = LABEL_VLAN_LIST;
398
399 //
400 // Create Hii Extend Label OpCode as the end opcode
401 //
402 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
403 EndOpCodeHandle,
404 &gEfiIfrTianoGuid,
405 NULL,
406 sizeof (EFI_IFR_GUID_LABEL)
407 );
408 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
409 EndLabel->Number = LABEL_END;
410
411 ZeroMem (PrivateData->VlanId, MAX_VLAN_NUMBER);
412 for (Index = 0; Index < NumberOfVlan; Index++) {
413 String = VlanStr;
414
415 StrCpyS (String, (sizeof (VlanStr) /sizeof (CHAR16)), L" VLAN ID:");
416 String += 10;
417 //
418 // Pad VlanId string up to 4 characters with space
419 //
420 UnicodeValueToStringS (VlanIdStr, sizeof (VlanIdStr), 0, VlanData[Index].VlanId, 5);
421 DigitalCount = StrnLenS (VlanIdStr, ARRAY_SIZE (VlanIdStr));
422 SetMem16 (String, (4 - DigitalCount) * sizeof (CHAR16), L' ');
423 StrCpyS (String + 4 - DigitalCount, (sizeof (VlanStr) /sizeof (CHAR16)) - 10 - (4 - DigitalCount), VlanIdStr);
424 String += 4;
425
426 StrCpyS (String, (sizeof (VlanStr) /sizeof (CHAR16)) - 10 - (4 - DigitalCount) - 4, L", Priority:");
427 String += 11;
428 UnicodeValueToStringS (
429 String,
430 sizeof (VlanStr) - ((UINTN)String - (UINTN)VlanStr),
431 0,
432 VlanData[Index].Priority,
433 4
434 );
435 String += StrnLenS (String, ARRAY_SIZE (VlanStr) - ((UINTN)String - (UINTN)VlanStr) / sizeof (CHAR16));
436 *String = 0;
437
438 StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanStr, NULL);
439 ASSERT (StringId != 0);
440
441 HiiCreateCheckBoxOpCode (
442 StartOpCodeHandle,
443 (EFI_QUESTION_ID) (VLAN_LIST_VAR_OFFSET + Index),
444 VLAN_CONFIGURATION_VARSTORE_ID,
445 (UINT16) (VLAN_LIST_VAR_OFFSET + Index),
446 StringId,
447 STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP),
448 0,
449 0,
450 NULL
451 );
452
453 //
454 // Save VLAN id to private data
455 //
456 PrivateData->VlanId[Index] = VlanData[Index].VlanId;
457 }
458
459 HiiUpdateForm (
460 PrivateData->HiiHandle, // HII handle
461 &gVlanConfigFormSetGuid, // Formset GUID
462 VLAN_CONFIGURATION_FORM_ID, // Form ID
463 StartOpCodeHandle, // Label for where to insert opcodes
464 EndOpCodeHandle // Replace data
465 );
466
467 HiiFreeOpCodeHandle (StartOpCodeHandle);
468 HiiFreeOpCodeHandle (EndOpCodeHandle);
469
470 if (VlanData != NULL) {
471 FreePool (VlanData);
472 }
473 }
474
475
476 /**
477 This function publish the VLAN configuration Form for a network device. The
478 HII Config Access protocol will be installed on a child handle of the network
479 device.
480
481 @param[in, out] PrivateData Points to VLAN configuration private data.
482
483 @retval EFI_SUCCESS HII Form is installed for this network device.
484 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
485 @retval Others Other errors as indicated.
486
487 **/
488 EFI_STATUS
489 InstallVlanConfigForm (
490 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
491 )
492 {
493 EFI_STATUS Status;
494 EFI_HII_HANDLE HiiHandle;
495 EFI_HANDLE DriverHandle;
496 CHAR16 Str[26 + sizeof (EFI_MAC_ADDRESS) * 2 + 1];
497 CHAR16 *MacString;
498 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
499 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
500 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
501
502 //
503 // Create child handle and install HII Config Access Protocol
504 //
505 ChildDevicePath = AppendDevicePathNode (
506 PrivateData->ParentDevicePath,
507 (CONST EFI_DEVICE_PATH_PROTOCOL *) &mHiiVendorDevicePathNode
508 );
509 if (ChildDevicePath == NULL) {
510 return EFI_OUT_OF_RESOURCES;
511 }
512 PrivateData->ChildDevicePath = ChildDevicePath;
513
514 DriverHandle = NULL;
515 ConfigAccess = &PrivateData->ConfigAccess;
516 Status = gBS->InstallMultipleProtocolInterfaces (
517 &DriverHandle,
518 &gEfiDevicePathProtocolGuid,
519 ChildDevicePath,
520 &gEfiHiiConfigAccessProtocolGuid,
521 ConfigAccess,
522 NULL
523 );
524 if (EFI_ERROR (Status)) {
525 return Status;
526 }
527 PrivateData->DriverHandle = DriverHandle;
528
529 //
530 // Establish the parent-child relationship between the new created
531 // child handle and the ControllerHandle.
532 //
533 Status = gBS->OpenProtocol (
534 PrivateData->ControllerHandle,
535 &gEfiVlanConfigProtocolGuid,
536 (VOID **)&VlanConfig,
537 PrivateData->ImageHandle,
538 PrivateData->DriverHandle,
539 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
540 );
541 if (EFI_ERROR (Status)) {
542 return Status;
543 }
544
545 //
546 // Publish the HII package list
547 //
548 HiiHandle = HiiAddPackages (
549 &gVlanConfigFormSetGuid,
550 DriverHandle,
551 VlanConfigDxeStrings,
552 VlanConfigBin,
553 NULL
554 );
555 if (HiiHandle == NULL) {
556 return EFI_OUT_OF_RESOURCES;
557 }
558 PrivateData->HiiHandle = HiiHandle;
559
560 //
561 // Update formset title help string.
562 //
563 MacString = NULL;
564 Status = NetLibGetMacString (PrivateData->ControllerHandle, PrivateData->ImageHandle, &MacString);
565 if (EFI_ERROR (Status)) {
566 return Status;
567 }
568 PrivateData->MacString = MacString;
569
570 StrCpyS (Str, sizeof (Str) / sizeof (CHAR16), L"VLAN Configuration (MAC:");
571 StrCatS (Str, sizeof (Str) / sizeof (CHAR16), MacString);
572 StrCatS (Str, sizeof (Str) / sizeof (CHAR16), L")");
573 HiiSetString (
574 HiiHandle,
575 STRING_TOKEN (STR_VLAN_FORM_SET_TITLE_HELP),
576 Str,
577 NULL
578 );
579
580 //
581 // Update form title help string.
582 //
583 HiiSetString (
584 HiiHandle,
585 STRING_TOKEN (STR_VLAN_FORM_HELP),
586 Str,
587 NULL
588 );
589
590 return EFI_SUCCESS;
591 }
592
593 /**
594 This function remove the VLAN configuration Form for a network device. The
595 child handle for HII Config Access protocol will be destroyed.
596
597 @param[in, out] PrivateData Points to VLAN configuration private data.
598
599 @retval EFI_SUCCESS HII Form has been uninstalled successfully.
600 @retval Others Other errors as indicated.
601
602 **/
603 EFI_STATUS
604 UninstallVlanConfigForm (
605 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
606 )
607 {
608 EFI_STATUS Status;
609 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
610
611 //
612 // End the parent-child relationship.
613 //
614 Status = gBS->CloseProtocol (
615 PrivateData->ControllerHandle,
616 &gEfiVlanConfigProtocolGuid,
617 PrivateData->ImageHandle,
618 PrivateData->DriverHandle
619 );
620 if (EFI_ERROR (Status)) {
621 return Status;
622 }
623
624 //
625 // Uninstall HII Config Access Protocol
626 //
627 if (PrivateData->DriverHandle != NULL) {
628 Status = gBS->UninstallMultipleProtocolInterfaces (
629 PrivateData->DriverHandle,
630 &gEfiDevicePathProtocolGuid,
631 PrivateData->ChildDevicePath,
632 &gEfiHiiConfigAccessProtocolGuid,
633 &PrivateData->ConfigAccess,
634 NULL
635 );
636 if (EFI_ERROR (Status)) {
637 gBS->OpenProtocol (
638 PrivateData->ControllerHandle,
639 &gEfiVlanConfigProtocolGuid,
640 (VOID **)&VlanConfig,
641 PrivateData->ImageHandle,
642 PrivateData->DriverHandle,
643 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
644 );
645 return Status;
646 }
647 PrivateData->DriverHandle = NULL;
648
649 if (PrivateData->ChildDevicePath != NULL) {
650 FreePool (PrivateData->ChildDevicePath);
651 PrivateData->ChildDevicePath = NULL;
652 }
653 }
654
655 //
656 // Free MAC string
657 //
658 if (PrivateData->MacString != NULL) {
659 FreePool (PrivateData->MacString);
660 PrivateData->MacString = NULL;
661 }
662
663 //
664 // Uninstall HII package list
665 //
666 if (PrivateData->HiiHandle != NULL) {
667 HiiRemovePackages (PrivateData->HiiHandle);
668 PrivateData->HiiHandle = NULL;
669 }
670 return EFI_SUCCESS;
671 }