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