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