示例#1
0
/**
  Create a MTFTP child for the service binding instance, then
  install the MTFTP protocol to the ChildHandle.

  @param  This                   The MTFTP service binding instance.
  @param  ChildHandle            The Child handle to install the MTFTP protocol.

  @retval EFI_INVALID_PARAMETER  The parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource for the new child.
  @retval EFI_SUCCESS            The child is successfully create.

**/
EFI_STATUS
EFIAPI
Mtftp4ServiceBindingCreateChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                *ChildHandle
  )
{
  MTFTP4_SERVICE            *MtftpSb;
  MTFTP4_PROTOCOL           *Instance;
  EFI_STATUS                Status;
  EFI_TPL                   OldTpl;
  VOID                      *Udp4;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = AllocatePool (sizeof (*Instance));

  if (Instance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  MtftpSb = MTFTP4_SERVICE_FROM_THIS (This);

  Mtftp4InitProtocol (MtftpSb, Instance);

  Instance->UnicastPort = UdpIoCreateIo (
                            MtftpSb->Controller,
                            MtftpSb->Image,
                            Mtftp4ConfigNullUdp,
                            UDP_IO_UDP4_VERSION,
                            Instance
                            );

  if (Instance->UnicastPort == NULL) {
    FreePool (Instance);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Install the MTFTP protocol onto ChildHandle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiMtftp4ProtocolGuid,
                  &Instance->Mtftp4,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    UdpIoFreeIo (Instance->UnicastPort);
    FreePool (Instance);
    return Status;
  }

  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)) {
    goto ON_ERROR;
  }

  //
  // Open the Udp4 protocol by child.
  //
  Status = gBS->OpenProtocol (
                  Instance->UnicastPort->UdpHandle,
                  &gEfiUdp4ProtocolGuid,
                  (VOID **) &Udp4,
                  gMtftp4DriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    //
    // Close the Udp4 protocol.
    //
    gBS->CloseProtocol (
           MtftpSb->ConnectUdp->UdpHandle,
           &gEfiUdp4ProtocolGuid,
           gMtftp4DriverBinding.DriverBindingHandle,
           ChildHandle
           );
    goto ON_ERROR;
  }

  //
  // Add it to the parent's child list.
  //
  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  InsertTailList (&MtftpSb->Children, &Instance->Link);
  MtftpSb->ChildrenNum++;

  gBS->RestoreTPL (OldTpl);

  return EFI_SUCCESS;

