]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
Fix GCC build break.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / MnpDxe / MnpDriver.c
CommitLineData
8a67d61d 1/** @file\r
2\r
b58baf6b 3Copyright (c) 2005 - 2008, Intel Corporation\r
8a67d61d 4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 MnpDriver.c\r
15\r
16Abstract:\r
17\r
18\r
19**/\r
20\r
21#include "MnpDriver.h"\r
8a67d61d 22#include "MnpImpl.h"\r
23\r
24\r
25EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {\r
26 MnpDriverBindingSupported,\r
27 MnpDriverBindingStart,\r
28 MnpDriverBindingStop,\r
29 0xa,\r
30 NULL,\r
31 NULL\r
32};\r
33\r
34\r
35/**\r
36 Test to see if this driver supports ControllerHandle.\r
37\r
38 @param This Protocol instance pointer.\r
39 @param ControllerHandle Handle of device to test.\r
40 @param RemainingDevicePath Optional parameter use to pick a specific child\r
41 device to start.\r
42\r
43 @retval EFI_SUCCES This driver supports this device.\r
44 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
45 @retval other This driver does not support this device.\r
46\r
47**/\r
48EFI_STATUS\r
49EFIAPI\r
50MnpDriverBindingSupported (\r
51 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
52 IN EFI_HANDLE ControllerHandle,\r
53 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
54 )\r
55{\r
b58baf6b 56 EFI_STATUS Status;\r
57 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
8a67d61d 58\r
59 //\r
60 // Test to see if MNP is already installed.\r
61 //\r
62 Status = gBS->OpenProtocol (\r
63 ControllerHandle,\r
64 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
65 NULL,\r
66 This->DriverBindingHandle,\r
67 ControllerHandle,\r
68 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
69 );\r
70 if (!EFI_ERROR (Status)) {\r
8a67d61d 71 return EFI_ALREADY_STARTED;\r
72 }\r
73\r
74 //\r
b58baf6b 75 // Test to open the Simple Network protocol BY_DRIVER.\r
8a67d61d 76 //\r
77 Status = gBS->OpenProtocol (\r
78 ControllerHandle,\r
79 &gEfiSimpleNetworkProtocolGuid,\r
b58baf6b 80 (VOID **) &Snp,\r
8a67d61d 81 This->DriverBindingHandle,\r
82 ControllerHandle,\r
b58baf6b 83 EFI_OPEN_PROTOCOL_BY_DRIVER\r
8a67d61d 84 );\r
85\r
b58baf6b 86 if (EFI_ERROR (Status)) {\r
87 return Status;\r
88 }\r
89\r
90 //\r
91 // Close the openned SNP protocol.\r
92 //\r
93 gBS->CloseProtocol (\r
94 ControllerHandle,\r
95 &gEfiSimpleNetworkProtocolGuid,\r
96 This->DriverBindingHandle,\r
97 ControllerHandle\r
98 );\r
99\r
100 return EFI_SUCCESS;\r
8a67d61d 101}\r
102\r
103\r
104/**\r
105 Start this driver on ControllerHandle.\r
106\r
107 @param This Protocol instance pointer.\r
108 @param ControllerHandle Handle of device to bind driver to.\r
109 @param RemainingDevicePath Optional parameter use to pick a specific child\r
110 device to start.\r
111\r
112 @retval EFI_SUCCES This driver is added to ControllerHandle.\r
113 @retval EFI_ALREADY_STARTED This driver is already running on\r
114 ControllerHandle.\r
115 @retval other This driver does not support this device.\r
116\r
117**/\r
118EFI_STATUS\r
119EFIAPI\r
120MnpDriverBindingStart (\r
121 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
122 IN EFI_HANDLE ControllerHandle,\r
123 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
124 )\r
125{\r
126 EFI_STATUS Status;\r
127 MNP_SERVICE_DATA *MnpServiceData;\r
128 BOOLEAN MnpInitialized;\r
129\r
130 MnpInitialized = FALSE;\r
131\r
e48e37fc 132 MnpServiceData = AllocateZeroPool (sizeof (MNP_SERVICE_DATA));\r
8a67d61d 133 if (MnpServiceData == NULL) {\r
e48e37fc 134 DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Service Data.\n"));\r
8a67d61d 135\r
136 return EFI_OUT_OF_RESOURCES;\r
137 }\r
138\r
139 //\r
140 // Initialize the Mnp Service Data.\r
141 //\r
142 Status = MnpInitializeServiceData (MnpServiceData, This->DriverBindingHandle, ControllerHandle);\r
143 if (EFI_ERROR (Status)) {\r
144\r
e48e37fc 145 DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart: MnpInitializeServiceData failed, %r.\n",Status));\r
8a67d61d 146 goto ErrorExit;\r
147 }\r
148\r
149 MnpInitialized = TRUE;\r
150\r
151 //\r
152 // Install the MNP Service Binding Protocol.\r
153 //\r
154 Status = gBS->InstallMultipleProtocolInterfaces (\r
155 &ControllerHandle,\r
156 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
157 &MnpServiceData->ServiceBinding,\r
158 NULL\r
159 );\r
160\r
161ErrorExit:\r
162\r
163 if (EFI_ERROR (Status)) {\r
164\r
165 if (MnpInitialized) {\r
166 //\r
167 // Flush the Mnp Service Data.\r
168 //\r
3ec64ac5 169 MnpFlushServiceData (MnpServiceData, This->DriverBindingHandle);\r
8a67d61d 170 }\r
171\r
e48e37fc 172 gBS->FreePool (MnpServiceData);\r
8a67d61d 173 }\r
174\r
175 return Status;\r
176}\r
177\r
178\r
179/**\r
180 Stop this driver on ControllerHandle.\r
181\r
182 @param This Protocol instance pointer.\r
183 @param ControllerHandle Handle of device to stop driver on.\r
184 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number\r
185 of children is zero stop the entire bus driver.\r
186 @param ChildHandleBuffer List of Child Handles to Stop.\r
187\r
188 @retval EFI_SUCCES This driver is removed ControllerHandle.\r
189 @retval other This driver was not removed from this device.\r
190\r
191**/\r
192EFI_STATUS\r
193EFIAPI\r
194MnpDriverBindingStop (\r
195 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
196 IN EFI_HANDLE ControllerHandle,\r
197 IN UINTN NumberOfChildren,\r
198 IN EFI_HANDLE *ChildHandleBuffer\r
199 )\r
200{\r
201 EFI_STATUS Status;\r
202 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
203 MNP_SERVICE_DATA *MnpServiceData;\r
204 MNP_INSTANCE_DATA *Instance;\r
205\r
206 //\r
207 // Retrieve the MNP service binding protocol from the ControllerHandle.\r
208 //\r
209 Status = gBS->OpenProtocol (\r
210 ControllerHandle,\r
211 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
212 (VOID **) &ServiceBinding,\r
213 This->DriverBindingHandle,\r
214 ControllerHandle,\r
215 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
216 );\r
217 if (EFI_ERROR (Status)) {\r
218\r
e48e37fc 219 DEBUG (\r
220 (EFI_D_ERROR,\r
221 "MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",\r
8a67d61d 222 Status)\r
223 );\r
c4a62a12 224 return EFI_DEVICE_ERROR;\r
8a67d61d 225 }\r
226\r
227 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
228\r
c4a62a12 229 if (NumberOfChildren == 0) {\r
8a67d61d 230 //\r
c4a62a12 231 // Uninstall the MNP Service Binding Protocol.\r
8a67d61d 232 //\r
c4a62a12 233 gBS->UninstallMultipleProtocolInterfaces (\r
234 ControllerHandle,\r
235 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
236 ServiceBinding,\r
237 NULL\r
238 );\r
8a67d61d 239\r
c4a62a12 240 //\r
241 // Flush the Mnp service data.\r
242 //\r
3ec64ac5 243 MnpFlushServiceData (MnpServiceData, This->DriverBindingHandle);\r
8a67d61d 244\r
e48e37fc 245 gBS->FreePool (MnpServiceData);\r
c4a62a12 246 } else {\r
e48e37fc 247 while (!IsListEmpty (&MnpServiceData->ChildrenList)) {\r
c4a62a12 248 //\r
249 // Don't use NetListRemoveHead here, the remove opreration will be done\r
250 // in ServiceBindingDestroyChild.\r
251 //\r
252 Instance = NET_LIST_HEAD (\r
253 &MnpServiceData->ChildrenList,\r
254 MNP_INSTANCE_DATA,\r
255 InstEntry\r
256 );\r
8a67d61d 257\r
c4a62a12 258 ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
259 }\r
8a67d61d 260 }\r
261\r
8a67d61d 262 return Status;\r
263}\r
264\r
265\r
266/**\r
267 Creates a child handle with a set of I/O services.\r
268\r
269 @param This Protocol instance pointer.\r
270 @param ChildHandle Pointer to the handle of the child to create. If\r
271 it is NULL, then a new handle is created. If it is\r
272 not NULL, then the I/O services are added to the\r
273 existing child handle.\r
274\r
275 @retval EFI_SUCCES The child handle was created with the I/O\r
276 services.\r
277 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create\r
278 the child.\r
279 @retval other The child handle was not created.\r
280\r
281**/\r
282EFI_STATUS\r
283EFIAPI\r
284MnpServiceBindingCreateChild (\r
285 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
286 IN EFI_HANDLE *ChildHandle\r
287 )\r
288{\r
289 EFI_STATUS Status;\r
290 MNP_SERVICE_DATA *MnpServiceData;\r
291 MNP_INSTANCE_DATA *Instance;\r
292 VOID *Snp;\r
293 EFI_TPL OldTpl;\r
294\r
295 if ((This == NULL) || (ChildHandle == NULL)) {\r
296\r
297 return EFI_INVALID_PARAMETER;\r
298 }\r
299\r
300 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
301\r
302 //\r
303 // Allocate buffer for the new instance.\r
304 //\r
e48e37fc 305 Instance = AllocateZeroPool (sizeof (MNP_INSTANCE_DATA));\r
8a67d61d 306 if (Instance == NULL) {\r
307\r
e48e37fc 308 DEBUG ((EFI_D_ERROR, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));\r
8a67d61d 309 return EFI_OUT_OF_RESOURCES;\r
310 }\r
311\r
312 //\r
313 // Init the instance data.\r
314 //\r
315 MnpInitializeInstanceData (MnpServiceData, Instance);\r
316\r
317 Status = gBS->InstallMultipleProtocolInterfaces (\r
318 ChildHandle,\r
319 &gEfiManagedNetworkProtocolGuid,\r
320 &Instance->ManagedNetwork,\r
321 NULL\r
322 );\r
323 if (EFI_ERROR (Status)) {\r
324\r
e48e37fc 325 DEBUG (\r
326 (EFI_D_ERROR,\r
327 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",\r
8a67d61d 328 Status)\r
329 );\r
330 goto ErrorExit;\r
331 }\r
332\r
333 //\r
334 // Save the instance's childhandle.\r
335 //\r
336 Instance->Handle = *ChildHandle;\r
337\r
338 Status = gBS->OpenProtocol (\r
339 MnpServiceData->ControllerHandle,\r
340 &gEfiSimpleNetworkProtocolGuid,\r
341 (VOID **) &Snp,\r
342 gMnpDriverBinding.DriverBindingHandle,\r
343 Instance->Handle,\r
344 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
345 );\r
346 if (EFI_ERROR (Status)) {\r
347 goto ErrorExit;\r
348 }\r
349\r
350 //\r
351 // Add the child instance into ChildrenList.\r
352 //\r
e48e37fc 353 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 354\r
e48e37fc 355 InsertTailList (&MnpServiceData->ChildrenList, &Instance->InstEntry);\r
8a67d61d 356 MnpServiceData->ChildrenNumber++;\r
357\r
e48e37fc 358 gBS->RestoreTPL (OldTpl);\r
8a67d61d 359\r
360ErrorExit:\r
361\r
362 if (EFI_ERROR (Status)) {\r
363\r
364 if (Instance->Handle != NULL) {\r
365\r
366 gBS->UninstallMultipleProtocolInterfaces (\r
367 &gEfiManagedNetworkProtocolGuid,\r
368 &Instance->ManagedNetwork,\r
369 NULL\r
370 );\r
371 }\r
372\r
e48e37fc 373 gBS->FreePool (Instance);\r
8a67d61d 374 }\r
375\r
376 return Status;\r
377}\r
378\r
379\r
380/**\r
381 Destroys a child handle with a set of I/O services.\r
382\r
383 @param This Protocol instance pointer.\r
384 @param ChildHandle Handle of the child to destroy.\r
385\r
386 @retval EFI_SUCCES The I/O services were removed from the child\r
387 handle.\r
388 @retval EFI_UNSUPPORTED The child handle does not support the I/O services\r
389 that are being removed.\r
390 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.\r
391 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because\r
392 its I/O services are being used.\r
393 @retval other The child handle was not destroyed.\r
394\r
395**/\r
396EFI_STATUS\r
397EFIAPI\r
398MnpServiceBindingDestroyChild (\r
399 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
400 IN EFI_HANDLE ChildHandle\r
401 )\r
402{\r
403 EFI_STATUS Status;\r
404 MNP_SERVICE_DATA *MnpServiceData;\r
405 EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;\r
406 MNP_INSTANCE_DATA *Instance;\r
407 EFI_TPL OldTpl;\r
408\r
409 if ((This == NULL) || (ChildHandle == NULL)) {\r
410\r
411 return EFI_INVALID_PARAMETER;\r
412 }\r
413\r
414 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
415\r
416 //\r
417 // Try to retrieve ManagedNetwork Protocol from ChildHandle.\r
418 //\r
419 Status = gBS->OpenProtocol (\r
420 ChildHandle,\r
421 &gEfiManagedNetworkProtocolGuid,\r
422 (VOID **) &ManagedNetwork,\r
423 gMnpDriverBinding.DriverBindingHandle,\r
424 ChildHandle,\r
425 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
426 );\r
427 if (EFI_ERROR (Status)) {\r
428\r
429 return EFI_UNSUPPORTED;\r
430 }\r
431\r
432 Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);\r
433\r
434 //\r
435 // MnpServiceBindingDestroyChild may be called twice: first called by\r
436 // MnpServiceBindingStop, second called by uninstalling the MNP protocol\r
437 // in this ChildHandle. Use destroyed to make sure the resource clean code\r
438 // will only excecute once.\r
439 //\r
440 if (Instance->Destroyed) {\r
441\r
442 return EFI_SUCCESS;\r
443 }\r
444\r
445 Instance->Destroyed = TRUE;\r
446\r
447 //\r
448 // Close the Simple Network protocol.\r
449 //\r
450 gBS->CloseProtocol (\r
451 MnpServiceData->ControllerHandle,\r
452 &gEfiSimpleNetworkProtocolGuid,\r
453 gMnpDriverBinding.DriverBindingHandle,\r
454 ChildHandle\r
455 );\r
456\r
457 //\r
458 // Uninstall the ManagedNetwork protocol.\r
459 //\r
460 Status = gBS->UninstallMultipleProtocolInterfaces (\r
461 ChildHandle,\r
462 &gEfiManagedNetworkProtocolGuid,\r
463 &Instance->ManagedNetwork,\r
464 NULL\r
465 );\r
466 if (EFI_ERROR (Status)) {\r
467\r
e48e37fc 468 DEBUG (\r
469 (EFI_D_ERROR,\r
470 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",\r
8a67d61d 471 Status)\r
472 );\r
473\r
474 Instance->Destroyed = FALSE;\r
475 return Status;\r
476 }\r
477\r
e48e37fc 478 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 479\r
480 //\r
481 // Reset the configuration.\r
482 //\r
483 ManagedNetwork->Configure (ManagedNetwork, NULL);\r
484\r
485 //\r
486 // Try to flush the RcvdPacketQueue.\r
487 //\r
488 MnpFlushRcvdDataQueue (Instance);\r
489\r
490 //\r
491 // Clean the RxTokenMap.\r
492 //\r
493 NetMapClean (&Instance->RxTokenMap);\r
494\r
495 //\r
496 // Remove this instance from the ChildrenList.\r
497 //\r
e48e37fc 498 RemoveEntryList (&Instance->InstEntry);\r
8a67d61d 499 MnpServiceData->ChildrenNumber--;\r
500\r
e48e37fc 501 gBS->RestoreTPL (OldTpl);\r
8a67d61d 502\r
e48e37fc 503 gBS->FreePool (Instance);\r
8a67d61d 504\r
505 return Status;\r
506}\r
507\r
8a67d61d 508\r
509EFI_STATUS\r
510EFIAPI\r
511MnpDriverEntryPoint (\r
512 IN EFI_HANDLE ImageHandle,\r
513 IN EFI_SYSTEM_TABLE *SystemTable\r
514 )\r
515/*++\r
516\r
517Routine Description:\r
518\r
519 The entry point for Mnp driver which installs the driver binding and component name\r
520 protocol on its ImageHandle.\r
521\r
522Arguments:\r
523\r
524 ImageHandle - The image handle of the driver.\r
525 SystemTable - The system table.\r
526\r
527Returns:\r
528\r
529 EFI_SUCCESS - If the driver binding and component name protocols are successfully\r
530 installed, otherwise if failed.\r
531\r
532--*/\r
533{\r
83cbd279 534 return EfiLibInstallDriverBindingComponentName2 (\r
da1d0201 535 ImageHandle,\r
536 SystemTable,\r
537 &gMnpDriverBinding,\r
538 ImageHandle,\r
539 &gMnpComponentName,\r
83cbd279 540 &gMnpComponentName2\r
da1d0201 541 );\r
8a67d61d 542}\r