]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / MnpDxe / MnpDriver.c
CommitLineData
8a67d61d 1/** @file\r
6e4bac4d 2 Implementation of driver entry point and driver binding protocol.\r
8a67d61d 3\r
216f7970 4Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
779ae357 6are licensed and made available under the terms and conditions\r
7of the BSD License which accompanies this distribution. The full\r
8text of the license may be found at<BR>\r
9http://opensource.org/licenses/bsd-license.php\r
8a67d61d 10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
8a67d61d 14**/\r
15\r
16#include "MnpDriver.h"\r
8a67d61d 17#include "MnpImpl.h"\r
779ae357 18#include "MnpVlan.h"\r
8a67d61d 19\r
20EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {\r
21 MnpDriverBindingSupported,\r
22 MnpDriverBindingStart,\r
23 MnpDriverBindingStop,\r
24 0xa,\r
25 NULL,\r
26 NULL\r
27};\r
28\r
216f7970 29/**\r
30 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
31 \r
32 @param[in] Entry The entry to be removed.\r
33 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
34\r
35 @retval EFI_SUCCESS The entry has been removed successfully.\r
36 @retval Others Fail to remove the entry.\r
37\r
38**/\r
39EFI_STATUS\r
40MnpDestroyServiceDataEntry (\r
41 IN LIST_ENTRY *Entry,\r
42 IN VOID *Context\r
43)\r
44{\r
45 MNP_SERVICE_DATA *MnpServiceData;\r
46 \r
47 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
48 return MnpDestroyServiceData (MnpServiceData);\r
49}\r
50\r
51/**\r
52 Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
53 \r
54 @param[in] Entry The entry to be removed.\r
55 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
56\r
57 @retval EFI_SUCCESS The entry has been removed successfully.\r
58 @retval Others Fail to remove the entry.\r
59\r
60**/\r
61EFI_STATUS\r
62MnpDestroyServiceChildEntry (\r
63 IN LIST_ENTRY *Entry,\r
64 IN VOID *Context\r
65)\r
66{\r
67 MNP_SERVICE_DATA *MnpServiceData;\r
68\r
69 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
70 return MnpDestroyServiceChild (MnpServiceData);\r
71}\r
72\r
8a67d61d 73/**\r
b6c4ecad 74 Test to see if this driver supports ControllerHandle. This service\r
75 is called by the EFI boot service ConnectController(). In\r
76 order to make drivers as small as possible, there are a few calling\r
77 restrictions for this service. ConnectController() must\r
78 follow these calling restrictions. If any other agent wishes to call\r
79 Supported() it must also follow these calling restrictions.\r
80\r
6e4bac4d 81 @param[in] This Protocol instance pointer.\r
82 @param[in] ControllerHandle Handle of device to test.\r
779ae357 83 @param[in] RemainingDevicePath Optional parameter use to pick a specific\r
6e4bac4d 84 child device to start.\r
b6c4ecad 85\r
6e4bac4d 86 @retval EFI_SUCCESS This driver supports this device.\r
87 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
88 @retval Others This driver does not support this device.\r
8a67d61d 89\r
90**/\r
91EFI_STATUS\r
92EFIAPI\r
93MnpDriverBindingSupported (\r
779ae357 94 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
95 IN EFI_HANDLE ControllerHandle,\r
96 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
8a67d61d 97 )\r
98{\r
b58baf6b 99 EFI_STATUS Status;\r
100 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
8a67d61d 101\r
8a67d61d 102 //\r
b58baf6b 103 // Test to open the Simple Network protocol BY_DRIVER.\r
8a67d61d 104 //\r
105 Status = gBS->OpenProtocol (\r
106 ControllerHandle,\r
107 &gEfiSimpleNetworkProtocolGuid,\r
b58baf6b 108 (VOID **) &Snp,\r
8a67d61d 109 This->DriverBindingHandle,\r
110 ControllerHandle,\r
b58baf6b 111 EFI_OPEN_PROTOCOL_BY_DRIVER\r
8a67d61d 112 );\r
b58baf6b 113 if (EFI_ERROR (Status)) {\r
114 return Status;\r
115 }\r
116\r
117 //\r
118 // Close the openned SNP protocol.\r
119 //\r
120 gBS->CloseProtocol (\r
121 ControllerHandle,\r
122 &gEfiSimpleNetworkProtocolGuid,\r
123 This->DriverBindingHandle,\r
124 ControllerHandle\r
125 );\r
126\r
127 return EFI_SUCCESS;\r
8a67d61d 128}\r
129\r
130\r
131/**\r
b6c4ecad 132 Start this driver on ControllerHandle. This service is called by the\r
779ae357 133 EFI boot service ConnectController(). In order to make drivers as small\r
6e4bac4d 134 as possible, there are a few calling restrictions for this service.\r
135 ConnectController() must follow these calling restrictions. If any other\r
136 agent wishes to call Start() it must also follow these calling restrictions.\r
137\r
138 @param[in] This Protocol instance pointer.\r
139 @param[in] ControllerHandle Handle of device to bind driver to.\r
779ae357 140 @param[in] RemainingDevicePath Optional parameter use to pick a specific\r
6e4bac4d 141 child device to start.\r
142\r
143 @retval EFI_SUCCESS This driver is added to ControllerHandle.\r
144 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.\r
145 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Mnp Service Data.\r
146 @retval Others This driver does not support this device.\r
779ae357 147\r
8a67d61d 148**/\r
149EFI_STATUS\r
150EFIAPI\r
151MnpDriverBindingStart (\r
779ae357 152 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
153 IN EFI_HANDLE ControllerHandle,\r
154 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
8a67d61d 155 )\r
156{\r
157 EFI_STATUS Status;\r
158 MNP_SERVICE_DATA *MnpServiceData;\r
779ae357 159 MNP_DEVICE_DATA *MnpDeviceData;\r
160 LIST_ENTRY *Entry;\r
161 VLAN_TCI *VlanVariable;\r
162 UINTN NumberOfVlan;\r
163 UINTN Index;\r
8a67d61d 164\r
779ae357 165 VlanVariable = NULL;\r
8a67d61d 166\r
779ae357 167 //\r
168 // Initialize the Mnp Device Data\r
169 //\r
170 MnpDeviceData = AllocateZeroPool (sizeof (MNP_DEVICE_DATA));\r
171 if (MnpDeviceData == NULL) {\r
172 DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));\r
8a67d61d 173\r
174 return EFI_OUT_OF_RESOURCES;\r
175 }\r
176\r
779ae357 177 Status = MnpInitializeDeviceData (MnpDeviceData, This->DriverBindingHandle, ControllerHandle);\r
8a67d61d 178 if (EFI_ERROR (Status)) {\r
779ae357 179 DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status));\r
8a67d61d 180\r
779ae357 181 FreePool (MnpDeviceData);\r
182 return Status;\r
8a67d61d 183 }\r
184\r
779ae357 185 //\r
186 // Check whether NIC driver has already produced VlanConfig protocol\r
187 //\r
188 Status = gBS->OpenProtocol (\r
189 ControllerHandle,\r
190 &gEfiVlanConfigProtocolGuid,\r
191 NULL,\r
192 This->DriverBindingHandle,\r
193 ControllerHandle,\r
194 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
195 );\r
196 if (!EFI_ERROR (Status)) {\r
197 //\r
198 // NIC hardware already implement VLAN,\r
199 // no need to provide software VLAN implementation in MNP driver\r
200 //\r
201 MnpDeviceData->NumberOfVlan = 0;\r
202 ZeroMem (&MnpDeviceData->VlanConfig, sizeof (EFI_VLAN_CONFIG_PROTOCOL));\r
203 MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);\r
204 Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
205 goto Exit;\r
206 }\r
8a67d61d 207\r
208 //\r
779ae357 209 // Install VLAN Config Protocol\r
8a67d61d 210 //\r
211 Status = gBS->InstallMultipleProtocolInterfaces (\r
212 &ControllerHandle,\r
779ae357 213 &gEfiVlanConfigProtocolGuid,\r
214 &MnpDeviceData->VlanConfig,\r
8a67d61d 215 NULL\r
216 );\r
779ae357 217 if (EFI_ERROR (Status)) {\r
218 goto Exit;\r
219 }\r
8a67d61d 220\r
779ae357 221 //\r
222 // Get current VLAN configuration from EFI Variable\r
223 //\r
224 NumberOfVlan = 0;\r
225 Status = MnpGetVlanVariable (MnpDeviceData, &NumberOfVlan, &VlanVariable);\r
226 if (EFI_ERROR (Status)) {\r
227 //\r
228 // No VLAN is set, create a default MNP service data for untagged frame\r
229 //\r
230 MnpDeviceData->NumberOfVlan = 0;\r
231 MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);\r
232 Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
233 goto Exit;\r
234 }\r
235\r
236 //\r
237 // Create MNP service data for each VLAN\r
238 //\r
239 MnpDeviceData->NumberOfVlan = NumberOfVlan;\r
240 for (Index = 0; Index < NumberOfVlan; Index++) {\r
241 MnpServiceData = MnpCreateServiceData (\r
242 MnpDeviceData,\r
243 VlanVariable[Index].Bits.Vid,\r
244 (UINT8) VlanVariable[Index].Bits.Priority\r
245 );\r
246\r
247 if (MnpServiceData == NULL) {\r
248 Status = EFI_OUT_OF_RESOURCES;\r
249\r
250 goto Exit;\r
251 }\r
252 }\r
253\r
254Exit:\r
255 if (VlanVariable != NULL) {\r
256 FreePool (VlanVariable);\r
257 }\r
8a67d61d 258\r
259 if (EFI_ERROR (Status)) {\r
779ae357 260 //\r
261 // Destroy all MNP service data\r
262 //\r
263 while (!IsListEmpty (&MnpDeviceData->ServiceList)) {\r
264 Entry = GetFirstNode (&MnpDeviceData->ServiceList);\r
265 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
266 MnpDestroyServiceData (MnpServiceData);\r
267 }\r
8a67d61d 268\r
779ae357 269 //\r
270 // Uninstall the VLAN Config Protocol if any\r
271 //\r
272 if (MnpDeviceData->VlanConfig.Set != NULL) {\r
273 gBS->UninstallMultipleProtocolInterfaces (\r
274 MnpDeviceData->ControllerHandle,\r
275 &gEfiVlanConfigProtocolGuid,\r
276 &MnpDeviceData->VlanConfig,\r
277 NULL\r
278 );\r
8a67d61d 279 }\r
280\r
779ae357 281 //\r
282 // Destroy Mnp Device Data\r
283 //\r
284 MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
285 FreePool (MnpDeviceData);\r
8a67d61d 286 }\r
287\r
288 return Status;\r
289}\r
290\r
8a67d61d 291/**\r
b6c4ecad 292 Stop this driver on ControllerHandle. This service is called by the\r
779ae357 293 EFI boot service DisconnectController(). In order to make drivers as\r
294 small as possible, there are a few calling restrictions for this service.\r
295 DisconnectController() must follow these calling restrictions. If any other\r
6e4bac4d 296 agent wishes to call Stop() it must also follow these calling restrictions.\r
779ae357 297\r
6e4bac4d 298 @param[in] This Protocol instance pointer.\r
299 @param[in] ControllerHandle Handle of device to stop driver on.\r
779ae357 300 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If\r
301 number of children is zero stop the entire\r
302 bus driver.\r
6e4bac4d 303 @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
b6c4ecad 304\r
6e4bac4d 305 @retval EFI_SUCCESS This driver is removed ControllerHandle.\r
306 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
8a67d61d 307\r
308**/\r
309EFI_STATUS\r
310EFIAPI\r
311MnpDriverBindingStop (\r
779ae357 312 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
313 IN EFI_HANDLE ControllerHandle,\r
314 IN UINTN NumberOfChildren,\r
315 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
8a67d61d 316 )\r
317{\r
318 EFI_STATUS Status;\r
319 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
779ae357 320 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;\r
321 MNP_DEVICE_DATA *MnpDeviceData;\r
8a67d61d 322 MNP_SERVICE_DATA *MnpServiceData;\r
216f7970 323 LIST_ENTRY *List;\r
324 UINTN ListLength;\r
8a67d61d 325\r
326 //\r
779ae357 327 // Try to retrieve MNP service binding protocol from the ControllerHandle\r
8a67d61d 328 //\r
329 Status = gBS->OpenProtocol (\r
330 ControllerHandle,\r
331 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
332 (VOID **) &ServiceBinding,\r
333 This->DriverBindingHandle,\r
334 ControllerHandle,\r
335 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
336 );\r
337 if (EFI_ERROR (Status)) {\r
779ae357 338 //\r
339 // Retrieve VLAN Config Protocol from the ControllerHandle\r
340 //\r
341 Status = gBS->OpenProtocol (\r
342 ControllerHandle,\r
343 &gEfiVlanConfigProtocolGuid,\r
344 (VOID **) &VlanConfig,\r
345 This->DriverBindingHandle,\r
346 ControllerHandle,\r
347 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
348 );\r
349 if (EFI_ERROR (Status)) {\r
350 DEBUG ((EFI_D_ERROR, "MnpDriverBindingStop: try to stop unknown Controller.\n"));\r
351 return EFI_DEVICE_ERROR;\r
352 }\r
8a67d61d 353\r
779ae357 354 MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (VlanConfig);\r
355 } else {\r
356 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
357 MnpDeviceData = MnpServiceData->MnpDeviceData;\r
8a67d61d 358 }\r
359\r
c4a62a12 360 if (NumberOfChildren == 0) {\r
8a67d61d 361 //\r
779ae357 362 // Destroy all MNP service data\r
8a67d61d 363 //\r
216f7970 364 List = &MnpDeviceData->ServiceList;\r
365 Status = NetDestroyLinkList (\r
366 List,\r
367 MnpDestroyServiceDataEntry,\r
368 NULL,\r
369 &ListLength\r
370 );\r
371 if (EFI_ERROR (Status) || ListLength !=0) {\r
372 return EFI_DEVICE_ERROR;\r
779ae357 373 }\r
8a67d61d 374\r
c4a62a12 375 //\r
779ae357 376 // Uninstall the VLAN Config Protocol if any\r
c4a62a12 377 //\r
779ae357 378 if (MnpDeviceData->VlanConfig.Set != NULL) {\r
379 gBS->UninstallMultipleProtocolInterfaces (\r
380 MnpDeviceData->ControllerHandle,\r
381 &gEfiVlanConfigProtocolGuid,\r
382 &MnpDeviceData->VlanConfig,\r
383 NULL\r
384 );\r
385 }\r
8a67d61d 386\r
779ae357 387 //\r
dd29f3ed 388 // Destroy Mnp Device Data\r
779ae357 389 //\r
390 MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
391 FreePool (MnpDeviceData);\r
392\r
216f7970 393 if (gMnpControllerNameTable != NULL) {\r
394 FreeUnicodeStringTable (gMnpControllerNameTable);\r
395 gMnpControllerNameTable = NULL;\r
396 }\r
779ae357 397 return EFI_SUCCESS;\r
398 }\r
399\r
400 //\r
401 // Stop all MNP child\r
402 //\r
216f7970 403 List = &MnpDeviceData->ServiceList;\r
404 Status = NetDestroyLinkList (\r
405 List,\r
406 MnpDestroyServiceChildEntry,\r
407 NULL,\r
408 &ListLength\r
409 );\r
410 if (EFI_ERROR (Status)) {\r
779ae357 411 return EFI_DEVICE_ERROR;\r
412 }\r
413\r
414 return EFI_SUCCESS;\r
8a67d61d 415}\r
416\r
417\r
418/**\r
6e4bac4d 419 Creates a child handle with a set of I/O services.\r
8a67d61d 420\r
6e4bac4d 421 @param[in] This Protocol instance pointer.\r
422 @param[in, out] ChildHandle Pointer to the handle of the child to create. If\r
423 it is NULL, then a new handle is created. If\r
779ae357 424 it is not NULL, then the I/O services are added\r
425 to the existing child handle.\r
8a67d61d 426\r
779ae357 427 @retval EFI_SUCCES The protocol was added to ChildHandle.\r
428 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
429 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to\r
6e4bac4d 430 create the child.\r
431 @retval Others The child handle was not created.\r
8a67d61d 432\r
433**/\r
434EFI_STATUS\r
435EFIAPI\r
436MnpServiceBindingCreateChild (\r
779ae357 437 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
438 IN OUT EFI_HANDLE *ChildHandle\r
8a67d61d 439 )\r
440{\r
441 EFI_STATUS Status;\r
442 MNP_SERVICE_DATA *MnpServiceData;\r
443 MNP_INSTANCE_DATA *Instance;\r
779ae357 444 VOID *MnpSb;\r
8a67d61d 445 EFI_TPL OldTpl;\r
446\r
447 if ((This == NULL) || (ChildHandle == NULL)) {\r
8a67d61d 448 return EFI_INVALID_PARAMETER;\r
449 }\r
450\r
451 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
452\r
453 //\r
454 // Allocate buffer for the new instance.\r
455 //\r
e48e37fc 456 Instance = AllocateZeroPool (sizeof (MNP_INSTANCE_DATA));\r
8a67d61d 457 if (Instance == NULL) {\r
e48e37fc 458 DEBUG ((EFI_D_ERROR, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));\r
779ae357 459\r
8a67d61d 460 return EFI_OUT_OF_RESOURCES;\r
461 }\r
462\r
463 //\r
464 // Init the instance data.\r
465 //\r
466 MnpInitializeInstanceData (MnpServiceData, Instance);\r
467\r
468 Status = gBS->InstallMultipleProtocolInterfaces (\r
469 ChildHandle,\r
470 &gEfiManagedNetworkProtocolGuid,\r
471 &Instance->ManagedNetwork,\r
472 NULL\r
473 );\r
474 if (EFI_ERROR (Status)) {\r
e48e37fc 475 DEBUG (\r
476 (EFI_D_ERROR,\r
477 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",\r
8a67d61d 478 Status)\r
479 );\r
779ae357 480\r
8a67d61d 481 goto ErrorExit;\r
482 }\r
483\r
484 //\r
485 // Save the instance's childhandle.\r
486 //\r
487 Instance->Handle = *ChildHandle;\r
488\r
489 Status = gBS->OpenProtocol (\r
779ae357 490 MnpServiceData->ServiceHandle,\r
491 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
492 (VOID **) &MnpSb,\r
8a67d61d 493 gMnpDriverBinding.DriverBindingHandle,\r
494 Instance->Handle,\r
495 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
496 );\r
497 if (EFI_ERROR (Status)) {\r
498 goto ErrorExit;\r
499 }\r
500\r
501 //\r
502 // Add the child instance into ChildrenList.\r
503 //\r
e48e37fc 504 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 505\r
e48e37fc 506 InsertTailList (&MnpServiceData->ChildrenList, &Instance->InstEntry);\r
8a67d61d 507 MnpServiceData->ChildrenNumber++;\r
508\r
e48e37fc 509 gBS->RestoreTPL (OldTpl);\r
8a67d61d 510\r
511ErrorExit:\r
512\r
513 if (EFI_ERROR (Status)) {\r
514\r
515 if (Instance->Handle != NULL) {\r
516\r
517 gBS->UninstallMultipleProtocolInterfaces (\r
0b29a17e 518 Instance->Handle,\r
8a67d61d 519 &gEfiManagedNetworkProtocolGuid,\r
520 &Instance->ManagedNetwork,\r
521 NULL\r
522 );\r
523 }\r
524\r
766c7483 525 FreePool (Instance);\r
8a67d61d 526 }\r
527\r
528 return Status;\r
529}\r
530\r
531\r
532/**\r
6e4bac4d 533 Destroys a child handle with a set of I/O services.\r
779ae357 534\r
535 The DestroyChild() function does the opposite of CreateChild(). It removes a\r
536 protocol that was installed by CreateChild() from ChildHandle. If the removed\r
537 protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.\r
538\r
539 @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL\r
6e4bac4d 540 instance.\r
541 @param[in] ChildHandle Handle of the child to destroy.\r
542\r
779ae357 543 @retval EFI_SUCCES The protocol was removed from ChildHandle.\r
6e4bac4d 544 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that\r
545 is being removed.\r
284ee2e8 546 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
6e4bac4d 547 @retval EFI_ACCESS_DENIED The protocol could not be removed from the\r
548 ChildHandle because its services are being\r
549 used.\r
550 @retval Others The child handle was not destroyed.\r
8a67d61d 551\r
552**/\r
553EFI_STATUS\r
554EFIAPI\r
555MnpServiceBindingDestroyChild (\r
779ae357 556 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
557 IN EFI_HANDLE ChildHandle\r
8a67d61d 558 )\r
559{\r
560 EFI_STATUS Status;\r
561 MNP_SERVICE_DATA *MnpServiceData;\r
562 EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;\r
563 MNP_INSTANCE_DATA *Instance;\r
564 EFI_TPL OldTpl;\r
565\r
566 if ((This == NULL) || (ChildHandle == NULL)) {\r
8a67d61d 567 return EFI_INVALID_PARAMETER;\r
568 }\r
569\r
570 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
571\r
572 //\r
573 // Try to retrieve ManagedNetwork Protocol from ChildHandle.\r
574 //\r
575 Status = gBS->OpenProtocol (\r
576 ChildHandle,\r
577 &gEfiManagedNetworkProtocolGuid,\r
578 (VOID **) &ManagedNetwork,\r
579 gMnpDriverBinding.DriverBindingHandle,\r
580 ChildHandle,\r
581 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
582 );\r
583 if (EFI_ERROR (Status)) {\r
8a67d61d 584 return EFI_UNSUPPORTED;\r
585 }\r
586\r
587 Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);\r
588\r
589 //\r
590 // MnpServiceBindingDestroyChild may be called twice: first called by\r
591 // MnpServiceBindingStop, second called by uninstalling the MNP protocol\r
592 // in this ChildHandle. Use destroyed to make sure the resource clean code\r
593 // will only excecute once.\r
594 //\r
595 if (Instance->Destroyed) {\r
8a67d61d 596 return EFI_SUCCESS;\r
597 }\r
598\r
599 Instance->Destroyed = TRUE;\r
600\r
601 //\r
602 // Close the Simple Network protocol.\r
603 //\r
604 gBS->CloseProtocol (\r
779ae357 605 MnpServiceData->ServiceHandle,\r
606 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
607 MnpServiceData->MnpDeviceData->ImageHandle,\r
8a67d61d 608 ChildHandle\r
609 );\r
610\r
611 //\r
612 // Uninstall the ManagedNetwork protocol.\r
613 //\r
614 Status = gBS->UninstallMultipleProtocolInterfaces (\r
615 ChildHandle,\r
616 &gEfiManagedNetworkProtocolGuid,\r
617 &Instance->ManagedNetwork,\r
618 NULL\r
619 );\r
620 if (EFI_ERROR (Status)) {\r
e48e37fc 621 DEBUG (\r
622 (EFI_D_ERROR,\r
623 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",\r
8a67d61d 624 Status)\r
625 );\r
626\r
627 Instance->Destroyed = FALSE;\r
628 return Status;\r
629 }\r
630\r
e48e37fc 631 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 632\r
633 //\r
634 // Reset the configuration.\r
635 //\r
636 ManagedNetwork->Configure (ManagedNetwork, NULL);\r
637\r
638 //\r
639 // Try to flush the RcvdPacketQueue.\r
640 //\r
641 MnpFlushRcvdDataQueue (Instance);\r
642\r
643 //\r
644 // Clean the RxTokenMap.\r
645 //\r
646 NetMapClean (&Instance->RxTokenMap);\r
647\r
648 //\r
649 // Remove this instance from the ChildrenList.\r
650 //\r
e48e37fc 651 RemoveEntryList (&Instance->InstEntry);\r
8a67d61d 652 MnpServiceData->ChildrenNumber--;\r
653\r
e48e37fc 654 gBS->RestoreTPL (OldTpl);\r
8a67d61d 655\r
766c7483 656 FreePool (Instance);\r
8a67d61d 657\r
658 return Status;\r
659}\r
660\r
b6c4ecad 661/**\r
662 The entry point for Mnp driver which installs the driver binding and component\r
663 name protocol on its ImageHandle.\r
664\r
6e4bac4d 665 @param[in] ImageHandle The image handle of the driver.\r
666 @param[in] SystemTable The system table.\r
b6c4ecad 667\r
779ae357 668 @retval EFI_SUCCES The driver binding and component name protocols are\r
b6c4ecad 669 successfully installed.\r
6e4bac4d 670 @retval Others Other errors as indicated.\r
8a67d61d 671\r
b6c4ecad 672**/\r
8a67d61d 673EFI_STATUS\r
674EFIAPI\r
675MnpDriverEntryPoint (\r
779ae357 676 IN EFI_HANDLE ImageHandle,\r
677 IN EFI_SYSTEM_TABLE *SystemTable\r
8a67d61d 678 )\r
8a67d61d 679{\r
83cbd279 680 return EfiLibInstallDriverBindingComponentName2 (\r
da1d0201 681 ImageHandle,\r
682 SystemTable,\r
683 &gMnpDriverBinding,\r
684 ImageHandle,\r
685 &gMnpComponentName,\r
83cbd279 686 &gMnpComponentName2\r
da1d0201 687 );\r
8a67d61d 688}\r