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