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; }