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