/** Uninstalls all instances of a protocol:interfacer from a handle. If the last protocol interface is remove from the handle, the handle is freed. @param UserHandle The handle to remove the protocol handler from @param Protocol The protocol, of protocol:interface, to remove @param Interface The interface, of protocol:interface, to remove @retval EFI_INVALID_PARAMETER Protocol is NULL. @retval EFI_SUCCESS Protocol interface successfully uninstalled. **/ EFI_STATUS EFIAPI CoreUninstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface ) { EFI_STATUS Status; IHANDLE *Handle; PROTOCOL_INTERFACE *Prot; // // Check that Protocol is valid // if (Protocol == NULL) { return EFI_INVALID_PARAMETER; } // // Check that UserHandle is a valid handle // Status = CoreValidateHandle (UserHandle); if (EFI_ERROR (Status)) { return Status; } // // Lock the protocol database // CoreAcquireProtocolLock (); // // Check that Protocol exists on UserHandle, and Interface matches the interface in the database // Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface); if (Prot == NULL) { Status = EFI_NOT_FOUND; goto Done; } // // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed // Status = CoreDisconnectControllersUsingProtocolInterface ( UserHandle, Prot ); if (EFI_ERROR (Status)) { // // One or more drivers refused to release, so return the error // goto Done; } // // Remove the protocol interface from the protocol // Status = EFI_NOT_FOUND; Handle = (IHANDLE *)UserHandle; Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface); if (Prot != NULL) { // // Update the Key to show that the handle has been created/modified // gHandleDatabaseKey++; Handle->Key = gHandleDatabaseKey; // // Remove the protocol interface from the handle // RemoveEntryList (&Prot->Link); // // Free the memory // Prot->Signature = 0; CoreFreePool (Prot); Status = EFI_SUCCESS; } // // If there are no more handlers for the handle, free the handle // if (IsListEmpty (&Handle->Protocols)) { Handle->Signature = 0; RemoveEntryList (&Handle->AllHandles); CoreFreePool (Handle); } Done: // // Done, unlock the database and return // CoreReleaseProtocolLock (); return Status; }
EFI_BOOTSERVICE EFI_STATUS EFIAPI CoreReinstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *OldInterface, IN VOID *NewInterface ) /*++ Routine Description: Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. Arguments: UserHandle - Handle on which the interface is to be reinstalled Protocol - The numeric ID of the interface OldInterface - A pointer to the old interface NewInterface - A pointer to the new interface Returns: Status code. On EFI_SUCCESS The protocol interface was installed On EFI_NOT_FOUND The OldInterface on the handle was not found On EFI_INVALID_PARAMETER One of the parameters has an invalid value --*/ { EFI_STATUS Status; IHANDLE *Handle; PROTOCOL_INTERFACE *Prot; PROTOCOL_ENTRY *ProtEntry; Status = CoreValidateHandle (UserHandle); if (EFI_ERROR (Status)) { return Status; } if (Protocol == NULL) { return EFI_INVALID_PARAMETER; } Handle = (IHANDLE *) UserHandle; // // Lock the protocol database // CoreAcquireProtocolLock (); // // Check that Protocol exists on UserHandle, and Interface matches the interface in the database // Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface); if (Prot == NULL) { CoreReleaseProtocolLock (); return EFI_NOT_FOUND; } // // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled // Status = CoreDisconnectControllersUsingProtocolInterface ( UserHandle, Prot ); if (EFI_ERROR (Status)) { // // One or more drivers refused to release, so return the error // CoreReleaseProtocolLock (); return Status; } // // Remove the protocol interface from the protocol // Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface); if (Prot == NULL) { CoreReleaseProtocolLock (); return EFI_NOT_FOUND; } ProtEntry = Prot->Protocol; // // Update the interface on the protocol // Prot->Interface = NewInterface; // // Add this protocol interface to the tail of the // protocol entry // InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); // // Update the Key to show that the handle has been created/modified // gHandleDatabaseKey++; Handle->Key = gHandleDatabaseKey; // // Release the lock and connect all drivers to UserHandle // CoreReleaseProtocolLock (); Status = CoreConnectController ( UserHandle, NULL, NULL, TRUE ); CoreAcquireProtocolLock (); // // Notify the notification list for this protocol // CoreNotifyProtocolEntry (ProtEntry); CoreReleaseProtocolLock (); return EFI_SUCCESS; }
/** Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. @param UserHandle Handle on which the interface is to be reinstalled @param Protocol The numeric ID of the interface @param OldInterface A pointer to the old interface @param NewInterface A pointer to the new interface @retval EFI_SUCCESS The protocol interface was installed @retval EFI_NOT_FOUND The OldInterface on the handle was not found @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value **/ EFI_STATUS EFIAPI CoreReinstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *OldInterface, IN VOID *NewInterface ) { EFI_STATUS Status; IHANDLE *Handle; PROTOCOL_INTERFACE *Prot; PROTOCOL_ENTRY *ProtEntry; Status = CoreValidateHandle (UserHandle); if (EFI_ERROR (Status)) { return Status; } if (Protocol == NULL) { return EFI_INVALID_PARAMETER; } Handle = (IHANDLE *) UserHandle; // // Lock the protocol database // CoreAcquireProtocolLock (); // // Check that Protocol exists on UserHandle, and Interface matches the interface in the database // Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface); if (Prot == NULL) { Status = EFI_NOT_FOUND; goto Done; } // // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled // Status = CoreDisconnectControllersUsingProtocolInterface ( UserHandle, Prot ); if (EFI_ERROR (Status)) { // // One or more drivers refused to release, so return the error // goto Done; } // // Remove the protocol interface from the protocol // Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface); if (Prot == NULL) { Status = EFI_NOT_FOUND; goto Done; } ProtEntry = Prot->Protocol; // // Update the interface on the protocol // Prot->Interface = NewInterface; // // Add this protocol interface to the tail of the // protocol entry // InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); // // Update the Key to show that the handle has been created/modified // gHandleDatabaseKey++; Handle->Key = gHandleDatabaseKey; // // Release the lock and connect all drivers to UserHandle // CoreReleaseProtocolLock (); // // Return code is ignored on purpose. // CoreConnectController ( UserHandle, NULL, NULL, TRUE ); CoreAcquireProtocolLock (); // // Notify the notification list for this protocol // CoreNotifyProtocolEntry (ProtEntry); Status = EFI_SUCCESS; Done: CoreReleaseProtocolLock (); return Status; }