예제 #1
0
파일: Mtftp4Driver.c 프로젝트: Kohrara/edk
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;
}
예제 #2
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;
}