3 Copyright (c) 2006, 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.
24 EFI_DRIVER_BINDING_PROTOCOL gUdp4DriverBinding
= {
25 Udp4DriverBindingSupported
,
26 Udp4DriverBindingStart
,
27 Udp4DriverBindingStop
,
33 EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding
= {
34 Udp4ServiceBindingCreateChild
,
35 Udp4ServiceBindingDestroyChild
40 Test to see if this driver supports ControllerHandle.
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_SUCCES This driver supports this device.
48 @retval EFI_ALREADY_STARTED This driver is already running on this device.
53 Udp4DriverBindingSupported (
54 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
55 IN EFI_HANDLE ControllerHandle
,
56 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
62 // Test for the Udp4ServiceBinding Protocol
64 Status
= gBS
->OpenProtocol (
66 &gEfiUdp4ServiceBindingProtocolGuid
,
68 This
->DriverBindingHandle
,
70 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
72 if (!EFI_ERROR (Status
)) {
73 return EFI_ALREADY_STARTED
;
77 // Test for the Ip4 Protocol
79 Status
= gBS
->OpenProtocol (
81 &gEfiIp4ServiceBindingProtocolGuid
,
83 This
->DriverBindingHandle
,
85 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
93 Start this driver on ControllerHandle.
95 @param This Protocol instance pointer.
96 @param ControllerHandle Handle of device to bind driver to
97 @param RemainingDevicePath Optional parameter use to pick a specific child
100 @retval EFI_SUCCES This driver is added to ControllerHandle
101 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
102 @retval other This driver does not support this device
107 Udp4DriverBindingStart (
108 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
109 IN EFI_HANDLE ControllerHandle
,
110 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
114 UDP4_SERVICE_DATA
*Udp4Service
;
117 // Allocate Private Context Data Structure.
119 Udp4Service
= AllocatePool (sizeof (UDP4_SERVICE_DATA
));
120 if (Udp4Service
== NULL
) {
121 return EFI_OUT_OF_RESOURCES
;
124 Status
= Udp4CreateService (Udp4Service
, This
->DriverBindingHandle
, ControllerHandle
);
125 if (EFI_ERROR (Status
)) {
126 gBS
->FreePool (Udp4Service
);
131 // Install the Udp4ServiceBindingProtocol on the ControllerHandle.
133 Status
= gBS
->InstallMultipleProtocolInterfaces (
135 &gEfiUdp4ServiceBindingProtocolGuid
,
136 &Udp4Service
->ServiceBinding
,
139 if (EFI_ERROR (Status
)) {
140 Udp4CleanService (Udp4Service
);
141 gBS
->FreePool (Udp4Service
);
143 Udp4SetVariableData (Udp4Service
);
151 Stop this driver on ControllerHandle.
153 @param This Protocol instance pointer.
154 @param ControllerHandle Handle of device to stop driver on
155 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
156 of children is zero stop the entire bus driver.
157 @param ChildHandleBuffer List of Child Handles to Stop.
159 @retval EFI_SUCCES This driver is removed ControllerHandle.
160 @retval other This driver was not removed from this device.
165 Udp4DriverBindingStop (
166 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
167 IN EFI_HANDLE ControllerHandle
,
168 IN UINTN NumberOfChildren
,
169 IN EFI_HANDLE
*ChildHandleBuffer
173 EFI_HANDLE NicHandle
;
174 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
175 UDP4_SERVICE_DATA
*Udp4Service
;
176 UDP4_INSTANCE_DATA
*Instance
;
179 // Find the NicHandle where UDP4 ServiceBinding Protocol is installed.
181 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiIp4ProtocolGuid
);
182 if (NicHandle
== NULL
) {
183 return EFI_DEVICE_ERROR
;
187 // Retrieve the UDP4 ServiceBinding Protocol.
189 Status
= gBS
->OpenProtocol (
191 &gEfiUdp4ServiceBindingProtocolGuid
,
192 (VOID
**) &ServiceBinding
,
193 This
->DriverBindingHandle
,
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL
197 if (EFI_ERROR (Status
)) {
198 return EFI_DEVICE_ERROR
;
201 Udp4Service
= UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding
);
203 if (NumberOfChildren
== 0) {
205 gBS
->UninstallMultipleProtocolInterfaces (
207 &gEfiUdp4ServiceBindingProtocolGuid
,
208 &Udp4Service
->ServiceBinding
,
212 Udp4ClearVariableData (Udp4Service
);
214 Udp4CleanService (Udp4Service
);
216 gBS
->FreePool (Udp4Service
);
219 while (!IsListEmpty (&Udp4Service
->ChildrenList
)) {
220 Instance
= NET_LIST_HEAD (&Udp4Service
->ChildrenList
, UDP4_INSTANCE_DATA
, Link
);
222 ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->ChildHandle
);
231 Creates a child handle with a set of I/O services.
233 @param This Protocol instance pointer.
234 @param ChildHandle Pointer to the handle of the child to create. If
235 it is NULL, then a new handle is created. If it
236 is not NULL, then the I/O services are added to
237 the existing child handle.
239 @retval EFI_SUCCES The child handle was created with the I/O services
240 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
242 @retval other The child handle was not created
247 Udp4ServiceBindingCreateChild (
248 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
249 IN EFI_HANDLE
*ChildHandle
253 UDP4_SERVICE_DATA
*Udp4Service
;
254 UDP4_INSTANCE_DATA
*Instance
;
258 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
259 return EFI_INVALID_PARAMETER
;
262 Udp4Service
= UDP4_SERVICE_DATA_FROM_THIS (This
);
265 // Allocate the instance private data structure.
267 Instance
= AllocateZeroPool (sizeof (UDP4_INSTANCE_DATA
));
268 if (Instance
== NULL
) {
269 return EFI_OUT_OF_RESOURCES
;
272 Udp4InitInstance (Udp4Service
, Instance
);
275 // Add an IpInfo for this instance.
277 Instance
->IpInfo
= IpIoAddIp (Udp4Service
->IpIo
);
278 if (Instance
->IpInfo
== NULL
) {
279 Status
= EFI_OUT_OF_RESOURCES
;
284 // Install the Udp4Protocol for this instance.
286 Status
= gBS
->InstallMultipleProtocolInterfaces (
288 &gEfiUdp4ProtocolGuid
,
289 &Instance
->Udp4Proto
,
292 if (EFI_ERROR (Status
)) {
296 Instance
->ChildHandle
= *ChildHandle
;
299 // Open the default Ip4 protocol in the IP_IO BY_CHILD.
301 Status
= gBS
->OpenProtocol (
302 Udp4Service
->IpIo
->ChildHandle
,
303 &gEfiIp4ProtocolGuid
,
305 gUdp4DriverBinding
.DriverBindingHandle
,
306 Instance
->ChildHandle
,
307 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
309 if (EFI_ERROR (Status
)) {
313 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
316 // Link this instance into the service context data and increase the ChildrenNumber.
318 InsertTailList (&Udp4Service
->ChildrenList
, &Instance
->Link
);
319 Udp4Service
->ChildrenNumber
++;
321 gBS
->RestoreTPL (OldTpl
);
327 if (Instance
->ChildHandle
!= NULL
) {
328 gBS
->UninstallMultipleProtocolInterfaces (
329 Instance
->ChildHandle
,
330 &gEfiUdp4ProtocolGuid
,
331 &Instance
->Udp4Proto
,
336 if (Instance
->IpInfo
!= NULL
) {
337 IpIoRemoveIp (Udp4Service
->IpIo
, Instance
->IpInfo
);
340 Udp4CleanInstance (Instance
);
342 gBS
->FreePool (Instance
);
349 Destroys a child handle with a set of I/O services.
351 @param This Protocol instance pointer.
352 @param ChildHandle Handle of the child to destroy
354 @retval EFI_SUCCES The I/O services were removed from the child
356 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
357 that are being removed
358 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
359 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
360 its I/O services are being used.
361 @retval other The child handle was not destroyed
366 Udp4ServiceBindingDestroyChild (
367 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
368 IN EFI_HANDLE ChildHandle
372 UDP4_SERVICE_DATA
*Udp4Service
;
373 EFI_UDP4_PROTOCOL
*Udp4Proto
;
374 UDP4_INSTANCE_DATA
*Instance
;
377 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
378 return EFI_INVALID_PARAMETER
;
381 Udp4Service
= UDP4_SERVICE_DATA_FROM_THIS (This
);
384 // Try to get the Udp4 protocol from the ChildHandle.
386 Status
= gBS
->OpenProtocol (
388 &gEfiUdp4ProtocolGuid
,
389 (VOID
**) &Udp4Proto
,
390 gUdp4DriverBinding
.DriverBindingHandle
,
392 EFI_OPEN_PROTOCOL_GET_PROTOCOL
394 if (EFI_ERROR (Status
)) {
395 return EFI_UNSUPPORTED
;
398 Instance
= UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto
);
400 if (Instance
->Destroyed
) {
405 // Use the Destroyed flag to avoid the re-entering of the following code.
407 Instance
->Destroyed
= TRUE
;
410 // Close the Ip4 protocol.
413 Udp4Service
->IpIo
->ChildHandle
,
414 &gEfiIp4ProtocolGuid
,
415 gUdp4DriverBinding
.DriverBindingHandle
,
416 Instance
->ChildHandle
420 // Uninstall the Udp4Protocol previously installed on the ChildHandle.
422 Status
= gBS
->UninstallMultipleProtocolInterfaces (
424 &gEfiUdp4ProtocolGuid
,
425 (VOID
*) &Instance
->Udp4Proto
,
428 if (EFI_ERROR (Status
)) {
429 Instance
->Destroyed
= FALSE
;
434 // Reset the configuration in case the instance's consumer forgets to do this.
436 Udp4Proto
->Configure (Udp4Proto
, NULL
);
439 // Remove the IpInfo this instance consumes.
441 IpIoRemoveIp (Udp4Service
->IpIo
, Instance
->IpInfo
);
443 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
446 // Remove this instance from the service context data's ChildrenList.
448 RemoveEntryList (&Instance
->Link
);
449 Udp4Service
->ChildrenNumber
--;
452 // Clean the instance.
454 Udp4CleanInstance (Instance
);
456 gBS
->RestoreTPL (OldTpl
);
458 gBS
->FreePool (Instance
);
466 Udp4DriverEntryPoint (
467 IN EFI_HANDLE ImageHandle
,
468 IN EFI_SYSTEM_TABLE
*SystemTable
474 The entry point for Udp4 driver which installs the driver binding
475 and component name protocol on its ImageHandle.
479 ImageHandle - The image handle of the driver.
480 SystemTable - The system table.
484 EFI_SUCCESS - if the driver binding and component name protocols are
485 successfully installed, otherwise if failed.
492 // Install the Udp4DriverBinding and Udp4ComponentName protocols.
494 Status
= EfiLibInstallDriverBindingComponentName2 (
502 if (!EFI_ERROR (Status
)) {
504 // Initialize the UDP random port.
506 mUdp4RandomPort
= (UINT16
) (((UINT16
) NetRandomInitSeed ()) % UDP4_PORT_KNOWN
+ UDP4_PORT_KNOWN
);