tcp4driver.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 700 行 · 第 1/2 页

C
700
字号

  //
  // Install the Tcp4ServiceBinding Protocol on the
  // controller handle
  //
  TcpServiceData->Tcp4ServiceBinding = mTcp4ServiceBinding;

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiTcp4ServiceBindingProtocolGuid,
                  &TcpServiceData->Tcp4ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {

    TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding"
      " Protocol failed for %r\n", Status));

    goto ReleaseTimer;
  }

  //
  // Initialize member in TcpServiceData
  //
  TcpServiceData->ControllerHandle    = ControllerHandle;
  TcpServiceData->Signature           = TCP4_DRIVER_SIGNATURE;
  TcpServiceData->DriverBindingHandle = This->DriverBindingHandle;

  TcpSetVariableData (TcpServiceData);

  return EFI_SUCCESS;

ReleaseTimer:

  Tcp4DestroyTimer ();

ReleaseIpIo:

  IpIoDestroy (TcpServiceData->IpIo);

ReleaseServiceData:

  NetFreePool (TcpServiceData);

  return Status;
}

EFI_STATUS
EFIAPI
Tcp4DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
/*++

Routine Description:

  Stop this driver on ControllerHandle.

Arguments:

  This              - Protocol instance pointer.
  ControllerHandle  - Handle of device to stop driver on.
  NumberOfChildren  - Number of Handles in ChildHandleBuffer. If
                      number of children is zero stop the entire
                      bus driver.
  ChildHandleBuffer - List of Child Handles to Stop.

Returns:

  EFI_SUCCESS       - This driver is removed from ControllerHandle.
  other             - This driver is not removed from ControllerHandle.

--*/
{
  EFI_STATUS                          Status;
  EFI_HANDLE                          NicHandle;
  EFI_SERVICE_BINDING_PROTOCOL        *Tcp4ServiceBinding;
  TCP4_SERVICE_DATA                   *TcpServiceData;
  TCP_CB                              *TcpPcb;
  SOCKET                              *Sock;
  TCP4_PROTO_DATA                     *TcpProto;
  NET_LIST_ENTRY                      *Entry;
  NET_LIST_ENTRY                      *NextEntry;

  // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed.
  //
  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Retrieve the TCP driver Data Structure
  //
  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiTcp4ServiceBindingProtocolGuid,
                  (VOID **) &Tcp4ServiceBinding,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {

    TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service "
      " Binding Protocol failed with %r\n", Status));

    return Status;
  }

  TcpServiceData = TCP4_FROM_THIS (Tcp4ServiceBinding);

  //
  // Kill TCP driver
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) {
    TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    //
    // Try to destroy this child
    //
    Sock     = TcpPcb->Sk;
    TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;

    if (TcpProto->TcpService == TcpServiceData) {
      Status = SockDestroyChild (Sock);

      if (EFI_ERROR (Status)) {

        TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
          "instance failed with %r\n", Status));
        return Status;
      }
    }
  }

  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpListenQue) {
    TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List);

    //
    // Try to destroy this child
    //
    Sock     = TcpPcb->Sk;
    TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;

    if (TcpProto->TcpService == TcpServiceData) {
      Status = SockDestroyChild (TcpPcb->Sk);
      if (EFI_ERROR (Status)) {

        TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp "
          "instance failed with %r\n", Status));
        return Status;
      }
    }
  }

  //
  // Uninstall TCP servicebinding protocol
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  NicHandle,
                  &gEfiTcp4ServiceBindingProtocolGuid,
                  Tcp4ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {

    TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service "
      "binding protocol failed with %r\n", Status));
    return Status;
  }

  //
  // Destroy the IpIO consumed by TCP driver
  //
  Status = IpIoDestroy (TcpServiceData->IpIo);

  //
  // Destroy the heartbeat timer.
  //
  Tcp4DestroyTimer ();

  //
  // Clear the variable.
  //
  TcpClearVariableData (TcpServiceData);

  //
  // Release the TCP service data
  //
  NetFreePool (TcpServiceData);

  return Status;
}

EFI_STATUS
EFIAPI
Tcp4ServiceBindingCreateChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    *ChildHandle
  )
/*++

Routine Description:

  Creates a child handle with a set of TCP4 services.

Arguments:

  This        - Protocol instance pointer.
  ChildHandle - Pointer to the handle of the child to create. 
                If it is NULL, then a new handle is created. If
                it is not NULL, then the I/O services are added
                to the existing child handle.

Returns:

  EFI_SUCCESS           - The child handle is created.
  EFI_INVALID_PARAMETER - One or more parameters are invalid.
  EFI_OUT_OF_RESOURCES  - There are not enough resources to create
                          the child.

--*/
{
  SOCKET            *Sock;
  TCP4_SERVICE_DATA *TcpServiceData;
  TCP4_PROTO_DATA   TcpProto;
  EFI_STATUS        Status;
  VOID              *Ip4;

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

  TcpServiceData      = TCP4_FROM_THIS (This);

  TcpProto.TcpService = TcpServiceData;
  TcpProto.TcpPcb     = NULL;

  //
  // Create a tcp instance with defualt Tcp default
  // sock init data and TcpProto
  //
  mTcp4DefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;

  Sock = SockCreateChild (&mTcp4DefaultSockData, &TcpProto, sizeof (TCP4_PROTO_DATA));
  if (NULL == Sock) {

    TCP4_DEBUG_ERROR (("Tcp4DriverBindingCreateChild: "
      "No resource to create a Tcp Child\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  *ChildHandle = Sock->SockHandle;

  //
  // Open the default Ip4 protocol of IP_IO BY_DRIVER.
  //
  Status = gBS->OpenProtocol (
                  TcpServiceData->IpIo->ChildHandle,
                  &gEfiIp4ProtocolGuid,
                  (VOID **) &Ip4,
                  TcpServiceData->DriverBindingHandle,
                  Sock->SockHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    SockDestroyChild (Sock);
  }

  return Status;
}

EFI_STATUS
EFIAPI
Tcp4ServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    ChildHandle
  )
/*++

Routine Description:

  Destroys a child handle with a set of UDP4 services.

Arguments:

  This        - Protocol instance pointer.
  ChildHandle - Handle of the child to be destroyed.

Returns:

  EFI_SUCCESS           - The TCP4 services are removed from 
                          the child handle.
  EFI_INVALID_PARAMETER - One or more parameters are invalid.
  other                 - The child handle is not destroyed.

--*/
{
  EFI_STATUS         Status;
  EFI_TCP4_PROTOCOL  *Tcp4;
  SOCKET             *Sock;
  TCP4_PROTO_DATA    *TcpProtoData;
  TCP4_SERVICE_DATA  *TcpServiceData;

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

  //
  // retrieve the Tcp4 protocol from ChildHandle
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiTcp4ProtocolGuid,
                  (VOID **) &Tcp4,
                  mTcp4DriverBinding.DriverBindingHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // destroy this sock and related Tcp protocol control
  // block
  //
  Sock           = SOCK_FROM_THIS (Tcp4);
  TcpProtoData   = (TCP4_PROTO_DATA *) Sock->ProtoReserved;
  TcpServiceData = TcpProtoData->TcpService;

  Status = SockDestroyChild (Sock);

  //
  // Close the Ip4 protocol.
  //
  gBS->CloseProtocol (
         TcpServiceData->IpIo->ChildHandle,
         &gEfiIp4ProtocolGuid,
         TcpServiceData->DriverBindingHandle,
         ChildHandle
         );

  return Status;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?