ata: Support delayed activation

This will allow us to switch to the new firmware version during shutdown when
the filesystems have been remounted readonly.

Activating manually means we don't have to get the user to shutdown and then
do a fresh power-on, rather than the more usual restart.
This commit is contained in:
Richard Hughes 2019-02-26 10:14:16 +00:00
parent 75784c5644
commit 8a3ab68fcb
2 changed files with 32 additions and 0 deletions

View File

@ -466,6 +466,26 @@ fu_ata_device_setup (FuDevice *device, GError **error)
return TRUE;
}
static gboolean
fu_ata_device_activate (FuDevice *device, GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
struct ata_tf tf = { 0x0 };
tf.dev = 0xa0 | ATA_USING_LBA;
tf.command = ATA_OP_DOWNLOAD_MICROCODE;
tf.feat = ATA_SUBCMD_MICROCODE_ACTIVATE;
if (!fu_ata_device_command (self, &tf, SG_DXFER_TO_DEV,
120 * 1000, /* a long time! */
NULL, 0, error)) {
g_prefix_error (error, "failed to activate firmware: ");
return FALSE;
}
/* success */
return TRUE;
}
static gboolean
fu_ata_device_close (FuDevice *device, GError **error)
{
@ -578,6 +598,7 @@ fu_ata_device_write_firmware (FuDevice *device, GBytes *fw, GError **error)
}
/* success! */
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION);
fu_device_set_progress (device, 100);
return TRUE;
}
@ -654,6 +675,7 @@ fu_ata_device_class_init (FuAtaDeviceClass *klass)
klass_device->set_quirk_kv = fu_ata_device_set_quirk_kv;
klass_device->open = fu_ata_device_open;
klass_device->setup = fu_ata_device_setup;
klass_device->activate = fu_ata_device_activate;
klass_device->close = fu_ata_device_close;
klass_device->write_firmware = fu_ata_device_write_firmware;
klass_udev_device->probe = fu_ata_device_probe;

View File

@ -58,3 +58,13 @@ fu_plugin_update (FuPlugin *plugin,
return FALSE;
return fu_device_write_firmware (device, blob_fw, error);
}
gboolean
fu_plugin_activate (FuPlugin *plugin, FuDevice *device, GError **error)
{
g_autoptr(FuDeviceLocker) locker = NULL;
locker = fu_device_locker_new (device, error);
if (locker == NULL)
return FALSE;
return fu_device_activate (device, error);
}