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
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.
21 #include "MnpDriver.h"
25 EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding
= {
26 MnpDriverBindingSupported
,
27 MnpDriverBindingStart
,
36 Test to see if this driver supports ControllerHandle.
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
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.
50 MnpDriverBindingSupported (
51 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
52 IN EFI_HANDLE ControllerHandle
,
53 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
57 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
60 // Test to see if MNP is already installed.
62 Status
= gBS
->OpenProtocol (
64 &gEfiManagedNetworkServiceBindingProtocolGuid
,
66 This
->DriverBindingHandle
,
68 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
70 if (!EFI_ERROR (Status
)) {
71 return EFI_ALREADY_STARTED
;
75 // Test to open the Simple Network protocol BY_DRIVER.
77 Status
= gBS
->OpenProtocol (
79 &gEfiSimpleNetworkProtocolGuid
,
81 This
->DriverBindingHandle
,
83 EFI_OPEN_PROTOCOL_BY_DRIVER
86 if (EFI_ERROR (Status
)) {
91 // Close the openned SNP protocol.
95 &gEfiSimpleNetworkProtocolGuid
,
96 This
->DriverBindingHandle
,
105 Start this driver on ControllerHandle.
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
112 @retval EFI_SUCCES This driver is added to ControllerHandle.
113 @retval EFI_ALREADY_STARTED This driver is already running on
115 @retval other This driver does not support this device.
120 MnpDriverBindingStart (
121 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
122 IN EFI_HANDLE ControllerHandle
,
123 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
127 MNP_SERVICE_DATA
*MnpServiceData
;
128 BOOLEAN MnpInitialized
;
130 MnpInitialized
= FALSE
;
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"));
136 return EFI_OUT_OF_RESOURCES
;
140 // Initialize the Mnp Service Data.
142 Status
= MnpInitializeServiceData (MnpServiceData
, This
->DriverBindingHandle
, ControllerHandle
);
143 if (EFI_ERROR (Status
)) {
145 DEBUG ((EFI_D_ERROR
, "MnpDriverBindingStart: MnpInitializeServiceData failed, %r.\n",Status
));
149 MnpInitialized
= TRUE
;
152 // Install the MNP Service Binding Protocol.
154 Status
= gBS
->InstallMultipleProtocolInterfaces (
156 &gEfiManagedNetworkServiceBindingProtocolGuid
,
157 &MnpServiceData
->ServiceBinding
,
163 if (EFI_ERROR (Status
)) {
165 if (MnpInitialized
) {
167 // Flush the Mnp Service Data.
169 MnpFlushServiceData (MnpServiceData
);
173 // Close the Simple Network Protocol.
177 &gEfiSimpleNetworkProtocolGuid
,
178 This
->DriverBindingHandle
,
182 gBS
->FreePool (MnpServiceData
);
190 Stop this driver on ControllerHandle.
192 @param This Protocol instance pointer.
193 @param ControllerHandle Handle of device to stop driver on.
194 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
195 of children is zero stop the entire bus driver.
196 @param ChildHandleBuffer List of Child Handles to Stop.
198 @retval EFI_SUCCES This driver is removed ControllerHandle.
199 @retval other This driver was not removed from this device.
204 MnpDriverBindingStop (
205 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
206 IN EFI_HANDLE ControllerHandle
,
207 IN UINTN NumberOfChildren
,
208 IN EFI_HANDLE
*ChildHandleBuffer
212 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
213 MNP_SERVICE_DATA
*MnpServiceData
;
214 MNP_INSTANCE_DATA
*Instance
;
217 // Retrieve the MNP service binding protocol from the ControllerHandle.
219 Status
= gBS
->OpenProtocol (
221 &gEfiManagedNetworkServiceBindingProtocolGuid
,
222 (VOID
**) &ServiceBinding
,
223 This
->DriverBindingHandle
,
225 EFI_OPEN_PROTOCOL_GET_PROTOCOL
227 if (EFI_ERROR (Status
)) {
231 "MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",
234 return EFI_DEVICE_ERROR
;
237 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
239 if (NumberOfChildren
== 0) {
241 // Uninstall the MNP Service Binding Protocol.
243 gBS
->UninstallMultipleProtocolInterfaces (
245 &gEfiManagedNetworkServiceBindingProtocolGuid
,
251 // Close the openned Snp protocol.
255 &gEfiSimpleNetworkProtocolGuid
,
256 This
->DriverBindingHandle
,
261 // Flush the Mnp service data.
263 MnpFlushServiceData (MnpServiceData
);
265 gBS
->FreePool (MnpServiceData
);
267 while (!IsListEmpty (&MnpServiceData
->ChildrenList
)) {
269 // Don't use NetListRemoveHead here, the remove opreration will be done
270 // in ServiceBindingDestroyChild.
272 Instance
= NET_LIST_HEAD (
273 &MnpServiceData
->ChildrenList
,
278 ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
287 Creates a child handle with a set of I/O services.
289 @param This Protocol instance pointer.
290 @param ChildHandle Pointer to the handle of the child to create. If
291 it is NULL, then a new handle is created. If it is
292 not NULL, then the I/O services are added to the
293 existing child handle.
295 @retval EFI_SUCCES The child handle was created with the I/O
297 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
299 @retval other The child handle was not created.
304 MnpServiceBindingCreateChild (
305 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
306 IN EFI_HANDLE
*ChildHandle
310 MNP_SERVICE_DATA
*MnpServiceData
;
311 MNP_INSTANCE_DATA
*Instance
;
315 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
317 return EFI_INVALID_PARAMETER
;
320 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
323 // Allocate buffer for the new instance.
325 Instance
= AllocateZeroPool (sizeof (MNP_INSTANCE_DATA
));
326 if (Instance
== NULL
) {
328 DEBUG ((EFI_D_ERROR
, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));
329 return EFI_OUT_OF_RESOURCES
;
333 // Init the instance data.
335 MnpInitializeInstanceData (MnpServiceData
, Instance
);
337 Status
= gBS
->InstallMultipleProtocolInterfaces (
339 &gEfiManagedNetworkProtocolGuid
,
340 &Instance
->ManagedNetwork
,
343 if (EFI_ERROR (Status
)) {
347 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
354 // Save the instance's childhandle.
356 Instance
->Handle
= *ChildHandle
;
358 Status
= gBS
->OpenProtocol (
359 MnpServiceData
->ControllerHandle
,
360 &gEfiSimpleNetworkProtocolGuid
,
362 gMnpDriverBinding
.DriverBindingHandle
,
364 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
366 if (EFI_ERROR (Status
)) {
371 // Add the child instance into ChildrenList.
373 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
375 InsertTailList (&MnpServiceData
->ChildrenList
, &Instance
->InstEntry
);
376 MnpServiceData
->ChildrenNumber
++;
378 gBS
->RestoreTPL (OldTpl
);
382 if (EFI_ERROR (Status
)) {
384 if (Instance
->Handle
!= NULL
) {
386 gBS
->UninstallMultipleProtocolInterfaces (
387 &gEfiManagedNetworkProtocolGuid
,
388 &Instance
->ManagedNetwork
,
393 gBS
->FreePool (Instance
);
401 Destroys a child handle with a set of I/O services.
403 @param This Protocol instance pointer.
404 @param ChildHandle Handle of the child to destroy.
406 @retval EFI_SUCCES The I/O services were removed from the child
408 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
409 that are being removed.
410 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
411 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
412 its I/O services are being used.
413 @retval other The child handle was not destroyed.
418 MnpServiceBindingDestroyChild (
419 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
420 IN EFI_HANDLE ChildHandle
424 MNP_SERVICE_DATA
*MnpServiceData
;
425 EFI_MANAGED_NETWORK_PROTOCOL
*ManagedNetwork
;
426 MNP_INSTANCE_DATA
*Instance
;
429 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
431 return EFI_INVALID_PARAMETER
;
434 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
437 // Try to retrieve ManagedNetwork Protocol from ChildHandle.
439 Status
= gBS
->OpenProtocol (
441 &gEfiManagedNetworkProtocolGuid
,
442 (VOID
**) &ManagedNetwork
,
443 gMnpDriverBinding
.DriverBindingHandle
,
445 EFI_OPEN_PROTOCOL_GET_PROTOCOL
447 if (EFI_ERROR (Status
)) {
449 return EFI_UNSUPPORTED
;
452 Instance
= MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork
);
455 // MnpServiceBindingDestroyChild may be called twice: first called by
456 // MnpServiceBindingStop, second called by uninstalling the MNP protocol
457 // in this ChildHandle. Use destroyed to make sure the resource clean code
458 // will only excecute once.
460 if (Instance
->Destroyed
) {
465 Instance
->Destroyed
= TRUE
;
468 // Close the Simple Network protocol.
471 MnpServiceData
->ControllerHandle
,
472 &gEfiSimpleNetworkProtocolGuid
,
473 gMnpDriverBinding
.DriverBindingHandle
,
478 // Uninstall the ManagedNetwork protocol.
480 Status
= gBS
->UninstallMultipleProtocolInterfaces (
482 &gEfiManagedNetworkProtocolGuid
,
483 &Instance
->ManagedNetwork
,
486 if (EFI_ERROR (Status
)) {
490 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
494 Instance
->Destroyed
= FALSE
;
498 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
501 // Reset the configuration.
503 ManagedNetwork
->Configure (ManagedNetwork
, NULL
);
506 // Try to flush the RcvdPacketQueue.
508 MnpFlushRcvdDataQueue (Instance
);
511 // Clean the RxTokenMap.
513 NetMapClean (&Instance
->RxTokenMap
);
516 // Remove this instance from the ChildrenList.
518 RemoveEntryList (&Instance
->InstEntry
);
519 MnpServiceData
->ChildrenNumber
--;
521 gBS
->RestoreTPL (OldTpl
);
523 gBS
->FreePool (Instance
);
531 MnpDriverEntryPoint (
532 IN EFI_HANDLE ImageHandle
,
533 IN EFI_SYSTEM_TABLE
*SystemTable
539 The entry point for Mnp driver which installs the driver binding and component name
540 protocol on its ImageHandle.
544 ImageHandle - The image handle of the driver.
545 SystemTable - The system table.
549 EFI_SUCCESS - If the driver binding and component name protocols are successfully
550 installed, otherwise if failed.
554 return EfiLibInstallDriverBindingComponentName2 (