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
,
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.
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
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
54 MnpDriverBindingSupported (
55 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
56 IN EFI_HANDLE ControllerHandle
,
57 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
61 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
64 // Test to see if MNP is already installed.
66 Status
= gBS
->OpenProtocol (
68 &gEfiManagedNetworkServiceBindingProtocolGuid
,
70 This
->DriverBindingHandle
,
72 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
74 if (!EFI_ERROR (Status
)) {
75 return EFI_ALREADY_STARTED
;
79 // Test to open the Simple Network protocol BY_DRIVER.
81 Status
= gBS
->OpenProtocol (
83 &gEfiSimpleNetworkProtocolGuid
,
85 This
->DriverBindingHandle
,
87 EFI_OPEN_PROTOCOL_BY_DRIVER
90 if (EFI_ERROR (Status
)) {
95 // Close the openned SNP protocol.
99 &gEfiSimpleNetworkProtocolGuid
,
100 This
->DriverBindingHandle
,
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.
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
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
128 MnpDriverBindingStart (
129 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
130 IN EFI_HANDLE ControllerHandle
,
131 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
135 MNP_SERVICE_DATA
*MnpServiceData
;
136 BOOLEAN MnpInitialized
;
138 MnpInitialized
= FALSE
;
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"));
144 return EFI_OUT_OF_RESOURCES
;
148 // Initialize the Mnp Service Data.
150 Status
= MnpInitializeServiceData (MnpServiceData
, This
->DriverBindingHandle
, ControllerHandle
);
151 if (EFI_ERROR (Status
)) {
153 DEBUG ((EFI_D_ERROR
, "MnpDriverBindingStart: MnpInitializeServiceData failed, %r.\n",Status
));
157 MnpInitialized
= TRUE
;
160 // Install the MNP Service Binding Protocol.
162 Status
= gBS
->InstallMultipleProtocolInterfaces (
164 &gEfiManagedNetworkServiceBindingProtocolGuid
,
165 &MnpServiceData
->ServiceBinding
,
171 if (EFI_ERROR (Status
)) {
173 if (MnpInitialized
) {
175 // Flush the Mnp Service Data.
177 MnpFlushServiceData (MnpServiceData
, This
->DriverBindingHandle
);
180 gBS
->FreePool (MnpServiceData
);
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.
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.
200 @retval EFI_SUCCESS This driver is removed ControllerHandle
201 @retval other This driver was not removed from this device
206 MnpDriverBindingStop (
207 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
208 IN EFI_HANDLE ControllerHandle
,
209 IN UINTN NumberOfChildren
,
210 IN EFI_HANDLE
*ChildHandleBuffer
214 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
215 MNP_SERVICE_DATA
*MnpServiceData
;
216 MNP_INSTANCE_DATA
*Instance
;
219 // Retrieve the MNP service binding protocol from the ControllerHandle.
221 Status
= gBS
->OpenProtocol (
223 &gEfiManagedNetworkServiceBindingProtocolGuid
,
224 (VOID
**) &ServiceBinding
,
225 This
->DriverBindingHandle
,
227 EFI_OPEN_PROTOCOL_GET_PROTOCOL
229 if (EFI_ERROR (Status
)) {
233 "MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",
236 return EFI_DEVICE_ERROR
;
239 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
241 if (NumberOfChildren
== 0) {
243 // Uninstall the MNP Service Binding Protocol.
245 gBS
->UninstallMultipleProtocolInterfaces (
247 &gEfiManagedNetworkServiceBindingProtocolGuid
,
253 // Flush the Mnp service data.
255 MnpFlushServiceData (MnpServiceData
, This
->DriverBindingHandle
);
257 gBS
->FreePool (MnpServiceData
);
259 while (!IsListEmpty (&MnpServiceData
->ChildrenList
)) {
261 // Don't use NetListRemoveHead here, the remove opreration will be done
262 // in ServiceBindingDestroyChild.
264 Instance
= NET_LIST_HEAD (
265 &MnpServiceData
->ChildrenList
,
270 ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
279 Creates a child handle with a set of I/O services.
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.
287 @retval EFI_SUCCES The child handle was created with the I/O
289 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
291 @retval other The child handle was not created.
296 MnpServiceBindingCreateChild (
297 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
298 IN EFI_HANDLE
*ChildHandle
302 MNP_SERVICE_DATA
*MnpServiceData
;
303 MNP_INSTANCE_DATA
*Instance
;
307 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
309 return EFI_INVALID_PARAMETER
;
312 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
315 // Allocate buffer for the new instance.
317 Instance
= AllocateZeroPool (sizeof (MNP_INSTANCE_DATA
));
318 if (Instance
== NULL
) {
320 DEBUG ((EFI_D_ERROR
, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));
321 return EFI_OUT_OF_RESOURCES
;
325 // Init the instance data.
327 MnpInitializeInstanceData (MnpServiceData
, Instance
);
329 Status
= gBS
->InstallMultipleProtocolInterfaces (
331 &gEfiManagedNetworkProtocolGuid
,
332 &Instance
->ManagedNetwork
,
335 if (EFI_ERROR (Status
)) {
339 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
346 // Save the instance's childhandle.
348 Instance
->Handle
= *ChildHandle
;
350 Status
= gBS
->OpenProtocol (
351 MnpServiceData
->ControllerHandle
,
352 &gEfiSimpleNetworkProtocolGuid
,
354 gMnpDriverBinding
.DriverBindingHandle
,
356 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
358 if (EFI_ERROR (Status
)) {
363 // Add the child instance into ChildrenList.
365 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
367 InsertTailList (&MnpServiceData
->ChildrenList
, &Instance
->InstEntry
);
368 MnpServiceData
->ChildrenNumber
++;
370 gBS
->RestoreTPL (OldTpl
);
374 if (EFI_ERROR (Status
)) {
376 if (Instance
->Handle
!= NULL
) {
378 gBS
->UninstallMultipleProtocolInterfaces (
379 &gEfiManagedNetworkProtocolGuid
,
380 &Instance
->ManagedNetwork
,
385 gBS
->FreePool (Instance
);
393 Destroys a child handle with a set of I/O services.
395 @param This Protocol instance pointer.
396 @param ChildHandle Handle of the child to destroy.
398 @retval EFI_SUCCES The I/O services were removed from the child
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.
410 MnpServiceBindingDestroyChild (
411 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
412 IN EFI_HANDLE ChildHandle
416 MNP_SERVICE_DATA
*MnpServiceData
;
417 EFI_MANAGED_NETWORK_PROTOCOL
*ManagedNetwork
;
418 MNP_INSTANCE_DATA
*Instance
;
421 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
423 return EFI_INVALID_PARAMETER
;
426 MnpServiceData
= MNP_SERVICE_DATA_FROM_THIS (This
);
429 // Try to retrieve ManagedNetwork Protocol from ChildHandle.
431 Status
= gBS
->OpenProtocol (
433 &gEfiManagedNetworkProtocolGuid
,
434 (VOID
**) &ManagedNetwork
,
435 gMnpDriverBinding
.DriverBindingHandle
,
437 EFI_OPEN_PROTOCOL_GET_PROTOCOL
439 if (EFI_ERROR (Status
)) {
441 return EFI_UNSUPPORTED
;
444 Instance
= MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork
);
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.
452 if (Instance
->Destroyed
) {
457 Instance
->Destroyed
= TRUE
;
460 // Close the Simple Network protocol.
463 MnpServiceData
->ControllerHandle
,
464 &gEfiSimpleNetworkProtocolGuid
,
465 gMnpDriverBinding
.DriverBindingHandle
,
470 // Uninstall the ManagedNetwork protocol.
472 Status
= gBS
->UninstallMultipleProtocolInterfaces (
474 &gEfiManagedNetworkProtocolGuid
,
475 &Instance
->ManagedNetwork
,
478 if (EFI_ERROR (Status
)) {
482 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
486 Instance
->Destroyed
= FALSE
;
490 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
493 // Reset the configuration.
495 ManagedNetwork
->Configure (ManagedNetwork
, NULL
);
498 // Try to flush the RcvdPacketQueue.
500 MnpFlushRcvdDataQueue (Instance
);
503 // Clean the RxTokenMap.
505 NetMapClean (&Instance
->RxTokenMap
);
508 // Remove this instance from the ChildrenList.
510 RemoveEntryList (&Instance
->InstEntry
);
511 MnpServiceData
->ChildrenNumber
--;
513 gBS
->RestoreTPL (OldTpl
);
515 gBS
->FreePool (Instance
);
521 The entry point for Mnp driver which installs the driver binding and component
522 name protocol on its ImageHandle.
524 @param ImageHandle The image handle of the driver.
525 @param SystemTable The system table.
527 @retval EFI_SUCCES the driver binding and component name protocols are
528 successfully installed.
529 @retval other failed.
534 MnpDriverEntryPoint (
535 IN EFI_HANDLE ImageHandle
,
536 IN EFI_SYSTEM_TABLE
*SystemTable
539 return EfiLibInstallDriverBindingComponentName2 (