/* In VirtIo 1.0, a device can reject a self-inconsistent feature bitmap through the new VSTAT_FEATURES_OK status bit. (For example if the driver requests a higher level feature but clears a prerequisite feature.) This function is a small wrapper around VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures() that also verifies if the VirtIo 1.0 device accepts the feature bitmap. */
EFI_STATUS EFIAPI Virtio10WriteFeatures(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT64 Features, IN OUT UINT8 *DeviceStatus)
/* In VirtIo 1.0, a device can reject a self-inconsistent feature bitmap through the new VSTAT_FEATURES_OK status bit. (For example if the driver requests a higher level feature but clears a prerequisite feature.) This function is a small wrapper around VIRTIO_DEVICE_PROTOCOL.SetGuestFeatures() that also verifies if the VirtIo 1.0 device accepts the feature bitmap. */
EFI_STATUS EFIAPI Virtio10WriteFeatures(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT64 Features, IN OUT UINT8 *DeviceStatus)
{
  EFI_STATUS  Status;
  if (VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
    return EFI_UNSUPPORTED;
  }
  Status = VirtIo->SetGuestFeatures (VirtIo, Features);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  *DeviceStatus |= VSTAT_FEATURES_OK;
  Status         = VirtIo->SetDeviceStatus (VirtIo, *DeviceStatus);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  Status = VirtIo->GetDeviceStatus (VirtIo, DeviceStatus);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  if ((*DeviceStatus & VSTAT_FEATURES_OK) == 0) {
    Status = EFI_UNSUPPORTED;
  }
  return Status;
}