/** 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; }
/** Destroy a TCP6 or TCP4 service binding instance. It will release all the resources allocated by the instance. @param[in] Controller Controller handle of device to bind driver to. @param[in] ImageHandle The TCP driver's image handle. @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of children is zero stop the entire bus driver. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL if NumberOfChildren is 0. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6 @retval EFI_SUCCESS The resources used by the instance were cleaned up. @retval Others Failed to clean up some of the resources. **/ EFI_STATUS TcpDestroyService ( IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer, OPTIONAL IN UINT8 IpVersion ) { EFI_HANDLE NicHandle; EFI_GUID *IpProtocolGuid; EFI_GUID *ServiceBindingGuid; EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; TCP_SERVICE_DATA *TcpServiceData; EFI_STATUS Status; LIST_ENTRY *List; TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6)); if (IpVersion == IP_VERSION_4) { IpProtocolGuid = &gEfiIp4ProtocolGuid; ServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid; } else { IpProtocolGuid = &gEfiIp6ProtocolGuid; ServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid; } NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid); if (NicHandle == NULL) { return EFI_SUCCESS; } Status = gBS->OpenProtocol ( NicHandle, ServiceBindingGuid, (VOID **) &ServiceBinding, ImageHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding); if (NumberOfChildren != 0) { List = &TcpServiceData->SocketList; Context.ServiceBinding = ServiceBinding; Context.NumberOfChildren = NumberOfChildren; Context.ChildHandleBuffer = ChildHandleBuffer; Status = NetDestroyLinkList ( List, TcpDestroyChildEntryInHandleBuffer, &Context, NULL ); } else if (IsListEmpty (&TcpServiceData->SocketList)) { // // Uninstall TCP servicebinding protocol // gBS->UninstallMultipleProtocolInterfaces ( NicHandle, ServiceBindingGuid, ServiceBinding, NULL ); // // Destroy the IpIO consumed by TCP driver // IpIoDestroy (TcpServiceData->IpIo); TcpServiceData->IpIo = NULL; // // Destroy the heartbeat timer. // TcpDestroyTimer (); // // Release the TCP service data // FreePool (TcpServiceData); Status = EFI_SUCCESS; } return Status; }