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