/** Flush the Tcb add its associated protocols. @param Tcb Pointer to the TCP_CB to be flushed. **/ VOID Tcp4FlushPcb ( IN TCP_CB *Tcb ) { SOCKET *Sock; TCP4_PROTO_DATA *TcpProto; IpIoConfigIp (Tcb->IpInfo, NULL); Sock = Tcb->Sk; TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved; if (SOCK_IS_CONFIGURED (Sock)) { RemoveEntryList (&Tcb->List); // // Uninstall the device path protocol. // if (Sock->DevicePath != NULL) { gBS->UninstallProtocolInterface ( Sock->SockHandle, &gEfiDevicePathProtocolGuid, Sock->DevicePath ); FreePool (Sock->DevicePath); } TcpSetVariableData (TcpProto->TcpService); } NetbufFreeList (&Tcb->SndQue); NetbufFreeList (&Tcb->RcvQue); Tcb->State = TCP_CLOSED; }
/** Create a new TCP4 or TCP6 driver service binding protocol @param[in] Controller Controller handle of device to bind driver to. @param[in] Image The TCP driver's image handle. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources. @retval EFI_SUCCESS A new IP6 service binding private was created. **/ EFI_STATUS TcpCreateService ( IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN UINT8 IpVersion ) { EFI_STATUS Status; EFI_GUID *IpServiceBindingGuid; EFI_GUID *TcpServiceBindingGuid; TCP_SERVICE_DATA *TcpServiceData; IP_IO_OPEN_DATA OpenData; if (IpVersion == IP_VERSION_4) { IpServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid; TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid; } else { IpServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid; TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid; } Status = gBS->OpenProtocol ( Controller, TcpServiceBindingGuid, NULL, Image, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (!EFI_ERROR (Status)) { return EFI_ALREADY_STARTED; } Status = gBS->OpenProtocol ( Controller, IpServiceBindingGuid, NULL, Image, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } // // Create the TCP service data. // TcpServiceData = AllocateZeroPool (sizeof (TCP_SERVICE_DATA)); if (TcpServiceData == NULL) { return EFI_OUT_OF_RESOURCES; } TcpServiceData->Signature = TCP_DRIVER_SIGNATURE; TcpServiceData->ControllerHandle = Controller; TcpServiceData->DriverBindingHandle = Image; TcpServiceData->IpVersion = IpVersion; CopyMem ( &TcpServiceData->ServiceBinding, &gTcpServiceBinding, sizeof (EFI_SERVICE_BINDING_PROTOCOL) ); TcpServiceData->IpIo = IpIoCreate (Image, Controller, IpVersion); if (TcpServiceData->IpIo == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_ERROR; } InitializeListHead (&TcpServiceData->SocketList); ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA)); if (IpVersion == IP_VERSION_4) { CopyMem ( &OpenData.IpConfigData.Ip4CfgData, &mIp4IoDefaultIpConfigData, sizeof (EFI_IP4_CONFIG_DATA) ); OpenData.IpConfigData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP; } else { CopyMem ( &OpenData.IpConfigData.Ip6CfgData, &mIp6IoDefaultIpConfigData, sizeof (EFI_IP6_CONFIG_DATA) ); OpenData.IpConfigData.Ip6CfgData.DefaultProtocol = EFI_IP_PROTO_TCP; } OpenData.PktRcvdNotify = TcpRxCallback; Status = IpIoOpen (TcpServiceData->IpIo, &OpenData); if (EFI_ERROR (Status)) { goto ON_ERROR; } Status = TcpCreateTimer (); if (EFI_ERROR (Status)) { goto ON_ERROR; } Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, TcpServiceBindingGuid, &TcpServiceData->ServiceBinding, NULL ); if (EFI_ERROR (Status)) { TcpDestroyTimer (); goto ON_ERROR; } TcpSetVariableData (TcpServiceData); return EFI_SUCCESS; ON_ERROR: if (TcpServiceData->IpIo != NULL) { IpIoDestroy (TcpServiceData->IpIo); TcpServiceData->IpIo = NULL; } FreePool (TcpServiceData); return Status; }