5.2.2 ReinstallProtocolInterface()

This service should be used only to indicate media change events and when a device path is modified or updated. Some examples of when this service must be used are: - A UEFI Driver that produces the Block I/O Protocol for a removable media device when the media in a removable media device is changed (i.e. Floppy, CD, DVD).

  • A UEFI Driver that produces the Serial I/O Protocol when the attributes are modified using SetAttributes()

  • A UEFI Driver that produces the Simple Network Protocol when the MAC address of the network interface is modified using StationAddress().

Internally, this service performs the following series of actions:

  1. UninstallProtocolInterface(), which may cause DisconnectController() to be called

  2. InstallProtocolInterface()

  3. ConnectController() to allow controllers that had to release the protocol a chance to connect to it again

Caution: This service may induce reentrancy if a driver makes a request that requires a UEFI

Driver for a parent device to call ReinstallProtocolInterface(). In this case, the driver making the request may not realize that the request causes the driver to be completely stopped and completely restarted when the request to the parent device is made.

For example, consider a terminal driver that wants to change the baud rate on the serial port. The baud rate is changed with a call to the Serial I/O Protocol's

SetAttributes(). This call changes the baud rate, which is reflected in the device path of the serial device, so the Device Path Protocol is reinstalled by the SetAttributes() service. This reinstallation forces the terminal driver to be disconnected. The terminal driver then attempts to connect to the serial device again, but the baud rate is the one that the terminal driver expects, so the terminal driver does not need to set the baud rate again.

Any consumer of a protocol that supports this media change concept needs to be aware that the protocol can be reinstalled at any time and that care must be taken in the design of drivers that use this type of protocol.

The following code fragments in Example 61 show what a UEFI driver that produces the Block I/O Protocol should do when the media in a removable media device is changed. The exact same protocol is reinstalled onto the controller handle. The specific action that detects if the media is not included in this code fragment. The original Block I/O Media structure is copied so it can be compared with the Block I/O Media structure after the media change detection logic is executed. The Block I/O Protocol is reinstalled if the Media ID is different, if the size of blocks on the mass storage device has changed, if the number of blocks on the mass storage device has changed, if the present status has changed, or if the media has changed from read-only to read-write or vice versa.

Example 61-Reinstall Block I/O Protocol for media change

#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
EFI_STATUS Status;
EFI_HANDLE ControllerHandle;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_BLOCK_IO_MEDIA OldMedia;
//
// Make a copy of the current Block I/O Media structure
//
CopyMem (&OldMedia, &(BlockIo->Media), sizeof (EFI_BLOCK_IO_MEDIA));
//
// Perform driver specific action(s) required to detect if the
// media has been changed and update Block I/O Media structure.
//
//
// Detect whether it is necessary to reinstall the Block I/O Protocol.
//
if ((BlockIo->Media->MediaId != OldMedia.MediaId) ||
(BlockIo->Media->MediaPresent != OldMedia.MediaPresent) ||
(BlockIo->Media->ReadOnly != OldMedia.ReadOnly) ||
(BlockIo->Media->BlockSize != OldMedia.BlockSize) ||
(BlockIo->Media->LastBlock != OldMedia.LastBlock) ) {
Status = gBS->ReinstallProtocolInterface (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
BlockIo,
BlockIo
);
if (EFI_ERROR (Status)) {
return Status;
}
}

The code fragments below show the Device Path Protocol for a Serial I/O device being reinstalled because the serial communication parameters that are expressed in a UART Device Path Node have been modified in a call to the SetAttributes() service of the Serial I/O Protocol.

Example 62-Reinstall Device Path Protocol for Serial I/O attributes change

#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
EFI_STATUS Status;
EFI_HANDLE ControllerHandle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
//
// Retrieve the Device Path Protocol instance on ControllerHandle
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
(VOID **)&DevicePath,
gImageHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check to see if the UART parameters have been modified
// and update UART node of DevicePath
//
//
//
//
Status = gBS->ReinstallProtocolInterface (
ControllerHandle,
&gEfiDevicePathProtocolGuid,
DevicePath,
DevicePath
);
if (EFI_ERROR (Status)) {
return Status;
}