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