mtftp4driver.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 674 行 · 第 1/2 页
C
674 行
This - The MTFTP driver binding protocol
Controller - The controller to stop
NumberOfChildren - The number of children
ChildHandleBuffer - The array of the child handle.
Returns:
EFI_SUCCESS - The driver is stopped on the controller.
EFI_DEVICE_ERROR - Failed to stop the driver on the controller.
--*/
{
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
MTFTP4_SERVICE *MtftpSb;
MTFTP4_PROTOCOL *Instance;
EFI_HANDLE NicHandle;
EFI_STATUS Status;
EFI_TPL OldTpl;
//
// MTFTP driver opens UDP child, So, Controller is a UDP
// child handle. Locate the Nic handle first. Then get the
// MTFTP private data back.
//
NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid);
if (NicHandle == NULL) {
return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
NicHandle,
&gEfiMtftp4ServiceBindingProtocolGuid,
(VOID **) &ServiceBinding,
This->DriverBindingHandle,
NicHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
MtftpSb = MTFTP4_SERVICE_FROM_THIS (ServiceBinding);
if (MtftpSb->InDestory) {
return EFI_SUCCESS;
}
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
MtftpSb->InDestory = TRUE;
while (!NetListIsEmpty (&MtftpSb->Children)) {
Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
}
if (MtftpSb->ChildrenNum != 0) {
Status = EFI_DEVICE_ERROR;
goto ON_ERROR;
}
Status = gBS->UninstallProtocolInterface (
NicHandle,
&gEfiMtftp4ServiceBindingProtocolGuid,
ServiceBinding
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Mtftp4CleanService (MtftpSb);
NetFreePool (MtftpSb);
NET_RESTORE_TPL (OldTpl);
return EFI_SUCCESS;
ON_ERROR:
MtftpSb->InDestory = FALSE;
NET_RESTORE_TPL (OldTpl);
return Status;
}
VOID
Mtftp4InitProtocol (
IN MTFTP4_SERVICE *MtftpSb,
IN MTFTP4_PROTOCOL *Instance
)
/*++
Routine Description:
Initialize a MTFTP protocol instance which is the child of MtftpSb.
Arguments:
MtftpSb - The MTFTP service binding protocol.
Instance - The MTFTP instance to initialize.
Returns:
None
--*/
{
NetZeroMem (Instance, sizeof (MTFTP4_PROTOCOL));
Instance->Signature = MTFTP4_PROTOCOL_SIGNATURE;
NetListInit (&Instance->Link);
Instance->Mtftp4 = gMtftp4ProtocolTemplate;
Instance->State = MTFTP4_STATE_UNCONFIGED;
Instance->Indestory = FALSE;
Instance->Service = MtftpSb;
NetListInit (&Instance->Blocks);
}
EFI_STATUS
Mtftp4ServiceBindingCreateChild (
IN EFI_SERVICE_BINDING_PROTOCOL *This,
IN OUT EFI_HANDLE *ChildHandle
)
/*++
Routine Description:
Create a MTFTP child for the service binding instance, then
install the MTFTP protocol to the ChildHandle.
Arguments:
This - The MTFTP service binding instance.
ChildHandle - The Child handle to install the MTFTP protocol.
Returns:
EFI_INVALID_PARAMETER - The parameter is invalid.
EFI_OUT_OF_RESOURCES - Failed to allocate resource for the new child.
EFI_SUCCESS - The child is successfully create.
--*/
{
MTFTP4_SERVICE *MtftpSb;
MTFTP4_PROTOCOL *Instance;
EFI_STATUS Status;
EFI_TPL OldTpl;
VOID *Udp4;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
}
Instance = NetAllocatePool (sizeof (*Instance));
if (Instance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);
Mtftp4InitProtocol (MtftpSb, Instance);
Instance->UnicastPort = UdpIoCreatePort (
MtftpSb->Controller,
MtftpSb->Image,
Mtftp4ConfigNullUdp,
Instance
);
if (Instance->UnicastPort == NULL) {
NetFreePool (Instance);
return EFI_OUT_OF_RESOURCES;
}
//
// Install the MTFTP protocol onto ChildHandle
//
Status = gBS->InstallMultipleProtocolInterfaces (
ChildHandle,
&gEfiMtftp4ProtocolGuid,
&Instance->Mtftp4,
NULL
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Instance->Handle = *ChildHandle;
//
// Open the Udp4 protocol BY_CHILD.
//
Status = gBS->OpenProtocol (
MtftpSb->ConnectUdp->UdpHandle,
&gEfiUdp4ProtocolGuid,
(VOID **) &Udp4,
gMtftp4DriverBinding.DriverBindingHandle,
Instance->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (EFI_ERROR (Status)) {
gBS->UninstallMultipleProtocolInterfaces (
Instance->Handle,
&gEfiMtftp4ProtocolGuid,
&Instance->Mtftp4,
NULL
);
goto ON_ERROR;
}
//
// Add it to the parent's child list.
//
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
NetListInsertTail (&MtftpSb->Children, &Instance->Link);
MtftpSb->ChildrenNum++;
NET_RESTORE_TPL (OldTpl);
ON_ERROR:
if (EFI_ERROR (Status)) {
UdpIoFreePort (Instance->UnicastPort);
NetFreePool (Instance);
}
return Status;
}
EFI_STATUS
Mtftp4ServiceBindingDestroyChild (
IN EFI_SERVICE_BINDING_PROTOCOL *This,
IN EFI_HANDLE ChildHandle
)
/*++
Routine Description:
Destory one of the service binding's child.
Arguments:
This - The service binding instance
ChildHandle - The child handle to destory
Returns:
EFI_INVALID_PARAMETER - The parameter is invaid.
EFI_UNSUPPORTED - The child may have already been destoried.
EFI_SUCCESS - The child is destoried and removed from the
parent's child list.
--*/
{
MTFTP4_SERVICE *MtftpSb;
MTFTP4_PROTOCOL *Instance;
EFI_MTFTP4_PROTOCOL *Mtftp4;
EFI_STATUS Status;
EFI_TPL OldTpl;
if ((This == NULL) || (ChildHandle == NULL)) {
return EFI_INVALID_PARAMETER;
}
//
// Retrieve the private context data structures
//
Status = gBS->OpenProtocol (
ChildHandle,
&gEfiMtftp4ProtocolGuid,
(VOID **) &Mtftp4,
gMtftp4DriverBinding.DriverBindingHandle,
ChildHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Instance = MTFTP4_PROTOCOL_FROM_THIS (Mtftp4);
MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);
if (Instance->Service != MtftpSb) {
return EFI_INVALID_PARAMETER;
}
if (Instance->Indestory) {
return EFI_SUCCESS;
}
Instance->Indestory = TRUE;
//
// Close the Udp4 protocol.
//
gBS->CloseProtocol (
MtftpSb->ConnectUdp->UdpHandle,
&gEfiUdp4ProtocolGuid,
gMtftp4DriverBinding.DriverBindingHandle,
ChildHandle
);
//
// Uninstall the MTFTP4 protocol first to enable a top down destruction.
//
Status = gBS->UninstallProtocolInterface (
ChildHandle,
&gEfiMtftp4ProtocolGuid,
Mtftp4
);
if (EFI_ERROR (Status)) {
Instance->Indestory = FALSE;
return Status;
}
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
Mtftp4CleanOperation (Instance, EFI_DEVICE_ERROR);
UdpIoFreePort (Instance->UnicastPort);
NetListRemoveEntry (&Instance->Link);
MtftpSb->ChildrenNum--;
NET_RESTORE_TPL (OldTpl);
NetFreePool (Instance);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?