]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
Sync the latest version from R8.
[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
c4a62a12 222 return EFI_DEVICE_ERROR;\r
8a67d61d 223 }\r
224\r
225 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
226\r
c4a62a12 227 if (NumberOfChildren == 0) {\r
8a67d61d 228 //\r
c4a62a12 229 // Uninstall the MNP Service Binding Protocol.\r
8a67d61d 230 //\r
c4a62a12 231 gBS->UninstallMultipleProtocolInterfaces (\r
232 ControllerHandle,\r
233 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
234 ServiceBinding,\r
235 NULL\r
236 );\r
8a67d61d 237\r
c4a62a12 238 //\r
239 // Close the openned Snp protocol.\r
240 //\r
241 gBS->CloseProtocol (\r
242 ControllerHandle,\r
243 &gEfiSimpleNetworkProtocolGuid,\r
244 This->DriverBindingHandle,\r
245 ControllerHandle\r
246 );\r
8a67d61d 247\r
c4a62a12 248 //\r
249 // Flush the Mnp service data.\r
250 //\r
251 MnpFlushServiceData (MnpServiceData);\r
8a67d61d 252\r
c4a62a12 253 NetFreePool (MnpServiceData);\r
254 } else {\r
255 while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) {\r
256 //\r
257 // Don't use NetListRemoveHead here, the remove opreration will be done\r
258 // in ServiceBindingDestroyChild.\r
259 //\r
260 Instance = NET_LIST_HEAD (\r
261 &MnpServiceData->ChildrenList,\r
262 MNP_INSTANCE_DATA,\r
263 InstEntry\r
264 );\r
8a67d61d 265\r
c4a62a12 266 ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
267 }\r
8a67d61d 268 }\r
269\r
8a67d61d 270 return Status;\r
271}\r
272\r
273\r
274/**\r
275 Creates a child handle with a set of I/O services.\r
276\r
277 @param This Protocol instance pointer.\r
278 @param ChildHandle Pointer to the handle of the child to create. If\r
279 it is NULL, then a new handle is created. If it is\r
280 not NULL, then the I/O services are added to the\r
281 existing child handle.\r
282\r
283 @retval EFI_SUCCES The child handle was created with the I/O\r
284 services.\r
285 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create\r
286 the child.\r
287 @retval other The child handle was not created.\r
288\r
289**/\r
290EFI_STATUS\r
291EFIAPI\r
292MnpServiceBindingCreateChild (\r
293 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
294 IN EFI_HANDLE *ChildHandle\r
295 )\r
296{\r
297 EFI_STATUS Status;\r
298 MNP_SERVICE_DATA *MnpServiceData;\r
299 MNP_INSTANCE_DATA *Instance;\r
300 VOID *Snp;\r
301 EFI_TPL OldTpl;\r
302\r
303 if ((This == NULL) || (ChildHandle == NULL)) {\r
304\r
305 return EFI_INVALID_PARAMETER;\r
306 }\r
307\r
308 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
309\r
310 //\r
311 // Allocate buffer for the new instance.\r
312 //\r
313 Instance = NetAllocateZeroPool (sizeof (MNP_INSTANCE_DATA));\r
314 if (Instance == NULL) {\r
315\r
316 MNP_DEBUG_ERROR (("MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));\r
317 return EFI_OUT_OF_RESOURCES;\r
318 }\r
319\r
320 //\r
321 // Init the instance data.\r
322 //\r
323 MnpInitializeInstanceData (MnpServiceData, Instance);\r
324\r
325 Status = gBS->InstallMultipleProtocolInterfaces (\r
326 ChildHandle,\r
327 &gEfiManagedNetworkProtocolGuid,\r
328 &Instance->ManagedNetwork,\r
329 NULL\r
330 );\r
331 if (EFI_ERROR (Status)) {\r
332\r
333 MNP_DEBUG_ERROR (\r
334 ("MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",\r
335 Status)\r
336 );\r
337 goto ErrorExit;\r
338 }\r
339\r
340 //\r
341 // Save the instance's childhandle.\r
342 //\r
343 Instance->Handle = *ChildHandle;\r
344\r
345 Status = gBS->OpenProtocol (\r
346 MnpServiceData->ControllerHandle,\r
347 &gEfiSimpleNetworkProtocolGuid,\r
348 (VOID **) &Snp,\r
349 gMnpDriverBinding.DriverBindingHandle,\r
350 Instance->Handle,\r
351 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
352 );\r
353 if (EFI_ERROR (Status)) {\r
354 goto ErrorExit;\r
355 }\r
356\r
357 //\r
358 // Add the child instance into ChildrenList.\r
359 //\r
360 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
361\r
362 NetListInsertTail (&MnpServiceData->ChildrenList, &Instance->InstEntry);\r
363 MnpServiceData->ChildrenNumber++;\r
364\r
365 NET_RESTORE_TPL (OldTpl);\r
366\r
367ErrorExit:\r
368\r
369 if (EFI_ERROR (Status)) {\r
370\r
371 if (Instance->Handle != NULL) {\r
372\r
373 gBS->UninstallMultipleProtocolInterfaces (\r
374 &gEfiManagedNetworkProtocolGuid,\r
375 &Instance->ManagedNetwork,\r
376 NULL\r
377 );\r
378 }\r
379\r
380 NetFreePool (Instance);\r
381 }\r
382\r
383 return Status;\r
384}\r
385\r
386\r
387/**\r
388 Destroys a child handle with a set of I/O services.\r
389\r
390 @param This Protocol instance pointer.\r
391 @param ChildHandle Handle of the child to destroy.\r
392\r
393 @retval EFI_SUCCES The I/O services were removed from the child\r
394 handle.\r
395 @retval EFI_UNSUPPORTED The child handle does not support the I/O services\r
396 that are being removed.\r
397 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.\r
398 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because\r
399 its I/O services are being used.\r
400 @retval other The child handle was not destroyed.\r
401\r
402**/\r
403EFI_STATUS\r
404EFIAPI\r
405MnpServiceBindingDestroyChild (\r
406 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
407 IN EFI_HANDLE ChildHandle\r
408 )\r
409{\r
410 EFI_STATUS Status;\r
411 MNP_SERVICE_DATA *MnpServiceData;\r
412 EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;\r
413 MNP_INSTANCE_DATA *Instance;\r
414 EFI_TPL OldTpl;\r
415\r
416 if ((This == NULL) || (ChildHandle == NULL)) {\r
417\r
418 return EFI_INVALID_PARAMETER;\r
419 }\r
420\r
421 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);\r
422\r
423 //\r
424 // Try to retrieve ManagedNetwork Protocol from ChildHandle.\r
425 //\r
426 Status = gBS->OpenProtocol (\r
427 ChildHandle,\r
428 &gEfiManagedNetworkProtocolGuid,\r
429 (VOID **) &ManagedNetwork,\r
430 gMnpDriverBinding.DriverBindingHandle,\r
431 ChildHandle,\r
432 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
433 );\r
434 if (EFI_ERROR (Status)) {\r
435\r
436 return EFI_UNSUPPORTED;\r
437 }\r
438\r
439 Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);\r
440\r
441 //\r
442 // MnpServiceBindingDestroyChild may be called twice: first called by\r
443 // MnpServiceBindingStop, second called by uninstalling the MNP protocol\r
444 // in this ChildHandle. Use destroyed to make sure the resource clean code\r
445 // will only excecute once.\r
446 //\r
447 if (Instance->Destroyed) {\r
448\r
449 return EFI_SUCCESS;\r
450 }\r
451\r
452 Instance->Destroyed = TRUE;\r
453\r
454 //\r
455 // Close the Simple Network protocol.\r
456 //\r
457 gBS->CloseProtocol (\r
458 MnpServiceData->ControllerHandle,\r
459 &gEfiSimpleNetworkProtocolGuid,\r
460 gMnpDriverBinding.DriverBindingHandle,\r
461 ChildHandle\r
462 );\r
463\r
464 //\r
465 // Uninstall the ManagedNetwork protocol.\r
466 //\r
467 Status = gBS->UninstallMultipleProtocolInterfaces (\r
468 ChildHandle,\r
469 &gEfiManagedNetworkProtocolGuid,\r
470 &Instance->ManagedNetwork,\r
471 NULL\r
472 );\r
473 if (EFI_ERROR (Status)) {\r
474\r
475 MNP_DEBUG_ERROR (\r
476 ("MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",\r
477 Status)\r
478 );\r
479\r
480 Instance->Destroyed = FALSE;\r
481 return Status;\r
482 }\r
483\r
484 OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
485\r
486 //\r
487 // Reset the configuration.\r
488 //\r
489 ManagedNetwork->Configure (ManagedNetwork, NULL);\r
490\r
491 //\r
492 // Try to flush the RcvdPacketQueue.\r
493 //\r
494 MnpFlushRcvdDataQueue (Instance);\r
495\r
496 //\r
497 // Clean the RxTokenMap.\r
498 //\r
499 NetMapClean (&Instance->RxTokenMap);\r
500\r
501 //\r
502 // Remove this instance from the ChildrenList.\r
503 //\r
504 NetListRemoveEntry (&Instance->InstEntry);\r
505 MnpServiceData->ChildrenNumber--;\r
506\r
507 NET_RESTORE_TPL (OldTpl);\r
508\r
509 NetFreePool (Instance);\r
510\r
511 return Status;\r
512}\r
513\r
8a67d61d 514\r
515EFI_STATUS\r
516EFIAPI\r
517MnpDriverEntryPoint (\r
518 IN EFI_HANDLE ImageHandle,\r
519 IN EFI_SYSTEM_TABLE *SystemTable\r
520 )\r
521/*++\r
522\r
523Routine Description:\r
524\r
525 The entry point for Mnp driver which installs the driver binding and component name\r
526 protocol on its ImageHandle.\r
527\r
528Arguments:\r
529\r
530 ImageHandle - The image handle of the driver.\r
531 SystemTable - The system table.\r
532\r
533Returns:\r
534\r
535 EFI_SUCCESS - If the driver binding and component name protocols are successfully\r
536 installed, otherwise if failed.\r
537\r
538--*/\r
539{\r
83cbd279 540 return EfiLibInstallDriverBindingComponentName2 (\r
da1d0201 541 ImageHandle,\r
542 SystemTable,\r
543 &gMnpDriverBinding,\r
544 ImageHandle,\r
545 &gMnpComponentName,\r
83cbd279 546 &gMnpComponentName2\r
da1d0201 547 );\r
8a67d61d 548}\r