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