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