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