2 Implementation of Mtftp drivers.
4 Copyright (c) 2006 - 2009, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php<BR>
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "Mtftp4Impl.h"
17 EFI_DRIVER_BINDING_PROTOCOL gMtftp4DriverBinding
= {
18 Mtftp4DriverBindingSupported
,
19 Mtftp4DriverBindingStart
,
20 Mtftp4DriverBindingStop
,
26 EFI_SERVICE_BINDING_PROTOCOL gMtftp4ServiceBindingTemplete
= {
27 Mtftp4ServiceBindingCreateChild
,
28 Mtftp4ServiceBindingDestroyChild
33 The driver entry point which installs multiple protocols to the ImageHandle.
35 @param ImageHandle The MTFTP's image handle.
36 @param SystemTable The system table.
38 @retval EFI_SUCCESS The handles are successfully installed on the image.
39 @retval others some EFI_ERROR occured.
44 Mtftp4DriverEntryPoint (
45 IN EFI_HANDLE ImageHandle
,
46 IN EFI_SYSTEM_TABLE
*SystemTable
49 return EfiLibInstallDriverBindingComponentName2 (
52 &gMtftp4DriverBinding
,
54 &gMtftp4ComponentName
,
55 &gMtftp4ComponentName2
61 Test whether MTFTP driver support this controller.
63 @param This The MTFTP driver binding instance
64 @param Controller The controller to test
65 @param RemainingDevicePath The remaining device path
67 @retval EFI_SUCCESS The controller has UDP service binding protocol
68 installed, MTFTP can support it.
69 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
70 RemainingDevicePath is already being managed by
71 the driver specified by This.
72 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
73 RemainingDevicePath is already being managed by a
74 different driver or an application that requires
76 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
77 RemainingDevicePath is not supported by the driver
83 Mtftp4DriverBindingSupported (
84 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
85 IN EFI_HANDLE Controller
,
86 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
91 Status
= gBS
->OpenProtocol (
93 &gEfiUdp4ServiceBindingProtocolGuid
,
95 This
->DriverBindingHandle
,
97 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
105 Config a NULL UDP that is used to keep the connection between UDP and MTFTP.
107 Just leave the Udp child unconfigured. When UDP is unloaded,
108 MTFTP will be informed with DriverBinding Stop.
110 @param UdpIo The UDP_IO to configure
111 @param Context The opaque parameter to the callback
113 @retval EFI_SUCCESS It always return EFI_SUCCESS directly.
117 Mtftp4ConfigNullUdp (
127 Create then initialize a MTFTP service binding instance.
129 @param Controller The controller to install the MTFTP service
131 @param Image The driver binding image of the MTFTP driver
132 @param Service The variable to receive the created service
135 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance
136 @retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep
138 @retval EFI_SUCCESS The service instance is created for the
143 Mtftp4CreateService (
144 IN EFI_HANDLE Controller
,
146 OUT MTFTP4_SERVICE
**Service
149 MTFTP4_SERVICE
*MtftpSb
;
153 MtftpSb
= AllocatePool (sizeof (MTFTP4_SERVICE
));
155 if (MtftpSb
== NULL
) {
156 return EFI_OUT_OF_RESOURCES
;
159 MtftpSb
->Signature
= MTFTP4_SERVICE_SIGNATURE
;
160 MtftpSb
->ServiceBinding
= gMtftp4ServiceBindingTemplete
;
161 MtftpSb
->InDestory
= FALSE
;
162 MtftpSb
->ChildrenNum
= 0;
163 InitializeListHead (&MtftpSb
->Children
);
165 MtftpSb
->Timer
= NULL
;
166 MtftpSb
->TimerToGetMap
= NULL
;
167 MtftpSb
->Controller
= Controller
;
168 MtftpSb
->Image
= Image
;
169 MtftpSb
->ConnectUdp
= NULL
;
172 // Create the timer and a udp to be notified when UDP is uninstalled
174 Status
= gBS
->CreateEvent (
175 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
182 if (EFI_ERROR (Status
)) {
188 // Create the timer used to time out the procedure which is used to
189 // get the default IP address.
191 Status
= gBS
->CreateEvent (
196 &MtftpSb
->TimerToGetMap
198 if (EFI_ERROR (Status
)) {
199 gBS
->CloseEvent (MtftpSb
->Timer
);
204 MtftpSb
->ConnectUdp
= UdpIoCreateIo (
212 if (MtftpSb
->ConnectUdp
== NULL
) {
213 gBS
->CloseEvent (MtftpSb
->TimerToGetMap
);
214 gBS
->CloseEvent (MtftpSb
->Timer
);
216 return EFI_DEVICE_ERROR
;
225 Release all the resource used the MTFTP service binding instance.
227 @param MtftpSb The MTFTP service binding instance.
232 IN MTFTP4_SERVICE
*MtftpSb
235 UdpIoFreeIo (MtftpSb
->ConnectUdp
);
236 gBS
->CloseEvent (MtftpSb
->TimerToGetMap
);
237 gBS
->CloseEvent (MtftpSb
->Timer
);
242 Start the MTFTP driver on this controller.
244 MTFTP driver will install a MTFTP SERVICE BINDING protocol on the supported
245 controller, which can be used to create/destroy MTFTP children.
247 @param This The MTFTP driver binding protocol.
248 @param Controller The controller to manage.
249 @param RemainingDevicePath Remaining device path.
251 @retval EFI_ALREADY_STARTED The MTFTP service binding protocol has been
252 started on the controller.
253 @retval EFI_SUCCESS The MTFTP service binding is installed on the
259 Mtftp4DriverBindingStart (
260 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
261 IN EFI_HANDLE Controller
,
262 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
265 MTFTP4_SERVICE
*MtftpSb
;
269 // Directly return if driver is already running.
271 Status
= gBS
->OpenProtocol (
273 &gEfiMtftp4ServiceBindingProtocolGuid
,
275 This
->DriverBindingHandle
,
277 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
280 if (Status
== EFI_SUCCESS
) {
281 return EFI_ALREADY_STARTED
;
284 Status
= Mtftp4CreateService (Controller
, This
->DriverBindingHandle
, &MtftpSb
);
286 if (EFI_ERROR (Status
)) {
290 Status
= gBS
->SetTimer (MtftpSb
->Timer
, TimerPeriodic
, TICKS_PER_SECOND
);
292 if (EFI_ERROR (Status
)) {
297 // Install the Mtftp4ServiceBinding Protocol onto Controller
299 Status
= gBS
->InstallMultipleProtocolInterfaces (
301 &gEfiMtftp4ServiceBindingProtocolGuid
,
302 &MtftpSb
->ServiceBinding
,
306 if (EFI_ERROR (Status
)) {
313 Mtftp4CleanService (MtftpSb
);
321 Stop the MTFTP driver on controller. The controller is a UDP
324 @param This The MTFTP driver binding protocol
325 @param Controller The controller to stop
326 @param NumberOfChildren The number of children
327 @param ChildHandleBuffer The array of the child handle.
329 @retval EFI_SUCCESS The driver is stopped on the controller.
330 @retval EFI_DEVICE_ERROR Failed to stop the driver on the controller.
335 Mtftp4DriverBindingStop (
336 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
337 IN EFI_HANDLE Controller
,
338 IN UINTN NumberOfChildren
,
339 IN EFI_HANDLE
*ChildHandleBuffer
342 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
343 MTFTP4_SERVICE
*MtftpSb
;
344 MTFTP4_PROTOCOL
*Instance
;
345 EFI_HANDLE NicHandle
;
350 // MTFTP driver opens UDP child, So, Controller is a UDP
351 // child handle. Locate the Nic handle first. Then get the
352 // MTFTP private data back.
354 NicHandle
= NetLibGetNicHandle (Controller
, &gEfiUdp4ProtocolGuid
);
356 if (NicHandle
== NULL
) {
357 return EFI_DEVICE_ERROR
;
360 Status
= gBS
->OpenProtocol (
362 &gEfiMtftp4ServiceBindingProtocolGuid
,
363 (VOID
**) &ServiceBinding
,
364 This
->DriverBindingHandle
,
366 EFI_OPEN_PROTOCOL_GET_PROTOCOL
369 if (EFI_ERROR (Status
)) {
370 return EFI_DEVICE_ERROR
;
373 MtftpSb
= MTFTP4_SERVICE_FROM_THIS (ServiceBinding
);
375 if (MtftpSb
->InDestory
) {
379 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
381 if (NumberOfChildren
== 0) {
383 MtftpSb
->InDestory
= TRUE
;
385 gBS
->UninstallProtocolInterface (
387 &gEfiMtftp4ServiceBindingProtocolGuid
,
391 Mtftp4CleanService (MtftpSb
);
396 while (!IsListEmpty (&MtftpSb
->Children
)) {
397 Instance
= NET_LIST_HEAD (&MtftpSb
->Children
, MTFTP4_PROTOCOL
, Link
);
398 Mtftp4ServiceBindingDestroyChild (ServiceBinding
, Instance
->Handle
);
401 if (MtftpSb
->ChildrenNum
!= 0) {
402 Status
= EFI_DEVICE_ERROR
;
406 gBS
->RestoreTPL (OldTpl
);
412 Initialize a MTFTP protocol instance which is the child of MtftpSb.
414 @param MtftpSb The MTFTP service binding protocol.
415 @param Instance The MTFTP instance to initialize.
420 IN MTFTP4_SERVICE
*MtftpSb
,
421 OUT MTFTP4_PROTOCOL
*Instance
424 ZeroMem (Instance
, sizeof (MTFTP4_PROTOCOL
));
426 Instance
->Signature
= MTFTP4_PROTOCOL_SIGNATURE
;
427 InitializeListHead (&Instance
->Link
);
428 CopyMem (&Instance
->Mtftp4
, &gMtftp4ProtocolTemplate
, sizeof (Instance
->Mtftp4
));
429 Instance
->State
= MTFTP4_STATE_UNCONFIGED
;
430 Instance
->InDestory
= FALSE
;
431 Instance
->Service
= MtftpSb
;
433 InitializeListHead (&Instance
->Blocks
);
438 Create a MTFTP child for the service binding instance, then
439 install the MTFTP protocol to the ChildHandle.
441 @param This The MTFTP service binding instance.
442 @param ChildHandle The Child handle to install the MTFTP protocol.
444 @retval EFI_INVALID_PARAMETER The parameter is invalid.
445 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the new child.
446 @retval EFI_SUCCESS The child is successfully create.
451 Mtftp4ServiceBindingCreateChild (
452 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
453 IN EFI_HANDLE
*ChildHandle
456 MTFTP4_SERVICE
*MtftpSb
;
457 MTFTP4_PROTOCOL
*Instance
;
462 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
463 return EFI_INVALID_PARAMETER
;
466 Instance
= AllocatePool (sizeof (*Instance
));
468 if (Instance
== NULL
) {
469 return EFI_OUT_OF_RESOURCES
;
472 MtftpSb
= MTFTP4_SERVICE_FROM_THIS (This
);
474 Mtftp4InitProtocol (MtftpSb
, Instance
);
476 Instance
->UnicastPort
= UdpIoCreateIo (
484 if (Instance
->UnicastPort
== NULL
) {
486 return EFI_OUT_OF_RESOURCES
;
490 // Install the MTFTP protocol onto ChildHandle
492 Status
= gBS
->InstallMultipleProtocolInterfaces (
494 &gEfiMtftp4ProtocolGuid
,
499 if (EFI_ERROR (Status
)) {
503 Instance
->Handle
= *ChildHandle
;
506 // Open the Udp4 protocol BY_CHILD.
508 Status
= gBS
->OpenProtocol (
509 MtftpSb
->ConnectUdp
->UdpHandle
,
510 &gEfiUdp4ProtocolGuid
,
512 gMtftp4DriverBinding
.DriverBindingHandle
,
514 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
516 if (EFI_ERROR (Status
)) {
517 gBS
->UninstallMultipleProtocolInterfaces (
519 &gEfiMtftp4ProtocolGuid
,
528 // Add it to the parent's child list.
530 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
532 InsertTailList (&MtftpSb
->Children
, &Instance
->Link
);
533 MtftpSb
->ChildrenNum
++;
535 gBS
->RestoreTPL (OldTpl
);
539 if (EFI_ERROR (Status
)) {
540 UdpIoFreeIo (Instance
->UnicastPort
);
549 Destory one of the service binding's child.
551 @param This The service binding instance
552 @param ChildHandle The child handle to destory
554 @retval EFI_INVALID_PARAMETER The parameter is invaid.
555 @retval EFI_UNSUPPORTED The child may have already been destoried.
556 @retval EFI_SUCCESS The child is destoried and removed from the
562 Mtftp4ServiceBindingDestroyChild (
563 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
564 IN EFI_HANDLE ChildHandle
567 MTFTP4_SERVICE
*MtftpSb
;
568 MTFTP4_PROTOCOL
*Instance
;
569 EFI_MTFTP4_PROTOCOL
*Mtftp4
;
573 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
574 return EFI_INVALID_PARAMETER
;
578 // Retrieve the private context data structures
580 Status
= gBS
->OpenProtocol (
582 &gEfiMtftp4ProtocolGuid
,
584 gMtftp4DriverBinding
.DriverBindingHandle
,
586 EFI_OPEN_PROTOCOL_GET_PROTOCOL
589 if (EFI_ERROR (Status
)) {
590 return EFI_UNSUPPORTED
;
593 Instance
= MTFTP4_PROTOCOL_FROM_THIS (Mtftp4
);
594 MtftpSb
= MTFTP4_SERVICE_FROM_THIS (This
);
596 if (Instance
->Service
!= MtftpSb
) {
597 return EFI_INVALID_PARAMETER
;
600 if (Instance
->InDestory
) {
604 Instance
->InDestory
= TRUE
;
607 // Close the Udp4 protocol.
610 MtftpSb
->ConnectUdp
->UdpHandle
,
611 &gEfiUdp4ProtocolGuid
,
612 gMtftp4DriverBinding
.DriverBindingHandle
,
617 // Uninstall the MTFTP4 protocol first to enable a top down destruction.
619 Status
= gBS
->UninstallProtocolInterface (
621 &gEfiMtftp4ProtocolGuid
,
625 if (EFI_ERROR (Status
)) {
626 Instance
->InDestory
= FALSE
;
630 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
632 Mtftp4CleanOperation (Instance
, EFI_DEVICE_ERROR
);
633 UdpIoFreeIo (Instance
->UnicastPort
);
635 RemoveEntryList (&Instance
->Link
);
636 MtftpSb
->ChildrenNum
--;
638 gBS
->RestoreTPL (OldTpl
);