]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c
Remove some useless EDK_RELEASE_VERSION, EFI_SPECIFICATION_VERSION ,and review VALID_...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Udp4Dxe / Udp4Driver.c
CommitLineData
8a67d61d 1/** @file\r
2\r
3Copyright (c) 2006, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 Udp4Driver.c\r
15\r
16Abstract:\r
17\r
18\r
19**/\r
20\r
21\r
22#include "Udp4Impl.h"\r
23\r
24EFI_DRIVER_BINDING_PROTOCOL gUdp4DriverBinding = {\r
25 Udp4DriverBindingSupported,\r
26 Udp4DriverBindingStart,\r
27 Udp4DriverBindingStop,\r
28 0xa,\r
29 NULL,\r
30 NULL\r
31};\r
32\r
33EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {\r
34 Udp4ServiceBindingCreateChild,\r
35 Udp4ServiceBindingDestroyChild\r
36};\r
37\r
38\r
39/**\r
bab52709 40 Test to see if this driver supports ControllerHandle. This service\r
41 is called by the EFI boot service ConnectController(). In\r
42 order to make drivers as small as possible, there are a few calling\r
43 restrictions for this service. ConnectController() must\r
44 follow these calling restrictions. If any other agent wishes to call\r
45 Supported() it must also follow these calling restrictions.\r
46\r
47 @param This Protocol instance pointer.\r
48 @param ControllerHandle Handle of device to test\r
49 @param RemainingDevicePath Optional parameter use to pick a specific child\r
50 device to start.\r
51\r
52 @retval EFI_SUCCESS This driver supports this device\r
53 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
54 @retval other This driver does not support this device\r
8a67d61d 55\r
56**/\r
57EFI_STATUS\r
58EFIAPI\r
59Udp4DriverBindingSupported (\r
60 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
61 IN EFI_HANDLE ControllerHandle,\r
62 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
63 )\r
64{\r
65 EFI_STATUS Status;\r
66\r
67 //\r
68 // Test for the Udp4ServiceBinding Protocol\r
69 //\r
70 Status = gBS->OpenProtocol (\r
71 ControllerHandle,\r
72 &gEfiUdp4ServiceBindingProtocolGuid,\r
73 NULL,\r
74 This->DriverBindingHandle,\r
75 ControllerHandle,\r
76 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
77 );\r
78 if (!EFI_ERROR (Status)) {\r
79 return EFI_ALREADY_STARTED;\r
80 }\r
81\r
82 //\r
83 // Test for the Ip4 Protocol\r
84 //\r
85 Status = gBS->OpenProtocol (\r
86 ControllerHandle,\r
87 &gEfiIp4ServiceBindingProtocolGuid,\r
88 NULL,\r
89 This->DriverBindingHandle,\r
90 ControllerHandle,\r
91 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
92 );\r
93\r
94 return Status;\r
95}\r
96\r
97\r
98/**\r
bab52709 99 Start this driver on ControllerHandle. This service is called by the\r
100 EFI boot service ConnectController(). In order to make\r
101 drivers as small as possible, there are a few calling restrictions for\r
102 this service. ConnectController() must follow these\r
103 calling restrictions. If any other agent wishes to call Start() it\r
104 must also follow these calling restrictions.\r
105\r
106 @param This Protocol instance pointer.\r
107 @param ControllerHandle Handle of device to bind driver to\r
108 @param RemainingDevicePath Optional parameter use to pick a specific child\r
109 device to start.\r
110\r
111 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
112 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
113 @retval other This driver does not support this device\r
8a67d61d 114\r
115**/\r
116EFI_STATUS\r
117EFIAPI\r
118Udp4DriverBindingStart (\r
119 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
120 IN EFI_HANDLE ControllerHandle,\r
121 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
122 )\r
123{\r
124 EFI_STATUS Status;\r
125 UDP4_SERVICE_DATA *Udp4Service;\r
126\r
127 //\r
128 // Allocate Private Context Data Structure.\r
129 //\r
e48e37fc 130 Udp4Service = AllocatePool (sizeof (UDP4_SERVICE_DATA));\r
8a67d61d 131 if (Udp4Service == NULL) {\r
132 return EFI_OUT_OF_RESOURCES;\r
133 }\r
134\r
135 Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);\r
136 if (EFI_ERROR (Status)) {\r
e48e37fc 137 gBS->FreePool (Udp4Service);\r
c4a62a12 138 return Status;\r
8a67d61d 139 }\r
140\r
141 //\r
142 // Install the Udp4ServiceBindingProtocol on the ControllerHandle.\r
143 //\r
144 Status = gBS->InstallMultipleProtocolInterfaces (\r
145 &ControllerHandle,\r
146 &gEfiUdp4ServiceBindingProtocolGuid,\r
147 &Udp4Service->ServiceBinding,\r
148 NULL\r
149 );\r
150 if (EFI_ERROR (Status)) {\r
c4a62a12 151 Udp4CleanService (Udp4Service);\r
e48e37fc 152 gBS->FreePool (Udp4Service);\r
c4a62a12 153 } else {\r
154 Udp4SetVariableData (Udp4Service);\r
8a67d61d 155 }\r
156\r
8a67d61d 157 return Status;\r
158}\r
159\r
160\r
161/**\r
bab52709 162 Stop this driver on ControllerHandle. This service is called by the\r
163 EFI boot service DisconnectController(). In order to\r
164 make drivers as small as possible, there are a few calling\r
165 restrictions for this service. DisconnectController()\r
166 must follow these calling restrictions. If any other agent wishes\r
167 to call Stop() it must also follow these calling restrictions.\r
168 \r
169 @param This Protocol instance pointer.\r
170 @param ControllerHandle Handle of device to stop driver on\r
171 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
172 children is zero stop the entire bus driver.\r
173 @param ChildHandleBuffer List of Child Handles to Stop.\r
174\r
175 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
176 @retval other This driver was not removed from this device\r
8a67d61d 177\r
178**/\r
179EFI_STATUS\r
180EFIAPI\r
181Udp4DriverBindingStop (\r
182 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
183 IN EFI_HANDLE ControllerHandle,\r
184 IN UINTN NumberOfChildren,\r
185 IN EFI_HANDLE *ChildHandleBuffer\r
186 )\r
187{\r
188 EFI_STATUS Status;\r
189 EFI_HANDLE NicHandle;\r
190 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;\r
191 UDP4_SERVICE_DATA *Udp4Service;\r
192 UDP4_INSTANCE_DATA *Instance;\r
193\r
194 //\r
195 // Find the NicHandle where UDP4 ServiceBinding Protocol is installed.\r
196 //\r
197 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);\r
198 if (NicHandle == NULL) {\r
c4a62a12 199 return EFI_DEVICE_ERROR;\r
8a67d61d 200 }\r
201\r
202 //\r
203 // Retrieve the UDP4 ServiceBinding Protocol.\r
204 //\r
205 Status = gBS->OpenProtocol (\r
206 NicHandle,\r
207 &gEfiUdp4ServiceBindingProtocolGuid,\r
208 (VOID **) &ServiceBinding,\r
209 This->DriverBindingHandle,\r
210 NicHandle,\r
211 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
212 );\r
213 if (EFI_ERROR (Status)) {\r
214 return EFI_DEVICE_ERROR;\r
215 }\r
216\r
217 Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
218\r
c4a62a12 219 if (NumberOfChildren == 0) {\r
8a67d61d 220\r
c4a62a12 221 gBS->UninstallMultipleProtocolInterfaces (\r
222 NicHandle,\r
223 &gEfiUdp4ServiceBindingProtocolGuid,\r
224 &Udp4Service->ServiceBinding,\r
225 NULL\r
226 );\r
8a67d61d 227\r
c4a62a12 228 Udp4ClearVariableData (Udp4Service);\r
8a67d61d 229\r
c4a62a12 230 Udp4CleanService (Udp4Service);\r
8a67d61d 231\r
e48e37fc 232 gBS->FreePool (Udp4Service);\r
c4a62a12 233 } else {\r
8a67d61d 234\r
e48e37fc 235 while (!IsListEmpty (&Udp4Service->ChildrenList)) {\r
c4a62a12 236 Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link);\r
8a67d61d 237\r
c4a62a12 238 ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);\r
239 }\r
240 }\r
241\r
242 return Status;\r
8a67d61d 243}\r
244\r
245\r
246/**\r
247 Creates a child handle with a set of I/O services.\r
248\r
bab52709 249 @param This Protocol instance pointer.\r
250 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
251 then a new handle is created. If it is not NULL, then the\r
252 I/O services are added to the existing child handle.\r
8a67d61d 253\r
bab52709 254 @retval EFI_SUCCES The child handle was created with the I/O services\r
255 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
256 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create\r
257 the child\r
258 @retval other The child handle was not created\r
8a67d61d 259\r
260**/\r
261EFI_STATUS\r
262EFIAPI\r
263Udp4ServiceBindingCreateChild (\r
264 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
265 IN EFI_HANDLE *ChildHandle\r
266 )\r
267{\r
268 EFI_STATUS Status;\r
269 UDP4_SERVICE_DATA *Udp4Service;\r
270 UDP4_INSTANCE_DATA *Instance;\r
271 EFI_TPL OldTpl;\r
272 VOID *Ip4;\r
273\r
274 if ((This == NULL) || (ChildHandle == NULL)) {\r
275 return EFI_INVALID_PARAMETER;\r
276 }\r
277\r
278 Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This);\r
279\r
280 //\r
281 // Allocate the instance private data structure.\r
282 //\r
e48e37fc 283 Instance = AllocateZeroPool (sizeof (UDP4_INSTANCE_DATA));\r
8a67d61d 284 if (Instance == NULL) {\r
285 return EFI_OUT_OF_RESOURCES;\r
286 }\r
287\r
288 Udp4InitInstance (Udp4Service, Instance);\r
289\r
290 //\r
291 // Add an IpInfo for this instance.\r
292 //\r
293 Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo);\r
294 if (Instance->IpInfo == NULL) {\r
295 Status = EFI_OUT_OF_RESOURCES;\r
c4a62a12 296 goto ON_ERROR;\r
8a67d61d 297 }\r
298\r
299 //\r
300 // Install the Udp4Protocol for this instance.\r
301 //\r
302 Status = gBS->InstallMultipleProtocolInterfaces (\r
303 ChildHandle,\r
304 &gEfiUdp4ProtocolGuid,\r
305 &Instance->Udp4Proto,\r
306 NULL\r
307 );\r
308 if (EFI_ERROR (Status)) {\r
c4a62a12 309 goto ON_ERROR;\r
8a67d61d 310 }\r
311\r
312 Instance->ChildHandle = *ChildHandle;\r
313\r
314 //\r
315 // Open the default Ip4 protocol in the IP_IO BY_CHILD.\r
316 //\r
317 Status = gBS->OpenProtocol (\r
318 Udp4Service->IpIo->ChildHandle,\r
319 &gEfiIp4ProtocolGuid,\r
320 (VOID **) &Ip4,\r
321 gUdp4DriverBinding.DriverBindingHandle,\r
322 Instance->ChildHandle,\r
323 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
324 );\r
325 if (EFI_ERROR (Status)) {\r
c4a62a12 326 goto ON_ERROR;\r
8a67d61d 327 }\r
328\r
e48e37fc 329 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 330\r
331 //\r
332 // Link this instance into the service context data and increase the ChildrenNumber.\r
333 //\r
e48e37fc 334 InsertTailList (&Udp4Service->ChildrenList, &Instance->Link);\r
8a67d61d 335 Udp4Service->ChildrenNumber++;\r
336\r
e48e37fc 337 gBS->RestoreTPL (OldTpl);\r
8a67d61d 338\r
c4a62a12 339 return EFI_SUCCESS;\r
8a67d61d 340\r
c4a62a12 341ON_ERROR:\r
8a67d61d 342\r
c4a62a12 343 if (Instance->ChildHandle != NULL) {\r
344 gBS->UninstallMultipleProtocolInterfaces (\r
345 Instance->ChildHandle,\r
346 &gEfiUdp4ProtocolGuid,\r
347 &Instance->Udp4Proto,\r
348 NULL\r
349 );\r
350 }\r
8a67d61d 351\r
c4a62a12 352 if (Instance->IpInfo != NULL) {\r
353 IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);\r
354 }\r
8a67d61d 355\r
356 Udp4CleanInstance (Instance);\r
357\r
e48e37fc 358 gBS->FreePool (Instance);\r
8a67d61d 359\r
360 return Status;\r
361}\r
362\r
363\r
364/**\r
365 Destroys a child handle with a set of I/O services.\r
366\r
bab52709 367 @param This Protocol instance pointer.\r
368 @param ChildHandle Handle of the child to destroy\r
8a67d61d 369\r
bab52709 370 @retval EFI_SUCCES The I/O services were removed from the child handle\r
371 @retval EFI_UNSUPPORTED The child handle does not support the I/O services\r
372 that are being removed.\r
373 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.\r
374 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because its\r
375 I/O services are being used.\r
376 @retval other The child handle was not destroyed\r
8a67d61d 377\r
378**/\r
379EFI_STATUS\r
380EFIAPI\r
381Udp4ServiceBindingDestroyChild (\r
382 IN EFI_SERVICE_BINDING_PROTOCOL *This,\r
383 IN EFI_HANDLE ChildHandle\r
384 )\r
385{\r
386 EFI_STATUS Status;\r
387 UDP4_SERVICE_DATA *Udp4Service;\r
388 EFI_UDP4_PROTOCOL *Udp4Proto;\r
389 UDP4_INSTANCE_DATA *Instance;\r
390 EFI_TPL OldTpl;\r
391\r
392 if ((This == NULL) || (ChildHandle == NULL)) {\r
393 return EFI_INVALID_PARAMETER;\r
394 }\r
395\r
396 Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This);\r
397\r
398 //\r
399 // Try to get the Udp4 protocol from the ChildHandle.\r
400 //\r
401 Status = gBS->OpenProtocol (\r
402 ChildHandle,\r
403 &gEfiUdp4ProtocolGuid,\r
404 (VOID **) &Udp4Proto,\r
405 gUdp4DriverBinding.DriverBindingHandle,\r
406 ChildHandle,\r
407 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
408 );\r
409 if (EFI_ERROR (Status)) {\r
410 return EFI_UNSUPPORTED;\r
411 }\r
412\r
413 Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto);\r
414\r
415 if (Instance->Destroyed) {\r
416 return EFI_SUCCESS;\r
417 }\r
418\r
419 //\r
420 // Use the Destroyed flag to avoid the re-entering of the following code.\r
421 //\r
422 Instance->Destroyed = TRUE;\r
423\r
424 //\r
425 // Close the Ip4 protocol.\r
426 //\r
427 gBS->CloseProtocol (\r
428 Udp4Service->IpIo->ChildHandle,\r
429 &gEfiIp4ProtocolGuid,\r
430 gUdp4DriverBinding.DriverBindingHandle,\r
431 Instance->ChildHandle\r
432 );\r
433\r
434 //\r
435 // Uninstall the Udp4Protocol previously installed on the ChildHandle.\r
436 //\r
437 Status = gBS->UninstallMultipleProtocolInterfaces (\r
438 ChildHandle,\r
439 &gEfiUdp4ProtocolGuid,\r
440 (VOID *) &Instance->Udp4Proto,\r
441 NULL\r
442 );\r
443 if (EFI_ERROR (Status)) {\r
444 Instance->Destroyed = FALSE;\r
445 return Status;\r
446 }\r
447\r
448 //\r
449 // Reset the configuration in case the instance's consumer forgets to do this.\r
450 //\r
451 Udp4Proto->Configure (Udp4Proto, NULL);\r
452\r
453 //\r
454 // Remove the IpInfo this instance consumes.\r
455 //\r
456 IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo);\r
457\r
e48e37fc 458 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
8a67d61d 459\r
460 //\r
461 // Remove this instance from the service context data's ChildrenList.\r
462 //\r
e48e37fc 463 RemoveEntryList (&Instance->Link);\r
8a67d61d 464 Udp4Service->ChildrenNumber--;\r
465\r
466 //\r
467 // Clean the instance.\r
468 //\r
469 Udp4CleanInstance (Instance);\r
470\r
e48e37fc 471 gBS->RestoreTPL (OldTpl);\r
8a67d61d 472\r
e48e37fc 473 gBS->FreePool (Instance);\r
8a67d61d 474\r
475 return EFI_SUCCESS;\r
476}\r
477\r
bab52709 478/**\r
479 This is the declaration of an EFI image entry point. This entry point is\r
480 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
481 both device drivers and bus drivers.\r
482 \r
483 The entry point for Udp4 driver which installs the driver binding\r
484 and component name protocol on its ImageHandle.\r
485\r
486 @param ImageHandle The firmware allocated handle for the UEFI image.\r
487 @param SystemTable A pointer to the EFI System Table.\r
488\r
489 @retval EFI_SUCCESS The operation completed successfully.\r
490 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
8a67d61d 491\r
bab52709 492**/\r
8a67d61d 493EFI_STATUS\r
494EFIAPI\r
495Udp4DriverEntryPoint (\r
496 IN EFI_HANDLE ImageHandle,\r
497 IN EFI_SYSTEM_TABLE *SystemTable\r
498 )\r
8a67d61d 499{\r
500 EFI_STATUS Status;\r
501\r
502 //\r
503 // Install the Udp4DriverBinding and Udp4ComponentName protocols.\r
504 //\r
83cbd279 505 Status = EfiLibInstallDriverBindingComponentName2 (\r
8a67d61d 506 ImageHandle,\r
507 SystemTable,\r
508 &gUdp4DriverBinding,\r
509 ImageHandle,\r
510 &gUdp4ComponentName,\r
83cbd279 511 &gUdp4ComponentName2\r
8a67d61d 512 );\r
513 if (!EFI_ERROR (Status)) {\r
514 //\r
515 // Initialize the UDP random port.\r
516 //\r
687a2e5f 517 mUdp4RandomPort = (UINT16) (((UINT16) NetRandomInitSeed ()) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN);\r
8a67d61d 518 }\r
519\r
520 return Status;\r
521}\r
522\r