ON_ERROR:
  if (Instance->Handle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Instance->Handle,
           &gEfiMtftp4ProtocolGuid,
           &Instance->Mtftp4,
           NULL
           );
  }

  UdpIoFreeIo (Instance->UnicastPort);
  FreePool (Instance);

  return Status;
}
示例#2
0
/**
  Destroy one of the service binding's child.

  @param  This                   The service binding instance
  @param  ChildHandle            The child handle to destroy

  @retval EFI_INVALID_PARAMETER  The parameter is invaid.
  @retval EFI_UNSUPPORTED        The child may have already been destroyed.
  @retval EFI_SUCCESS            The child is destroyed and removed from the
                                 parent's child list.

**/
EFI_STATUS
EFIAPI
Mtftp4ServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                   ChildHandle
  )
{
  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->InDestroy) {
    return EFI_SUCCESS;
  }

  Instance->InDestroy = TRUE;

  //
  // Close the Udp4 protocol.
  //
  gBS->CloseProtocol (
         MtftpSb->ConnectUdp->UdpHandle,
         &gEfiUdp4ProtocolGuid,
         gMtftp4DriverBinding.DriverBindingHandle,
         ChildHandle
         );

  gBS->CloseProtocol (
         Instance->UnicastPort->UdpHandle,
         &gEfiUdp4ProtocolGuid,
         gMtftp4DriverBinding.DriverBindingHandle,
         ChildHandle
         );

  if (Instance->McastUdpPort != NULL) {
    gBS->CloseProtocol (
           Instance->McastUdpPort->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->InDestroy = FALSE;
    return Status;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Mtftp4CleanOperation (Instance, EFI_DEVICE_ERROR);
  UdpIoFreeIo (Instance->UnicastPort);

  RemoveEntryList (&Instance->Link);
  MtftpSb->ChildrenNum--;

  gBS->RestoreTPL (OldTpl);

  FreePool (Instance);
  return EFI_SUCCESS;
}
示例#3
0
/**
  Stop the MTFTP driver on controller. The controller is a UDP
  child handle.

  @param  This                   The MTFTP driver binding protocol
  @param  Controller             The controller to stop
  @param  NumberOfChildren       The number of children
  @param  ChildHandleBuffer      The array of the child handle.

  @retval EFI_SUCCESS            The driver is stopped on the controller.
  @retval EFI_DEVICE_ERROR       Failed to stop the driver on the controller.

**/
EFI_STATUS
EFIAPI
Mtftp4DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  )
{
  EFI_SERVICE_BINDING_PROTOCOL               *ServiceBinding;
  MTFTP4_SERVICE                             *MtftpSb;
  EFI_HANDLE                                 NicHandle;
  EFI_STATUS                                 Status;
  LIST_ENTRY                                 *List;
  MTFTP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;

  //
  // 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 (!IsListEmpty (&MtftpSb->Children)) {
    //
    // Destroy the Mtftp4 child instance in ChildHandleBuffer.
    //
    List = &MtftpSb->Children;
    Context.ServiceBinding    = ServiceBinding;
    Context.NumberOfChildren  = NumberOfChildren;
    Context.ChildHandleBuffer = ChildHandleBuffer;
    Status = NetDestroyLinkList (
               List,
               Mtftp4DestroyChildEntryInHandleBuffer,
               &Context,
               NULL
               );
  }

  if (NumberOfChildren == 0 && IsListEmpty (&MtftpSb->Children)) {
    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp4ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp4CleanService (MtftpSb);
    if (gMtftp4ControllerNameTable != NULL) {
      FreeUnicodeStringTable (gMtftp4ControllerNameTable);
      gMtftp4ControllerNameTable = NULL;
    }
    FreePool (MtftpSb);

    Status = EFI_SUCCESS;
  }

  return Status;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
EFI_STATUS
Mtftp4DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
  IN  EFI_HANDLE                  Controller,
  IN  UINTN                       NumberOfChildren,
  IN  EFI_HANDLE                  *ChildHandleBuffer
  )
/*++

Routine Description:

  Stop the MTFTP driver on controller. The controller is a UDP 
  child handle.

Arguments:

  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_DEVICE_ERROR;
  }
  
  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);

  if (NumberOfChildren == 0) {

    MtftpSb->InDestory = TRUE;

    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp4ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp4CleanService (MtftpSb);

    NetFreePool (MtftpSb);
  } else {

    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;
    }
  }

  NET_RESTORE_TPL (OldTpl);
  return Status;
}
示例#7
0
/**
  Stop the MTFTP driver on controller. The controller is a UDP
  child handle.

  @param  This                   The MTFTP driver binding protocol
  @param  Controller             The controller to stop
  @param  NumberOfChildren       The number of children
  @param  ChildHandleBuffer      The array of the child handle.

  @retval EFI_SUCCESS            The driver is stopped on the controller.
  @retval EFI_DEVICE_ERROR       Failed to stop the driver on the controller.

**/
EFI_STATUS
EFIAPI
Mtftp4DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  )
{
  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_DEVICE_ERROR;
  }

  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 = gBS->RaiseTPL (TPL_CALLBACK);

  if (NumberOfChildren == 0) {

    MtftpSb->InDestory = TRUE;

    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiMtftp4ServiceBindingProtocolGuid,
           ServiceBinding
           );

    Mtftp4CleanService (MtftpSb);

    FreePool (MtftpSb);
  } else {

    while (!IsListEmpty (&MtftpSb->Children)) {
      Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link);
      Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
    }

    if (MtftpSb->ChildrenNum != 0) {
      Status = EFI_DEVICE_ERROR;
    }
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}