/** 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; }
/** Start the MTFTP driver on this controller. MTFTP driver will install a MTFTP SERVICE BINDING protocol on the supported controller, which can be used to create/destroy MTFTP children. @param This The MTFTP driver binding protocol. @param Controller The controller to manage. @param RemainingDevicePath Remaining device path. @retval EFI_ALREADY_STARTED The MTFTP service binding protocol has been started on the controller. @retval EFI_SUCCESS The MTFTP service binding is installed on the controller. **/ EFI_STATUS EFIAPI Mtftp4DriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { MTFTP4_SERVICE *MtftpSb; EFI_STATUS Status; // // Directly return if driver is already running. // Status = gBS->OpenProtocol ( Controller, &gEfiMtftp4ServiceBindingProtocolGuid, NULL, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (Status == EFI_SUCCESS) { return EFI_ALREADY_STARTED; } Status = Mtftp4CreateService (Controller, This->DriverBindingHandle, &MtftpSb); if (EFI_ERROR (Status)) { return Status; } ASSERT (MtftpSb != NULL); Status = gBS->SetTimer (MtftpSb->Timer, TimerPeriodic, TICKS_PER_SECOND); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Install the Mtftp4ServiceBinding Protocol onto Controller // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiMtftp4ServiceBindingProtocolGuid, &MtftpSb->ServiceBinding, NULL ); if (EFI_ERROR (Status)) { goto ON_ERROR; } return EFI_SUCCESS; ON_ERROR: Mtftp4CleanService (MtftpSb); FreePool (MtftpSb); return Status; }
EFI_STATUS Mtftp4DriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) /*++ Routine Description: Start the MTFTP driver on this controller. MTFTP driver will install a MTFTP SERVICE BINDING protocol on the supported controller, which can be used to create/destroy MTFTP children. Arguments: This - The MTFTP driver binding protocol. Controller - The controller to manage. RemainingDevicePath - Remaining device path. Returns: EFI_ALREADY_STARTED - The MTFTP service binding protocol has been started on the controller. EFI_SUCCESS - The MTFTP service binding is installed on the controller. --*/ { MTFTP4_SERVICE *MtftpSb; EFI_STATUS Status; // // Directly return if driver is already running. // Status = gBS->OpenProtocol ( Controller, &gEfiMtftp4ServiceBindingProtocolGuid, NULL, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (Status == EFI_SUCCESS) { return EFI_ALREADY_STARTED; } Status = Mtftp4CreateService (Controller, This->DriverBindingHandle, &MtftpSb); if (EFI_ERROR (Status)) { return Status; } Status = gBS->SetTimer (MtftpSb->Timer, TimerPeriodic, TICKS_PER_SECOND); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Install the Mtftp4ServiceBinding Protocol onto Controller // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiMtftp4ServiceBindingProtocolGuid, &MtftpSb->ServiceBinding, NULL ); if (EFI_ERROR (Status)) { goto ON_ERROR; } return EFI_SUCCESS; ON_ERROR: Mtftp4CleanService (MtftpSb); NetFreePool (MtftpSb); return Status; }
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; }
/** 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; }