mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-05 15:55:45 +00:00
Allow using a per-device global percentage completion
It's actually quite hard to build a front-end for fwupd at the moment as you're never sure when the progress bar is going to zip back to 0% and start all over again. Some plugins go 0..100% for write, others go 0..100% for erase, then again for write, then *again* for verify. By creating a helper object we can easily split up the progress of the specific task, e.g. write_firmware(). We can encode at the plugin level "the erase takes 50% of the time, the write takes 40% and the read takes 10%". This means we can have a progressbar which goes up just once at a consistent speed.
This commit is contained in:
parent
f959b198d2
commit
40cd18fa97
@ -146,6 +146,7 @@ and then calls the vfuncs to update the device.
|
||||
fu_plugin_write_firmware (FuPlugin *plugin,
|
||||
FuDevice *dev,
|
||||
GBytes *blob_fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -212,19 +213,19 @@ handle the device ID, although the registered plugin can change during the
|
||||
attach and detach phases.
|
||||
|
||||
gboolean
|
||||
fu_plugin_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
fu_plugin_detach (FuPlugin *plugin, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
if (hardware_in_bootloader)
|
||||
return TRUE;
|
||||
return _device_detach(device, error);
|
||||
return _device_detach(device, progress, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
fu_plugin_attach (FuPlugin *plugin, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
if (!hardware_in_bootloader)
|
||||
return TRUE;
|
||||
return _device_attach(device, error);
|
||||
return _device_attach(device, progress, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -18,6 +18,12 @@ Remember: Plugins should be upstream!
|
||||
* Migrate from fu_device_get_protocol() to fu_device_get_protocols() and fu_device_set_protocol() to fu_device_add_protocol()
|
||||
* Migrate from fu_device_has_custom_flag() to fu_device_has_private_flag()
|
||||
* Migrate from fu_udev_device_set_readonly() to fu_udev_device_set_flags()
|
||||
* Migrate from fu_device_sleep_with_progress() to fu_progress_sleep() -- but be aware the unit of time has changed from *seconds* to *milliseconds*
|
||||
* Migrate from fu_device_get_status() to fu_progress_get_status()
|
||||
* Migrate from fu_device_set_status() to fu_progress_set_status()
|
||||
* Migrate from fu_device_get_progress() to fu_progress_get_percentage()
|
||||
* Migrate from fu_device_set_progress_full() to fu_progress_set_percentage_full()
|
||||
* Migrate from fu_device_set_progress() to fu_progress_set_steps(), fu_progress_add_step() and fu_progress_done -- see the FuProgress docs for more details!
|
||||
|
||||
## Planned API/ABI changes for next release
|
||||
|
||||
|
@ -50,3 +50,5 @@ guint64
|
||||
fu_device_get_private_flags(FuDevice *self);
|
||||
void
|
||||
fu_device_set_private_flags(FuDevice *self, guint64 flag);
|
||||
void
|
||||
fu_device_set_progress(FuDevice *self, FuProgress *progress);
|
||||
|
@ -54,7 +54,6 @@ typedef struct {
|
||||
GRWLock parent_guids_mutex;
|
||||
GPtrArray *parent_physical_ids; /* (nullable) */
|
||||
guint remove_delay; /* ms */
|
||||
guint progress;
|
||||
guint battery_level;
|
||||
guint battery_threshold;
|
||||
guint request_cnts[FWUPD_REQUEST_KIND_LAST];
|
||||
@ -90,7 +89,6 @@ typedef struct {
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PROGRESS,
|
||||
PROP_BATTERY_LEVEL,
|
||||
PROP_BATTERY_THRESHOLD,
|
||||
PROP_PHYSICAL_ID,
|
||||
@ -115,9 +113,6 @@ fu_device_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec
|
||||
FuDevice *self = FU_DEVICE(object);
|
||||
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
switch (prop_id) {
|
||||
case PROP_PROGRESS:
|
||||
g_value_set_uint(value, priv->progress);
|
||||
break;
|
||||
case PROP_BATTERY_LEVEL:
|
||||
g_value_set_uint(value, priv->battery_level);
|
||||
break;
|
||||
@ -153,9 +148,6 @@ fu_device_set_property(GObject *object, guint prop_id, const GValue *value, GPar
|
||||
{
|
||||
FuDevice *self = FU_DEVICE(object);
|
||||
switch (prop_id) {
|
||||
case PROP_PROGRESS:
|
||||
fu_device_set_progress(self, g_value_get_uint(value));
|
||||
break;
|
||||
case PROP_BATTERY_LEVEL:
|
||||
fu_device_set_battery_level(self, g_value_get_uint(value));
|
||||
break;
|
||||
@ -3065,123 +3057,6 @@ fu_device_set_remove_delay(FuDevice *self, guint remove_delay)
|
||||
priv->remove_delay = remove_delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_get_status:
|
||||
* @self: a #FuDevice
|
||||
*
|
||||
* Returns what the device is currently doing.
|
||||
*
|
||||
* Returns: the status value, e.g. %FWUPD_STATUS_DEVICE_WRITE
|
||||
*
|
||||
* Since: 1.0.3
|
||||
**/
|
||||
FwupdStatus
|
||||
fu_device_get_status(FuDevice *self)
|
||||
{
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), 0);
|
||||
return fwupd_device_get_status(FWUPD_DEVICE(self));
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_status:
|
||||
* @self: a #FuDevice
|
||||
* @status: the status value, e.g. %FWUPD_STATUS_DEVICE_WRITE
|
||||
*
|
||||
* Sets what the device is currently doing.
|
||||
*
|
||||
* Since: 1.0.3
|
||||
**/
|
||||
void
|
||||
fu_device_set_status(FuDevice *self, FwupdStatus status)
|
||||
{
|
||||
g_return_if_fail(FU_IS_DEVICE(self));
|
||||
fwupd_device_set_status(FWUPD_DEVICE(self), status);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_get_progress:
|
||||
* @self: a #FuDevice
|
||||
*
|
||||
* Returns the progress completion.
|
||||
*
|
||||
* Returns: value in percent
|
||||
*
|
||||
* Since: 1.0.3
|
||||
**/
|
||||
guint
|
||||
fu_device_get_progress(FuDevice *self)
|
||||
{
|
||||
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), 0);
|
||||
return priv->progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_progress:
|
||||
* @self: a #FuDevice
|
||||
* @progress: the progress percentage value
|
||||
*
|
||||
* Sets the progress completion.
|
||||
*
|
||||
* Since: 1.0.3
|
||||
**/
|
||||
void
|
||||
fu_device_set_progress(FuDevice *self, guint progress)
|
||||
{
|
||||
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_DEVICE(self));
|
||||
if (priv->progress == progress)
|
||||
return;
|
||||
priv->progress = progress;
|
||||
g_object_notify(G_OBJECT(self), "progress");
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_progress_full:
|
||||
* @self: a #FuDevice
|
||||
* @progress_done: the bytes already done
|
||||
* @progress_total: the total number of bytes
|
||||
*
|
||||
* Sets the progress completion using the raw progress values.
|
||||
*
|
||||
* Since: 1.0.3
|
||||
**/
|
||||
void
|
||||
fu_device_set_progress_full(FuDevice *self, gsize progress_done, gsize progress_total)
|
||||
{
|
||||
gdouble percentage = 0.f;
|
||||
g_return_if_fail(FU_IS_DEVICE(self));
|
||||
if (progress_total > 0)
|
||||
percentage = (100.f * (gdouble)progress_done) / (gdouble)progress_total;
|
||||
fu_device_set_progress(self, (guint)percentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_sleep_with_progress:
|
||||
* @self: a #FuDevice
|
||||
* @delay_secs: the delay in seconds
|
||||
*
|
||||
* Sleeps, setting the device progress from 0..100% as time continues.
|
||||
* The value is gven in whole seconds as it does not make sense to show the
|
||||
* progressbar advancing so quickly for durations of less than one second.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fu_device_sleep_with_progress(FuDevice *self, guint delay_secs)
|
||||
{
|
||||
gulong delay_us_pc = (delay_secs * G_USEC_PER_SEC) / 100;
|
||||
|
||||
g_return_if_fail(FU_IS_DEVICE(self));
|
||||
g_return_if_fail(delay_secs > 0);
|
||||
|
||||
fu_device_set_progress(self, 0);
|
||||
for (guint i = 0; i < 100; i++) {
|
||||
g_usleep(delay_us_pc);
|
||||
fu_device_set_progress(self, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_update_state:
|
||||
* @self: a #FuDevice
|
||||
@ -3547,6 +3422,7 @@ fu_device_get_results(FuDevice *self, GError **error)
|
||||
* fu_device_write_firmware:
|
||||
* @self: a #FuDevice
|
||||
* @fw: firmware blob
|
||||
* @progress: a #FuProgress
|
||||
* @flags: install flags, e.g. %FWUPD_INSTALL_FLAG_FORCE
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
@ -3557,7 +3433,11 @@ fu_device_get_results(FuDevice *self, GError **error)
|
||||
* Since: 1.0.8
|
||||
**/
|
||||
gboolean
|
||||
fu_device_write_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags, GError **error)
|
||||
fu_device_write_firmware(FuDevice *self,
|
||||
GBytes *fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
@ -3565,6 +3445,7 @@ fu_device_write_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags, GE
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* no plugin-specific method */
|
||||
@ -3574,6 +3455,7 @@ fu_device_write_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags, GE
|
||||
}
|
||||
|
||||
/* prepare (e.g. decompress) firmware */
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DECOMPRESSING);
|
||||
firmware = fu_device_prepare_firmware(self, fw, flags, error);
|
||||
if (firmware == NULL)
|
||||
return FALSE;
|
||||
@ -3581,7 +3463,7 @@ fu_device_write_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags, GE
|
||||
g_debug("installing onto %s:\n%s", fu_device_get_id(self), str);
|
||||
|
||||
/* call vfunc */
|
||||
if (!klass->write_firmware(self, firmware, flags, error))
|
||||
if (!klass->write_firmware(self, firmware, progress, flags, error))
|
||||
return FALSE;
|
||||
|
||||
/* the device set an UpdateMessage (possibly from a quirk, or XML file)
|
||||
@ -3633,7 +3515,6 @@ fu_device_prepare_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags,
|
||||
|
||||
/* optionally subclassed */
|
||||
if (klass->prepare_firmware != NULL) {
|
||||
fu_device_set_status(self, FWUPD_STATUS_DECOMPRESSING);
|
||||
firmware = klass->prepare_firmware(self, fw, flags, error);
|
||||
if (firmware == NULL)
|
||||
return NULL;
|
||||
@ -3674,6 +3555,7 @@ fu_device_prepare_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags,
|
||||
/**
|
||||
* fu_device_read_firmware:
|
||||
* @self: a #FuDevice
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Reads firmware from the device by calling a plugin-specific vfunc.
|
||||
@ -3688,12 +3570,13 @@ fu_device_prepare_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags,
|
||||
* Since: 1.0.8
|
||||
**/
|
||||
FuFirmware *
|
||||
fu_device_read_firmware(FuDevice *self, GError **error)
|
||||
fu_device_read_firmware(FuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), NULL);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), NULL);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* device does not support reading for verification CRCs */
|
||||
@ -3704,10 +3587,10 @@ fu_device_read_firmware(FuDevice *self, GError **error)
|
||||
|
||||
/* call vfunc */
|
||||
if (klass->read_firmware != NULL)
|
||||
return klass->read_firmware(self, error);
|
||||
return klass->read_firmware(self, progress, error);
|
||||
|
||||
/* use the default FuFirmware when only ->dump_firmware is provided */
|
||||
fw = fu_device_dump_firmware(self, error);
|
||||
fw = fu_device_dump_firmware(self, progress, error);
|
||||
if (fw == NULL)
|
||||
return NULL;
|
||||
return fu_firmware_new_from_bytes(fw);
|
||||
@ -3716,6 +3599,7 @@ fu_device_read_firmware(FuDevice *self, GError **error)
|
||||
/**
|
||||
* fu_device_dump_firmware:
|
||||
* @self: a #FuDevice
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Reads the raw firmware image from the device by calling a plugin-specific
|
||||
@ -3728,11 +3612,12 @@ fu_device_read_firmware(FuDevice *self, GError **error)
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GBytes *
|
||||
fu_device_dump_firmware(FuDevice *self, GError **error)
|
||||
fu_device_dump_firmware(FuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), NULL);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), NULL);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* use the default FuFirmware when only ->dump_firmware is provided */
|
||||
@ -3742,12 +3627,13 @@ fu_device_dump_firmware(FuDevice *self, GError **error)
|
||||
}
|
||||
|
||||
/* proxy */
|
||||
return klass->dump_firmware(self, error);
|
||||
return klass->dump_firmware(self, progress, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_detach:
|
||||
* @self: a #FuDevice
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Detaches a device from the application into bootloader mode.
|
||||
@ -3757,11 +3643,12 @@ fu_device_dump_firmware(FuDevice *self, GError **error)
|
||||
* Since: 1.0.8
|
||||
**/
|
||||
gboolean
|
||||
fu_device_detach(FuDevice *self, GError **error)
|
||||
fu_device_detach(FuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* no plugin-specific method */
|
||||
@ -3769,12 +3656,13 @@ fu_device_detach(FuDevice *self, GError **error)
|
||||
return TRUE;
|
||||
|
||||
/* call vfunc */
|
||||
return klass->detach(self, error);
|
||||
return klass->detach(self, progress, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_attach:
|
||||
* @self: a #FuDevice
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Attaches a device from the bootloader into application mode.
|
||||
@ -3784,11 +3672,12 @@ fu_device_detach(FuDevice *self, GError **error)
|
||||
* Since: 1.0.8
|
||||
**/
|
||||
gboolean
|
||||
fu_device_attach(FuDevice *self, GError **error)
|
||||
fu_device_attach(FuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* no plugin-specific method */
|
||||
@ -3796,7 +3685,7 @@ fu_device_attach(FuDevice *self, GError **error)
|
||||
return TRUE;
|
||||
|
||||
/* call vfunc */
|
||||
return klass->attach(self, error);
|
||||
return klass->attach(self, progress, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4126,6 +4015,30 @@ fu_device_rescan(FuDevice *self, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_set_progress:
|
||||
* @self: a #FuDevice
|
||||
* @progress: a #FuProgress
|
||||
*
|
||||
* Sets steps on the progress object used to write firmware.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
|
||||
g_return_if_fail(FU_IS_DEVICE(self));
|
||||
g_return_if_fail(FU_IS_PROGRESS(progress));
|
||||
g_return_if_fail(FU_IS_PROGRESS(progress));
|
||||
|
||||
/* subclassed */
|
||||
if (klass->set_progress == NULL)
|
||||
return;
|
||||
klass->set_progress(self, progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_device_convert_instance_ids:
|
||||
* @self: a #FuDevice
|
||||
@ -4217,6 +4130,7 @@ fu_device_setup(FuDevice *self, GError **error)
|
||||
/**
|
||||
* fu_device_activate:
|
||||
* @self: a #FuDevice
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Activates up a device, which normally means the device switches to a new
|
||||
@ -4227,16 +4141,17 @@ fu_device_setup(FuDevice *self, GError **error)
|
||||
* Since: 1.2.6
|
||||
**/
|
||||
gboolean
|
||||
fu_device_activate(FuDevice *self, GError **error)
|
||||
fu_device_activate(FuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDeviceClass *klass = FU_DEVICE_GET_CLASS(self);
|
||||
|
||||
g_return_val_if_fail(FU_IS_DEVICE(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* subclassed */
|
||||
if (klass->activate != NULL) {
|
||||
if (!klass->activate(self, error))
|
||||
if (!klass->activate(self, progress, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -4647,15 +4562,6 @@ fu_device_class_init(FuDeviceClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property(object_class, PROP_BACKEND_ID, pspec);
|
||||
|
||||
pspec = g_param_spec_uint("progress",
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
100,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property(object_class, PROP_PROGRESS, pspec);
|
||||
|
||||
pspec = g_param_spec_uint("battery-level",
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "fu-common-version.h"
|
||||
#include "fu-context.h"
|
||||
#include "fu-firmware.h"
|
||||
#include "fu-progress.h"
|
||||
#include "fu-security-attrs.h"
|
||||
|
||||
#define FU_TYPE_DEVICE (fu_device_get_type())
|
||||
@ -23,11 +24,18 @@ struct _FuDeviceClass {
|
||||
void (*to_string)(FuDevice *self, guint indent, GString *str);
|
||||
gboolean (*write_firmware)(FuDevice *self,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
FuFirmware *(*read_firmware)(FuDevice *self, GError **error)G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*detach)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*attach)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
FuFirmware *(*read_firmware)(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error)G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*detach)(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*attach)(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*open)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*close)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*probe)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
@ -43,7 +51,9 @@ struct _FuDeviceClass {
|
||||
gboolean (*setup)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
void (*incorporate)(FuDevice *self, FuDevice *donor);
|
||||
gboolean (*poll)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*activate)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*activate)(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*reload)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*prepare)(FuDevice *self,
|
||||
FwupdInstallFlags flags,
|
||||
@ -58,7 +68,9 @@ struct _FuDeviceClass {
|
||||
const gchar *driver,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean (*unbind_driver)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GBytes *(*dump_firmware)(FuDevice *self, GError **error)G_GNUC_WARN_UNUSED_RESULT;
|
||||
GBytes *(*dump_firmware)(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error)G_GNUC_WARN_UNUSED_RESULT;
|
||||
void (*add_security_attrs)(FuDevice *self, FuSecurityAttrs *attrs);
|
||||
gboolean (*ready)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
void (*child_added)(FuDevice *self, /* signal */
|
||||
@ -68,8 +80,9 @@ struct _FuDeviceClass {
|
||||
void (*request)(FuDevice *self, /* signal */
|
||||
FwupdRequest *request);
|
||||
gboolean (*get_results)(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
void (*set_progress)(FuDevice *self, FuProgress *progress);
|
||||
/*< private >*/
|
||||
gpointer padding[5];
|
||||
gpointer padding[16];
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -498,10 +511,6 @@ guint
|
||||
fu_device_get_remove_delay(FuDevice *self);
|
||||
void
|
||||
fu_device_set_remove_delay(FuDevice *self, guint remove_delay);
|
||||
FwupdStatus
|
||||
fu_device_get_status(FuDevice *self);
|
||||
void
|
||||
fu_device_set_status(FuDevice *self, FwupdStatus status);
|
||||
void
|
||||
fu_device_set_firmware_size(FuDevice *self, guint64 size);
|
||||
void
|
||||
@ -513,10 +522,6 @@ fu_device_get_firmware_size_min(FuDevice *self);
|
||||
guint64
|
||||
fu_device_get_firmware_size_max(FuDevice *self);
|
||||
guint
|
||||
fu_device_get_progress(FuDevice *self);
|
||||
void
|
||||
fu_device_set_progress(FuDevice *self, guint progress);
|
||||
guint
|
||||
fu_device_get_battery_level(FuDevice *self);
|
||||
void
|
||||
fu_device_set_battery_level(FuDevice *self, guint battery_level);
|
||||
@ -525,10 +530,6 @@ fu_device_get_battery_threshold(FuDevice *self);
|
||||
void
|
||||
fu_device_set_battery_threshold(FuDevice *self, guint battery_threshold);
|
||||
void
|
||||
fu_device_set_progress_full(FuDevice *self, gsize progress_done, gsize progress_total);
|
||||
void
|
||||
fu_device_sleep_with_progress(FuDevice *self, guint delay_secs);
|
||||
void
|
||||
fu_device_set_update_state(FuDevice *self, FwupdUpdateState update_state);
|
||||
void
|
||||
fu_device_set_context(FuDevice *self, FuContext *ctx);
|
||||
@ -547,19 +548,26 @@ fu_device_has_internal_flag(FuDevice *self, FuDeviceInternalFlags flag);
|
||||
gboolean
|
||||
fu_device_get_results(FuDevice *self, GError **error);
|
||||
gboolean
|
||||
fu_device_write_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags, GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_device_write_firmware(FuDevice *self,
|
||||
GBytes *fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
FuFirmware *
|
||||
fu_device_prepare_firmware(FuDevice *self, GBytes *fw, FwupdInstallFlags flags, GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
FuFirmware *
|
||||
fu_device_read_firmware(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_device_read_firmware(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GBytes *
|
||||
fu_device_dump_firmware(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_device_dump_firmware(FuDevice *self,
|
||||
FuProgress *progress,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_device_attach(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_device_attach(FuDevice *self, FuProgress *progress, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_device_detach(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_device_detach(FuDevice *self, FuProgress *progress, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_device_reload(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
@ -585,7 +593,7 @@ fu_device_setup(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_device_rescan(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_device_activate(FuDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_device_activate(FuDevice *self, FuProgress *progress, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
void
|
||||
fu_device_probe_invalidate(FuDevice *self);
|
||||
gboolean
|
||||
|
@ -57,9 +57,11 @@ fu_plugin_runner_composite_cleanup(FuPlugin *self,
|
||||
GPtrArray *devices,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_plugin_runner_detach(FuPlugin *self, FuDevice *device, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_plugin_runner_detach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_plugin_runner_reload(FuPlugin *self, FuDevice *device, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
@ -84,13 +86,17 @@ gboolean
|
||||
fu_plugin_runner_write_firmware(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags flags, GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
fu_plugin_runner_verify(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
FuPluginVerifyFlags flags,
|
||||
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
fu_plugin_runner_activate(FuPlugin *self, FuDevice *device, GError **error);
|
||||
fu_plugin_runner_activate(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error);
|
||||
gboolean
|
||||
fu_plugin_runner_unlock(FuPlugin *self, FuDevice *device, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
|
@ -98,6 +98,7 @@ fu_plugin_coldplug_cleanup(FuPlugin *plugin, GError **error);
|
||||
* @plugin: a plugin
|
||||
* @dev: a device
|
||||
* @blob_fw: a data blob
|
||||
* @progress: a #FuProgress
|
||||
* @flags: install flags
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
@ -109,6 +110,7 @@ gboolean
|
||||
fu_plugin_write_firmware(FuPlugin *plugin,
|
||||
FuDevice *dev,
|
||||
GBytes *blob_fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
/**
|
||||
@ -150,7 +152,7 @@ fu_plugin_unlock(FuPlugin *plugin, FuDevice *dev, GError **error);
|
||||
* Since: 1.2.6
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_activate(FuPlugin *plugin, FuDevice *dev, GError **error);
|
||||
fu_plugin_activate(FuPlugin *plugin, FuDevice *dev, FuProgress *progress, GError **error);
|
||||
/**
|
||||
* fu_plugin_clear_results:
|
||||
* @plugin: a plugin
|
||||
@ -186,7 +188,7 @@ fu_plugin_get_results(FuPlugin *plugin, FuDevice *dev, GError **error);
|
||||
* Since: 1.0.2
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_attach(FuPlugin *plugin, FuDevice *dev, GError **error);
|
||||
fu_plugin_attach(FuPlugin *plugin, FuDevice *dev, FuProgress *progress, GError **error);
|
||||
/**
|
||||
* fu_plugin_detach:
|
||||
* @plugin: a plugin
|
||||
@ -198,7 +200,7 @@ fu_plugin_attach(FuPlugin *plugin, FuDevice *dev, GError **error);
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_detach(FuPlugin *plugin, FuDevice *dev, GError **error);
|
||||
fu_plugin_detach(FuPlugin *plugin, FuDevice *dev, FuProgress *progress, GError **error);
|
||||
/**
|
||||
* fu_plugin_prepare:
|
||||
* @plugin: a plugin
|
||||
|
@ -68,6 +68,10 @@ typedef void (*FuPluginInitFunc)(FuPlugin *self);
|
||||
typedef gboolean (*FuPluginStartupFunc)(FuPlugin *self, GError **error);
|
||||
typedef void (*FuPluginDeviceRegisterFunc)(FuPlugin *self, FuDevice *device);
|
||||
typedef gboolean (*FuPluginDeviceFunc)(FuPlugin *self, FuDevice *device, GError **error);
|
||||
typedef gboolean (*FuPluginDeviceProgressFunc)(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
typedef gboolean (*FuPluginFlaggedDeviceFunc)(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
FwupdInstallFlags flags,
|
||||
@ -80,6 +84,7 @@ typedef gboolean (*FuPluginVerifyFunc)(FuPlugin *self,
|
||||
typedef gboolean (*FuPluginUpdateFunc)(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error);
|
||||
typedef void (*FuPluginSecurityAttrsFunc)(FuPlugin *self, FuSecurityAttrs *attrs);
|
||||
@ -670,42 +675,43 @@ fu_plugin_get_context(FuPlugin *self)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_device_attach(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_device_attach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDevice *proxy = fu_device_get_proxy_with_fallback(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
locker = fu_device_locker_new(proxy, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
return fu_device_attach(device, error);
|
||||
return fu_device_attach(device, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_device_detach(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_device_detach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDevice *proxy = fu_device_get_proxy_with_fallback(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
locker = fu_device_locker_new(proxy, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
return fu_device_detach(device, error);
|
||||
return fu_device_detach(device, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_device_activate(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_device_activate(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDevice *proxy = fu_device_get_proxy_with_fallback(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
locker = fu_device_locker_new(proxy, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
return fu_device_activate(device, error);
|
||||
return fu_device_activate(device, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_device_write_firmware(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
GBytes *fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -722,7 +728,7 @@ fu_plugin_device_write_firmware(FuPlugin *self,
|
||||
g_autofree gchar *fn = NULL;
|
||||
g_autofree gchar *localstatedir = NULL;
|
||||
|
||||
fw_old = fu_device_dump_firmware(device, error);
|
||||
fw_old = fu_device_dump_firmware(device, progress, error);
|
||||
if (fw_old == NULL) {
|
||||
g_prefix_error(error, "failed to backup old firmware: ");
|
||||
return FALSE;
|
||||
@ -740,7 +746,7 @@ fu_plugin_device_write_firmware(FuPlugin *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return fu_device_write_firmware(device, fw, flags, error);
|
||||
return fu_device_write_firmware(device, fw, progress, flags, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -761,7 +767,10 @@ fu_plugin_device_get_results(FuPlugin *self, FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_device_read_firmware(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_device_read_firmware(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDevice *proxy = fu_device_get_proxy_with_fallback(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -771,12 +780,12 @@ fu_plugin_device_read_firmware(FuPlugin *self, FuDevice *device, GError **error)
|
||||
locker = fu_device_locker_new(proxy, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
if (!fu_device_detach(device, error))
|
||||
if (!fu_device_detach(device, progress, error))
|
||||
return FALSE;
|
||||
firmware = fu_device_read_firmware(device, error);
|
||||
firmware = fu_device_read_firmware(device, progress, error);
|
||||
if (firmware == NULL) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
if (!fu_device_attach(device, &error_local))
|
||||
if (!fu_device_attach(device, progress, &error_local))
|
||||
g_debug("ignoring attach failure: %s", error_local->message);
|
||||
g_prefix_error(error, "failed to read firmware: ");
|
||||
return FALSE;
|
||||
@ -784,7 +793,7 @@ fu_plugin_device_read_firmware(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fw = fu_firmware_write(firmware, error);
|
||||
if (fw == NULL) {
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
if (!fu_device_attach(device, &error_local))
|
||||
if (!fu_device_attach(device, progress, &error_local))
|
||||
g_debug("ignoring attach failure: %s", error_local->message);
|
||||
g_prefix_error(error, "failed to write firmware: ");
|
||||
return FALSE;
|
||||
@ -794,7 +803,7 @@ fu_plugin_device_read_firmware(FuPlugin *self, FuDevice *device, GError **error)
|
||||
hash = g_compute_checksum_for_bytes(checksum_types[i], fw);
|
||||
fu_device_add_checksum(device, hash);
|
||||
}
|
||||
return fu_device_attach(device, error);
|
||||
return fu_device_attach(device, progress, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -909,6 +918,58 @@ fu_plugin_runner_device_generic(FuPlugin *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_runner_device_generic_progress(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
const gchar *symbol_name,
|
||||
FuPluginDeviceProgressFunc device_func,
|
||||
GError **error)
|
||||
{
|
||||
FuPluginPrivate *priv = GET_PRIVATE(self);
|
||||
FuPluginDeviceProgressFunc func = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* not enabled */
|
||||
if (fu_plugin_has_flag(self, FWUPD_PLUGIN_FLAG_DISABLED))
|
||||
return TRUE;
|
||||
|
||||
/* no object loaded */
|
||||
if (priv->module == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* optional */
|
||||
g_module_symbol(priv->module, symbol_name, (gpointer *)&func);
|
||||
if (func == NULL) {
|
||||
if (device_func != NULL) {
|
||||
g_debug("running superclassed %s(%s)",
|
||||
symbol_name + 10,
|
||||
fu_plugin_get_name(self));
|
||||
return device_func(self, device, progress, error);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
g_debug("%s(%s)", symbol_name + 10, fu_plugin_get_name(self));
|
||||
if (!func(self, device, progress, &error_local)) {
|
||||
if (error_local == NULL) {
|
||||
g_critical("unset plugin error in %s(%s)",
|
||||
fu_plugin_get_name(self),
|
||||
symbol_name + 10);
|
||||
g_set_error_literal(&error_local,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"unspecified error");
|
||||
}
|
||||
g_propagate_prefixed_error(error,
|
||||
g_steal_pointer(&error_local),
|
||||
"failed to %s using %s: ",
|
||||
symbol_name + 10,
|
||||
fu_plugin_get_name(self));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_runner_flagged_device_generic(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
@ -1238,6 +1299,7 @@ fu_plugin_runner_cleanup(FuPlugin *self, FuDevice *device, FwupdInstallFlags fla
|
||||
* fu_plugin_runner_attach:
|
||||
* @self: a #FuPlugin
|
||||
* @device: a device
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Runs the update_attach routine for the plugin
|
||||
@ -1247,19 +1309,21 @@ fu_plugin_runner_cleanup(FuPlugin *self, FuDevice *device, FwupdInstallFlags fla
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
return fu_plugin_runner_device_generic(self,
|
||||
device,
|
||||
"fu_plugin_attach",
|
||||
fu_plugin_device_attach,
|
||||
error);
|
||||
return fu_plugin_runner_device_generic_progress(self,
|
||||
device,
|
||||
progress,
|
||||
"fu_plugin_attach",
|
||||
fu_plugin_device_attach,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_plugin_runner_detach:
|
||||
* @self: a #FuPlugin
|
||||
* @device: a device
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Runs the update_detach routine for the plugin
|
||||
@ -1269,13 +1333,14 @@ fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, GError **error)
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_runner_detach(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_runner_detach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
return fu_plugin_runner_device_generic(self,
|
||||
device,
|
||||
"fu_plugin_detach",
|
||||
fu_plugin_device_detach,
|
||||
error);
|
||||
return fu_plugin_runner_device_generic_progress(self,
|
||||
device,
|
||||
progress,
|
||||
"fu_plugin_detach",
|
||||
fu_plugin_device_detach,
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1770,6 +1835,7 @@ fu_plugin_runner_device_created(FuPlugin *self, FuDevice *device, GError **error
|
||||
* fu_plugin_runner_verify:
|
||||
* @self: a #FuPlugin
|
||||
* @device: a device
|
||||
* @progress: a #FuProgress
|
||||
* @flags: verify flags
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
@ -1780,7 +1846,11 @@ fu_plugin_runner_device_created(FuPlugin *self, FuDevice *device, GError **error
|
||||
* Since: 0.8.0
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags flags, GError **error)
|
||||
fu_plugin_runner_verify(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
FuPluginVerifyFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuPluginPrivate *priv = GET_PRIVATE(self);
|
||||
FuPluginVerifyFunc func = NULL;
|
||||
@ -1789,6 +1859,7 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
|
||||
g_return_val_if_fail(FU_IS_PLUGIN(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_DEVICE(device), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* not enabled */
|
||||
@ -1810,7 +1881,7 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
fu_device_get_id(device));
|
||||
return FALSE;
|
||||
}
|
||||
return fu_plugin_device_read_firmware(self, device, error);
|
||||
return fu_plugin_device_read_firmware(self, device, progress, error);
|
||||
}
|
||||
|
||||
/* clear any existing verification checksums */
|
||||
@ -1818,11 +1889,12 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
g_ptr_array_set_size(checksums, 0);
|
||||
|
||||
/* run additional detach */
|
||||
if (!fu_plugin_runner_device_generic(self,
|
||||
device,
|
||||
"fu_plugin_detach",
|
||||
fu_plugin_device_detach,
|
||||
error))
|
||||
if (!fu_plugin_runner_device_generic_progress(self,
|
||||
device,
|
||||
progress,
|
||||
"fu_plugin_detach",
|
||||
fu_plugin_device_detach,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* run vfunc */
|
||||
@ -1841,11 +1913,12 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
"failed to verify using %s: ",
|
||||
fu_plugin_get_name(self));
|
||||
/* make the device "work" again, but don't prefix the error */
|
||||
if (!fu_plugin_runner_device_generic(self,
|
||||
device,
|
||||
"fu_plugin_attach",
|
||||
fu_plugin_device_attach,
|
||||
&error_attach)) {
|
||||
if (!fu_plugin_runner_device_generic_progress(self,
|
||||
device,
|
||||
progress,
|
||||
"fu_plugin_attach",
|
||||
fu_plugin_device_attach,
|
||||
&error_attach)) {
|
||||
g_warning("failed to attach whilst aborting verify(): %s",
|
||||
error_attach->message);
|
||||
}
|
||||
@ -1853,11 +1926,12 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
}
|
||||
|
||||
/* run optional attach */
|
||||
if (!fu_plugin_runner_device_generic(self,
|
||||
device,
|
||||
"fu_plugin_attach",
|
||||
fu_plugin_device_attach,
|
||||
error))
|
||||
if (!fu_plugin_runner_device_generic_progress(self,
|
||||
device,
|
||||
progress,
|
||||
"fu_plugin_attach",
|
||||
fu_plugin_device_attach,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* success */
|
||||
@ -1868,6 +1942,7 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
* fu_plugin_runner_activate:
|
||||
* @self: a #FuPlugin
|
||||
* @device: a device
|
||||
* @progress: a #FuProgress
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Call into the plugin's activate routine
|
||||
@ -1877,12 +1952,13 @@ fu_plugin_runner_verify(FuPlugin *self, FuDevice *device, FuPluginVerifyFlags fl
|
||||
* Since: 1.2.6
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_runner_activate(FuPlugin *self, FuDevice *device, GError **error)
|
||||
fu_plugin_runner_activate(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint64 flags;
|
||||
|
||||
g_return_val_if_fail(FU_IS_PLUGIN(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_DEVICE(device), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* final check */
|
||||
@ -1897,11 +1973,12 @@ fu_plugin_runner_activate(FuPlugin *self, FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
/* run vfunc */
|
||||
if (!fu_plugin_runner_device_generic(self,
|
||||
device,
|
||||
"fu_plugin_activate",
|
||||
fu_plugin_device_activate,
|
||||
error))
|
||||
if (!fu_plugin_runner_device_generic_progress(self,
|
||||
device,
|
||||
progress,
|
||||
"fu_plugin_activate",
|
||||
fu_plugin_device_activate,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* update with correct flags */
|
||||
@ -1957,6 +2034,7 @@ fu_plugin_runner_unlock(FuPlugin *self, FuDevice *device, GError **error)
|
||||
* @self: a #FuPlugin
|
||||
* @device: a device
|
||||
* @blob_fw: a data blob
|
||||
* @progress: a #FuProgress
|
||||
* @flags: install flags
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
@ -1970,6 +2048,7 @@ gboolean
|
||||
fu_plugin_runner_write_firmware(FuPlugin *self,
|
||||
FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1979,6 +2058,7 @@ fu_plugin_runner_write_firmware(FuPlugin *self,
|
||||
|
||||
g_return_val_if_fail(FU_IS_PLUGIN(self), FALSE);
|
||||
g_return_val_if_fail(FU_IS_DEVICE(device), FALSE);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(progress), FALSE);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
||||
|
||||
/* not enabled */
|
||||
@ -1997,11 +2077,16 @@ fu_plugin_runner_write_firmware(FuPlugin *self,
|
||||
g_module_symbol(priv->module, "fu_plugin_write_firmware", (gpointer *)&update_func);
|
||||
if (update_func == NULL) {
|
||||
g_debug("superclassed write_firmware(%s)", fu_plugin_get_name(self));
|
||||
return fu_plugin_device_write_firmware(self, device, blob_fw, flags, error);
|
||||
return fu_plugin_device_write_firmware(self,
|
||||
device,
|
||||
blob_fw,
|
||||
progress,
|
||||
flags,
|
||||
error);
|
||||
}
|
||||
|
||||
/* online */
|
||||
if (!update_func(self, device, blob_fw, flags, &error_local)) {
|
||||
if (!update_func(self, device, blob_fw, progress, flags, &error_local)) {
|
||||
if (error_local == NULL) {
|
||||
g_critical("unset plugin error in update(%s)", fu_plugin_get_name(self));
|
||||
g_set_error_literal(&error_local,
|
||||
|
921
libfwupdplugin/fu-progress.c
Normal file
921
libfwupdplugin/fu-progress.c
Normal file
@ -0,0 +1,921 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "FuProgress"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "fu-progress.h"
|
||||
|
||||
/**
|
||||
* FuProgress:
|
||||
*
|
||||
* Objects can use fu_progress_set_percentage() if the absolute percentage
|
||||
* is known. Percentages should always go up, not down.
|
||||
*
|
||||
* Modules usually set the number of steps that are expected using
|
||||
* fu_progress_set_steps() and then after each section is completed,
|
||||
* the fu_progress_step_done() function should be called. This will automatically
|
||||
* call fu_progress_set_percentage() with the correct values.
|
||||
*
|
||||
* #FuProgress allows sub-modules to be "chained up" to the parent module
|
||||
* so that as the sub-module progresses, so does the parent.
|
||||
* The child can be reused for each section, and chains can be deep.
|
||||
*
|
||||
* To get a child object, you should use fu_progress_get_child() and then
|
||||
* use the result in any sub-process. You should ensure that the child
|
||||
* is not re-used without calling fu_progress_step_done().
|
||||
*
|
||||
* There are a few nice touches in this module, so that if a module only has
|
||||
* one progress step, the child progress is used for parent updates.
|
||||
*
|
||||
* static void
|
||||
* _do_something(FuProgress *self)
|
||||
* {
|
||||
* // setup correct number of steps
|
||||
* fu_progress_set_steps(self, 2);
|
||||
*
|
||||
* // run a sub function
|
||||
* _do_something_else1(fu_progress_get_child(self));
|
||||
*
|
||||
* // this section done
|
||||
* fu_progress_step_done(self);
|
||||
*
|
||||
* // run another sub function
|
||||
* _do_something_else2(fu_progress_get_child(self));
|
||||
*
|
||||
* // this progress done (all complete)
|
||||
* fu_progress_step_done(self);
|
||||
* }
|
||||
*
|
||||
* See also: [class@FuDevice]
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
gchar *id;
|
||||
FuProgressFlags flags;
|
||||
guint percentage;
|
||||
FwupdStatus status;
|
||||
GPtrArray *steps;
|
||||
gboolean profile;
|
||||
GTimer *timer;
|
||||
guint step_now;
|
||||
guint step_max;
|
||||
gulong percentage_child_id;
|
||||
gulong status_child_id;
|
||||
FuProgress *child;
|
||||
FuProgress *parent; /* no-ref */
|
||||
} FuProgressPrivate;
|
||||
|
||||
typedef struct {
|
||||
FwupdStatus status;
|
||||
guint value;
|
||||
gdouble profile;
|
||||
} FuProgressStep;
|
||||
|
||||
enum { SIGNAL_PERCENTAGE_CHANGED, SIGNAL_STATUS_CHANGED, SIGNAL_LAST };
|
||||
|
||||
static guint signals[SIGNAL_LAST] = {0};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(FuProgress, fu_progress, G_TYPE_OBJECT)
|
||||
#define GET_PRIVATE(o) (fu_progress_get_instance_private(o))
|
||||
|
||||
/**
|
||||
* fu_progress_get_id:
|
||||
* @self: a #FuProgress
|
||||
*
|
||||
* Return the id of the progress, which is normally set by the caller.
|
||||
*
|
||||
* Returns: progress ID
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
const gchar *
|
||||
fu_progress_get_id(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), NULL);
|
||||
return priv->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_set_id:
|
||||
* @self: a #FuProgress
|
||||
* @id: progress ID, normally `G_STRLOC`
|
||||
*
|
||||
* Sets the id of the progress.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_set_id(FuProgress *self, const gchar *id)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(id != NULL);
|
||||
|
||||
/* not changed */
|
||||
if (g_strcmp0(priv->id, id) == 0)
|
||||
return;
|
||||
|
||||
/* set id */
|
||||
g_free(priv->id);
|
||||
priv->id = g_strdup(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_get_status:
|
||||
* @self: a #FuProgress
|
||||
*
|
||||
* Return the status of the progress, which is normally indirectly by fu_progress_add_step().
|
||||
*
|
||||
* Returns: status
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
FwupdStatus
|
||||
fu_progress_get_status(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), FWUPD_STATUS_UNKNOWN);
|
||||
return priv->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_flag_to_string:
|
||||
* @flag: an internal progress flag, e.g. %FU_PROGRESS_FLAG_GUESSED
|
||||
*
|
||||
* Converts an progress flag to a string.
|
||||
*
|
||||
* Returns: identifier string
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
const gchar *
|
||||
fu_progress_flag_to_string(FuProgressFlags flag)
|
||||
{
|
||||
if (flag == FU_PROGRESS_FLAG_GUESSED)
|
||||
return "guessed";
|
||||
if (flag == FU_PROGRESS_FLAG_NO_PROFILE)
|
||||
return "no-profile";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_flag_from_string:
|
||||
* @flag: a string, e.g. `guessed`
|
||||
*
|
||||
* Converts a string to an progress flag.
|
||||
*
|
||||
* Returns: enumerated value
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
FuProgressFlags
|
||||
fu_progress_flag_from_string(const gchar *flag)
|
||||
{
|
||||
if (g_strcmp0(flag, "guessed") == 0)
|
||||
return FU_PROGRESS_FLAG_GUESSED;
|
||||
if (g_strcmp0(flag, "no-profile") == 0)
|
||||
return FU_PROGRESS_FLAG_NO_PROFILE;
|
||||
return FU_PROGRESS_FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_add_flag:
|
||||
* @self: a #FuProgress
|
||||
* @flag: an internal progress flag, e.g. %FU_PROGRESS_FLAG_GUESSED
|
||||
*
|
||||
* Adds a flag.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_add_flag(FuProgress *self, FuProgressFlags flag)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
priv->flags |= flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_remove_flag:
|
||||
* @self: a #FuProgress
|
||||
* @flag: an internal progress flag, e.g. %FU_PROGRESS_FLAG_GUESSED
|
||||
*
|
||||
* Removes a flag.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_remove_flag(FuProgress *self, FuProgressFlags flag)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
priv->flags &= ~flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_has_flag:
|
||||
* @self: a #FuProgress
|
||||
* @flag: an internal progress flag, e.g. %FU_PROGRESS_FLAG_GUESSED
|
||||
*
|
||||
* Tests for a flag.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
gboolean
|
||||
fu_progress_has_flag(FuProgress *self, FuProgressFlags flag)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), FALSE);
|
||||
return (priv->flags & flag) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_set_status:
|
||||
* @self: a #FuProgress
|
||||
* @status: device status
|
||||
*
|
||||
* Sets the status of the progress.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_set_status(FuProgress *self, FwupdStatus status)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
|
||||
/* not changed */
|
||||
if (priv->status == status)
|
||||
return;
|
||||
|
||||
/* save */
|
||||
priv->status = status;
|
||||
g_signal_emit(self, signals[SIGNAL_STATUS_CHANGED], 0, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_get_percentage:
|
||||
* @self: a #FuProgress
|
||||
*
|
||||
* Get the last set progress percentage.
|
||||
*
|
||||
* Return value: The percentage value, or %G_MAXUINT for error
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
guint
|
||||
fu_progress_get_percentage(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), G_MAXUINT);
|
||||
return priv->percentage;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_build_parent_chain(FuProgress *self, GString *str, guint level)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
if (priv->parent != NULL)
|
||||
fu_progress_build_parent_chain(priv->parent, str, level + 1);
|
||||
g_string_append_printf(str,
|
||||
"%u) %s (%u/%u)\n",
|
||||
level,
|
||||
priv->id,
|
||||
priv->step_now,
|
||||
priv->step_max);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_set_percentage:
|
||||
* @self: a #FuProgress
|
||||
* @percentage: value between 0% and 100%
|
||||
*
|
||||
* Sets the progress percentage complete.
|
||||
*
|
||||
* NOTE: this must be above what was previously set, or it will be rejected.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_set_percentage(FuProgress *self, guint percentage)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(percentage <= 100);
|
||||
|
||||
/* is it the same */
|
||||
if (percentage == priv->percentage)
|
||||
return;
|
||||
|
||||
/* is it less */
|
||||
if (percentage < priv->percentage) {
|
||||
if (priv->profile) {
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
fu_progress_build_parent_chain(self, str, 0);
|
||||
g_warning("percentage should not go down from %u to %u: %s",
|
||||
priv->percentage,
|
||||
percentage,
|
||||
str->str);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* save */
|
||||
priv->percentage = percentage;
|
||||
g_signal_emit(self, signals[SIGNAL_PERCENTAGE_CHANGED], 0, percentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_set_percentage_full:
|
||||
* @self: a #FuDevice
|
||||
* @progress_done: the bytes already done
|
||||
* @progress_total: the total number of bytes
|
||||
*
|
||||
* Sets the progress completion using the raw progress values.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_set_percentage_full(FuProgress *self, gsize progress_done, gsize progress_total)
|
||||
{
|
||||
gdouble percentage = 0.f;
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(progress_done <= progress_total);
|
||||
if (progress_total > 0)
|
||||
percentage = (100.f * (gdouble)progress_done) / (gdouble)progress_total;
|
||||
fu_progress_set_percentage(self, (guint)percentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_set_profile:
|
||||
* @self: A #FuProgress
|
||||
* @profile: if profiling should be enabled
|
||||
*
|
||||
* This enables profiling of FuProgress. This may be useful in development,
|
||||
* but be warned; enabling profiling makes #FuProgress very slow.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_set_profile(FuProgress *self, gboolean profile)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
priv->profile = profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_get_profile:
|
||||
* @self: A #FuProgress
|
||||
* @profile:
|
||||
*
|
||||
* Returns if the profile is enabled for this progress.
|
||||
*
|
||||
* Return value: if profiling should be enabled
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
static gboolean
|
||||
fu_progress_get_profile(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), FALSE);
|
||||
return priv->profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_reset:
|
||||
* @self: A #FuProgress
|
||||
*
|
||||
* Resets the #FuProgress object to unset
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_reset(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
|
||||
/* reset values */
|
||||
priv->step_max = 0;
|
||||
priv->step_now = 0;
|
||||
priv->percentage = 0;
|
||||
|
||||
/* only use the timer if profiling; it's expensive */
|
||||
if (priv->profile)
|
||||
g_timer_start(priv->timer);
|
||||
|
||||
/* disconnect client */
|
||||
if (priv->percentage_child_id != 0) {
|
||||
g_signal_handler_disconnect(priv->child, priv->percentage_child_id);
|
||||
priv->percentage_child_id = 0;
|
||||
}
|
||||
if (priv->status_child_id != 0) {
|
||||
g_signal_handler_disconnect(priv->child, priv->status_child_id);
|
||||
priv->status_child_id = 0;
|
||||
}
|
||||
g_clear_object(&priv->child);
|
||||
|
||||
/* no more step data */
|
||||
g_ptr_array_set_size(priv->steps, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_set_steps:
|
||||
* @self: A #FuProgress
|
||||
* @step_max: The number of sub-tasks in this progress, can be 0
|
||||
*
|
||||
* Sets the number of sub-tasks, i.e. how many times the fu_progress_step_done()
|
||||
* function will be called in the loop.
|
||||
*
|
||||
* The progress ID must be set fu_progress_set_id() before this method is used.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_set_steps(FuProgress *self, guint step_max)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(priv->id != NULL);
|
||||
|
||||
/* only use the timer if profiling; it's expensive */
|
||||
if (priv->profile)
|
||||
g_timer_start(priv->timer);
|
||||
|
||||
/* set step_max */
|
||||
priv->step_max = step_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_get_steps:
|
||||
* @self: A #FuProgress
|
||||
*
|
||||
* Gets the number of sub-tasks, i.e. how many times the fu_progress_step_done()
|
||||
* function will be called in the loop.
|
||||
*
|
||||
* Return value: number of sub-tasks in this progress
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
guint
|
||||
fu_progress_get_steps(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), G_MAXUINT);
|
||||
return priv->step_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_add_step:
|
||||
* @self: A #FuProgress
|
||||
* @status: status value to use for this phase
|
||||
* @value: A step weighting variable argument array
|
||||
*
|
||||
* This sets the step weighting, which you will want to do if one action
|
||||
* will take a bigger chunk of time than another.
|
||||
*
|
||||
* The progress ID must be set fu_progress_set_id() before this method is used.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_add_step(FuProgress *self, FwupdStatus status, guint value)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
FuProgressStep *step;
|
||||
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(priv->id != NULL);
|
||||
|
||||
/* current status */
|
||||
if (priv->steps->len == 0)
|
||||
fu_progress_set_status(self, status);
|
||||
|
||||
/* save data */
|
||||
step = g_new0(FuProgressStep, 1);
|
||||
step->status = status;
|
||||
step->value = value;
|
||||
step->profile = .0;
|
||||
g_ptr_array_add(priv->steps, step);
|
||||
|
||||
/* in case anything is not using ->steps */
|
||||
fu_progress_set_steps(self, priv->steps->len);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_finished:
|
||||
* @self: A #FuProgress
|
||||
*
|
||||
* Called when the step_now sub-task wants to finish early and still complete.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_finished(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(priv->id != NULL);
|
||||
|
||||
/* is already at 100%? */
|
||||
if (priv->step_now == priv->step_max)
|
||||
return;
|
||||
|
||||
/* all done */
|
||||
priv->step_now = priv->step_max;
|
||||
fu_progress_set_percentage(self, 100);
|
||||
fu_progress_set_status(self, FWUPD_STATUS_UNKNOWN);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
fu_progress_discrete_to_percent(guint discrete, guint step_max)
|
||||
{
|
||||
/* check we are in range */
|
||||
if (discrete > step_max)
|
||||
return 100;
|
||||
if (step_max == 0) {
|
||||
g_warning("step_max is 0!");
|
||||
return 0;
|
||||
}
|
||||
return ((gdouble)discrete * (100.0f / (gdouble)(step_max)));
|
||||
}
|
||||
|
||||
static gdouble
|
||||
fu_progress_get_step_percentage(FuProgress *self, guint idx)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
guint current = 0;
|
||||
guint total = 0;
|
||||
|
||||
for (guint i = 0; i < priv->steps->len; i++) {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, i);
|
||||
if (i <= idx)
|
||||
current += step->value;
|
||||
total += step->value;
|
||||
}
|
||||
return ((gdouble)current * 100.f) / (gdouble)total;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_child_status_changed_cb(FuProgress *child, FwupdStatus status, FuProgress *self)
|
||||
{
|
||||
fu_progress_set_status(self, status);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_child_percentage_changed_cb(FuProgress *child, guint percentage, FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
gdouble offset;
|
||||
gdouble range;
|
||||
gdouble extra;
|
||||
guint parent_percentage;
|
||||
|
||||
/* propagate up the stack if FuProgress has only one step */
|
||||
if (priv->step_max == 1) {
|
||||
fu_progress_set_percentage(self, percentage);
|
||||
return;
|
||||
}
|
||||
|
||||
/* did we call done on a self that did not have a size set? */
|
||||
if (priv->step_max == 0)
|
||||
return;
|
||||
|
||||
/* already at >= 100% */
|
||||
if (priv->step_now >= priv->step_max) {
|
||||
g_warning("already at %u/%u step_max", priv->step_now, priv->step_max);
|
||||
return;
|
||||
}
|
||||
|
||||
/* we have to deal with non-linear step_max */
|
||||
if (priv->steps->len > 0) {
|
||||
/* we don't store zero */
|
||||
if (priv->step_now == 0) {
|
||||
gdouble pc = fu_progress_get_step_percentage(self, 0);
|
||||
parent_percentage = percentage * pc / 100;
|
||||
} else {
|
||||
gdouble pc1 = fu_progress_get_step_percentage(self, priv->step_now - 1);
|
||||
gdouble pc2 = fu_progress_get_step_percentage(self, priv->step_now);
|
||||
/* bi-linearly interpolate */
|
||||
parent_percentage = (((100 - percentage) * pc1) + (percentage * pc2)) / 100;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get the offset */
|
||||
offset = fu_progress_discrete_to_percent(priv->step_now, priv->step_max);
|
||||
|
||||
/* get the range between the parent step and the next parent step */
|
||||
range = fu_progress_discrete_to_percent(priv->step_now + 1, priv->step_max) - offset;
|
||||
if (range < 0.01)
|
||||
return;
|
||||
|
||||
/* get the extra contributed by the child */
|
||||
extra = ((gdouble)percentage / 100.0f) * range;
|
||||
|
||||
/* emit from the parent */
|
||||
parent_percentage = (guint)(offset + extra);
|
||||
out:
|
||||
fu_progress_set_percentage(self, parent_percentage);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_set_parent(FuProgress *self, FuProgress *parent)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
priv->parent = parent; /* no ref! */
|
||||
priv->profile = fu_progress_get_profile(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_get_child:
|
||||
* @self: A #FuProgress
|
||||
*
|
||||
* Monitor a child and proxy back up to the parent with the correct percentage.
|
||||
*
|
||||
* Return value: (transfer none): A new %FuProgress or %NULL for failure
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
FuProgress *
|
||||
fu_progress_get_child(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
|
||||
g_return_val_if_fail(FU_IS_PROGRESS(self), NULL);
|
||||
g_return_val_if_fail(priv->id != NULL, NULL);
|
||||
|
||||
/* already created child */
|
||||
if (priv->child != NULL)
|
||||
return priv->child;
|
||||
|
||||
/* connect up signals */
|
||||
priv->child = fu_progress_new(NULL);
|
||||
priv->percentage_child_id =
|
||||
g_signal_connect(priv->child,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_progress_child_percentage_changed_cb),
|
||||
self);
|
||||
priv->status_child_id = g_signal_connect(priv->child,
|
||||
"status-changed",
|
||||
G_CALLBACK(fu_progress_child_status_changed_cb),
|
||||
self);
|
||||
fu_progress_set_parent(priv->child, self);
|
||||
return priv->child;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_show_profile(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
gdouble division;
|
||||
gdouble total_time = 0.0f;
|
||||
gboolean close_enough = TRUE;
|
||||
g_autoptr(GString) str = NULL;
|
||||
|
||||
/* not accurate enough for a profile result */
|
||||
if (priv->flags & FU_PROGRESS_FLAG_NO_PROFILE)
|
||||
return;
|
||||
|
||||
/* get the total time so we can work out the divisor */
|
||||
str = g_string_new("raw timing data was { ");
|
||||
for (guint i = 0; i < priv->step_max; i++) {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, i);
|
||||
g_string_append_printf(str, "%.3f, ", step->profile);
|
||||
}
|
||||
if (priv->step_max > 0)
|
||||
g_string_set_size(str, str->len - 2);
|
||||
g_string_append(str, " } -- ");
|
||||
|
||||
/* get the total time so we can work out the divisor */
|
||||
for (guint i = 0; i < priv->step_max; i++) {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, i);
|
||||
total_time += step->profile;
|
||||
}
|
||||
if (total_time < 0.001)
|
||||
return;
|
||||
division = total_time / 100.0f;
|
||||
|
||||
/* what we set */
|
||||
g_string_append(str, "steps were set as [ ");
|
||||
for (guint i = 0; i < priv->step_max; i++) {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, i);
|
||||
g_string_append_printf(str, "%u ", step->value);
|
||||
}
|
||||
|
||||
/* what we _should_ have set */
|
||||
g_string_append_printf(str, "] but should have been [ ");
|
||||
for (guint i = 0; i < priv->step_max; i++) {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, i);
|
||||
g_string_append_printf(str, "%.0f ", step->profile / division);
|
||||
|
||||
/* this is sufficiently different to what we guessed */
|
||||
if (fabs((gdouble)step->value - step->profile / division) > 5)
|
||||
close_enough = FALSE;
|
||||
}
|
||||
g_string_append(str, "]");
|
||||
if (priv->flags & FU_PROGRESS_FLAG_GUESSED) {
|
||||
#ifdef SUPPORTED_BUILD
|
||||
g_debug("%s at %s", str->str, priv->id);
|
||||
#else
|
||||
g_warning("%s at %s", str->str, priv->id);
|
||||
g_warning("Please see "
|
||||
"https://github.com/fwupd/fwupd/wiki/Daemon-Warning:-FuProgress-steps");
|
||||
#endif
|
||||
} else if (!close_enough) {
|
||||
g_debug("%s at %s", str->str, priv->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_step_done:
|
||||
* @self: A #FuProgress
|
||||
*
|
||||
* Called when the step_now sub-task has finished.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_step_done(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
gdouble percentage;
|
||||
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(priv->id != NULL);
|
||||
|
||||
/* did we call done on a self that did not have a size set? */
|
||||
if (priv->step_max == 0) {
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
fu_progress_build_parent_chain(self, str, 0);
|
||||
g_warning("progress done when no size set! [%s]: %s", priv->id, str->str);
|
||||
return;
|
||||
}
|
||||
|
||||
/* save the duration in the array */
|
||||
if (priv->profile) {
|
||||
if (priv->steps->len > 0) {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, priv->step_now);
|
||||
step->profile = g_timer_elapsed(priv->timer, NULL);
|
||||
}
|
||||
g_timer_start(priv->timer);
|
||||
}
|
||||
|
||||
/* is already at 100%? */
|
||||
if (priv->step_now >= priv->step_max) {
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
fu_progress_build_parent_chain(self, str, 0);
|
||||
g_warning("already at 100%% [%s]: %s", priv->id, str->str);
|
||||
return;
|
||||
}
|
||||
|
||||
/* is child not at 100%? */
|
||||
if (priv->child != NULL) {
|
||||
FuProgressPrivate *child_priv = GET_PRIVATE(priv->child);
|
||||
if (child_priv->step_now != child_priv->step_max) {
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
fu_progress_build_parent_chain(priv->child, str, 0);
|
||||
g_warning("child is at %u/%u step_max and parent done [%s]\n%s",
|
||||
child_priv->step_now,
|
||||
child_priv->step_max,
|
||||
priv->id,
|
||||
str->str);
|
||||
/* do not abort, as we want to clean this up */
|
||||
}
|
||||
}
|
||||
|
||||
/* another */
|
||||
priv->step_now++;
|
||||
|
||||
/* update status */
|
||||
if (priv->steps->len > 0) {
|
||||
if (priv->step_now == priv->step_max) {
|
||||
fu_progress_set_status(self, FWUPD_STATUS_UNKNOWN);
|
||||
} else {
|
||||
FuProgressStep *step = g_ptr_array_index(priv->steps, priv->step_now);
|
||||
fu_progress_set_status(self, step->status);
|
||||
}
|
||||
}
|
||||
|
||||
/* find new percentage */
|
||||
if (priv->steps->len == 0) {
|
||||
percentage = fu_progress_discrete_to_percent(priv->step_now, priv->step_max);
|
||||
} else {
|
||||
percentage = fu_progress_get_step_percentage(self, priv->step_now - 1);
|
||||
}
|
||||
fu_progress_set_percentage(self, (guint)percentage);
|
||||
|
||||
/* show any profiling stats */
|
||||
if (priv->profile && priv->step_now == priv->step_max && priv->steps->len > 0)
|
||||
fu_progress_show_profile(self);
|
||||
|
||||
/* reset child if it exists */
|
||||
if (priv->child != NULL)
|
||||
fu_progress_reset(priv->child);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_sleep:
|
||||
* @self: a #FuProgress
|
||||
* @delay_ms: the delay in milliseconds
|
||||
*
|
||||
* Sleeps, setting the device progress from 0..100% as time continues.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
void
|
||||
fu_progress_sleep(FuProgress *self, guint delay_ms)
|
||||
{
|
||||
gulong delay_us_pc = (delay_ms * 1000) / 100;
|
||||
|
||||
g_return_if_fail(FU_IS_PROGRESS(self));
|
||||
g_return_if_fail(delay_ms > 0);
|
||||
|
||||
fu_progress_set_percentage(self, 0);
|
||||
for (guint i = 0; i < 100; i++) {
|
||||
g_usleep(delay_us_pc);
|
||||
fu_progress_set_percentage(self, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_init(FuProgress *self)
|
||||
{
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
priv->timer = g_timer_new();
|
||||
priv->steps = g_ptr_array_new_with_free_func(g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_finalize(GObject *object)
|
||||
{
|
||||
FuProgress *self = FU_PROGRESS(object);
|
||||
FuProgressPrivate *priv = GET_PRIVATE(self);
|
||||
|
||||
fu_progress_reset(self);
|
||||
g_free(priv->id);
|
||||
g_ptr_array_unref(priv->steps);
|
||||
g_timer_destroy(priv->timer);
|
||||
|
||||
G_OBJECT_CLASS(fu_progress_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_class_init(FuProgressClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->finalize = fu_progress_finalize;
|
||||
|
||||
signals[SIGNAL_PERCENTAGE_CHANGED] =
|
||||
g_signal_new("percentage-changed",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(FuProgressClass, percentage_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_UINT);
|
||||
signals[SIGNAL_STATUS_CHANGED] =
|
||||
g_signal_new("status-changed",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(FuProgressClass, status_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_UINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progress_new:
|
||||
* @id: (nullable): progress ID, normally `G_STRLOC`
|
||||
*
|
||||
* Return value: A new #FuProgress instance.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
**/
|
||||
FuProgress *
|
||||
fu_progress_new(const gchar *id)
|
||||
{
|
||||
FuProgress *self;
|
||||
self = g_object_new(FU_TYPE_PROGRESS, NULL);
|
||||
if (id != NULL)
|
||||
fu_progress_set_id(self, id);
|
||||
return FU_PROGRESS(self);
|
||||
}
|
110
libfwupdplugin/fu-progress.h
Normal file
110
libfwupdplugin/fu-progress.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupd.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define FU_TYPE_PROGRESS (fu_progress_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(FuProgress, fu_progress, FU, PROGRESS, GObject)
|
||||
|
||||
struct _FuProgressClass {
|
||||
GObjectClass parent_class;
|
||||
/* signals */
|
||||
void (*percentage_changed)(FuProgress *self, guint value);
|
||||
void (*status_changed)(FuProgress *self, FwupdStatus status);
|
||||
/*< private >*/
|
||||
gpointer padding[29];
|
||||
};
|
||||
|
||||
/**
|
||||
* FuProgressFlags:
|
||||
*
|
||||
* The progress internal flags.
|
||||
**/
|
||||
typedef guint64 FuProgressFlags;
|
||||
|
||||
/**
|
||||
* FU_PROGRESS_FLAG_NONE:
|
||||
*
|
||||
* No flags set.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
*/
|
||||
#define FU_PROGRESS_FLAG_NONE (0)
|
||||
|
||||
/**
|
||||
* FU_PROGRESS_FLAG_UNKNOWN:
|
||||
*
|
||||
* Unknown flag value.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
*/
|
||||
#define FU_PROGRESS_FLAG_UNKNOWN G_MAXUINT64
|
||||
|
||||
/**
|
||||
* FU_PROGRESS_FLAG_GUESSED:
|
||||
*
|
||||
* The steps have not been measured on real hardware and have been guessed.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
*/
|
||||
#define FU_PROGRESS_FLAG_GUESSED (1ull << 0)
|
||||
|
||||
/**
|
||||
* FU_PROGRESS_FLAG_NO_PROFILE:
|
||||
*
|
||||
* The steps cannot be accurate enough for a profile result.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
*/
|
||||
#define FU_PROGRESS_FLAG_NO_PROFILE (1ull << 1)
|
||||
|
||||
FuProgress *
|
||||
fu_progress_new(const gchar *id);
|
||||
const gchar *
|
||||
fu_progress_get_id(FuProgress *self);
|
||||
void
|
||||
fu_progress_set_id(FuProgress *self, const gchar *id);
|
||||
const gchar *
|
||||
fu_progress_flag_to_string(FuProgressFlags flag);
|
||||
FuProgressFlags
|
||||
fu_progress_flag_from_string(const gchar *flag);
|
||||
void
|
||||
fu_progress_add_flag(FuProgress *self, FuProgressFlags flag);
|
||||
void
|
||||
fu_progress_remove_flag(FuProgress *self, FuProgressFlags flag);
|
||||
gboolean
|
||||
fu_progress_has_flag(FuProgress *self, FuProgressFlags flag);
|
||||
FwupdStatus
|
||||
fu_progress_get_status(FuProgress *self);
|
||||
void
|
||||
fu_progress_set_status(FuProgress *self, FwupdStatus status);
|
||||
void
|
||||
fu_progress_set_percentage(FuProgress *self, guint percentage);
|
||||
void
|
||||
fu_progress_set_percentage_full(FuProgress *self, gsize progress_done, gsize progress_total);
|
||||
guint
|
||||
fu_progress_get_percentage(FuProgress *self);
|
||||
void
|
||||
fu_progress_set_profile(FuProgress *self, gboolean profile);
|
||||
void
|
||||
fu_progress_reset(FuProgress *self);
|
||||
void
|
||||
fu_progress_set_steps(FuProgress *self, guint step_max);
|
||||
guint
|
||||
fu_progress_get_steps(FuProgress *self);
|
||||
void
|
||||
fu_progress_add_step(FuProgress *self, FwupdStatus status, guint value);
|
||||
void
|
||||
fu_progress_finished(FuProgress *self);
|
||||
void
|
||||
fu_progress_step_done(FuProgress *self);
|
||||
FuProgress *
|
||||
fu_progress_get_child(FuProgress *self);
|
||||
void
|
||||
fu_progress_sleep(FuProgress *self, guint delay_ms);
|
@ -3401,6 +3401,223 @@ fu_ifd_image_xml_func(void)
|
||||
g_assert_cmpstr(csum1, ==, csum2);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
guint last_percentage;
|
||||
guint updates;
|
||||
} FuProgressHelper;
|
||||
|
||||
static void
|
||||
fu_progress_percentage_changed_cb(FuProgress *progress, guint percentage, gpointer data)
|
||||
{
|
||||
FuProgressHelper *helper = (FuProgressHelper *)data;
|
||||
helper->last_percentage = percentage;
|
||||
helper->updates++;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_func(void)
|
||||
{
|
||||
FuProgressHelper helper = {0};
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
g_signal_connect(progress,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_progress_percentage_changed_cb),
|
||||
&helper);
|
||||
|
||||
fu_progress_set_steps(progress, 5);
|
||||
|
||||
fu_progress_step_done(progress);
|
||||
g_assert_cmpint(helper.updates, ==, 1);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 20);
|
||||
|
||||
for (guint i = 0; i < 4; i++)
|
||||
fu_progress_step_done(progress);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 100);
|
||||
g_assert_cmpint(helper.updates, ==, 5);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_child_func(void)
|
||||
{
|
||||
FuProgressHelper helper = {0};
|
||||
FuProgress *child;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* reset */
|
||||
fu_progress_set_steps(progress, 2);
|
||||
g_signal_connect(progress,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_progress_percentage_changed_cb),
|
||||
&helper);
|
||||
|
||||
/* parent: |-----------------------|-----------------------|
|
||||
* step1: |-----------------------|
|
||||
* child: |-------------|---------|
|
||||
*/
|
||||
|
||||
/* PARENT UPDATE */
|
||||
g_debug("parent update #1");
|
||||
fu_progress_step_done(progress);
|
||||
g_assert_cmpint(helper.updates, ==, 1);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 50);
|
||||
|
||||
/* now test with a child */
|
||||
child = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(child, G_STRLOC);
|
||||
fu_progress_set_steps(child, 2);
|
||||
|
||||
g_debug("child update #1");
|
||||
fu_progress_step_done(child);
|
||||
g_assert_cmpint(helper.updates, ==, 2);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 75);
|
||||
|
||||
/* child update */
|
||||
g_debug("child update #2");
|
||||
fu_progress_step_done(child);
|
||||
g_assert_cmpint(helper.updates, ==, 3);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 100);
|
||||
|
||||
/* parent update */
|
||||
g_debug("parent update #2");
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* ensure we ignored the duplicate */
|
||||
g_assert_cmpint(helper.updates, ==, 3);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 100);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_parent_one_step_proxy_func(void)
|
||||
{
|
||||
FuProgressHelper helper = {0};
|
||||
FuProgress *child;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* one step */
|
||||
fu_progress_set_steps(progress, 1);
|
||||
g_signal_connect(progress,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_progress_percentage_changed_cb),
|
||||
&helper);
|
||||
|
||||
/* now test with a child */
|
||||
child = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(child, G_STRLOC);
|
||||
fu_progress_set_steps(child, 2);
|
||||
|
||||
/* child set value */
|
||||
fu_progress_set_percentage(child, 33);
|
||||
|
||||
/* ensure 1 updates for progress with one step and ensure using child value as parent */
|
||||
g_assert_cmpint(helper.updates, ==, 1);
|
||||
g_assert_cmpint(helper.last_percentage, ==, 33);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_non_equal_steps_func(void)
|
||||
{
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
FuProgress *child;
|
||||
FuProgress *grandchild;
|
||||
|
||||
/* test non-equal steps */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 20);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 60);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 20);
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 0);
|
||||
g_assert_cmpint(fu_progress_get_status(progress), ==, FWUPD_STATUS_DEVICE_ERASE);
|
||||
|
||||
/* child step should increment according to the custom steps */
|
||||
child = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(child, G_STRLOC);
|
||||
fu_progress_set_steps(child, 2);
|
||||
|
||||
/* start child */
|
||||
fu_progress_step_done(child);
|
||||
|
||||
/* verify 10% */
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 10);
|
||||
|
||||
/* finish child */
|
||||
fu_progress_step_done(child);
|
||||
|
||||
fu_progress_step_done(progress);
|
||||
g_assert_cmpint(fu_progress_get_status(progress), ==, FWUPD_STATUS_DEVICE_WRITE);
|
||||
|
||||
/* verify 20% */
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 20);
|
||||
|
||||
/* child step should increment according to the custom steps */
|
||||
child = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(child, G_STRLOC);
|
||||
fu_progress_set_id(child, G_STRLOC);
|
||||
fu_progress_add_step(child, FWUPD_STATUS_DEVICE_RESTART, 25);
|
||||
fu_progress_add_step(child, FWUPD_STATUS_DEVICE_WRITE, 75);
|
||||
g_assert_cmpint(fu_progress_get_status(progress), ==, FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
/* start child */
|
||||
fu_progress_step_done(child);
|
||||
g_assert_cmpint(fu_progress_get_status(progress), ==, FWUPD_STATUS_DEVICE_WRITE);
|
||||
|
||||
/* verify bilinear interpolation is working */
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 35);
|
||||
|
||||
/*
|
||||
* 0 20 80 100
|
||||
* |---------||----------------------------||---------|
|
||||
* | 35 |
|
||||
* |-------||-------------------| (25%)
|
||||
* | 75.5 |
|
||||
* |---------------||--| (90%)
|
||||
*/
|
||||
grandchild = fu_progress_get_child(child);
|
||||
fu_progress_set_id(grandchild, G_STRLOC);
|
||||
fu_progress_add_step(grandchild, FWUPD_STATUS_DEVICE_ERASE, 90);
|
||||
fu_progress_add_step(grandchild, FWUPD_STATUS_DEVICE_WRITE, 10);
|
||||
|
||||
fu_progress_step_done(grandchild);
|
||||
|
||||
/* verify bilinear interpolation (twice) is working for subpercentage */
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 75);
|
||||
|
||||
fu_progress_step_done(grandchild);
|
||||
|
||||
/* finish child */
|
||||
fu_progress_step_done(child);
|
||||
|
||||
fu_progress_step_done(progress);
|
||||
g_assert_cmpint(fu_progress_get_status(progress), ==, FWUPD_STATUS_DEVICE_READ);
|
||||
|
||||
/* verify 80% */
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 80);
|
||||
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify 100% */
|
||||
g_assert_cmpint(fu_progress_get_percentage(progress), ==, 100);
|
||||
g_assert_cmpint(fu_progress_get_status(progress), ==, FWUPD_STATUS_UNKNOWN);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progress_finish_func(void)
|
||||
{
|
||||
FuProgress *child;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* check straight finish */
|
||||
fu_progress_set_steps(progress, 3);
|
||||
|
||||
child = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(child, G_STRLOC);
|
||||
fu_progress_set_steps(child, 3);
|
||||
fu_progress_finished(child);
|
||||
|
||||
/* parent step done after child finish */
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -3416,6 +3633,11 @@ main(int argc, char **argv)
|
||||
g_setenv("FWUPD_OFFLINE_TRIGGER", "/tmp/fwupd-self-test/system-update", TRUE);
|
||||
g_setenv("FWUPD_LOCALSTATEDIR", "/tmp/fwupd-self-test/var", TRUE);
|
||||
|
||||
g_test_add_func("/fwupd/progress", fu_progress_func);
|
||||
g_test_add_func("/fwupd/progress{child}", fu_progress_child_func);
|
||||
g_test_add_func("/fwupd/progress{parent-1-step}", fu_progress_parent_one_step_proxy_func);
|
||||
g_test_add_func("/fwupd/progress{no-equal}", fu_progress_non_equal_steps_func);
|
||||
g_test_add_func("/fwupd/progress{finish}", fu_progress_finish_func);
|
||||
g_test_add_func("/fwupd/security-attrs{hsi}", fu_security_attrs_hsi_func);
|
||||
g_test_add_func("/fwupd/plugin{devices}", fu_plugin_devices_func);
|
||||
g_test_add_func("/fwupd/plugin{device-inhibit-children}",
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <libfwupdplugin/fu-io-channel.h>
|
||||
#include <libfwupdplugin/fu-plugin-vfuncs.h>
|
||||
#include <libfwupdplugin/fu-plugin.h>
|
||||
#include <libfwupdplugin/fu-progress.h>
|
||||
#include <libfwupdplugin/fu-security-attrs.h>
|
||||
#include <libfwupdplugin/fu-srec-firmware.h>
|
||||
#include <libfwupdplugin/fu-udev-device.h>
|
||||
|
@ -150,11 +150,6 @@ LIBFWUPDPLUGIN_1.0.3 {
|
||||
fu_common_read_uint32;
|
||||
fu_common_write_uint16;
|
||||
fu_common_write_uint32;
|
||||
fu_device_get_progress;
|
||||
fu_device_get_status;
|
||||
fu_device_set_progress;
|
||||
fu_device_set_progress_full;
|
||||
fu_device_set_status;
|
||||
fu_usb_device_is_open;
|
||||
local: *;
|
||||
} LIBFWUPDPLUGIN_1.0.2;
|
||||
@ -550,7 +545,6 @@ LIBFWUPDPLUGIN_1.5.0 {
|
||||
fu_device_dump_firmware;
|
||||
fu_device_report_metadata_post;
|
||||
fu_device_report_metadata_pre;
|
||||
fu_device_sleep_with_progress;
|
||||
fu_device_unbind_driver;
|
||||
fu_efivar_get_data_bytes;
|
||||
fu_efivar_secure_boot_enabled_full;
|
||||
@ -867,6 +861,7 @@ LIBFWUPDPLUGIN_1.6.2 {
|
||||
|
||||
LIBFWUPDPLUGIN_1.7.0 {
|
||||
global:
|
||||
fu_device_set_progress;
|
||||
fu_plugin_runner_attach;
|
||||
fu_plugin_runner_cleanup;
|
||||
fu_plugin_runner_detach;
|
||||
@ -874,5 +869,28 @@ LIBFWUPDPLUGIN_1.7.0 {
|
||||
fu_plugin_runner_reload;
|
||||
fu_plugin_runner_write_firmware;
|
||||
fu_plugin_set_config_value;
|
||||
fu_progress_add_flag;
|
||||
fu_progress_add_step;
|
||||
fu_progress_finished;
|
||||
fu_progress_flag_from_string;
|
||||
fu_progress_flag_to_string;
|
||||
fu_progress_get_child;
|
||||
fu_progress_get_id;
|
||||
fu_progress_get_percentage;
|
||||
fu_progress_get_status;
|
||||
fu_progress_get_steps;
|
||||
fu_progress_get_type;
|
||||
fu_progress_has_flag;
|
||||
fu_progress_new;
|
||||
fu_progress_remove_flag;
|
||||
fu_progress_reset;
|
||||
fu_progress_set_id;
|
||||
fu_progress_set_percentage;
|
||||
fu_progress_set_percentage_full;
|
||||
fu_progress_set_profile;
|
||||
fu_progress_set_status;
|
||||
fu_progress_set_steps;
|
||||
fu_progress_sleep;
|
||||
fu_progress_step_done;
|
||||
local: *;
|
||||
} LIBFWUPDPLUGIN_1.6.2;
|
||||
|
@ -28,6 +28,7 @@ fwupdplugin_src = [
|
||||
'fu-io-channel.c', # fuzzing
|
||||
'fu-plugin.c',
|
||||
'fu-quirks.c', # fuzzing
|
||||
'fu-progress.c', # fuzzing
|
||||
'fu-security-attrs.c',
|
||||
'fu-smbios.c', # fuzzing
|
||||
'fu-srec-firmware.c', # fuzzing
|
||||
@ -101,6 +102,7 @@ fwupdplugin_headers = [
|
||||
'fu-plugin.h',
|
||||
'fu-quirks.h',
|
||||
'fu-security-attrs.h',
|
||||
'fu-progress.h',
|
||||
'fu-smbios.h',
|
||||
'fu-srec-firmware.h',
|
||||
'fu-efi-signature.h',
|
||||
|
@ -238,6 +238,7 @@ fu_altos_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_altos_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -258,6 +259,13 @@ fu_altos_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* open */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* attach */
|
||||
|
||||
/* check sizes */
|
||||
if (self->addr_base == 0x0 || self->addr_bound == 0x0) {
|
||||
g_set_error_literal(error,
|
||||
@ -311,7 +319,8 @@ fu_altos_device_write_firmware(FuDevice *device,
|
||||
error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
for (guint i = 0; i < flash_len; i += 0x100) {
|
||||
g_autoptr(GString) str = NULL;
|
||||
guint8 buf_tmp[0x100];
|
||||
@ -360,23 +369,24 @@ fu_altos_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_device_set_progress_full(device, i, flash_len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 0x100,
|
||||
flash_len);
|
||||
g_string_append_len(buf, str->str, str->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* go to application mode */
|
||||
if (!fu_altos_device_tty_write(self, "a\n", -1, error))
|
||||
return FALSE;
|
||||
|
||||
/* progress complete */
|
||||
fu_device_set_progress_full(device, flash_len, flash_len);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_altos_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_altos_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuAltosDevice *self = FU_ALTOS_DEVICE(device);
|
||||
guint flash_len;
|
||||
@ -427,9 +437,9 @@ fu_altos_device_dump_firmware(FuDevice *device, GError **error)
|
||||
return NULL;
|
||||
|
||||
/* progress */
|
||||
fu_device_set_progress_full(device,
|
||||
i - self->addr_base,
|
||||
self->addr_bound - self->addr_base);
|
||||
fu_progress_set_percentage_full(progress,
|
||||
i - self->addr_base,
|
||||
self->addr_bound - self->addr_base);
|
||||
g_string_append_len(buf, str->str, str->len);
|
||||
}
|
||||
|
||||
@ -542,6 +552,17 @@ fu_altos_device_probe(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_device_init(FuAltosDevice *self)
|
||||
{
|
||||
@ -567,5 +588,6 @@ fu_altos_device_class_init(FuAltosDeviceClass *klass)
|
||||
klass_device->prepare_firmware = fu_altos_device_prepare_firmware;
|
||||
klass_device->write_firmware = fu_altos_device_write_firmware;
|
||||
klass_device->dump_firmware = fu_altos_device_dump_firmware;
|
||||
klass_device->set_progress = fu_altos_device_set_progress;
|
||||
object_class->finalize = fu_altos_device_finalize;
|
||||
}
|
||||
|
@ -275,6 +275,7 @@ static gboolean
|
||||
fu_analogix_device_write_image(FuAnalogixDevice *self,
|
||||
FuFirmware *image,
|
||||
guint16 req_val,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
AnxUpdateStatus status = UPDATE_STATUS_INVALID;
|
||||
@ -282,6 +283,12 @@ fu_analogix_device_write_image(FuAnalogixDevice *self,
|
||||
g_autoptr(GBytes) block_bytes = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 10); /* initialization */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
|
||||
/* offset into firmware */
|
||||
block_bytes = fu_firmware_get_bytes(image, error);
|
||||
if (block_bytes == NULL)
|
||||
@ -301,9 +308,9 @@ fu_analogix_device_write_image(FuAnalogixDevice *self,
|
||||
}
|
||||
if (!fu_analogix_device_get_update_status(self, &status, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write data */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(block_bytes, 0x00, 0x00, BILLBOARD_MAX_PACKET_SIZE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
@ -321,8 +328,11 @@ fu_analogix_device_write_image(FuAnalogixDevice *self,
|
||||
g_prefix_error(error, "failed status on chk %u: ", i);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(FU_DEVICE(self), i, chunks->len - 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 1,
|
||||
chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -331,6 +341,7 @@ fu_analogix_device_write_image(FuAnalogixDevice *self,
|
||||
static gboolean
|
||||
fu_analogix_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -340,44 +351,69 @@ fu_analogix_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(FuFirmware) fw_srx = NULL;
|
||||
g_autoptr(FuFirmware) fw_stx = NULL;
|
||||
|
||||
/* OCM -> SECURE_TX -> SECURE_RX -> CUSTOM_DEF */
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 25); /* cus */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 25); /* stx */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 25); /* srx */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 25); /* ocm */
|
||||
|
||||
/* CUSTOM_DEF */
|
||||
fw_cus = fu_firmware_get_image_by_id(firmware, "custom", NULL);
|
||||
if (fw_cus != NULL) {
|
||||
if (!fu_analogix_device_write_image(self,
|
||||
fw_cus,
|
||||
ANX_BB_WVAL_UPDATE_CUSTOM_DEF,
|
||||
fu_progress_get_child(progress),
|
||||
error)) {
|
||||
g_prefix_error(error, "program custom define failed: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* SECURE_TX */
|
||||
fw_stx = fu_firmware_get_image_by_id(firmware, "stx", NULL);
|
||||
if (fw_stx != NULL) {
|
||||
if (!fu_analogix_device_write_image(self,
|
||||
fw_stx,
|
||||
ANX_BB_WVAL_UPDATE_SECURE_TX,
|
||||
fu_progress_get_child(progress),
|
||||
error)) {
|
||||
g_prefix_error(error, "program secure TX failed: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* SECURE_RX */
|
||||
fw_srx = fu_firmware_get_image_by_id(firmware, "srx", NULL);
|
||||
if (fw_srx != NULL) {
|
||||
if (!fu_analogix_device_write_image(self,
|
||||
fw_srx,
|
||||
ANX_BB_WVAL_UPDATE_SECURE_RX,
|
||||
fu_progress_get_child(progress),
|
||||
error)) {
|
||||
g_prefix_error(error, "program secure RX failed: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* OCM */
|
||||
fw_ocm = fu_firmware_get_image_by_id(firmware, "ocm", NULL);
|
||||
if (fw_ocm != NULL) {
|
||||
if (!fu_analogix_device_write_image(self, fw_ocm, ANX_BB_WVAL_UPDATE_OCM, error)) {
|
||||
if (!fu_analogix_device_write_image(self,
|
||||
fw_ocm,
|
||||
ANX_BB_WVAL_UPDATE_OCM,
|
||||
fu_progress_get_child(progress),
|
||||
error)) {
|
||||
g_prefix_error(error, "program OCM failed: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -402,6 +438,17 @@ fu_analogix_device_close(FuDevice *device, GError **error)
|
||||
return FU_DEVICE_CLASS(fu_analogix_device_parent_class)->close(device, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_analogix_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_analogix_device_init(FuAnalogixDevice *self)
|
||||
{
|
||||
@ -423,4 +470,5 @@ fu_analogix_device_class_init(FuAnalogixDeviceClass *klass)
|
||||
klass_device->probe = fu_analogix_device_probe;
|
||||
klass_device->prepare_firmware = fu_analogix_device_prepare_firmware;
|
||||
klass_device->close = fu_analogix_device_close;
|
||||
klass_device->set_progress = fu_analogix_device_set_progress;
|
||||
}
|
||||
|
@ -654,7 +654,7 @@ fu_ata_device_setup(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ata_device_activate(FuDevice *device, GError **error)
|
||||
fu_ata_device_activate(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuAtaDevice *self = FU_ATA_DEVICE(device);
|
||||
struct ata_tf tf = {0x0};
|
||||
@ -760,6 +760,7 @@ fu_ata_device_fw_download(FuAtaDevice *self,
|
||||
static gboolean
|
||||
fu_ata_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -797,7 +798,7 @@ fu_ata_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(fw, 0x00, 0x00, chunksz);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
@ -810,12 +811,11 @@ fu_ata_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to write chunk %u: ", i);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len + 1);
|
||||
fu_progress_set_percentage_full(progress, (gsize)i + 1, (gsize)chunks->len);
|
||||
}
|
||||
|
||||
/* success! */
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION);
|
||||
fu_device_set_progress(device, 100);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -855,6 +855,17 @@ fu_ata_device_set_quirk_kv(FuDevice *device, const gchar *key, const gchar *valu
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ata_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ata_device_init(FuAtaDevice *self)
|
||||
{
|
||||
@ -890,6 +901,7 @@ fu_ata_device_class_init(FuAtaDeviceClass *klass)
|
||||
klass_device->activate = fu_ata_device_activate;
|
||||
klass_device->write_firmware = fu_ata_device_write_firmware;
|
||||
klass_device->probe = fu_ata_device_probe;
|
||||
klass_device->set_progress = fu_ata_device_set_progress;
|
||||
}
|
||||
|
||||
FuAtaDevice *
|
||||
|
@ -300,7 +300,7 @@ fu_bcm57xx_device_nvram_check(FuBcm57xxDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_bcm57xx_device_activate(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_device_activate(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuBcm57xxDevice *self = FU_BCM57XX_DEVICE(device);
|
||||
g_autoptr(FuDeviceLocker) locker1 = NULL;
|
||||
@ -320,7 +320,7 @@ fu_bcm57xx_device_activate(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* activate, causing APE reset, then close, then attach */
|
||||
if (!fu_device_activate(FU_DEVICE(self->recovery), error))
|
||||
if (!fu_device_activate(FU_DEVICE(self->recovery), progress, error))
|
||||
return FALSE;
|
||||
|
||||
/* ensure we attach before we close */
|
||||
@ -328,20 +328,20 @@ fu_bcm57xx_device_activate(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* wait for the device to restart before calling reload() */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
fu_device_sleep_with_progress(device, 5); /* seconds */
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_BUSY);
|
||||
fu_progress_sleep(progress, 5000);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_bcm57xx_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuBcm57xxDevice *self = FU_BCM57XX_DEVICE(device);
|
||||
const gsize bufsz = fu_device_get_firmware_size_max(FU_DEVICE(self));
|
||||
g_autofree guint8 *buf = g_malloc0(bufsz);
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
chunks = fu_chunk_array_mutable_new(buf, bufsz, 0x0, 0x0, FU_BCM57XX_BLOCK_SZ);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
@ -351,7 +351,7 @@ fu_bcm57xx_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_chunk_get_data_sz(chk),
|
||||
error))
|
||||
return NULL;
|
||||
fu_device_set_progress_full(device, i, chunks->len - 1);
|
||||
fu_progress_set_percentage_full(progress, i + 1, chunks->len - 1);
|
||||
}
|
||||
|
||||
/* read from hardware */
|
||||
@ -359,13 +359,13 @@ fu_bcm57xx_device_dump_firmware(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static FuFirmware *
|
||||
fu_bcm57xx_device_read_firmware(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_device_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(FuFirmware) firmware = fu_bcm57xx_firmware_new();
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
|
||||
/* read from hardware */
|
||||
fw = fu_bcm57xx_device_dump_firmware(device, error);
|
||||
fw = fu_bcm57xx_device_dump_firmware(device, progress, error);
|
||||
if (fw == NULL)
|
||||
return NULL;
|
||||
if (!fu_firmware_parse(firmware, fw, FWUPD_INSTALL_FLAG_NONE, error))
|
||||
@ -394,6 +394,7 @@ fu_bcm57xx_device_prepare_firmware(FuDevice *device,
|
||||
g_autoptr(FuFirmware) img_ape = NULL;
|
||||
g_autoptr(FuFirmware) img_stage1 = NULL;
|
||||
g_autoptr(FuFirmware) img_stage2 = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GPtrArray) images = NULL;
|
||||
|
||||
/* try to parse NVRAM, stage1 or APE */
|
||||
@ -423,7 +424,7 @@ fu_bcm57xx_device_prepare_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* get the existing firmware from the device */
|
||||
fw_old = fu_bcm57xx_device_dump_firmware(device, error);
|
||||
fw_old = fu_bcm57xx_device_dump_firmware(device, progress, error);
|
||||
if (fw_old == NULL)
|
||||
return NULL;
|
||||
if (!fu_firmware_parse(firmware, fw_old, flags, error)) {
|
||||
@ -467,6 +468,7 @@ fu_bcm57xx_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_bcm57xx_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -475,14 +477,21 @@ fu_bcm57xx_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) blob_verify = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DECOMPRESSING, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 80);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 19);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2);
|
||||
|
||||
/* build the images into one linear blob of the correct size */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DECOMPRESSING);
|
||||
blob = fu_firmware_write(firmware, error);
|
||||
if (blob == NULL)
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* hit hardware */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(blob, 0x0, 0x0, FU_BCM57XX_BLOCK_SZ);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
@ -492,19 +501,28 @@ fu_bcm57xx_device_write_firmware(FuDevice *device,
|
||||
fu_chunk_get_data_sz(chk),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, i, chunks->len - 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 1,
|
||||
chunks->len - 1);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
blob_verify = fu_bcm57xx_device_dump_firmware(device, error);
|
||||
blob_verify =
|
||||
fu_bcm57xx_device_dump_firmware(device, fu_progress_get_child(progress), error);
|
||||
if (blob_verify == NULL)
|
||||
return FALSE;
|
||||
if (!fu_common_bytes_compare(blob, blob_verify, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* reset APE */
|
||||
return fu_device_activate(device, error);
|
||||
if (!fu_device_activate(device, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -616,6 +634,17 @@ fu_bcm57xx_device_close(FuDevice *device, GError **error)
|
||||
return g_close(self->ethtool_fd, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_bcm57xx_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_bcm57xx_device_init(FuBcm57xxDevice *self)
|
||||
{
|
||||
@ -654,4 +683,5 @@ fu_bcm57xx_device_class_init(FuBcm57xxDeviceClass *klass)
|
||||
klass_device->dump_firmware = fu_bcm57xx_device_dump_firmware;
|
||||
klass_device->probe = fu_bcm57xx_device_probe;
|
||||
klass_device->to_string = fu_bcm57xx_device_to_string;
|
||||
klass_device->set_progress = fu_bcm57xx_device_set_progress;
|
||||
}
|
||||
|
@ -341,6 +341,7 @@ fu_bcm57xx_recovery_device_nvram_read(FuBcm57xxRecoveryDevice *self,
|
||||
guint32 address,
|
||||
guint32 *buf,
|
||||
gsize bufsz,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
for (guint i = 0; i < bufsz; i++) {
|
||||
@ -376,7 +377,7 @@ fu_bcm57xx_recovery_device_nvram_read(FuBcm57xxRecoveryDevice *self,
|
||||
return FALSE;
|
||||
buf[i] = GUINT32_FROM_BE(val32);
|
||||
address += sizeof(guint32);
|
||||
fu_device_set_progress_full(FU_DEVICE(self), i, bufsz);
|
||||
fu_progress_set_percentage_full(progress, i + 1, bufsz);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -388,6 +389,7 @@ fu_bcm57xx_recovery_device_nvram_write(FuBcm57xxRecoveryDevice *self,
|
||||
guint32 address,
|
||||
const guint32 *buf,
|
||||
gsize bufsz_dwrds,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
const guint32 page_size_dwrds = 64;
|
||||
@ -434,7 +436,7 @@ fu_bcm57xx_recovery_device_nvram_write(FuBcm57xxRecoveryDevice *self,
|
||||
return FALSE;
|
||||
}
|
||||
address += sizeof(guint32);
|
||||
fu_device_set_progress_full(FU_DEVICE(self), i, bufsz_dwrds);
|
||||
fu_progress_set_percentage_full(progress, i + 1, bufsz_dwrds);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -442,14 +444,14 @@ fu_bcm57xx_recovery_device_nvram_write(FuBcm57xxRecoveryDevice *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_bcm57xx_recovery_device_detach(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_recovery_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
/* unbind tg3 */
|
||||
return fu_device_unbind_driver(device, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_bcm57xx_recovery_device_attach(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_recovery_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
@ -470,7 +472,7 @@ fu_bcm57xx_recovery_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_bcm57xx_recovery_device_activate(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_recovery_device_activate(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
BcmRegAPEMode mode = {0};
|
||||
FuBcm57xxRecoveryDevice *self = FU_BCM57XX_RECOVERY_DEVICE(device);
|
||||
@ -497,7 +499,7 @@ fu_bcm57xx_recovery_device_activate(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_bcm57xx_recovery_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_bcm57xx_recovery_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuBcm57xxRecoveryDevice *self = FU_BCM57XX_RECOVERY_DEVICE(device);
|
||||
gsize bufsz_dwrds = fu_device_get_firmware_size_max(FU_DEVICE(self)) / sizeof(guint32);
|
||||
@ -506,7 +508,7 @@ fu_bcm57xx_recovery_device_dump_firmware(FuDevice *device, GError **error)
|
||||
g_autoptr(FuDeviceLocker) locker2 = NULL;
|
||||
|
||||
/* read from hardware */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
locker = fu_device_locker_new_full(
|
||||
self,
|
||||
(FuDeviceLockerFunc)fu_bcm57xx_recovery_device_nvram_acquire_lock,
|
||||
@ -521,7 +523,12 @@ fu_bcm57xx_recovery_device_dump_firmware(FuDevice *device, GError **error)
|
||||
error);
|
||||
if (locker2 == NULL)
|
||||
return NULL;
|
||||
if (!fu_bcm57xx_recovery_device_nvram_read(self, 0x0, buf_dwrds, bufsz_dwrds, error))
|
||||
if (!fu_bcm57xx_recovery_device_nvram_read(self,
|
||||
0x0,
|
||||
buf_dwrds,
|
||||
bufsz_dwrds,
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
if (!fu_device_locker_close(locker2, error))
|
||||
return NULL;
|
||||
@ -557,6 +564,7 @@ fu_bcm57xx_recovery_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_bcm57xx_recovery_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -569,11 +577,18 @@ fu_bcm57xx_recovery_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(FuDeviceLocker) locker2 = NULL;
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DECOMPRESSING, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 95);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 5);
|
||||
|
||||
/* build the images into one linear blob of the correct size */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DECOMPRESSING);
|
||||
blob = fu_firmware_write(firmware, error);
|
||||
if (blob == NULL)
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* align into uint32_t buffer */
|
||||
buf = g_bytes_get_data(blob, &bufsz);
|
||||
@ -590,7 +605,6 @@ fu_bcm57xx_recovery_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* hit hardware */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
locker = fu_device_locker_new_full(
|
||||
self,
|
||||
(FuDeviceLockerFunc)fu_bcm57xx_recovery_device_nvram_acquire_lock,
|
||||
@ -605,15 +619,26 @@ fu_bcm57xx_recovery_device_write_firmware(FuDevice *device,
|
||||
error);
|
||||
if (locker2 == NULL)
|
||||
return FALSE;
|
||||
if (!fu_bcm57xx_recovery_device_nvram_write(self, 0x0, buf_dwrds, bufsz_dwrds, error))
|
||||
if (!fu_bcm57xx_recovery_device_nvram_write(self,
|
||||
0x0,
|
||||
buf_dwrds,
|
||||
bufsz_dwrds,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
if (!fu_device_locker_close(locker2, error))
|
||||
return FALSE;
|
||||
if (!fu_device_locker_close(locker, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* reset APE */
|
||||
return fu_device_activate(device, error);
|
||||
if (!fu_device_activate(device, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -623,6 +648,15 @@ fu_bcm57xx_recovery_device_setup(FuDevice *device, GError **error)
|
||||
guint32 fwversion = 0;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker2 = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 10); /* enable */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 80); /* nvram */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 10); /* veraddr */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 10); /* version */
|
||||
|
||||
locker = fu_device_locker_new_full(
|
||||
self,
|
||||
@ -638,14 +672,17 @@ fu_bcm57xx_recovery_device_setup(FuDevice *device, GError **error)
|
||||
error);
|
||||
if (locker2 == NULL)
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* get NVRAM version */
|
||||
if (!fu_bcm57xx_recovery_device_nvram_read(self,
|
||||
BCM_NVRAM_STAGE1_BASE + BCM_NVRAM_STAGE1_VERSION,
|
||||
&fwversion,
|
||||
1,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
if (fwversion != 0x0) {
|
||||
g_autofree gchar *fwversion_str = NULL;
|
||||
|
||||
@ -656,6 +693,8 @@ fu_bcm57xx_recovery_device_setup(FuDevice *device, GError **error)
|
||||
fu_device_set_version(device, fwversion_str);
|
||||
fu_device_set_version_raw(device, fwversion);
|
||||
fu_device_set_branch(device, BCM_FW_BRANCH_OSS_FIRMWARE);
|
||||
fu_progress_step_done(progress);
|
||||
fu_progress_step_done(progress);
|
||||
} else {
|
||||
guint32 bufver[4] = {0x0};
|
||||
guint32 veraddr = 0;
|
||||
@ -667,8 +706,10 @@ fu_bcm57xx_recovery_device_setup(FuDevice *device, GError **error)
|
||||
BCM_NVRAM_STAGE1_VERADDR,
|
||||
&veraddr,
|
||||
1,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
veraddr = GUINT32_FROM_BE(veraddr);
|
||||
if (veraddr > BCM_PHYS_ADDR_DEFAULT)
|
||||
veraddr -= BCM_PHYS_ADDR_DEFAULT;
|
||||
@ -676,8 +717,10 @@ fu_bcm57xx_recovery_device_setup(FuDevice *device, GError **error)
|
||||
BCM_NVRAM_STAGE1_BASE + veraddr,
|
||||
bufver,
|
||||
4,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
veritem = fu_bcm57xx_veritem_new((guint8 *)bufver, sizeof(bufver));
|
||||
if (veritem != NULL) {
|
||||
fu_device_set_version(device, veritem->version);
|
||||
@ -796,6 +839,17 @@ fu_bcm57xx_recovery_device_close(FuDevice *device, GError **error)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
fu_bcm57xx_recovery_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_bcm57xx_recovery_device_init(FuBcm57xxRecoveryDevice *self)
|
||||
{
|
||||
@ -842,6 +896,7 @@ fu_bcm57xx_recovery_device_class_init(FuBcm57xxRecoveryDeviceClass *klass)
|
||||
klass_device->attach = fu_bcm57xx_recovery_device_attach;
|
||||
klass_device->detach = fu_bcm57xx_recovery_device_detach;
|
||||
klass_device->probe = fu_bcm57xx_recovery_device_probe;
|
||||
klass_device->set_progress = fu_bcm57xx_recovery_device_set_progress;
|
||||
}
|
||||
|
||||
FuBcm57xxRecoveryDevice *
|
||||
|
@ -354,11 +354,68 @@ fu_ccgx_dmc_get_image_write_status_cb(FuDevice *device, gpointer user_data, GErr
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ccgx_dmc_write_firmware_record(FuCcgxDmcDevice *self,
|
||||
FuCcgxDmcFirmwareSegmentRecord *seg_rcd,
|
||||
gsize *fw_data_written,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GPtrArray *data_records = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 99);
|
||||
|
||||
/* write start row and number of rows to a device */
|
||||
if (!fu_ccgx_dmc_device_send_write_command(self,
|
||||
seg_rcd->start_row,
|
||||
seg_rcd->num_rows,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send data records */
|
||||
data_records = seg_rcd->data_records;
|
||||
for (guint32 data_index = 0; data_index < data_records->len; data_index++) {
|
||||
GBytes *data_rcd = g_ptr_array_index(data_records, data_index);
|
||||
const guint8 *row_buffer = NULL;
|
||||
gsize row_size = 0;
|
||||
|
||||
/* write row data */
|
||||
row_buffer = g_bytes_get_data(data_rcd, &row_size);
|
||||
if (!fu_ccgx_dmc_device_send_row_data(self, row_buffer, (guint16)row_size, error))
|
||||
return FALSE;
|
||||
|
||||
/* increase fw written size */
|
||||
*fw_data_written += row_size;
|
||||
|
||||
/* get status */
|
||||
if (!fu_device_retry(FU_DEVICE(self),
|
||||
fu_ccgx_dmc_get_image_write_status_cb,
|
||||
DMC_FW_WRITE_STATUS_RETRY_COUNT,
|
||||
NULL,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* done */
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
data_index + 1,
|
||||
data_records->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ccgx_dmc_write_firmware_image(FuDevice *device,
|
||||
FuCcgxDmcFirmwareRecord *img_rcd,
|
||||
gsize *fw_data_written,
|
||||
const gsize fw_data_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuCcgxDmcDevice *self = FU_CCGX_DMC_DEVICE(device);
|
||||
@ -369,44 +426,17 @@ fu_ccgx_dmc_write_firmware_image(FuDevice *device,
|
||||
|
||||
/* get segment records */
|
||||
seg_records = img_rcd->seg_records;
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, seg_records->len);
|
||||
for (guint32 seg_index = 0; seg_index < seg_records->len; seg_index++) {
|
||||
GPtrArray *data_records = NULL;
|
||||
FuCcgxDmcFirmwareSegmentRecord *seg_rcd = g_ptr_array_index(seg_records, seg_index);
|
||||
|
||||
/* write start row and number of rows to a device */
|
||||
if (!fu_ccgx_dmc_device_send_write_command(self,
|
||||
seg_rcd->start_row,
|
||||
seg_rcd->num_rows,
|
||||
error))
|
||||
if (!fu_ccgx_dmc_write_firmware_record(self,
|
||||
seg_rcd,
|
||||
fw_data_written,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* get data records */
|
||||
data_records = seg_rcd->data_records;
|
||||
for (guint32 data_index = 0; data_index < data_records->len; data_index++) {
|
||||
GBytes *data_rcd = g_ptr_array_index(data_records, data_index);
|
||||
const guint8 *row_buffer = NULL;
|
||||
gsize row_size = 0;
|
||||
|
||||
/* write row data */
|
||||
row_buffer = g_bytes_get_data(data_rcd, &row_size);
|
||||
if (!fu_ccgx_dmc_device_send_row_data(self,
|
||||
row_buffer,
|
||||
(guint16)row_size,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* increase fw written size */
|
||||
*fw_data_written += row_size;
|
||||
fu_device_set_progress_full(device, *fw_data_written, fw_data_size);
|
||||
|
||||
/* get status */
|
||||
if (!fu_device_retry(FU_DEVICE(self),
|
||||
fu_ccgx_dmc_get_image_write_status_cb,
|
||||
DMC_FW_WRITE_STATUS_RETRY_COUNT,
|
||||
NULL,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -414,6 +444,7 @@ fu_ccgx_dmc_write_firmware_image(FuDevice *device,
|
||||
static gboolean
|
||||
fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -431,6 +462,12 @@ fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
gsize fw_data_written = 0;
|
||||
guint8 img_index = 0;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98);
|
||||
|
||||
/* get fwct record */
|
||||
fwct_blob = fu_ccgx_dmc_firmware_get_fwct_record(FU_CCGX_DMC_FIRMWARE(firmware));
|
||||
fwct_buf = g_bytes_get_data(fwct_blob, &fwct_sz);
|
||||
@ -449,9 +486,9 @@ fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
custom_meta_data = g_bytes_get_data(custom_meta_blob, &custom_meta_bufsz);
|
||||
|
||||
/* reset */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_ccgx_dmc_device_send_reset_state_machine(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* start fw upgrade with custom metadata */
|
||||
if (!fu_ccgx_dmc_device_send_start_upgrade(self,
|
||||
@ -463,11 +500,11 @@ fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
/* send fwct data */
|
||||
if (!fu_ccgx_dmc_device_send_fwct(self, fwct_buf, fwct_sz, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* get total fw size */
|
||||
image_records = fu_ccgx_dmc_firmware_get_image_records(FU_CCGX_DMC_FIRMWARE(firmware));
|
||||
fw_data_size = fu_ccgx_dmc_firmware_get_fw_data_size(FU_CCGX_DMC_FIRMWARE(firmware));
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
while (1) {
|
||||
/* get interrupt request */
|
||||
if (!fu_ccgx_dmc_device_read_intr_req(self, &dmc_int_rqt, error))
|
||||
@ -494,10 +531,10 @@ fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
img_rcd,
|
||||
&fw_data_written,
|
||||
fw_data_size,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dmc_int_rqt.opcode != DMC_INT_OPCODE_FW_UPGRADE_STATUS) {
|
||||
if (dmc_int_rqt.opcode == DMC_INT_OPCODE_FWCT_ANALYSIS_STATUS) {
|
||||
g_set_error(error,
|
||||
@ -515,7 +552,6 @@ fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
dmc_int_rqt.data[0]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dmc_int_rqt.data[0] == DMC_DEVICE_STATUS_UPDATE_PHASE_1_COMPLETE) {
|
||||
self->update_model = DMC_UPDATE_MODEL_DOWNLOAD_TRIGGER;
|
||||
} else if (dmc_int_rqt.data[0] == DMC_DEVICE_STATUS_FW_DOWNLOADED_UPDATE_PEND) {
|
||||
@ -528,6 +564,9 @@ fu_ccgx_dmc_write_firmware(FuDevice *device,
|
||||
dmc_int_rqt.data[0]);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -565,7 +604,7 @@ fu_ccgx_dmc_device_prepare_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ccgx_dmc_device_attach(FuDevice *device, GError **error)
|
||||
fu_ccgx_dmc_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuCcgxDmcDevice *self = FU_CCGX_DMC_DEVICE(device);
|
||||
gboolean manual_replug;
|
||||
@ -603,7 +642,6 @@ fu_ccgx_dmc_device_attach(FuDevice *device, GError **error)
|
||||
if (manual_replug)
|
||||
return TRUE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
@ -671,6 +709,17 @@ fu_ccgx_dmc_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_hid_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_NO_PROFILE); /* actually 0, 20, 0, 80! */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 75); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 25); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_dmc_device_init(FuCcgxDmcDevice *self)
|
||||
{
|
||||
@ -697,4 +746,5 @@ fu_ccgx_dmc_device_class_init(FuCcgxDmcDeviceClass *klass)
|
||||
klass_device->attach = fu_ccgx_dmc_device_attach;
|
||||
klass_device->setup = fu_ccgx_dmc_device_setup;
|
||||
klass_device->set_quirk_kv = fu_ccgx_dmc_device_set_quirk_kv;
|
||||
klass_device->set_progress = fu_ccgx_hid_device_set_progress;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ fu_ccgx_hid_device_enable_hpi_mode_cb(FuDevice *device, gpointer user_data, GErr
|
||||
{
|
||||
guint8 buf[5] = {0xEE, 0xBC, 0xA6, 0xB9, 0xA8};
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_hid_device_set_report(FU_HID_DEVICE(device),
|
||||
buf[0],
|
||||
buf,
|
||||
@ -39,7 +38,7 @@ fu_ccgx_hid_device_enable_hpi_mode_cb(FuDevice *device, gpointer user_data, GErr
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ccgx_hid_device_detach(FuDevice *device, GError **error)
|
||||
fu_ccgx_hid_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
if (!fu_device_retry(device,
|
||||
fu_ccgx_hid_device_enable_hpi_mode_cb,
|
||||
@ -77,6 +76,17 @@ fu_ccgx_hid_device_setup(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_hid_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_hid_device_init(FuCcgxHidDevice *self)
|
||||
{
|
||||
@ -93,4 +103,5 @@ fu_ccgx_hid_device_class_init(FuCcgxHidDeviceClass *klass)
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
klass_device->detach = fu_ccgx_hid_device_detach;
|
||||
klass_device->setup = fu_ccgx_hid_device_setup;
|
||||
klass_device->set_progress = fu_ccgx_hid_device_set_progress;
|
||||
}
|
||||
|
@ -34,6 +34,15 @@ struct _FuCcgxHpiDevice {
|
||||
guint32 flash_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* FU_CCGX_HPI_DEVICE_IS_IN_RESTART:
|
||||
*
|
||||
* Device is in restart and should not be closed manually.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
*/
|
||||
#define FU_CCGX_HPI_DEVICE_IS_IN_RESTART (1 << 0)
|
||||
|
||||
G_DEFINE_TYPE(FuCcgxHpiDevice, fu_ccgx_hpi_device, FU_TYPE_USB_DEVICE)
|
||||
|
||||
#define HPI_CMD_REG_READ_WRITE_DELAY_US 10000
|
||||
@ -1027,7 +1036,7 @@ fu_ccgx_hpi_read_flash(FuCcgxHpiDevice *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ccgx_hpi_device_detach(FuDevice *device, GError **error)
|
||||
fu_ccgx_hpi_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuCcgxHpiDevice *self = FU_CCGX_HPI_DEVICE(device);
|
||||
guint8 buf[] = {
|
||||
@ -1042,7 +1051,6 @@ fu_ccgx_hpi_device_detach(FuDevice *device, GError **error)
|
||||
/* jump to Alt FW */
|
||||
if (!fu_ccgx_hpi_device_clear_all_events(self, HPI_CMD_COMMAND_CLEAR_EVENT_TIME_MS, error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_ccgx_hpi_device_reg_write(self,
|
||||
CY_PD_JUMP_TO_BOOT_REG_ADDR,
|
||||
buf,
|
||||
@ -1054,13 +1062,14 @@ fu_ccgx_hpi_device_detach(FuDevice *device, GError **error)
|
||||
|
||||
/* sym not required */
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
fu_device_add_private_flag(device, FU_CCGX_HPI_DEVICE_IS_IN_RESTART);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ccgx_hpi_device_attach(FuDevice *device, GError **error)
|
||||
fu_ccgx_hpi_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuCcgxHpiDevice *self = FU_CCGX_HPI_DEVICE(device);
|
||||
guint8 buf[] = {
|
||||
@ -1069,7 +1078,6 @@ fu_ccgx_hpi_device_attach(FuDevice *device, GError **error)
|
||||
};
|
||||
if (!fu_ccgx_hpi_device_clear_all_events(self, HPI_CMD_COMMAND_CLEAR_EVENT_TIME_MS, error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_ccgx_hpi_device_reg_write_no_resp(self,
|
||||
CY_PD_REG_RESET_ADDR,
|
||||
buf,
|
||||
@ -1079,6 +1087,7 @@ fu_ccgx_hpi_device_attach(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
fu_device_add_private_flag(device, FU_CCGX_HPI_DEVICE_IS_IN_RESTART);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1252,6 +1261,7 @@ fu_ccgx_hpi_save_metadata(FuCcgxHpiDevice *self,
|
||||
static gboolean
|
||||
fu_ccgx_hpi_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1261,6 +1271,14 @@ fu_ccgx_hpi_write_firmware(FuDevice *device,
|
||||
FWMode fw_mode_alt = fu_ccgx_fw_mode_get_alternate(self->fw_mode);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* invalidate metadata */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 80);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* leave-flash */
|
||||
|
||||
/* enter flash mode */
|
||||
locker = fu_device_locker_new_full(self,
|
||||
(FuDeviceLockerFunc)fu_ccgx_hpi_enter_flash_mode,
|
||||
@ -1270,16 +1288,14 @@ fu_ccgx_hpi_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* invalidate metadata for alternate image */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
if (!fu_ccgx_hpi_load_metadata(self, fw_mode_alt, &metadata, error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
metadata.metadata_valid = 0x00;
|
||||
if (!fu_ccgx_hpi_save_metadata(self, fw_mode_alt, &metadata, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write new image */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < records->len; i++) {
|
||||
FuCcgxFirmwareRecord *rcd = g_ptr_array_index(records, i);
|
||||
|
||||
@ -1294,19 +1310,23 @@ fu_ccgx_hpi_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)records->len - 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)records->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* validate fw */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!fu_ccgx_hpi_validate_fw(self, fw_mode_alt, error)) {
|
||||
g_prefix_error(error, "fw validate error: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* this is a good time to leave the flash mode *before* rebooting */
|
||||
if (!fu_device_locker_close(locker, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -1586,7 +1606,7 @@ fu_ccgx_hpi_device_close(FuDevice *device, GError **error)
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* do not close handle when device restarts */
|
||||
if (fu_device_get_status(device) == FWUPD_STATUS_DEVICE_RESTART)
|
||||
if (fu_device_has_private_flag(device, FU_CCGX_HPI_DEVICE_IS_IN_RESTART))
|
||||
return TRUE;
|
||||
if (!g_usb_device_release_interface(fu_usb_device_get_dev(FU_USB_DEVICE(device)),
|
||||
self->inf_num,
|
||||
@ -1603,6 +1623,17 @@ fu_ccgx_hpi_device_close(FuDevice *device, GError **error)
|
||||
return FU_DEVICE_CLASS(fu_ccgx_hpi_device_parent_class)->close(device, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_hpi_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ccgx_hpi_device_init(FuCcgxHpiDevice *self)
|
||||
{
|
||||
@ -1649,4 +1680,5 @@ fu_ccgx_hpi_device_class_init(FuCcgxHpiDeviceClass *klass)
|
||||
klass_device->set_quirk_kv = fu_ccgx_hpi_device_set_quirk_kv;
|
||||
klass_device->open = fu_ccgx_hpi_device_open;
|
||||
klass_device->close = fu_ccgx_hpi_device_close;
|
||||
klass_device->set_progress = fu_ccgx_hpi_device_set_progress;
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ fu_colorhug_device_msg(FuColorhugDevice *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_colorhug_device_detach(FuDevice *device, GError **error)
|
||||
fu_colorhug_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuColorhugDevice *self = FU_COLORHUG_DEVICE(device);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
@ -206,8 +206,6 @@ fu_colorhug_device_detach(FuDevice *device, GError **error)
|
||||
g_debug("already in bootloader mode, skipping");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_colorhug_device_msg(self,
|
||||
CH_CMD_RESET,
|
||||
NULL,
|
||||
@ -227,7 +225,7 @@ fu_colorhug_device_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_colorhug_device_attach(FuDevice *device, GError **error)
|
||||
fu_colorhug_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuColorhugDevice *self = FU_COLORHUG_DEVICE(device);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
@ -237,8 +235,6 @@ fu_colorhug_device_attach(FuDevice *device, GError **error)
|
||||
g_debug("already in runtime mode, skipping");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_colorhug_device_msg(self,
|
||||
CH_CMD_BOOT_FLASH,
|
||||
NULL,
|
||||
@ -444,6 +440,7 @@ ch_colorhug_device_calculate_checksum(const guint8 *data, guint32 len)
|
||||
static gboolean
|
||||
fu_colorhug_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -451,27 +448,33 @@ fu_colorhug_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 19);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 44);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 35);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* build packets */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
self->start_addr,
|
||||
0x00, /* page_sz */
|
||||
CH_FLASH_TRANSFER_BLOCK_SIZE);
|
||||
|
||||
/* don't auto-boot firmware */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_colorhug_device_set_flash_success(self, FALSE, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* erase flash */
|
||||
if (!fu_colorhug_device_erase(self, self->start_addr, g_bytes_get_size(fw), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write each block */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
self->start_addr,
|
||||
0x00, /* page_sz */
|
||||
CH_FLASH_TRANSFER_BLOCK_SIZE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
guint8 buf[CH_FLASH_TRANSFER_BLOCK_SIZE + 4];
|
||||
@ -507,11 +510,13 @@ fu_colorhug_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len * 2);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
guint8 buf[3];
|
||||
@ -550,13 +555,26 @@ fu_colorhug_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)chunks->len + i, (gsize)chunks->len * 2);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_colorhug_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 57); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 43); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_colorhug_device_init(FuColorhugDevice *self)
|
||||
{
|
||||
@ -582,4 +600,5 @@ fu_colorhug_device_class_init(FuColorhugDeviceClass *klass)
|
||||
klass_device->setup = fu_colorhug_device_setup;
|
||||
klass_device->open = fu_colorhug_device_open;
|
||||
klass_device->probe = fu_colorhug_device_probe;
|
||||
klass_device->set_progress = fu_colorhug_device_set_progress;
|
||||
}
|
||||
|
@ -618,6 +618,7 @@ static gboolean
|
||||
fu_cros_ec_usb_device_transfer_section(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuCrosEcFirmwareSection *section,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuCrosEcUsbDevice *self = FU_CROS_EC_USB_DEVICE(device);
|
||||
@ -805,6 +806,7 @@ fu_cros_ec_usb_device_jump_to_rw(FuDevice *device)
|
||||
static gboolean
|
||||
fu_cros_ec_usb_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -880,7 +882,10 @@ fu_cros_ec_usb_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, sections->len);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < sections->len; i++) {
|
||||
FuCrosEcFirmwareSection *section = g_ptr_array_index(sections, i);
|
||||
|
||||
@ -890,6 +895,7 @@ fu_cros_ec_usb_device_write_firmware(FuDevice *device,
|
||||
if (!fu_cros_ec_usb_device_transfer_section(device,
|
||||
firmware,
|
||||
section,
|
||||
fu_progress_get_child(progress),
|
||||
&error_local)) {
|
||||
if (g_error_matches(error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
@ -900,6 +906,7 @@ fu_cros_ec_usb_device_write_firmware(FuDevice *device,
|
||||
fu_device_add_flag(
|
||||
device,
|
||||
FWUPD_DEVICE_FLAG_ANOTHER_WRITE_REQUIRED);
|
||||
fu_progress_finished(progress);
|
||||
return TRUE;
|
||||
}
|
||||
g_propagate_error(error, g_steal_pointer(&error_local));
|
||||
@ -914,6 +921,7 @@ fu_cros_ec_usb_device_write_firmware(FuDevice *device,
|
||||
section->version.triplet);
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
/* send done */
|
||||
fu_cros_ec_usb_device_send_done(device);
|
||||
@ -981,7 +989,7 @@ fu_cros_ec_usb_device_prepare_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_cros_ec_usb_device_attach(FuDevice *device, GError **error)
|
||||
fu_cros_ec_usb_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuCrosEcUsbDevice *self = FU_CROS_EC_USB_DEVICE(device);
|
||||
|
||||
@ -996,7 +1004,6 @@ fu_cros_ec_usb_device_attach(FuDevice *device, GError **error)
|
||||
* ro -> rw.
|
||||
*/
|
||||
fu_device_remove_private_flag(device, FU_CROS_EC_USB_DEVICE_FLAG_SPECIAL);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1009,7 +1016,6 @@ fu_cros_ec_usb_device_attach(FuDevice *device, GError **error)
|
||||
} else {
|
||||
fu_cros_ec_usb_device_jump_to_rw(device);
|
||||
}
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
|
||||
/* success */
|
||||
@ -1017,7 +1023,7 @@ fu_cros_ec_usb_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_cros_ec_usb_device_detach(FuDevice *device, GError **error)
|
||||
fu_cros_ec_usb_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuCrosEcUsbDevice *self = FU_CROS_EC_USB_DEVICE(device);
|
||||
|
||||
@ -1035,8 +1041,6 @@ fu_cros_ec_usb_device_detach(FuDevice *device, GError **error)
|
||||
fu_device_set_remove_delay(device, CROS_EC_REMOVE_DELAY_RE_ENUMERATE);
|
||||
if (!fu_cros_ec_usb_device_reset_to_ro(device, error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
}
|
||||
|
||||
@ -1088,6 +1092,17 @@ fu_cros_ec_usb_device_to_string(FuDevice *device, guint idt, GString *str)
|
||||
fu_common_string_append_kx(str, idt, "WriteableOffset", self->writeable_offset);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_cros_ec_usb_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_cros_ec_usb_device_class_init(FuCrosEcUsbDeviceClass *klass)
|
||||
{
|
||||
@ -1101,4 +1116,5 @@ fu_cros_ec_usb_device_class_init(FuCrosEcUsbDeviceClass *klass)
|
||||
klass_device->open = fu_cros_ec_usb_device_open;
|
||||
klass_device->probe = fu_cros_ec_usb_device_probe;
|
||||
klass_device->close = fu_cros_ec_usb_device_close;
|
||||
klass_device->set_progress = fu_cros_ec_usb_device_set_progress;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ fu_dell_dock_hub_probe(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_dell_dock_hub_write_fw(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -63,6 +64,12 @@ fu_dell_dock_hub_write_fw(FuDevice *device,
|
||||
g_return_val_if_fail(device != NULL, FALSE);
|
||||
g_return_val_if_fail(FU_IS_FIRMWARE(firmware), FALSE);
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 49);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 50);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -81,11 +88,12 @@ fu_dell_dock_hub_write_fw(FuDevice *device,
|
||||
if (!fu_dell_dock_hid_raise_mcu_clock(device, TRUE, error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
/* erase */
|
||||
if (!fu_dell_dock_hid_erase_bank(device, 1, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
/* write */
|
||||
do {
|
||||
/* last packet */
|
||||
if (fw_size - nwritten < write_size)
|
||||
@ -96,10 +104,11 @@ fu_dell_dock_hub_write_fw(FuDevice *device,
|
||||
nwritten += write_size;
|
||||
data += write_size;
|
||||
address += write_size;
|
||||
fu_device_set_progress_full(device, nwritten, fw_size);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress), nwritten, fw_size);
|
||||
} while (nwritten < fw_size);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
/* verify */
|
||||
if (!fu_dell_dock_hid_verify_update(device, &result, error))
|
||||
return FALSE;
|
||||
if (!result) {
|
||||
@ -109,9 +118,9 @@ fu_dell_dock_hub_write_fw(FuDevice *device,
|
||||
"Failed to verify the update");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* dock will reboot to re-read; this is to appease the daemon */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_PAIR);
|
||||
fu_device_set_version(device, dynamic_version);
|
||||
return TRUE;
|
||||
@ -166,6 +175,16 @@ fu_dell_dock_hub_finalize(GObject *object)
|
||||
G_OBJECT_CLASS(fu_dell_dock_hub_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_hub_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_hub_init(FuDellDockHub *self)
|
||||
{
|
||||
@ -185,6 +204,7 @@ fu_dell_dock_hub_class_init(FuDellDockHubClass *klass)
|
||||
klass_device->probe = fu_dell_dock_hub_probe;
|
||||
klass_device->write_firmware = fu_dell_dock_hub_write_fw;
|
||||
klass_device->set_quirk_kv = fu_dell_dock_hub_set_quirk_kv;
|
||||
klass_device->set_progress = fu_dell_dock_hub_set_progress;
|
||||
}
|
||||
|
||||
FuDellDockHub *
|
||||
|
@ -660,7 +660,7 @@ fu_dell_dock_ec_reset(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dell_dock_ec_activate(FuDevice *device, GError **error)
|
||||
fu_dell_dock_ec_activate(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDellDockECFWUpdateStatus status;
|
||||
|
||||
@ -787,6 +787,7 @@ fu_dell_dock_ec_commit_package(FuDevice *device, GBytes *blob_fw, GError **error
|
||||
static gboolean
|
||||
fu_dell_dock_ec_write_fw(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -802,6 +803,11 @@ fu_dell_dock_ec_write_fw(FuDevice *device,
|
||||
g_return_val_if_fail(device != NULL, FALSE);
|
||||
g_return_val_if_fail(FU_IS_FIRMWARE(firmware), FALSE);
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 15);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 85);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -832,11 +838,12 @@ fu_dell_dock_ec_write_fw(FuDevice *device,
|
||||
if (!fu_dell_dock_hid_raise_mcu_clock(fu_device_get_proxy(device), TRUE, error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
/* erase */
|
||||
if (!fu_dell_dock_hid_erase_bank(fu_device_get_proxy(device), 0xff, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
/* write */
|
||||
do {
|
||||
/* last packet */
|
||||
if (fw_size - nwritten < write_size)
|
||||
@ -850,11 +857,12 @@ fu_dell_dock_ec_write_fw(FuDevice *device,
|
||||
g_prefix_error(error, "write over HID failed: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(device, nwritten, fw_size);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress), nwritten, fw_size);
|
||||
nwritten += write_size;
|
||||
data += write_size;
|
||||
address += write_size;
|
||||
} while (nwritten < fw_size);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
if (!fu_dell_dock_hid_raise_mcu_clock(fu_device_get_proxy(device), FALSE, error))
|
||||
return FALSE;
|
||||
@ -989,6 +997,17 @@ fu_dell_dock_ec_finalize(GObject *object)
|
||||
G_OBJECT_CLASS(fu_dell_dock_ec_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_ec_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_ec_init(FuDellDockEc *self)
|
||||
{
|
||||
@ -1010,6 +1029,7 @@ fu_dell_dock_ec_class_init(FuDellDockEcClass *klass)
|
||||
klass_device->close = fu_dell_dock_ec_close;
|
||||
klass_device->write_firmware = fu_dell_dock_ec_write_fw;
|
||||
klass_device->set_quirk_kv = fu_dell_dock_ec_set_quirk_kv;
|
||||
klass_device->set_progress = fu_dell_dock_ec_set_progress;
|
||||
}
|
||||
|
||||
FuDellDockEc *
|
||||
|
@ -500,7 +500,11 @@ fu_dell_dock_mst_erase_bank(FuDevice *proxy, MSTBank bank, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dell_dock_write_flash_bank(FuDevice *device, GBytes *blob_fw, MSTBank bank, GError **error)
|
||||
fu_dell_dock_write_flash_bank(FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
MSTBank bank,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
const MSTBankAttributes *attribs = NULL;
|
||||
gsize write_size = 32;
|
||||
@ -527,7 +531,7 @@ fu_dell_dock_write_flash_bank(FuDevice *device, GBytes *blob_fw, MSTBank bank, G
|
||||
i);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(device, i - attribs->start, end - attribs->start);
|
||||
fu_progress_set_percentage_full(progress, i - attribs->start, end - attribs->start);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -706,15 +710,67 @@ fu_dell_dock_mst_invalidate_bank(FuDevice *proxy, MSTBank bank_in_use, GError **
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dell_dock_mst_write_bank(FuDevice *device,
|
||||
GBytes *fw,
|
||||
guint8 bank,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
const guint retries = 2;
|
||||
for (guint i = 0; i < retries; i++) {
|
||||
gboolean checksum = FALSE;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 15);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 84);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 1);
|
||||
|
||||
if (!fu_dell_dock_mst_erase_bank(fu_device_get_proxy(device), bank, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
if (!fu_dell_dock_write_flash_bank(device,
|
||||
fw,
|
||||
bank,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
if (!fu_dell_dock_mst_checksum_bank(fu_device_get_proxy(device),
|
||||
fw,
|
||||
bank,
|
||||
&checksum,
|
||||
error))
|
||||
return FALSE;
|
||||
if (!checksum) {
|
||||
g_debug("MST: Failed to verify checksum on bank %u", bank);
|
||||
fu_progress_reset(progress);
|
||||
continue;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
g_debug("MST: Bank %u successfully flashed", bank);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* failed after all our retries */
|
||||
g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to write to bank %u", bank);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dell_dock_mst_write_fw(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuDellDockMst *self = FU_DELL_DOCK_MST(device);
|
||||
FuProgress *progress_local;
|
||||
MSTBank bank_in_use = 0;
|
||||
guint retries = 2;
|
||||
gboolean checksum = FALSE;
|
||||
guint8 order[2] = {ESM, Bank0};
|
||||
guint16 chip_id;
|
||||
@ -726,6 +782,11 @@ fu_dell_dock_mst_write_fw(FuDevice *device,
|
||||
g_return_val_if_fail(FU_IS_FIRMWARE(firmware), FALSE);
|
||||
g_return_val_if_fail(fu_device_get_proxy(device) != NULL, FALSE);
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* enable */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 99);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -764,8 +825,12 @@ fu_dell_dock_mst_write_fw(FuDevice *device,
|
||||
/* ESM needs special handling during flash process*/
|
||||
if (!fu_dell_dock_mst_stop_esm(fu_device_get_proxy(device), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* Write each bank in order */
|
||||
progress_local = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(progress_local, G_STRLOC);
|
||||
fu_progress_set_steps(progress_local, 2);
|
||||
for (guint phase = 0; phase < 2; phase++) {
|
||||
g_debug("MST: Checking bank %u", order[phase]);
|
||||
if (!fu_dell_dock_mst_checksum_bank(fu_device_get_proxy(device),
|
||||
@ -776,51 +841,26 @@ fu_dell_dock_mst_write_fw(FuDevice *device,
|
||||
return FALSE;
|
||||
if (checksum) {
|
||||
g_debug("MST: bank %u is already up to date", order[phase]);
|
||||
fu_progress_step_done(progress_local);
|
||||
continue;
|
||||
}
|
||||
g_debug("MST: bank %u needs to be updated", order[phase]);
|
||||
for (guint i = 0; i < retries; i++) {
|
||||
fu_device_set_progress_full(device, 0, 100);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_dell_dock_mst_erase_bank(fu_device_get_proxy(device),
|
||||
order[phase],
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_dell_dock_write_flash_bank(device, fw, order[phase], error))
|
||||
return FALSE;
|
||||
if (!fu_dell_dock_mst_checksum_bank(fu_device_get_proxy(device),
|
||||
fw,
|
||||
order[phase],
|
||||
&checksum,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!checksum) {
|
||||
g_debug("MST: Failed to verify checksum on bank %u", order[phase]);
|
||||
continue;
|
||||
}
|
||||
g_debug("MST: Bank %u successfully flashed", order[phase]);
|
||||
break;
|
||||
}
|
||||
/* failed after all our retries */
|
||||
if (!checksum) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to write to bank %u",
|
||||
order[phase]);
|
||||
if (!fu_dell_dock_mst_write_bank(device,
|
||||
fw,
|
||||
order[phase],
|
||||
fu_progress_get_child(progress_local),
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress_local);
|
||||
}
|
||||
/* invalidate the previous bank */
|
||||
if (!fu_dell_dock_mst_invalidate_bank(fu_device_get_proxy(device), bank_in_use, error)) {
|
||||
g_prefix_error(error, "failed to invalidate bank %u: ", bank_in_use);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* dock will reboot to re-read; this is to appease the daemon */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_TRIPLET);
|
||||
fu_device_set_version(device, dynamic_version);
|
||||
|
||||
@ -935,6 +975,16 @@ fu_dell_dock_mst_close(FuDevice *device, GError **error)
|
||||
return fu_device_close(fu_device_get_proxy(device), error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_mst_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_mst_init(FuDellDockMst *self)
|
||||
{
|
||||
@ -952,6 +1002,7 @@ fu_dell_dock_mst_class_init(FuDellDockMstClass *klass)
|
||||
klass_device->probe = fu_dell_dock_mst_probe;
|
||||
klass_device->write_firmware = fu_dell_dock_mst_write_fw;
|
||||
klass_device->set_quirk_kv = fu_dell_dock_mst_set_quirk_kv;
|
||||
klass_device->set_progress = fu_dell_dock_mst_set_progress;
|
||||
}
|
||||
|
||||
FuDellDockMst *
|
||||
|
@ -50,6 +50,7 @@ G_DEFINE_TYPE(FuDellDockTbt, fu_dell_dock_tbt, FU_TYPE_DEVICE)
|
||||
static gboolean
|
||||
fu_dell_dock_tbt_write_fw(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -106,7 +107,7 @@ fu_dell_dock_tbt_write_fw(FuDevice *device,
|
||||
return FALSE;
|
||||
g_usleep(2000000);
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < image_size; i += HIDI2C_MAX_WRITE, buffer += HIDI2C_MAX_WRITE) {
|
||||
guint8 write_size = (image_size - i) > HIDI2C_MAX_WRITE ? HIDI2C_MAX_WRITE
|
||||
: (image_size - i);
|
||||
@ -119,11 +120,11 @@ fu_dell_dock_tbt_write_fw(FuDevice *device,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_progress_full(device, i, image_size);
|
||||
fu_progress_set_percentage_full(progress, i, image_size);
|
||||
}
|
||||
g_debug("writing took %f seconds", g_timer_elapsed(timer, NULL));
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_BUSY);
|
||||
|
||||
if (fu_dell_dock_ec_tbt_passive(fu_device_get_parent(device))) {
|
||||
g_debug("using passive flow for Thunderbolt");
|
||||
@ -135,7 +136,6 @@ fu_dell_dock_tbt_write_fw(FuDevice *device,
|
||||
}
|
||||
|
||||
/* dock will reboot to re-read; this is to appease the daemon */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_PAIR);
|
||||
fu_device_set_version(device, dynamic_version);
|
||||
|
||||
|
@ -60,6 +60,7 @@ fu_dell_dock_status_setup(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_dell_dock_status_write(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -96,7 +97,6 @@ fu_dell_dock_status_write(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* dock will reboot to re-read; this is to appease the daemon */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_set_version_format(device, FWUPD_VERSION_FORMAT_QUAD);
|
||||
fu_device_set_version(device, dynamic_version);
|
||||
return TRUE;
|
||||
@ -143,6 +143,16 @@ fu_dell_dock_status_finalize(GObject *object)
|
||||
G_OBJECT_CLASS(fu_dell_dock_status_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_status_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 13); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 72); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 9); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 7); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dell_dock_status_init(FuDellDockStatus *self)
|
||||
{
|
||||
@ -160,6 +170,7 @@ fu_dell_dock_status_class_init(FuDellDockStatusClass *klass)
|
||||
klass_device->open = fu_dell_dock_status_open;
|
||||
klass_device->close = fu_dell_dock_status_close;
|
||||
klass_device->set_quirk_kv = fu_dell_dock_status_set_quirk_kv;
|
||||
klass_device->set_progress = fu_dell_dock_status_set_progress;
|
||||
}
|
||||
|
||||
FuDellDockStatus *
|
||||
|
@ -357,6 +357,7 @@ fu_dell_dock_usb4_hub_nvm_write(FuDevice *device,
|
||||
const guint8 *buf,
|
||||
guint32 length,
|
||||
guint32 nvm_addr,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint8 metadata[4];
|
||||
@ -389,8 +390,8 @@ fu_dell_dock_usb4_hub_nvm_write(FuDevice *device,
|
||||
}
|
||||
|
||||
/* 2 Write data in 64 byte blocks */
|
||||
fu_device_set_progress_full(device, bytes_done, bytes_total);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_percentage_full(progress, bytes_done, bytes_total);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
while (length > 0) {
|
||||
/* write data to mbox data regs */
|
||||
if (!fu_dell_dock_usb4_mbox_data_write(device, buf, 64, error)) {
|
||||
@ -404,14 +405,14 @@ fu_dell_dock_usb4_hub_nvm_write(FuDevice *device,
|
||||
}
|
||||
buf += 64;
|
||||
length -= 64;
|
||||
fu_device_set_progress_full(device, bytes_done += 64, bytes_total);
|
||||
fu_progress_set_percentage_full(progress, bytes_done += 64, bytes_total);
|
||||
}
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_BUSY);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dell_dock_usb4_activate(FuDevice *device, GError **error)
|
||||
fu_dell_dock_usb4_activate(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = fu_device_locker_new(device, error);
|
||||
if (locker == NULL)
|
||||
@ -429,6 +430,7 @@ fu_dell_dock_usb4_activate(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_dell_dock_usb4_write_fw(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -522,7 +524,7 @@ fu_dell_dock_usb4_write_fw(FuDevice *device,
|
||||
/* firmware install */
|
||||
fw_buf += fw_header_offset;
|
||||
fw_blob_size -= fw_header_offset;
|
||||
if (!fu_dell_dock_usb4_hub_nvm_write(device, fw_buf, fw_blob_size, 0, error))
|
||||
if (!fu_dell_dock_usb4_hub_nvm_write(device, fw_buf, fw_blob_size, 0, progress, error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION);
|
||||
|
@ -311,7 +311,8 @@ fu_plugin_composite_cleanup(FuPlugin *plugin, GPtrArray *devices, GError **error
|
||||
return FALSE;
|
||||
|
||||
if (needs_activation && dev != NULL) {
|
||||
if (!fu_device_activate(dev, error))
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
if (!fu_device_activate(dev, progress, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,7 @@ fu_plugin_dell_tpm_func(gconstpointer user_data)
|
||||
g_autoptr(GBytes) blob_fw = g_bytes_new_static(fw, sizeof(fw));
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
#ifdef HAVE_GETUID
|
||||
if (tpm_server_running == NULL && (getuid() != 0 || geteuid() != 0)) {
|
||||
@ -234,6 +235,7 @@ fu_plugin_dell_tpm_func(gconstpointer user_data)
|
||||
ret = fu_plugin_runner_write_firmware(self->plugin_uefi_capsule,
|
||||
device_v20,
|
||||
blob_fw,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
@ -244,6 +246,7 @@ fu_plugin_dell_tpm_func(gconstpointer user_data)
|
||||
ret = fu_plugin_runner_write_firmware(self->plugin_uefi_capsule,
|
||||
device_v20,
|
||||
blob_fw,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_FORCE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
|
@ -58,7 +58,7 @@ fu_dfu_csr_device_to_string(FuDevice *device, guint idt, GString *str)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dfu_csr_device_attach(FuDevice *device, GError **error)
|
||||
fu_dfu_csr_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint8 buf[] = {FU_DFU_CSR_REPORT_ID_CONTROL, FU_DFU_CSR_CONTROL_RESET};
|
||||
if (!fu_hid_device_set_report(FU_HID_DEVICE(device),
|
||||
@ -180,7 +180,7 @@ fu_dfu_csr_device_upload_chunk(FuDfuCsrDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_dfu_csr_device_upload(FuDevice *device, GError **error)
|
||||
fu_dfu_csr_device_upload(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuCsrDevice *self = FU_DFU_CSR_DEVICE(device);
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
@ -188,7 +188,7 @@ fu_dfu_csr_device_upload(FuDevice *device, GError **error)
|
||||
gsize done_sz = 0;
|
||||
|
||||
/* notify UI */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
|
||||
chunks = g_ptr_array_new_with_free_func((GDestroyNotify)g_bytes_unref);
|
||||
for (guint32 i = 0; i < 0x3ffffff; i++) {
|
||||
@ -253,7 +253,7 @@ fu_dfu_csr_device_upload(FuDevice *device, GError **error)
|
||||
/* add to chunk array */
|
||||
done_sz += chunk_sz;
|
||||
g_ptr_array_add(chunks, g_steal_pointer(&chunk));
|
||||
fu_device_set_progress_full(device, done_sz, (gsize)total_sz);
|
||||
fu_progress_set_percentage_full(progress, done_sz, (gsize)total_sz);
|
||||
|
||||
/* we're done */
|
||||
if (chunk_sz < 64 - FU_DFU_CSR_COMMAND_HEADER_SIZE)
|
||||
@ -366,6 +366,7 @@ fu_dfu_csr_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_dfu_csr_device_download(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -381,7 +382,7 @@ fu_dfu_csr_device_download(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* notify UI */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
|
||||
/* create chunks */
|
||||
chunks = fu_chunk_array_new_from_bytes(blob,
|
||||
@ -400,7 +401,7 @@ fu_dfu_csr_device_download(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)idx, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(progress, (gsize)idx + 1, (gsize)chunks->len);
|
||||
}
|
||||
|
||||
/* all done */
|
||||
@ -438,6 +439,17 @@ fu_dfu_csr_device_setup(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dfu_csr_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dfu_csr_device_init(FuDfuCsrDevice *self)
|
||||
{
|
||||
@ -459,4 +471,5 @@ fu_dfu_csr_device_class_init(FuDfuCsrDeviceClass *klass)
|
||||
klass_device->attach = fu_dfu_csr_device_attach;
|
||||
klass_device->setup = fu_dfu_csr_device_setup;
|
||||
klass_device->probe = fu_dfu_csr_device_probe;
|
||||
klass_device->set_progress = fu_dfu_csr_device_set_progress;
|
||||
}
|
||||
|
@ -906,7 +906,7 @@ fu_dfu_device_refresh(FuDfuDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dfu_device_request_detach(FuDfuDevice *self, GError **error)
|
||||
fu_dfu_device_request_detach(FuDfuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(self));
|
||||
@ -954,7 +954,7 @@ fu_dfu_device_reload(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dfu_device_detach(FuDevice *device, GError **error)
|
||||
fu_dfu_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuDevice *self = FU_DFU_DEVICE(device);
|
||||
FuDfuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
@ -989,20 +989,18 @@ fu_dfu_device_detach(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* inform UI there's going to be a detach:attach */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_dfu_device_request_detach(self, error))
|
||||
if (!fu_dfu_device_request_detach(self, progress, error))
|
||||
return FALSE;
|
||||
|
||||
/* do a host reset */
|
||||
if ((priv->attributes & FU_DFU_DEVICE_ATTR_WILL_DETACH) == 0) {
|
||||
g_debug("doing device reset as host will not self-reset");
|
||||
if (!fu_dfu_device_reset(self, error))
|
||||
if (!fu_dfu_device_reset(self, progress, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* success */
|
||||
priv->force_version = 0x0;
|
||||
fu_device_set_status(device, FWUPD_STATUS_IDLE);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1308,24 +1306,17 @@ fu_dfu_device_probe(FuDevice *device, GError **error)
|
||||
|
||||
/* hardware from Jabra literally reboots if you try to retry a failed
|
||||
* write -- there's no way to avoid blocking the daemon like this... */
|
||||
if (fu_device_has_private_flag(FU_DEVICE(self), FU_DFU_DEVICE_FLAG_ATTACH_EXTRA_RESET))
|
||||
fu_device_sleep_with_progress(device, 10); /* seconds */
|
||||
if (fu_device_has_private_flag(FU_DEVICE(self), FU_DFU_DEVICE_FLAG_ATTACH_EXTRA_RESET)) {
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
fu_progress_sleep(progress, 10000);
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_dfu_device_reset:
|
||||
* @self: a #FuDfuDevice
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Resets the USB device.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
gboolean
|
||||
fu_dfu_device_reset(FuDfuDevice *self, GError **error)
|
||||
fu_dfu_device_reset(FuDfuDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(self));
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
@ -1358,7 +1349,7 @@ fu_dfu_device_reset(FuDfuDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dfu_device_attach(FuDevice *device, GError **error)
|
||||
fu_dfu_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuDevice *self = FU_DFU_DEVICE(device);
|
||||
FuDfuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
@ -1373,14 +1364,10 @@ fu_dfu_device_attach(FuDevice *device, GError **error)
|
||||
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
|
||||
return TRUE;
|
||||
|
||||
/* inform UI there's going to be a re-attach */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
/* handle weirdness */
|
||||
if (fu_device_has_private_flag(FU_DEVICE(self), FU_DFU_DEVICE_FLAG_DETACH_FOR_ATTACH)) {
|
||||
if (!fu_dfu_device_request_detach(self, error))
|
||||
if (!fu_dfu_device_request_detach(self, progress, error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_IDLE);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1395,7 +1382,7 @@ fu_dfu_device_attach(FuDevice *device, GError **error)
|
||||
target_zero = fu_dfu_device_get_target_by_alt_setting(self, 0, error);
|
||||
if (target_zero == NULL)
|
||||
return FALSE;
|
||||
chunk = fu_dfu_target_upload_chunk(target_zero, 0, 0, error);
|
||||
chunk = fu_dfu_target_upload_chunk(target_zero, 0, 0, progress, error);
|
||||
if (chunk == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
@ -1409,28 +1396,15 @@ fu_dfu_device_attach(FuDevice *device, GError **error)
|
||||
if (fu_device_has_private_flag(FU_DEVICE(self), FU_DFU_DEVICE_FLAG_NO_BUS_RESET_ATTACH) &&
|
||||
fu_dfu_device_has_attribute(self, FU_DFU_DEVICE_ATTR_WILL_DETACH))
|
||||
g_debug("Bus reset is not required. Device will reboot to normal");
|
||||
else if (!fu_dfu_target_attach(target, error))
|
||||
else if (!fu_dfu_target_attach(target, progress, error))
|
||||
return FALSE;
|
||||
|
||||
/* success */
|
||||
priv->force_version = 0x0;
|
||||
fu_device_set_status(device, FWUPD_STATUS_IDLE);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dfu_device_percentage_cb(FuDfuTarget *target, guint percentage, FuDfuDevice *self)
|
||||
{
|
||||
fu_device_set_progress(FU_DEVICE(self), percentage);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dfu_device_action_cb(FuDfuTarget *target, FwupdStatus action, FuDfuDevice *self)
|
||||
{
|
||||
fu_device_set_status(FU_DEVICE(self), action);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_dfu_device_upload:
|
||||
* @self: a #FuDfuDevice
|
||||
@ -1442,7 +1416,10 @@ fu_dfu_device_action_cb(FuDfuTarget *target, FwupdStatus action, FuDfuDevice *se
|
||||
* Returns: (transfer full): the uploaded firmware, or %NULL for error
|
||||
**/
|
||||
FuFirmware *
|
||||
fu_dfu_device_upload(FuDfuDevice *self, FuDfuTargetTransferFlags flags, GError **error)
|
||||
fu_dfu_device_upload(FuDfuDevice *self,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuDevicePrivate *priv = GET_PRIVATE(self);
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(self));
|
||||
@ -1474,11 +1451,11 @@ fu_dfu_device_upload(FuDfuDevice *self, FuDfuTargetTransferFlags flags, GError *
|
||||
fu_dfu_firmware_set_release(FU_DFU_FIRMWARE(firmware), 0xffff);
|
||||
|
||||
/* upload from each target */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, priv->targets->len);
|
||||
for (guint i = 0; i < priv->targets->len; i++) {
|
||||
FuDfuTarget *target;
|
||||
const gchar *alt_name;
|
||||
gulong id1;
|
||||
gulong id2;
|
||||
|
||||
/* upload to target and proxy signals */
|
||||
target = g_ptr_array_index(priv->targets, i);
|
||||
@ -1489,26 +1466,19 @@ fu_dfu_device_upload(FuDfuDevice *self, FuDfuTargetTransferFlags flags, GError *
|
||||
g_debug("ignoring target %s", alt_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
id1 = g_signal_connect(target,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_dfu_device_percentage_cb),
|
||||
self);
|
||||
id2 = g_signal_connect(target,
|
||||
"action-changed",
|
||||
G_CALLBACK(fu_dfu_device_action_cb),
|
||||
self);
|
||||
if (!fu_dfu_target_upload(target, firmware, DFU_TARGET_TRANSFER_FLAG_NONE, error))
|
||||
if (!fu_dfu_target_upload(target,
|
||||
firmware,
|
||||
fu_progress_get_child(progress),
|
||||
DFU_TARGET_TRANSFER_FLAG_NONE,
|
||||
error))
|
||||
return NULL;
|
||||
g_signal_handler_disconnect(target, id1);
|
||||
g_signal_handler_disconnect(target, id2);
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
/* do not do the dummy upload for quirked devices */
|
||||
priv->done_upload_or_download = TRUE;
|
||||
|
||||
/* success */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_IDLE);
|
||||
return g_object_ref(firmware);
|
||||
}
|
||||
|
||||
@ -1534,6 +1504,7 @@ fu_dfu_device_id_compatible(guint16 id_file, guint16 id_runtime, guint16 id_dev)
|
||||
static gboolean
|
||||
fu_dfu_device_download(FuDfuDevice *self,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1625,13 +1596,13 @@ fu_dfu_device_download(FuDfuDevice *self,
|
||||
images = fu_firmware_get_images(firmware);
|
||||
if (images->len == 0)
|
||||
g_ptr_array_add(images, g_object_ref(firmware));
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, images->len);
|
||||
for (guint i = 0; i < images->len; i++) {
|
||||
FuFirmware *image = g_ptr_array_index(images, i);
|
||||
FuDfuTargetTransferFlags flags_local = DFU_TARGET_TRANSFER_FLAG_NONE;
|
||||
const gchar *alt_name;
|
||||
guint8 alt;
|
||||
gulong id1;
|
||||
gulong id2;
|
||||
g_autoptr(FuDfuTarget) target_tmp = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
@ -1658,26 +1629,20 @@ fu_dfu_device_download(FuDfuDevice *self,
|
||||
if (!FU_IS_DFU_FIRMWARE(firmware) ||
|
||||
fu_dfu_firmware_get_version(FU_DFU_FIRMWARE(firmware)) == 0x0)
|
||||
flags_local |= DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC;
|
||||
id1 = g_signal_connect(target_tmp,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_dfu_device_percentage_cb),
|
||||
self);
|
||||
id2 = g_signal_connect(target_tmp,
|
||||
"action-changed",
|
||||
G_CALLBACK(fu_dfu_device_action_cb),
|
||||
self);
|
||||
ret = fu_dfu_target_download(target_tmp, image, flags_local, error);
|
||||
g_signal_handler_disconnect(target_tmp, id1);
|
||||
g_signal_handler_disconnect(target_tmp, id2);
|
||||
ret = fu_dfu_target_download(target_tmp,
|
||||
image,
|
||||
fu_progress_get_child(progress),
|
||||
flags_local,
|
||||
error);
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
/* do not do the dummy upload for quirked devices */
|
||||
priv->done_upload_or_download = TRUE;
|
||||
|
||||
/* success */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_IDLE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1720,7 +1685,7 @@ fu_dfu_device_error_fixup(FuDfuDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_dfu_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_dfu_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuDevice *self = FU_DFU_DEVICE(device);
|
||||
g_autoptr(FuFirmware) firmware = NULL;
|
||||
@ -1738,7 +1703,7 @@ fu_dfu_device_dump_firmware(FuDevice *device, GError **error)
|
||||
g_debug("uploading from device->host");
|
||||
if (!fu_dfu_device_refresh_and_clear(self, error))
|
||||
return NULL;
|
||||
firmware = fu_dfu_device_upload(self, DFU_TARGET_TRANSFER_FLAG_NONE, error);
|
||||
firmware = fu_dfu_device_upload(self, progress, DFU_TARGET_TRANSFER_FLAG_NONE, error);
|
||||
if (firmware == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -1764,6 +1729,7 @@ fu_dfu_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_dfu_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1779,7 +1745,7 @@ fu_dfu_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* hit hardware */
|
||||
return fu_dfu_device_download(self, firmware, transfer_flags, error);
|
||||
return fu_dfu_device_download(self, firmware, progress, transfer_flags, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1869,6 +1835,16 @@ fu_dfu_device_get_attributes_as_string(FuDfuDevice *self)
|
||||
return g_string_free(str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dfu_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 88); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 10); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_dfu_device_finalize(GObject *object)
|
||||
{
|
||||
@ -1897,6 +1873,7 @@ fu_dfu_device_class_init(FuDfuDeviceClass *klass)
|
||||
klass_device->open = fu_dfu_device_open;
|
||||
klass_device->close = fu_dfu_device_close;
|
||||
klass_device->probe = fu_dfu_device_probe;
|
||||
klass_device->set_progress = fu_dfu_device_set_progress;
|
||||
object_class->finalize = fu_dfu_device_finalize;
|
||||
}
|
||||
|
||||
@ -1971,7 +1948,4 @@ fu_dfu_device_init(FuDfuDevice *self)
|
||||
FU_DFU_DEVICE_FLAG_NO_BUS_RESET_ATTACH,
|
||||
"no-bus-reset-attach");
|
||||
fu_device_register_private_flag(FU_DEVICE(self), FU_DFU_DEVICE_FLAG_GD32, "gd32");
|
||||
fu_device_register_private_flag(FU_DEVICE(self),
|
||||
FU_DFU_DEVICE_FLAG_ALLOW_ZERO_POLLTIMEOUT,
|
||||
"allow-zero-polltimeout");
|
||||
}
|
||||
|
@ -65,9 +65,12 @@ fu_dfu_device_get_runtime_pid(FuDfuDevice *self);
|
||||
guint16
|
||||
fu_dfu_device_get_runtime_release(FuDfuDevice *self);
|
||||
gboolean
|
||||
fu_dfu_device_reset(FuDfuDevice *self, GError **error);
|
||||
fu_dfu_device_reset(FuDfuDevice *self, FuProgress *progress, GError **error);
|
||||
FuFirmware *
|
||||
fu_dfu_device_upload(FuDfuDevice *self, FuDfuTargetTransferFlags flags, GError **error);
|
||||
fu_dfu_device_upload(FuDfuDevice *self,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_dfu_device_refresh(FuDfuDevice *self, GError **error);
|
||||
gboolean
|
||||
|
@ -82,7 +82,7 @@ G_DEFINE_TYPE_WITH_PRIVATE(FuDfuTargetAvr, fu_dfu_target_avr, FU_TYPE_DFU_TARGET
|
||||
#define ATMEL_MANUFACTURER_CODE2 0x1e
|
||||
|
||||
static gboolean
|
||||
fu_dfu_target_avr_mass_erase(FuDfuTarget *target, GError **error)
|
||||
fu_dfu_target_avr_mass_erase(FuDfuTarget *target, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) data_in = NULL;
|
||||
guint8 buf[3];
|
||||
@ -95,18 +95,15 @@ fu_dfu_target_avr_mass_erase(FuDfuTarget *target, GError **error)
|
||||
buf[1] = DFU_AVR32_CMD_ERASE;
|
||||
buf[2] = 0xff;
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
g_debug("mass erasing");
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot mass-erase: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_IDLE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dfu_target_avr_attach(FuDfuTarget *target, GError **error)
|
||||
fu_dfu_target_avr_attach(FuDfuTarget *target, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint8 buf[3];
|
||||
g_autoptr(GBytes) data_empty = NULL;
|
||||
@ -118,7 +115,7 @@ fu_dfu_target_avr_attach(FuDfuTarget *target, GError **error)
|
||||
buf[1] = DFU_AVR32_CMD_START_APPLI;
|
||||
buf[2] = DFU_AVR32_START_APPLI_RESET;
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, &error_local)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, &error_local)) {
|
||||
if (g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) {
|
||||
g_debug("ignoring as device rebooting: %s", error_local->message);
|
||||
return TRUE;
|
||||
@ -129,7 +126,7 @@ fu_dfu_target_avr_attach(FuDfuTarget *target, GError **error)
|
||||
|
||||
/* do zero-sized download to initiate the reset */
|
||||
data_empty = g_bytes_new(NULL, 0);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_empty, &error_local)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_empty, progress, &error_local)) {
|
||||
if (g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) {
|
||||
g_debug("ignoring as device rebooting: %s", error_local->message);
|
||||
return TRUE;
|
||||
@ -153,7 +150,10 @@ fu_dfu_target_avr_attach(FuDfuTarget *target, GError **error)
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
static gboolean
|
||||
fu_dfu_target_avr_select_memory_unit(FuDfuTarget *target, guint8 memory_unit, GError **error)
|
||||
fu_dfu_target_avr_select_memory_unit(FuDfuTarget *target,
|
||||
guint8 memory_unit,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) data_in = NULL;
|
||||
guint8 buf[4];
|
||||
@ -172,7 +172,7 @@ fu_dfu_target_avr_select_memory_unit(FuDfuTarget *target, guint8 memory_unit, GE
|
||||
buf[3] = memory_unit;
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
g_debug("selecting memory unit 0x%02x", (guint)memory_unit);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot select memory unit: ");
|
||||
return FALSE;
|
||||
}
|
||||
@ -190,7 +190,10 @@ fu_dfu_target_avr_select_memory_unit(FuDfuTarget *target, guint8 memory_unit, GE
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
static gboolean
|
||||
fu_dfu_target_avr_select_memory_page(FuDfuTarget *target, guint16 memory_page, GError **error)
|
||||
fu_dfu_target_avr_select_memory_page(FuDfuTarget *target,
|
||||
guint16 memory_page,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) data_in = NULL;
|
||||
guint8 buf[4];
|
||||
@ -213,7 +216,7 @@ fu_dfu_target_avr_select_memory_page(FuDfuTarget *target, guint16 memory_page, G
|
||||
buf[3] = memory_page & 0xff;
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
g_debug("selecting memory page 0x%01x", (guint)memory_page);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot select memory page: ");
|
||||
return FALSE;
|
||||
}
|
||||
@ -231,7 +234,10 @@ fu_dfu_target_avr_select_memory_page(FuDfuTarget *target, guint16 memory_page, G
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
static gboolean
|
||||
fu_dfu_target_avr32_select_memory_page(FuDfuTarget *target, guint16 memory_page, GError **error)
|
||||
fu_dfu_target_avr32_select_memory_page(FuDfuTarget *target,
|
||||
guint16 memory_page,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) data_in = NULL;
|
||||
guint8 buf[5];
|
||||
@ -243,7 +249,7 @@ fu_dfu_target_avr32_select_memory_page(FuDfuTarget *target, guint16 memory_page,
|
||||
fu_common_write_uint16(&buf[3], memory_page, G_BIG_ENDIAN);
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
g_debug("selecting memory page 0x%02x", (guint)memory_page);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot select memory page: ");
|
||||
return FALSE;
|
||||
}
|
||||
@ -265,6 +271,7 @@ static gboolean
|
||||
fu_dfu_target_avr_read_memory(FuDfuTarget *target,
|
||||
guint16 addr_start,
|
||||
guint16 addr_end,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) data_in = NULL;
|
||||
@ -277,7 +284,7 @@ fu_dfu_target_avr_read_memory(FuDfuTarget *target,
|
||||
fu_common_write_uint16(&buf[4], addr_end, G_BIG_ENDIAN);
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
g_debug("reading memory from 0x%04x to 0x%04x", (guint)addr_start, (guint)addr_end);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error,
|
||||
"cannot read memory 0x%04x to 0x%04x: ",
|
||||
(guint)addr_start,
|
||||
@ -298,7 +305,11 @@ fu_dfu_target_avr_read_memory(FuDfuTarget *target,
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
static gboolean
|
||||
fu_dfu_target_avr_read_command(FuDfuTarget *target, guint8 page, guint8 addr, GError **error)
|
||||
fu_dfu_target_avr_read_command(FuDfuTarget *target,
|
||||
guint8 page,
|
||||
guint8 addr,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) data_in = NULL;
|
||||
guint8 buf[3];
|
||||
@ -309,7 +320,7 @@ fu_dfu_target_avr_read_command(FuDfuTarget *target, guint8 page, guint8 addr, GE
|
||||
buf[2] = addr;
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
g_debug("read command page:0x%02x addr:0x%02x", (guint)page, (guint)addr);
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot read command page: ");
|
||||
return FALSE;
|
||||
}
|
||||
@ -326,18 +337,21 @@ fu_dfu_target_avr_read_command(FuDfuTarget *target, guint8 page, guint8 addr, GE
|
||||
* Returns: a 4-byte %GBytes object for success, else %NULL
|
||||
**/
|
||||
static GBytes *
|
||||
fu_dfu_target_avr32_get_chip_signature(FuDfuTarget *target, GError **error)
|
||||
fu_dfu_target_avr32_get_chip_signature(FuDfuTarget *target, FuProgress *progress, GError **error)
|
||||
{
|
||||
/* select unit, and request 4 bytes */
|
||||
if (!fu_dfu_target_avr_select_memory_unit(target, DFU_AVR32_MEMORY_UNIT_SIGNATURE, error))
|
||||
if (!fu_dfu_target_avr_select_memory_unit(target,
|
||||
DFU_AVR32_MEMORY_UNIT_SIGNATURE,
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
if (!fu_dfu_target_avr32_select_memory_page(target, 0x00, error))
|
||||
if (!fu_dfu_target_avr32_select_memory_page(target, 0x00, progress, error))
|
||||
return NULL;
|
||||
if (!fu_dfu_target_avr_read_memory(target, 0x00, 0x03, error))
|
||||
if (!fu_dfu_target_avr_read_memory(target, 0x00, 0x03, progress, error))
|
||||
return NULL;
|
||||
|
||||
/* get data back */
|
||||
return fu_dfu_target_upload_chunk(target, 0x00, 0, error);
|
||||
return fu_dfu_target_upload_chunk(target, 0x00, 0, progress, error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,7 +364,7 @@ fu_dfu_target_avr32_get_chip_signature(FuDfuTarget *target, GError **error)
|
||||
* Returns: a 4-byte %GBytes object for success, else %NULL
|
||||
**/
|
||||
static GBytes *
|
||||
fu_dfu_target_avr_get_chip_signature(FuDfuTarget *target, GError **error)
|
||||
fu_dfu_target_avr_get_chip_signature(FuDfuTarget *target, FuProgress *progress, GError **error)
|
||||
{
|
||||
struct {
|
||||
guint8 page;
|
||||
@ -371,11 +385,12 @@ fu_dfu_target_avr_get_chip_signature(FuDfuTarget *target, GError **error)
|
||||
if (!fu_dfu_target_avr_read_command(target,
|
||||
signature_locations[i].page,
|
||||
signature_locations[i].addr,
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
/* get data back */
|
||||
chunk_byte = fu_dfu_target_upload_chunk(target, 0x00, 0x01, error);
|
||||
chunk_byte = fu_dfu_target_upload_chunk(target, 0x00, 0x01, progress, error);
|
||||
if (chunk_byte == NULL)
|
||||
return NULL;
|
||||
if (g_bytes_get_size(chunk_byte) != 1) {
|
||||
@ -405,6 +420,7 @@ fu_dfu_target_avr_setup(FuDfuTarget *target, GError **error)
|
||||
gsize sz;
|
||||
guint32 device_id_be;
|
||||
g_autofree gchar *chip_id_guid = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GBytes) chunk_sig = NULL;
|
||||
|
||||
/* already done */
|
||||
@ -414,11 +430,11 @@ fu_dfu_target_avr_setup(FuDfuTarget *target, GError **error)
|
||||
/* different methods for AVR vs. AVR32 */
|
||||
if (fu_device_has_private_flag(FU_DEVICE(fu_dfu_target_get_device(target)),
|
||||
FU_DFU_DEVICE_FLAG_LEGACY_PROTOCOL)) {
|
||||
chunk_sig = fu_dfu_target_avr_get_chip_signature(target, error);
|
||||
chunk_sig = fu_dfu_target_avr_get_chip_signature(target, progress, error);
|
||||
if (chunk_sig == NULL)
|
||||
return FALSE;
|
||||
} else {
|
||||
chunk_sig = fu_dfu_target_avr32_get_chip_signature(target, error);
|
||||
chunk_sig = fu_dfu_target_avr32_get_chip_signature(target, progress, error);
|
||||
if (chunk_sig == NULL) {
|
||||
g_prefix_error(error, "failed to get chip signature: ");
|
||||
return FALSE;
|
||||
@ -477,6 +493,7 @@ fu_dfu_target_avr_setup(FuDfuTarget *target, GError **error)
|
||||
static gboolean
|
||||
fu_dfu_target_avr_download_element(FuDfuTarget *target,
|
||||
FuChunk *chk,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -505,13 +522,21 @@ fu_dfu_target_avr_download_element(FuDfuTarget *target,
|
||||
0xff,
|
||||
0xff}; /* release */
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
|
||||
/* select a memory and erase everything */
|
||||
if (!fu_dfu_target_avr_select_memory_unit(target,
|
||||
fu_dfu_target_get_alt_setting(target),
|
||||
progress,
|
||||
error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_target_avr_mass_erase(target, error))
|
||||
if (!fu_dfu_target_avr_mass_erase(target, progress, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify the element isn't larger than the target size */
|
||||
blob = fu_chunk_get_bytes(chk);
|
||||
@ -554,11 +579,8 @@ fu_dfu_target_avr_download_element(FuDfuTarget *target,
|
||||
fu_dfu_sector_get_address(sector),
|
||||
ATMEL_64KB_PAGE,
|
||||
ATMEL_MAX_TRANSFER_SIZE);
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_DEVICE_WRITE);
|
||||
|
||||
/* process each chunk */
|
||||
fu_progress_set_id(fu_progress_get_child(progress), G_STRLOC);
|
||||
fu_progress_set_steps(fu_progress_get_child(progress), chunks->len);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk2 = g_ptr_array_index(chunks, i);
|
||||
g_autofree guint8 *buf = NULL;
|
||||
@ -570,11 +592,13 @@ fu_dfu_target_avr_download_element(FuDfuTarget *target,
|
||||
FU_DFU_DEVICE_FLAG_LEGACY_PROTOCOL)) {
|
||||
if (!fu_dfu_target_avr_select_memory_page(target,
|
||||
fu_chunk_get_page(chk2),
|
||||
progress,
|
||||
error))
|
||||
return FALSE;
|
||||
} else {
|
||||
if (!fu_dfu_target_avr32_select_memory_page(target,
|
||||
fu_chunk_get_page(chk2),
|
||||
progress,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
@ -598,16 +622,15 @@ fu_dfu_target_avr_download_element(FuDfuTarget *target,
|
||||
fu_chunk_get_data_sz(chk2) + header_sz + sizeof(footer));
|
||||
g_debug("sending %" G_GSIZE_FORMAT " bytes to the hardware",
|
||||
g_bytes_get_size(chunk_tmp));
|
||||
if (!fu_dfu_target_download_chunk(target, i, chunk_tmp, error))
|
||||
if (!fu_dfu_target_download_chunk(target, i, chunk_tmp, progress, error))
|
||||
return FALSE;
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_percentage(target, i + 1, chunks->len);
|
||||
fu_progress_step_done(fu_progress_get_child(progress));
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* done */
|
||||
fu_dfu_target_set_percentage_raw(target, 100);
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_IDLE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -616,6 +639,7 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
guint32 address,
|
||||
gsize expected_size,
|
||||
gsize maximum_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint16 page_last = G_MAXUINT16;
|
||||
@ -630,6 +654,7 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
/* select unit */
|
||||
if (!fu_dfu_target_avr_select_memory_unit(target,
|
||||
fu_dfu_target_get_alt_setting(target),
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
@ -661,7 +686,7 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
ATMEL_MAX_TRANSFER_SIZE);
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
|
||||
/* process each chunk */
|
||||
blobs = g_ptr_array_new_with_free_func((GDestroyNotify)g_bytes_unref);
|
||||
@ -675,11 +700,13 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
FU_DFU_DEVICE_FLAG_LEGACY_PROTOCOL)) {
|
||||
if (!fu_dfu_target_avr_select_memory_page(target,
|
||||
fu_chunk_get_page(chk),
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
} else {
|
||||
if (!fu_dfu_target_avr32_select_memory_page(target,
|
||||
fu_chunk_get_page(chk),
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
}
|
||||
@ -691,6 +718,7 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
fu_chunk_get_address(chk),
|
||||
fu_chunk_get_address(chk) +
|
||||
fu_chunk_get_data_sz(chk) - 1,
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
@ -698,7 +726,8 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
g_debug("requesting %i bytes from the hardware for chunk 0x%x",
|
||||
ATMEL_MAX_TRANSFER_SIZE,
|
||||
i);
|
||||
blob_tmp = fu_dfu_target_upload_chunk(target, i, ATMEL_MAX_TRANSFER_SIZE, error);
|
||||
blob_tmp =
|
||||
fu_dfu_target_upload_chunk(target, i, ATMEL_MAX_TRANSFER_SIZE, progress, error);
|
||||
if (blob_tmp == NULL)
|
||||
return NULL;
|
||||
g_ptr_array_add(blobs, blob_tmp);
|
||||
@ -714,13 +743,9 @@ fu_dfu_target_avr_upload_element(FuDfuTarget *target,
|
||||
}
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_percentage(target, i + 1, chunks->len);
|
||||
fu_progress_set_percentage_full(progress, i + 1, chunks->len);
|
||||
}
|
||||
|
||||
/* done */
|
||||
fu_dfu_target_set_percentage_raw(target, 100);
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_IDLE);
|
||||
|
||||
/* truncate the image if any sectors are empty, i.e. all 0xff */
|
||||
if (chunk_valid == G_MAXUINT) {
|
||||
g_debug("all %u chunks are empty", blobs->len);
|
||||
|
@ -16,11 +16,19 @@ FuDfuTarget *
|
||||
fu_dfu_target_new(void);
|
||||
|
||||
GBytes *
|
||||
fu_dfu_target_upload_chunk(FuDfuTarget *self, guint16 index, gsize buf_sz, GError **error);
|
||||
fu_dfu_target_upload_chunk(FuDfuTarget *self,
|
||||
guint16 index,
|
||||
gsize buf_sz,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_dfu_target_download_chunk(FuDfuTarget *self, guint16 index, GBytes *bytes, GError **error);
|
||||
fu_dfu_target_download_chunk(FuDfuTarget *self,
|
||||
guint16 index,
|
||||
GBytes *bytes,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_dfu_target_attach(FuDfuTarget *self, GError **error);
|
||||
fu_dfu_target_attach(FuDfuTarget *self, FuProgress *progress, GError **error);
|
||||
void
|
||||
fu_dfu_target_set_alt_idx(FuDfuTarget *self, guint8 alt_idx);
|
||||
void
|
||||
@ -28,12 +36,6 @@ fu_dfu_target_set_alt_setting(FuDfuTarget *self, guint8 alt_setting);
|
||||
|
||||
/* for the other implementations */
|
||||
void
|
||||
fu_dfu_target_set_action(FuDfuTarget *self, FwupdStatus action);
|
||||
void
|
||||
fu_dfu_target_set_percentage_raw(FuDfuTarget *self, guint percentage);
|
||||
void
|
||||
fu_dfu_target_set_percentage(FuDfuTarget *self, guint value, guint total);
|
||||
void
|
||||
fu_dfu_target_set_alt_name(FuDfuTarget *self, const gchar *alt_name);
|
||||
void
|
||||
fu_dfu_target_set_device(FuDfuTarget *self, FuDfuDevice *device);
|
||||
|
@ -27,16 +27,16 @@ G_DEFINE_TYPE(FuDfuTargetStm, fu_dfu_target_stm, FU_TYPE_DFU_TARGET)
|
||||
#define DFU_STM_CMD_READ_UNPROTECT 0x92
|
||||
|
||||
static gboolean
|
||||
fu_dfu_target_stm_attach(FuDfuTarget *target, GError **error)
|
||||
fu_dfu_target_stm_attach(FuDfuTarget *target, FuProgress *progress, GError **error)
|
||||
{
|
||||
/* downloading empty payload will cause a dfu to leave,
|
||||
* the returned status will be dfuMANIFEST and expect the device to disconnect */
|
||||
g_autoptr(GBytes) bytes_tmp = g_bytes_new(NULL, 0);
|
||||
return fu_dfu_target_download_chunk(target, 2, bytes_tmp, error);
|
||||
return fu_dfu_target_download_chunk(target, 2, bytes_tmp, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_dfu_target_stm_mass_erase(FuDfuTarget *target, GError **error)
|
||||
fu_dfu_target_stm_mass_erase(FuDfuTarget *target, FuProgress *progress, GError **error)
|
||||
{
|
||||
GBytes *data_in;
|
||||
guint8 buf[1];
|
||||
@ -44,7 +44,7 @@ fu_dfu_target_stm_mass_erase(FuDfuTarget *target, GError **error)
|
||||
/* format buffer */
|
||||
buf[0] = DFU_STM_CMD_ERASE;
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot mass-erase: ");
|
||||
return FALSE;
|
||||
}
|
||||
@ -53,18 +53,12 @@ fu_dfu_target_stm_mass_erase(FuDfuTarget *target, GError **error)
|
||||
return fu_dfu_target_check_status(target, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_dfu_target_stm_set_address:
|
||||
* @target: a #FuDfuTarget
|
||||
* @address: memory address
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Sets the address used for the next download or upload request.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
/* sets the address used for the next download or upload request */
|
||||
static gboolean
|
||||
fu_dfu_target_stm_set_address(FuDfuTarget *target, guint32 address, GError **error)
|
||||
fu_dfu_target_stm_set_address(FuDfuTarget *target,
|
||||
guint32 address,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *data_in;
|
||||
guint8 buf[5];
|
||||
@ -73,7 +67,7 @@ fu_dfu_target_stm_set_address(FuDfuTarget *target, guint32 address, GError **err
|
||||
buf[0] = DFU_STM_CMD_SET_ADDRESS_POINTER;
|
||||
memcpy(buf + 1, &address, 4);
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot set address 0x%x: ", address);
|
||||
return FALSE;
|
||||
}
|
||||
@ -88,6 +82,7 @@ fu_dfu_target_stm_upload_element(FuDfuTarget *target,
|
||||
guint32 address,
|
||||
gsize expected_size,
|
||||
gsize maximum_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuDevice *device = fu_dfu_target_get_device(target);
|
||||
@ -123,11 +118,11 @@ fu_dfu_target_stm_upload_element(FuDfuTarget *target,
|
||||
}
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
|
||||
/* manually set the sector address */
|
||||
g_debug("setting DfuSe address to 0x%04x", (guint)offset);
|
||||
if (!fu_dfu_target_stm_set_address(target, offset, error))
|
||||
if (!fu_dfu_target_stm_set_address(target, offset, progress, error))
|
||||
return NULL;
|
||||
|
||||
/* abort back to IDLE */
|
||||
@ -144,6 +139,7 @@ fu_dfu_target_stm_upload_element(FuDfuTarget *target,
|
||||
chunk_tmp = fu_dfu_target_upload_chunk(target,
|
||||
idx + 2,
|
||||
0, /* device transfer size */
|
||||
progress,
|
||||
error);
|
||||
if (chunk_tmp == NULL)
|
||||
return NULL;
|
||||
@ -160,7 +156,7 @@ fu_dfu_target_stm_upload_element(FuDfuTarget *target,
|
||||
|
||||
/* update UI */
|
||||
if (chunk_size > 0)
|
||||
fu_dfu_target_set_percentage(target, total_size, percentage_size);
|
||||
fu_progress_set_percentage_full(progress, total_size, percentage_size);
|
||||
|
||||
/* detect short write as EOF */
|
||||
if (chunk_size < transfer_size)
|
||||
@ -189,10 +185,6 @@ fu_dfu_target_stm_upload_element(FuDfuTarget *target,
|
||||
}
|
||||
}
|
||||
|
||||
/* done */
|
||||
fu_dfu_target_set_percentage_raw(target, 100);
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_IDLE);
|
||||
|
||||
/* create new image */
|
||||
contents = fu_dfu_utils_bytes_join_array(chunks);
|
||||
if (expected_size > 0) {
|
||||
@ -218,7 +210,10 @@ fu_dfu_target_stm_upload_element(FuDfuTarget *target,
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
static gboolean
|
||||
fu_dfu_target_stm_erase_address(FuDfuTarget *target, guint32 address, GError **error)
|
||||
fu_dfu_target_stm_erase_address(FuDfuTarget *target,
|
||||
guint32 address,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *data_in;
|
||||
guint8 buf[5];
|
||||
@ -227,7 +222,7 @@ fu_dfu_target_stm_erase_address(FuDfuTarget *target, guint32 address, GError **e
|
||||
buf[0] = DFU_STM_CMD_ERASE;
|
||||
memcpy(buf + 1, &address, 4);
|
||||
data_in = g_bytes_new_static(buf, sizeof(buf));
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, error)) {
|
||||
if (!fu_dfu_target_download_chunk(target, 0, data_in, progress, error)) {
|
||||
g_prefix_error(error, "cannot erase address 0x%x: ", address);
|
||||
return FALSE;
|
||||
}
|
||||
@ -240,11 +235,13 @@ fu_dfu_target_stm_erase_address(FuDfuTarget *target, guint32 address, GError **e
|
||||
static gboolean
|
||||
fu_dfu_target_stm_download_element(FuDfuTarget *target,
|
||||
FuChunk *chk,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuDevice *device = fu_dfu_target_get_device(target);
|
||||
FuDfuSector *sector;
|
||||
FuProgress *progress_local;
|
||||
guint nr_chunks;
|
||||
guint zone_last = G_MAXUINT;
|
||||
guint16 transfer_size = fu_dfu_device_get_transfer_size(device);
|
||||
@ -263,6 +260,13 @@ fu_dfu_target_stm_download_element(FuDfuTarget *target,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 89);
|
||||
|
||||
/* 1st pass: work out which sectors need erasing */
|
||||
sectors_array = g_ptr_array_new();
|
||||
sectors_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
@ -306,23 +310,28 @@ fu_dfu_target_stm_download_element(FuDfuTarget *target,
|
||||
offset_dev += fu_dfu_sector_get_size(sector);
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* 2nd pass: actually erase sectors */
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_DEVICE_ERASE);
|
||||
progress_local = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(progress_local, G_STRLOC);
|
||||
fu_progress_set_steps(progress_local, sectors_array->len);
|
||||
for (guint i = 0; i < sectors_array->len; i++) {
|
||||
sector = g_ptr_array_index(sectors_array, i);
|
||||
g_debug("erasing sector at 0x%04x", fu_dfu_sector_get_address(sector));
|
||||
if (!fu_dfu_target_stm_erase_address(target,
|
||||
fu_dfu_sector_get_address(sector),
|
||||
fu_progress_get_child(progress_local),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_dfu_target_set_percentage(target, i + 1, sectors_array->len);
|
||||
fu_progress_step_done(progress_local);
|
||||
}
|
||||
fu_dfu_target_set_percentage_raw(target, 100);
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_IDLE);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* 3rd pass: write data */
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_DEVICE_WRITE);
|
||||
progress_local = fu_progress_get_child(progress);
|
||||
fu_progress_set_id(progress_local, G_STRLOC);
|
||||
fu_progress_set_steps(progress_local, nr_chunks);
|
||||
for (guint i = 0; i < nr_chunks; i++) {
|
||||
gsize length;
|
||||
guint32 offset;
|
||||
@ -340,7 +349,10 @@ fu_dfu_target_stm_download_element(FuDfuTarget *target,
|
||||
/* manually set the sector address */
|
||||
if (fu_dfu_sector_get_zone(sector) != zone_last) {
|
||||
g_debug("setting address to 0x%04x", (guint)offset_dev);
|
||||
if (!fu_dfu_target_stm_set_address(target, (guint32)offset_dev, error))
|
||||
if (!fu_dfu_target_stm_set_address(target,
|
||||
(guint32)offset_dev,
|
||||
fu_progress_get_child(progress_local),
|
||||
error))
|
||||
return FALSE;
|
||||
zone_last = fu_dfu_sector_get_zone(sector);
|
||||
}
|
||||
@ -356,7 +368,11 @@ fu_dfu_target_stm_download_element(FuDfuTarget *target,
|
||||
offset_dev,
|
||||
g_bytes_get_size(bytes_tmp));
|
||||
/* ST uses wBlockNum=0 for DfuSe commands and wBlockNum=1 is reserved */
|
||||
if (!fu_dfu_target_download_chunk(target, (i + 2), bytes_tmp, error))
|
||||
if (!fu_dfu_target_download_chunk(target,
|
||||
(i + 2),
|
||||
bytes_tmp,
|
||||
fu_progress_get_child(progress_local),
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* getting the status moves the state machine to DNLOAD-IDLE */
|
||||
@ -364,12 +380,9 @@ fu_dfu_target_stm_download_element(FuDfuTarget *target,
|
||||
return FALSE;
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_percentage(target, offset, g_bytes_get_size(bytes));
|
||||
fu_progress_step_done(progress_local);
|
||||
}
|
||||
|
||||
/* done */
|
||||
fu_dfu_target_set_percentage_raw(target, 100);
|
||||
fu_dfu_target_set_action(target, FWUPD_STATUS_IDLE);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
|
@ -45,10 +45,6 @@ typedef struct {
|
||||
FwupdStatus old_action;
|
||||
} FuDfuTargetPrivate;
|
||||
|
||||
enum { SIGNAL_PERCENTAGE_CHANGED, SIGNAL_ACTION_CHANGED, SIGNAL_LAST };
|
||||
|
||||
static guint signals[SIGNAL_LAST] = {0};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(FuDfuTarget, fu_dfu_target, G_TYPE_OBJECT)
|
||||
#define GET_PRIVATE(o) (fu_dfu_target_get_instance_private(o))
|
||||
|
||||
@ -56,45 +52,6 @@ static void
|
||||
fu_dfu_target_class_init(FuDfuTargetClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
/**
|
||||
* FuDfuTarget::percentage-changed:
|
||||
* @device: the #FuDfuTarget instance that emitted the signal
|
||||
* @percentage: the new percentage
|
||||
*
|
||||
* The ::percentage-changed signal is emitted when the percentage changes.
|
||||
**/
|
||||
signals[SIGNAL_PERCENTAGE_CHANGED] =
|
||||
g_signal_new("percentage-changed",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(FuDfuTargetClass, percentage_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* FuDfuTarget::action-changed:
|
||||
* @device: the #FuDfuTarget instance that emitted the signal
|
||||
* @action: the new FwupdStatus
|
||||
*
|
||||
* The ::action-changed signal is emitted when the high level action changes.
|
||||
**/
|
||||
signals[SIGNAL_ACTION_CHANGED] =
|
||||
g_signal_new("action-changed",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(FuDfuTargetClass, action_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_UINT);
|
||||
|
||||
object_class->finalize = fu_dfu_target_finalize;
|
||||
}
|
||||
|
||||
@ -750,7 +707,7 @@ fu_dfu_target_setup(FuDfuTarget *self, GError **error)
|
||||
* Returns: %TRUE for success
|
||||
**/
|
||||
gboolean
|
||||
fu_dfu_target_mass_erase(FuDfuTarget *self, GError **error)
|
||||
fu_dfu_target_mass_erase(FuDfuTarget *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuTargetClass *klass = FU_DFU_TARGET_GET_CLASS(self);
|
||||
if (!fu_dfu_target_setup(self, error))
|
||||
@ -762,11 +719,15 @@ fu_dfu_target_mass_erase(FuDfuTarget *self, GError **error)
|
||||
"mass erase not supported");
|
||||
return FALSE;
|
||||
}
|
||||
return klass->mass_erase(self, error);
|
||||
return klass->mass_erase(self, progress, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_dfu_target_download_chunk(FuDfuTarget *self, guint16 index, GBytes *bytes, GError **error)
|
||||
fu_dfu_target_download_chunk(FuDfuTarget *self,
|
||||
guint16 index,
|
||||
GBytes *bytes,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(priv->device));
|
||||
@ -807,10 +768,8 @@ fu_dfu_target_download_chunk(FuDfuTarget *self, guint16 index, GBytes *bytes, GE
|
||||
}
|
||||
|
||||
/* wait for the device to write contents to the EEPROM */
|
||||
if (g_bytes_get_size(bytes) == 0 && fu_dfu_device_get_download_timeout(priv->device) > 0) {
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_IDLE);
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_DEVICE_BUSY);
|
||||
}
|
||||
if (g_bytes_get_size(bytes) == 0 && fu_dfu_device_get_download_timeout(priv->device) > 0)
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (fu_dfu_device_get_download_timeout(priv->device) > 0) {
|
||||
g_debug("sleeping for %ums…", fu_dfu_device_get_download_timeout(priv->device));
|
||||
g_usleep(fu_dfu_device_get_download_timeout(priv->device) * 1000);
|
||||
@ -825,7 +784,11 @@ fu_dfu_target_download_chunk(FuDfuTarget *self, guint16 index, GBytes *bytes, GE
|
||||
}
|
||||
|
||||
GBytes *
|
||||
fu_dfu_target_upload_chunk(FuDfuTarget *self, guint16 index, gsize buf_sz, GError **error)
|
||||
fu_dfu_target_upload_chunk(FuDfuTarget *self,
|
||||
guint16 index,
|
||||
gsize buf_sz,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(priv->device));
|
||||
@ -882,25 +845,6 @@ fu_dfu_target_set_alt_setting(FuDfuTarget *self, guint8 alt_setting)
|
||||
priv->alt_setting = alt_setting;
|
||||
}
|
||||
|
||||
void
|
||||
fu_dfu_target_set_action(FuDfuTarget *self, FwupdStatus action)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
|
||||
/* unchanged */
|
||||
if (priv->old_action == action)
|
||||
return;
|
||||
if (priv->old_action != FWUPD_STATUS_IDLE && action != FWUPD_STATUS_IDLE) {
|
||||
g_debug("ignoring action %s as %s already set and not idle",
|
||||
fwupd_status_to_string(action),
|
||||
fwupd_status_to_string(priv->old_action));
|
||||
return;
|
||||
}
|
||||
g_debug("setting action %s", fwupd_status_to_string(action));
|
||||
g_signal_emit(self, signals[SIGNAL_ACTION_CHANGED], 0, action);
|
||||
priv->old_action = action;
|
||||
}
|
||||
|
||||
FuDfuDevice *
|
||||
fu_dfu_target_get_device(FuDfuTarget *self)
|
||||
{
|
||||
@ -908,34 +852,8 @@ fu_dfu_target_get_device(FuDfuTarget *self)
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
void
|
||||
fu_dfu_target_set_percentage_raw(FuDfuTarget *self, guint percentage)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
if (percentage == priv->old_percentage)
|
||||
return;
|
||||
g_debug("setting percentage %u%% of %s",
|
||||
percentage,
|
||||
fwupd_status_to_string(priv->old_action));
|
||||
g_signal_emit(self, signals[SIGNAL_PERCENTAGE_CHANGED], 0, percentage);
|
||||
priv->old_percentage = percentage;
|
||||
}
|
||||
|
||||
void
|
||||
fu_dfu_target_set_percentage(FuDfuTarget *self, guint value, guint total)
|
||||
{
|
||||
guint percentage;
|
||||
|
||||
g_return_if_fail(total > 0);
|
||||
|
||||
percentage = (value * 100) / total;
|
||||
if (percentage >= 100)
|
||||
return;
|
||||
fu_dfu_target_set_percentage_raw(self, percentage);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_dfu_target_attach(FuDfuTarget *self, GError **error)
|
||||
fu_dfu_target_attach(FuDfuTarget *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
FuDfuTargetClass *klass = FU_DFU_TARGET_GET_CLASS(self);
|
||||
@ -946,10 +864,10 @@ fu_dfu_target_attach(FuDfuTarget *self, GError **error)
|
||||
|
||||
/* implemented as part of a superclass */
|
||||
if (klass->attach != NULL)
|
||||
return klass->attach(self, error);
|
||||
return klass->attach(self, progress, error);
|
||||
|
||||
/* normal DFU mode just needs a bus reset */
|
||||
return fu_dfu_device_reset(priv->device, error);
|
||||
return fu_dfu_device_reset(priv->device, progress, error);
|
||||
}
|
||||
|
||||
static FuChunk *
|
||||
@ -957,6 +875,7 @@ fu_dfu_target_upload_element_dfu(FuDfuTarget *self,
|
||||
guint32 address,
|
||||
gsize expected_size,
|
||||
gsize maximum_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
@ -969,7 +888,7 @@ fu_dfu_target_upload_element_dfu(FuDfuTarget *self,
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
|
||||
/* get all the chunks from the hardware */
|
||||
chunks = g_ptr_array_new_with_free_func((GDestroyNotify)g_bytes_unref);
|
||||
@ -980,6 +899,7 @@ fu_dfu_target_upload_element_dfu(FuDfuTarget *self,
|
||||
chunk_tmp = fu_dfu_target_upload_chunk(self,
|
||||
idx,
|
||||
0, /* device transfer size */
|
||||
progress,
|
||||
error);
|
||||
if (chunk_tmp == NULL)
|
||||
return NULL;
|
||||
@ -995,7 +915,7 @@ fu_dfu_target_upload_element_dfu(FuDfuTarget *self,
|
||||
|
||||
/* update UI */
|
||||
if (chunk_size > 0)
|
||||
fu_dfu_target_set_percentage(self, total_size, percentage_size);
|
||||
fu_progress_set_percentage_full(progress, total_size, percentage_size);
|
||||
|
||||
/* detect short write as EOF */
|
||||
if (chunk_size < transfer_size)
|
||||
@ -1017,8 +937,7 @@ fu_dfu_target_upload_element_dfu(FuDfuTarget *self,
|
||||
}
|
||||
|
||||
/* done */
|
||||
fu_dfu_target_set_percentage_raw(self, 100);
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_IDLE);
|
||||
fu_progress_set_percentage(progress, 100);
|
||||
|
||||
/* create new image */
|
||||
contents = fu_dfu_utils_bytes_join_array(chunks);
|
||||
@ -1030,15 +949,22 @@ fu_dfu_target_upload_element(FuDfuTarget *self,
|
||||
guint32 address,
|
||||
gsize expected_size,
|
||||
gsize maximum_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuTargetClass *klass = FU_DFU_TARGET_GET_CLASS(self);
|
||||
|
||||
/* implemented as part of a superclass */
|
||||
if (klass->upload_element != NULL) {
|
||||
return klass->upload_element(self, address, expected_size, maximum_size, error);
|
||||
return klass
|
||||
->upload_element(self, address, expected_size, maximum_size, progress, error);
|
||||
}
|
||||
return fu_dfu_target_upload_element_dfu(self, address, expected_size, maximum_size, error);
|
||||
return fu_dfu_target_upload_element_dfu(self,
|
||||
address,
|
||||
expected_size,
|
||||
maximum_size,
|
||||
progress,
|
||||
error);
|
||||
}
|
||||
|
||||
static guint32
|
||||
@ -1059,6 +985,7 @@ fu_dfu_target_get_size_of_zone(FuDfuTarget *self, guint16 zone)
|
||||
gboolean
|
||||
fu_dfu_target_upload(FuDfuTarget *self,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1104,6 +1031,8 @@ fu_dfu_target_upload(FuDfuTarget *self,
|
||||
fu_firmware_set_idx(image, priv->alt_setting);
|
||||
|
||||
/* get all the sectors for the device */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, priv->sectors->len);
|
||||
for (guint i = 0; i < priv->sectors->len; i++) {
|
||||
g_autoptr(FuChunk) chk = NULL;
|
||||
|
||||
@ -1125,12 +1054,14 @@ fu_dfu_target_upload(FuDfuTarget *self,
|
||||
fu_dfu_sector_get_address(sector),
|
||||
0, /* expected */
|
||||
zone_size, /* maximum */
|
||||
fu_progress_get_child(progress),
|
||||
error);
|
||||
if (chk == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* this chunk was uploaded okay */
|
||||
fu_firmware_add_chunk(image, chk);
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -1172,6 +1103,7 @@ _g_bytes_compare_verbose(GBytes *bytes1, GBytes *bytes2)
|
||||
static gboolean
|
||||
fu_dfu_target_download_element_dfu(FuDfuTarget *self,
|
||||
FuChunk *chk,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1190,7 +1122,7 @@ fu_dfu_target_download_element_dfu(FuDfuTarget *self,
|
||||
"zero-length firmware");
|
||||
return FALSE;
|
||||
}
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint32 i = 0; i < nr_chunks + 1; i++) {
|
||||
gsize length;
|
||||
guint32 offset;
|
||||
@ -1213,17 +1145,13 @@ fu_dfu_target_download_element_dfu(FuDfuTarget *self,
|
||||
g_debug("writing #%04x chunk of size %" G_GSIZE_FORMAT,
|
||||
i,
|
||||
g_bytes_get_size(bytes_tmp));
|
||||
if (!fu_dfu_target_download_chunk(self, i, bytes_tmp, error))
|
||||
if (!fu_dfu_target_download_chunk(self, i, bytes_tmp, progress, error))
|
||||
return FALSE;
|
||||
|
||||
/* update UI */
|
||||
fu_dfu_target_set_percentage(self, offset, g_bytes_get_size(bytes));
|
||||
fu_progress_set_percentage_full(progress, i + 1, nr_chunks + 1);
|
||||
}
|
||||
|
||||
/* done */
|
||||
fu_dfu_target_set_percentage_raw(self, 100);
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_IDLE);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
@ -1231,20 +1159,41 @@ fu_dfu_target_download_element_dfu(FuDfuTarget *self,
|
||||
static gboolean
|
||||
fu_dfu_target_download_element(FuDfuTarget *self,
|
||||
FuChunk *chk,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuDfuTargetPrivate *priv = GET_PRIVATE(self);
|
||||
FuDfuTargetClass *klass = FU_DFU_TARGET_GET_CLASS(self);
|
||||
|
||||
/* progress */
|
||||
if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY &&
|
||||
fu_dfu_device_has_attribute(priv->device, FU_DFU_DEVICE_ATTR_CAN_UPLOAD)) {
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 96);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 4);
|
||||
} else {
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, 1);
|
||||
}
|
||||
|
||||
/* implemented as part of a superclass */
|
||||
if (klass->download_element != NULL) {
|
||||
if (!klass->download_element(self, chk, flags, error))
|
||||
if (!klass->download_element(self,
|
||||
chk,
|
||||
fu_progress_get_child(progress),
|
||||
flags,
|
||||
error))
|
||||
return FALSE;
|
||||
} else {
|
||||
if (!fu_dfu_target_download_element_dfu(self, chk, flags, error))
|
||||
if (!fu_dfu_target_download_element_dfu(self,
|
||||
chk,
|
||||
fu_progress_get_child(progress),
|
||||
flags,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify */
|
||||
if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY &&
|
||||
@ -1252,12 +1201,12 @@ fu_dfu_target_download_element(FuDfuTarget *self,
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
g_autoptr(GBytes) bytes_tmp = NULL;
|
||||
g_autoptr(FuChunk) chunk_tmp = NULL;
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
bytes = fu_chunk_get_bytes(chk);
|
||||
chunk_tmp = fu_dfu_target_upload_element(self,
|
||||
fu_chunk_get_address(chk),
|
||||
g_bytes_get_size(bytes),
|
||||
g_bytes_get_size(bytes),
|
||||
fu_progress_get_child(progress),
|
||||
error);
|
||||
if (chunk_tmp == NULL)
|
||||
return FALSE;
|
||||
@ -1272,7 +1221,7 @@ fu_dfu_target_download_element(FuDfuTarget *self,
|
||||
bytes_cmp_str);
|
||||
return FALSE;
|
||||
}
|
||||
fu_dfu_target_set_action(self, FWUPD_STATUS_IDLE);
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1293,6 +1242,7 @@ fu_dfu_target_download_element(FuDfuTarget *self,
|
||||
gboolean
|
||||
fu_dfu_target_download(FuDfuTarget *self,
|
||||
FuFirmware *image,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1348,7 +1298,7 @@ fu_dfu_target_download(FuDfuTarget *self,
|
||||
}
|
||||
|
||||
/* download to device */
|
||||
if (!fu_dfu_target_download_element(self, chk, flags, error))
|
||||
if (!fu_dfu_target_download_element(self, chk, progress, flags, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -40,19 +40,20 @@ typedef enum {
|
||||
|
||||
struct _FuDfuTargetClass {
|
||||
GUsbDeviceClass parent_class;
|
||||
void (*percentage_changed)(FuDfuTarget *self, guint percentage);
|
||||
void (*action_changed)(FuDfuTarget *self, FwupdStatus action);
|
||||
gboolean (*setup)(FuDfuTarget *self, GError **error);
|
||||
gboolean (*attach)(FuDfuTarget *self, GError **error);
|
||||
gboolean (*detach)(FuDfuTarget *self, GError **error);
|
||||
gboolean (*mass_erase)(FuDfuTarget *self, GError **error);
|
||||
gboolean (*attach)(FuDfuTarget *self, FuProgress *progress, GError **error);
|
||||
gboolean (*detach)(FuDfuTarget *self, FuProgress *progress, GError **error);
|
||||
gboolean (*mass_erase)(FuDfuTarget *self, FuProgress *progress, GError **error);
|
||||
FuChunk *(*upload_element)(FuDfuTarget *self,
|
||||
guint32 address,
|
||||
gsize expected_size,
|
||||
gsize maximum_size,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
gboolean (*download_element)(FuDfuTarget *self,
|
||||
FuChunk *chk,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error);
|
||||
};
|
||||
@ -70,6 +71,7 @@ fu_dfu_target_get_alt_name_for_display(FuDfuTarget *self, GError **error);
|
||||
gboolean
|
||||
fu_dfu_target_upload(FuDfuTarget *self,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error);
|
||||
gboolean
|
||||
@ -77,9 +79,10 @@ fu_dfu_target_setup(FuDfuTarget *self, GError **error);
|
||||
gboolean
|
||||
fu_dfu_target_download(FuDfuTarget *self,
|
||||
FuFirmware *image,
|
||||
FuProgress *progress,
|
||||
FuDfuTargetTransferFlags flags,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_dfu_target_mass_erase(FuDfuTarget *self, GError **error);
|
||||
fu_dfu_target_mass_erase(FuDfuTarget *self, FuProgress *progress, GError **error);
|
||||
void
|
||||
fu_dfu_target_to_string(FuDfuTarget *self, guint idt, GString *str);
|
||||
|
@ -259,7 +259,6 @@ fu_dfu_device_wait_for_replug(FuDfuTool *self, FuDfuDevice *device, guint timeou
|
||||
return FALSE;
|
||||
|
||||
/* re-open with new device set */
|
||||
fu_device_set_status(FU_DEVICE(device), FWUPD_STATUS_IDLE);
|
||||
fu_usb_device_set_dev(FU_USB_DEVICE(device), usb_device2);
|
||||
if (!fu_device_open(FU_DEVICE(device), error))
|
||||
return FALSE;
|
||||
@ -444,11 +443,11 @@ fu_dfu_tool_replace_data(FuDfuTool *self, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_tool_action_changed_cb(FuDevice *device, GParamSpec *pspec, FuDfuTool *self)
|
||||
fu_tool_action_changed_cb(FuProgress *progress, gpointer dummy, FuDfuTool *self)
|
||||
{
|
||||
g_print("%s:\t%u%%\n",
|
||||
fwupd_status_to_string(fu_device_get_status(device)),
|
||||
fu_device_get_progress(device));
|
||||
fwupd_status_to_string(fu_progress_get_status(progress)),
|
||||
fu_progress_get_percentage(progress));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -461,6 +460,7 @@ fu_dfu_tool_read_alt(FuDfuTool *self, gchar **values, GError **error)
|
||||
g_autoptr(FuDfuTarget) target = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* check args */
|
||||
if (g_strv_length(values) < 2) {
|
||||
@ -485,13 +485,16 @@ fu_dfu_tool_read_alt(FuDfuTool *self, gchar **values, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* set up progress */
|
||||
g_signal_connect(device, "notify::status", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "notify::progress", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(progress, "status-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(progress,
|
||||
"percentage-changed",
|
||||
G_CALLBACK(fu_tool_action_changed_cb),
|
||||
self);
|
||||
|
||||
/* APP -> DFU */
|
||||
if (!fu_device_has_flag(FU_DEVICE(device), FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_debug("detaching");
|
||||
if (!fu_device_detach(FU_DEVICE(device), error))
|
||||
if (!fu_device_detach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self,
|
||||
device,
|
||||
@ -522,11 +525,11 @@ fu_dfu_tool_read_alt(FuDfuTool *self, gchar **values, GError **error)
|
||||
firmware = fu_dfuse_firmware_new();
|
||||
fu_dfu_firmware_set_vid(FU_DFU_FIRMWARE(firmware), fu_dfu_device_get_runtime_vid(device));
|
||||
fu_dfu_firmware_set_pid(FU_DFU_FIRMWARE(firmware), fu_dfu_device_get_runtime_pid(device));
|
||||
if (!fu_dfu_target_upload(target, firmware, flags, error))
|
||||
if (!fu_dfu_target_upload(target, firmware, progress, flags, error))
|
||||
return FALSE;
|
||||
|
||||
/* do host reset */
|
||||
if (!fu_device_attach(FU_DEVICE(device), error))
|
||||
if (!fu_device_attach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self,
|
||||
device,
|
||||
@ -557,6 +560,7 @@ fu_dfu_tool_read(FuDfuTool *self, gchar **values, GError **error)
|
||||
g_autoptr(FuFirmware) firmware = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* check args */
|
||||
if (g_strv_length(values) != 1) {
|
||||
@ -579,7 +583,7 @@ fu_dfu_tool_read(FuDfuTool *self, gchar **values, GError **error)
|
||||
|
||||
/* APP -> DFU */
|
||||
if (!fu_device_has_flag(FU_DEVICE(device), FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
if (!fu_device_detach(FU_DEVICE(device), error))
|
||||
if (!fu_device_detach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self,
|
||||
device,
|
||||
@ -590,14 +594,14 @@ fu_dfu_tool_read(FuDfuTool *self, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
/* transfer */
|
||||
g_signal_connect(device, "notify::status", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "notify::progress", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
firmware = fu_dfu_device_upload(device, flags, error);
|
||||
g_signal_connect(device, "status-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "percentage-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
firmware = fu_dfu_device_upload(device, progress, flags, error);
|
||||
if (firmware == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* do host reset */
|
||||
if (!fu_device_attach(FU_DEVICE(device), error))
|
||||
if (!fu_device_attach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self,
|
||||
device,
|
||||
@ -630,6 +634,7 @@ fu_dfu_tool_write_alt(FuDfuTool *self, gchar **values, GError **error)
|
||||
g_autoptr(FuDfuTarget) target = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* check args */
|
||||
if (g_strv_length(values) < 2) {
|
||||
@ -661,13 +666,13 @@ fu_dfu_tool_write_alt(FuDfuTool *self, gchar **values, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* set up progress */
|
||||
g_signal_connect(device, "notify::status", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "notify::progress", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "status-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "percentage-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
|
||||
/* APP -> DFU */
|
||||
if (!fu_device_has_flag(FU_DEVICE(device), FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_debug("detaching");
|
||||
if (!fu_device_detach(FU_DEVICE(device), error))
|
||||
if (!fu_device_detach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self, device, 5000, error))
|
||||
return FALSE;
|
||||
@ -721,11 +726,11 @@ fu_dfu_tool_write_alt(FuDfuTool *self, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
/* transfer */
|
||||
if (!fu_dfu_target_download(target, image, flags, error))
|
||||
if (!fu_dfu_target_download(target, image, progress, flags, error))
|
||||
return FALSE;
|
||||
|
||||
/* do host reset */
|
||||
if (!fu_device_attach(FU_DEVICE(device), error))
|
||||
if (!fu_device_attach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self,
|
||||
device,
|
||||
@ -745,6 +750,7 @@ fu_dfu_tool_write(FuDfuTool *self, gchar **values, GError **error)
|
||||
g_autoptr(FuDfuDevice) device = NULL;
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* check args */
|
||||
if (g_strv_length(values) < 1) {
|
||||
@ -772,7 +778,7 @@ fu_dfu_tool_write(FuDfuTool *self, gchar **values, GError **error)
|
||||
|
||||
/* APP -> DFU */
|
||||
if (!fu_device_has_flag(FU_DEVICE(device), FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
if (!fu_device_detach(FU_DEVICE(device), error))
|
||||
if (!fu_device_detach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
if (!fu_dfu_device_wait_for_replug(self,
|
||||
device,
|
||||
@ -788,13 +794,13 @@ fu_dfu_tool_write(FuDfuTool *self, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
/* transfer */
|
||||
g_signal_connect(device, "notify::status", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "notify::progress", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
if (!fu_device_write_firmware(FU_DEVICE(device), fw, flags, error))
|
||||
g_signal_connect(device, "status-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
g_signal_connect(device, "percentage-changed", G_CALLBACK(fu_tool_action_changed_cb), self);
|
||||
if (!fu_device_write_firmware(FU_DEVICE(device), fw, progress, flags, error))
|
||||
return FALSE;
|
||||
|
||||
/* do host reset */
|
||||
if (!fu_device_attach(FU_DEVICE(device), error))
|
||||
if (!fu_device_attach(FU_DEVICE(device), progress, error))
|
||||
return FALSE;
|
||||
|
||||
if (fu_dfu_device_has_attribute(device, FU_DFU_DEVICE_ATTR_MANIFEST_TOL)) {
|
||||
|
@ -374,7 +374,7 @@ fu_ebitdo_device_setup(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ebitdo_device_detach(FuDevice *device, GError **error)
|
||||
fu_ebitdo_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(FwupdRequest) request = fwupd_request_new();
|
||||
|
||||
@ -437,7 +437,6 @@ fu_ebitdo_device_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
/* wait */
|
||||
fu_device_set_progress(device, 0);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
|
||||
/* emit request */
|
||||
@ -452,6 +451,7 @@ fu_ebitdo_device_detach(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_ebitdo_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -489,6 +489,12 @@ fu_ebitdo_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* header */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 97);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 2);
|
||||
|
||||
/* get header and payload */
|
||||
fw_hdr = fu_firmware_get_image_by_id_bytes(firmware, FU_FIRMWARE_ID_HEADER, error);
|
||||
if (fw_hdr == NULL)
|
||||
@ -498,7 +504,6 @@ fu_ebitdo_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* set up the firmware header */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
buf = g_bytes_get_data(fw_hdr, &bufsz);
|
||||
if (!fu_ebitdo_device_send(self,
|
||||
FU_EBITDO_PKT_TYPE_USER_CMD,
|
||||
@ -514,6 +519,7 @@ fu_ebitdo_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to get ACK for fw update header: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* flash the firmware in 32 byte blocks */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw_payload, 0x0, 0x0, 32);
|
||||
@ -543,8 +549,11 @@ fu_ebitdo_device_write_firmware(FuDevice *device,
|
||||
fu_chunk_get_address(chk));
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(device, fu_chunk_get_idx(chk), chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 1,
|
||||
chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* set the "encode id" which is likely a checksum, bluetooth pairing
|
||||
* or maybe just security-through-obscurity -- also note:
|
||||
@ -584,20 +593,20 @@ fu_ebitdo_device_write_firmware(FuDevice *device,
|
||||
g_propagate_error(error, g_steal_pointer(&error_local));
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ebitdo_device_attach(FuDevice *device, GError **error)
|
||||
fu_ebitdo_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(device));
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* when doing a soft-reboot the device does not re-enumerate properly
|
||||
* so manually reboot the GUsbDevice */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!g_usb_device_reset(usb_device, &error_local)) {
|
||||
g_prefix_error(&error_local, "failed to force-reset device: ");
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_WILL_DISAPPEAR)) {
|
||||
@ -659,6 +668,17 @@ fu_ebitdo_device_prepare_firmware(FuDevice *device,
|
||||
return g_steal_pointer(&firmware);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ebitdo_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_NO_PROFILE);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 97); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ebitdo_device_init(FuEbitdoDevice *self)
|
||||
{
|
||||
@ -678,4 +698,5 @@ fu_ebitdo_device_class_init(FuEbitdoDeviceClass *klass)
|
||||
klass_device->open = fu_ebitdo_device_open;
|
||||
klass_device->probe = fu_ebitdo_device_probe;
|
||||
klass_device->prepare_firmware = fu_ebitdo_device_prepare_firmware;
|
||||
klass_device->set_progress = fu_ebitdo_set_progress;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ struct _FuElantpHidDevice {
|
||||
G_DEFINE_TYPE(FuElantpHidDevice, fu_elantp_hid_device, FU_TYPE_UDEV_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_elantp_hid_device_detach(FuDevice *device, GError **error);
|
||||
fu_elantp_hid_device_detach(FuDevice *device, FuProgress *progress, GError **error);
|
||||
|
||||
static void
|
||||
fu_elantp_hid_device_to_string(FuDevice *device, guint idt, GString *str)
|
||||
@ -300,6 +300,7 @@ fu_elantp_hid_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_elantp_hid_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -314,17 +315,25 @@ fu_elantp_hid_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 10); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 50);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 30);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 10); /* reset */
|
||||
|
||||
/* simple image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* detach */
|
||||
if (!fu_elantp_hid_device_detach(device, error))
|
||||
if (!fu_elantp_hid_device_detach(device, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
buf = g_bytes_get_data(fw, &bufsz);
|
||||
iap_addr = fu_elantp_firmware_get_iap_addr(firmware_elantp);
|
||||
chunks = fu_chunk_array_new(buf + iap_addr, bufsz - iap_addr, 0x0, 0x0, self->fw_page_size);
|
||||
@ -368,11 +377,13 @@ fu_elantp_hid_device_write_firmware(FuDevice *device,
|
||||
|
||||
/* update progress */
|
||||
checksum += csum_tmp;
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify the written checksum */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!fu_elantp_hid_device_read_cmd(self,
|
||||
ETP_CMD_I2C_IAP_CHECKSUM,
|
||||
csum_buf,
|
||||
@ -395,16 +406,16 @@ fu_elantp_hid_device_write_firmware(FuDevice *device,
|
||||
checksum_device);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* wait for a reset */
|
||||
fu_device_set_progress(device, 0);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
g_usleep(ELANTP_DELAY_COMPLETE * 1000);
|
||||
fu_progress_sleep(fu_progress_get_child(progress), ELANTP_DELAY_COMPLETE);
|
||||
fu_progress_step_done(progress);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_elantp_hid_device_detach(FuDevice *device, GError **error)
|
||||
fu_elantp_hid_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuElantpHidDevice *self = FU_ELANTP_HID_DEVICE(device);
|
||||
guint16 iap_ver;
|
||||
@ -415,7 +426,6 @@ fu_elantp_hid_device_detach(FuDevice *device, GError **error)
|
||||
/* sanity check */
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_debug("in bootloader mode, reset IC");
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_elantp_hid_device_write_cmd(self,
|
||||
ETP_CMD_I2C_IAP_RESET,
|
||||
ETP_I2C_IAP_RESET,
|
||||
@ -513,7 +523,7 @@ fu_elantp_hid_device_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_elantp_hid_device_attach(FuDevice *device, GError **error)
|
||||
fu_elantp_hid_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuElantpHidDevice *self = FU_ELANTP_HID_DEVICE(device);
|
||||
|
||||
@ -524,7 +534,6 @@ fu_elantp_hid_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
/* reset back to runtime */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_elantp_hid_device_write_cmd(self, ETP_CMD_I2C_IAP_RESET, ETP_I2C_IAP_RESET, error))
|
||||
return FALSE;
|
||||
g_usleep(ELANTP_DELAY_RESET * 1000);
|
||||
@ -583,6 +592,17 @@ fu_elantp_hid_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_elantp_hid_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_elantp_hid_device_init(FuElantpHidDevice *self)
|
||||
{
|
||||
@ -618,4 +638,5 @@ fu_elantp_hid_device_class_init(FuElantpHidDeviceClass *klass)
|
||||
klass_device->write_firmware = fu_elantp_hid_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_elantp_hid_device_prepare_firmware;
|
||||
klass_device->probe = fu_elantp_hid_device_probe;
|
||||
klass_device->set_progress = fu_elantp_hid_device_set_progress;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ struct _FuElantpI2cDevice {
|
||||
G_DEFINE_TYPE(FuElantpI2cDevice, fu_elantp_i2c_device, FU_TYPE_UDEV_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_elantp_i2c_device_detach(FuDevice *device, GError **error);
|
||||
fu_elantp_i2c_device_detach(FuDevice *device, FuProgress *progress, GError **error);
|
||||
|
||||
static void
|
||||
fu_elantp_i2c_device_to_string(FuDevice *device, guint idt, GString *str)
|
||||
@ -372,6 +372,7 @@ fu_elantp_i2c_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_elantp_i2c_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -386,17 +387,25 @@ fu_elantp_i2c_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1);
|
||||
|
||||
/* simple image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* detach */
|
||||
if (!fu_elantp_i2c_device_detach(device, error))
|
||||
if (!fu_elantp_i2c_device_detach(device, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
buf = g_bytes_get_data(fw, &bufsz);
|
||||
iap_addr = fu_elantp_firmware_get_iap_addr(firmware_elantp);
|
||||
chunks = fu_chunk_array_new(buf + iap_addr, bufsz - iap_addr, 0x0, 0x0, self->fw_page_size);
|
||||
@ -442,11 +451,13 @@ fu_elantp_i2c_device_write_firmware(FuDevice *device,
|
||||
|
||||
/* update progress */
|
||||
checksum += csum_tmp;
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify the written checksum */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!fu_elantp_i2c_device_read_cmd(self,
|
||||
ETP_CMD_I2C_IAP_CHECKSUM,
|
||||
csum_buf,
|
||||
@ -469,16 +480,16 @@ fu_elantp_i2c_device_write_firmware(FuDevice *device,
|
||||
checksum_device);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* wait for a reset */
|
||||
fu_device_set_progress(device, 0);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
g_usleep(ELANTP_DELAY_COMPLETE * 1000);
|
||||
fu_progress_sleep(fu_progress_get_child(progress), ELANTP_DELAY_COMPLETE);
|
||||
fu_progress_step_done(progress);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_elantp_i2c_device_detach(FuDevice *device, GError **error)
|
||||
fu_elantp_i2c_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint16 iap_ver;
|
||||
guint16 ic_type;
|
||||
@ -489,7 +500,6 @@ fu_elantp_i2c_device_detach(FuDevice *device, GError **error)
|
||||
/* sanity check */
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_debug("in bootloader mode, reset IC");
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_elantp_i2c_device_write_cmd(self,
|
||||
ETP_CMD_I2C_IAP_RESET,
|
||||
ETP_I2C_IAP_RESET,
|
||||
@ -607,7 +617,7 @@ fu_elantp_i2c_device_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_elantp_i2c_device_attach(FuDevice *device, GError **error)
|
||||
fu_elantp_i2c_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuElantpI2cDevice *self = FU_ELANTP_I2C_DEVICE(device);
|
||||
|
||||
@ -618,7 +628,6 @@ fu_elantp_i2c_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
/* reset back to runtime */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_elantp_i2c_device_write_cmd(self, ETP_CMD_I2C_IAP_RESET, ETP_I2C_IAP_RESET, error))
|
||||
return FALSE;
|
||||
g_usleep(ELANTP_DELAY_RESET * 1000);
|
||||
@ -690,6 +699,17 @@ fu_elantp_i2c_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_elantp_i2c_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_elantp_i2c_device_init(FuElantpI2cDevice *self)
|
||||
{
|
||||
@ -725,4 +745,5 @@ fu_elantp_i2c_device_class_init(FuElantpI2cDeviceClass *klass)
|
||||
klass_device->prepare_firmware = fu_elantp_i2c_device_prepare_firmware;
|
||||
klass_device->probe = fu_elantp_i2c_device_probe;
|
||||
klass_device->open = fu_elantp_i2c_device_open;
|
||||
klass_device->set_progress = fu_elantp_i2c_device_set_progress;
|
||||
}
|
||||
|
@ -343,6 +343,7 @@ fu_emmc_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_emmc_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -357,6 +358,13 @@ fu_emmc_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* ffu */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 50);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 45);
|
||||
|
||||
if (!fu_emmc_read_extcsd(FU_EMMC_DEVICE(device), ext_csd, sizeof(ext_csd), error))
|
||||
return FALSE;
|
||||
|
||||
@ -394,6 +402,7 @@ fu_emmc_device_write_firmware(FuDevice *device,
|
||||
(EXT_CSD_NORMAL_MODE << 8) | EXT_CSD_CMD_SET_NORMAL;
|
||||
multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
|
||||
multi_cmd->cmds[2].write_flag = 1;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* build packets */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
@ -446,9 +455,12 @@ fu_emmc_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len - 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* sanity check */
|
||||
total_done = (gsize)sect_done * (gsize)self->sect_size;
|
||||
@ -511,10 +523,22 @@ fu_emmc_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_emmc_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_emmc_device_init(FuEmmcDevice *self)
|
||||
{
|
||||
@ -539,4 +563,5 @@ fu_emmc_device_class_init(FuEmmcDeviceClass *klass)
|
||||
klass_device->prepare_firmware = fu_emmc_device_prepare_firmware;
|
||||
klass_device->probe = fu_emmc_device_probe;
|
||||
klass_device->write_firmware = fu_emmc_device_write_firmware;
|
||||
klass_device->set_progress = fu_emmc_device_set_progress;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ fu_ep963x_device_write_icp(FuEp963xDevice *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ep963x_device_detach(FuDevice *device, GError **error)
|
||||
fu_ep963x_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuEp963xDevice *self = FU_EP963X_DEVICE(device);
|
||||
const guint8 buf[] = {'E', 'P', '9', '6', '3'};
|
||||
@ -135,13 +135,12 @@ fu_ep963x_device_detach(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_ep963x_device_attach(FuDevice *device, GError **error)
|
||||
fu_ep963x_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuEp963xDevice *self = FU_EP963X_DEVICE(device);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
@ -151,8 +150,6 @@ fu_ep963x_device_attach(FuDevice *device, GError **error)
|
||||
g_debug("already in runtime mode, skipping");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_ep963x_device_write(self,
|
||||
FU_EP963_USB_CONTROL_ID,
|
||||
FU_EP963_OPCODE_SUBMCU_PROGRAM_FINISHED,
|
||||
@ -244,6 +241,7 @@ fu_ep963x_device_wait_cb(FuDevice *device, gpointer user_data, GError **error)
|
||||
static gboolean
|
||||
fu_ep963x_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -252,13 +250,18 @@ fu_ep963x_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) blocks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* ICP */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 95);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* reset the block index */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_ep963x_device_write(self,
|
||||
FU_EP963_USB_CONTROL_ID,
|
||||
FU_EP963_OPCODE_SUBMCU_ENTER_ICP,
|
||||
@ -272,6 +275,7 @@ fu_ep963x_device_write_firmware(FuDevice *device,
|
||||
error_local->message);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write each block */
|
||||
blocks = fu_chunk_array_new_from_bytes(fw, 0x00, 0x00, FU_EP963_TRANSFER_BLOCK_SIZE);
|
||||
@ -343,13 +347,27 @@ fu_ep963x_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ep963x_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_ep963x_device_init(FuEp963xDevice *self)
|
||||
{
|
||||
@ -370,4 +388,5 @@ fu_ep963x_device_class_init(FuEp963xDeviceClass *klass)
|
||||
klass_device->attach = fu_ep963x_device_attach;
|
||||
klass_device->detach = fu_ep963x_device_detach;
|
||||
klass_device->setup = fu_ep963x_device_setup;
|
||||
klass_device->set_progress = fu_ep963x_device_set_progress;
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ typedef enum {
|
||||
static gboolean
|
||||
fu_fastboot_device_read(FuDevice *device,
|
||||
gchar **str,
|
||||
FuProgress *progress,
|
||||
FuFastbootDeviceReadFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -201,9 +202,9 @@ fu_fastboot_device_read(FuDevice *device,
|
||||
tmp = g_strndup((const gchar *)buf + 4, self->blocksz - 4);
|
||||
if (memcmp(buf, "INFO", 4) == 0) {
|
||||
if (g_strcmp0(tmp, "erasing flash") == 0)
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_ERASE);
|
||||
else if (g_strcmp0(tmp, "writing flash") == 0)
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
else
|
||||
g_debug("INFO returned unknown: %s", tmp);
|
||||
continue;
|
||||
@ -245,7 +246,7 @@ fu_fastboot_device_getvar(FuDevice *device, const gchar *key, gchar **str, GErro
|
||||
g_autofree gchar *tmp = g_strdup_printf("getvar:%s", key);
|
||||
if (!fu_fastboot_device_writestr(device, tmp, error))
|
||||
return FALSE;
|
||||
if (!fu_fastboot_device_read(device, str, FU_FASTBOOT_DEVICE_READ_FLAG_NONE, error)) {
|
||||
if (!fu_fastboot_device_read(device, str, NULL, FU_FASTBOOT_DEVICE_READ_FLAG_NONE, error)) {
|
||||
g_prefix_error(error, "failed to getvar %s: ", key);
|
||||
return FALSE;
|
||||
}
|
||||
@ -255,25 +256,33 @@ fu_fastboot_device_getvar(FuDevice *device, const gchar *key, gchar **str, GErro
|
||||
static gboolean
|
||||
fu_fastboot_device_cmd(FuDevice *device,
|
||||
const gchar *cmd,
|
||||
FuProgress *progress,
|
||||
FuFastbootDeviceReadFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
if (!fu_fastboot_device_writestr(device, cmd, error))
|
||||
return FALSE;
|
||||
if (!fu_fastboot_device_read(device, NULL, flags, error))
|
||||
if (!fu_fastboot_device_read(device, NULL, progress, flags, error))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_fastboot_device_flash(FuDevice *device, const gchar *partition, GError **error)
|
||||
fu_fastboot_device_flash(FuDevice *device,
|
||||
const gchar *partition,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree gchar *tmp = g_strdup_printf("flash:%s", partition);
|
||||
return fu_fastboot_device_cmd(device, tmp, FU_FASTBOOT_DEVICE_READ_FLAG_STATUS_POLL, error);
|
||||
return fu_fastboot_device_cmd(device,
|
||||
tmp,
|
||||
progress,
|
||||
FU_FASTBOOT_DEVICE_READ_FLAG_STATUS_POLL,
|
||||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_fastboot_device_download(FuDevice *device, GBytes *fw, GError **error)
|
||||
fu_fastboot_device_download(FuDevice *device, GBytes *fw, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuFastbootDevice *self = FU_FASTBOOT_DEVICE(device);
|
||||
gsize sz = g_bytes_get_size(fw);
|
||||
@ -281,11 +290,15 @@ fu_fastboot_device_download(FuDevice *device, GBytes *fw, GError **error)
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* tell the client the size of data to expect */
|
||||
if (!fu_fastboot_device_cmd(device, tmp, FU_FASTBOOT_DEVICE_READ_FLAG_STATUS_POLL, error))
|
||||
if (!fu_fastboot_device_cmd(device,
|
||||
tmp,
|
||||
progress,
|
||||
FU_FASTBOOT_DEVICE_READ_FLAG_STATUS_POLL,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* send the data in chunks */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
0x00, /* start addr */
|
||||
0x00, /* page_sz */
|
||||
@ -297,9 +310,13 @@ fu_fastboot_device_download(FuDevice *device, GBytes *fw, GError **error)
|
||||
fu_chunk_get_data_sz(chk),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len * 2);
|
||||
fu_progress_set_percentage_full(progress, (gsize)i + 1, (gsize)chunks->len);
|
||||
}
|
||||
if (!fu_fastboot_device_read(device, NULL, FU_FASTBOOT_DEVICE_READ_FLAG_STATUS_POLL, error))
|
||||
if (!fu_fastboot_device_read(device,
|
||||
NULL,
|
||||
progress,
|
||||
FU_FASTBOOT_DEVICE_READ_FLAG_STATUS_POLL,
|
||||
error))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
@ -360,6 +377,7 @@ static gboolean
|
||||
fu_fastboot_device_write_qfil_part(FuDevice *device,
|
||||
FuArchive *archive,
|
||||
XbNode *part,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *data;
|
||||
@ -384,15 +402,16 @@ fu_fastboot_device_write_qfil_part(FuDevice *device,
|
||||
partition += 2;
|
||||
|
||||
/* flash the partition */
|
||||
if (!fu_fastboot_device_download(device, data, error))
|
||||
if (!fu_fastboot_device_download(device, data, progress, error))
|
||||
return FALSE;
|
||||
return fu_fastboot_device_flash(device, partition, error);
|
||||
return fu_fastboot_device_flash(device, partition, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_fastboot_device_write_motorola_part(FuDevice *device,
|
||||
FuArchive *archive,
|
||||
XbNode *part,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *op = xb_node_get_attr(part, "operation");
|
||||
@ -456,6 +475,7 @@ fu_fastboot_device_write_motorola_part(FuDevice *device,
|
||||
/* erase the partition */
|
||||
return fu_fastboot_device_cmd(device,
|
||||
cmd,
|
||||
progress,
|
||||
FU_FASTBOOT_DEVICE_READ_FLAG_NONE,
|
||||
error);
|
||||
}
|
||||
@ -512,16 +532,20 @@ fu_fastboot_device_write_motorola_part(FuDevice *device,
|
||||
}
|
||||
|
||||
/* flash the partition */
|
||||
if (!fu_fastboot_device_download(device, data, error))
|
||||
if (!fu_fastboot_device_download(device, data, progress, error))
|
||||
return FALSE;
|
||||
return fu_fastboot_device_flash(device, partition, error);
|
||||
return fu_fastboot_device_flash(device, partition, progress, error);
|
||||
}
|
||||
|
||||
/* dumb operation that doesn't expect a response */
|
||||
if (g_strcmp0(op, "boot") == 0 || g_strcmp0(op, "continue") == 0 ||
|
||||
g_strcmp0(op, "reboot") == 0 || g_strcmp0(op, "reboot-bootloader") == 0 ||
|
||||
g_strcmp0(op, "powerdown") == 0) {
|
||||
return fu_fastboot_device_cmd(device, op, FU_FASTBOOT_DEVICE_READ_FLAG_NONE, error);
|
||||
return fu_fastboot_device_cmd(device,
|
||||
op,
|
||||
progress,
|
||||
FU_FASTBOOT_DEVICE_READ_FLAG_NONE,
|
||||
error);
|
||||
}
|
||||
|
||||
/* unknown */
|
||||
@ -530,7 +554,10 @@ fu_fastboot_device_write_motorola_part(FuDevice *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_fastboot_device_write_motorola(FuDevice *device, FuArchive *archive, GError **error)
|
||||
fu_fastboot_device_write_motorola(FuDevice *device,
|
||||
FuArchive *archive,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *data;
|
||||
g_autoptr(GPtrArray) parts = NULL;
|
||||
@ -553,10 +580,17 @@ fu_fastboot_device_write_motorola(FuDevice *device, FuArchive *archive, GError *
|
||||
parts = xb_silo_query(silo, "parts/part", 0, error);
|
||||
if (parts == NULL)
|
||||
return FALSE;
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, parts->len);
|
||||
for (guint i = 0; i < parts->len; i++) {
|
||||
XbNode *part = g_ptr_array_index(parts, i);
|
||||
if (!fu_fastboot_device_write_motorola_part(device, archive, part, error))
|
||||
if (!fu_fastboot_device_write_motorola_part(device,
|
||||
archive,
|
||||
part,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -564,7 +598,10 @@ fu_fastboot_device_write_motorola(FuDevice *device, FuArchive *archive, GError *
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_fastboot_device_write_qfil(FuDevice *device, FuArchive *archive, GError **error)
|
||||
fu_fastboot_device_write_qfil(FuDevice *device,
|
||||
FuArchive *archive,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *data;
|
||||
g_autoptr(GPtrArray) parts = NULL;
|
||||
@ -587,10 +624,17 @@ fu_fastboot_device_write_qfil(FuDevice *device, FuArchive *archive, GError **err
|
||||
parts = xb_silo_query(silo, "nandboot/partitions/partition", 0, error);
|
||||
if (parts == NULL)
|
||||
return FALSE;
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, parts->len);
|
||||
for (guint i = 0; i < parts->len; i++) {
|
||||
XbNode *part = g_ptr_array_index(parts, i);
|
||||
if (!fu_fastboot_device_write_qfil_part(device, archive, part, error))
|
||||
if (!fu_fastboot_device_write_qfil_part(device,
|
||||
archive,
|
||||
part,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -600,6 +644,7 @@ fu_fastboot_device_write_qfil(FuDevice *device, FuArchive *archive, GError **err
|
||||
static gboolean
|
||||
fu_fastboot_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -618,9 +663,9 @@ fu_fastboot_device_write_firmware(FuDevice *device,
|
||||
|
||||
/* load the manifest of operations */
|
||||
if (fu_archive_lookup_by_fn(archive, "partition_nand.xml", NULL) != NULL)
|
||||
return fu_fastboot_device_write_qfil(device, archive, error);
|
||||
return fu_fastboot_device_write_qfil(device, archive, progress, error);
|
||||
if (fu_archive_lookup_by_fn(archive, "flashfile.xml", NULL) != NULL) {
|
||||
return fu_fastboot_device_write_motorola(device, archive, error);
|
||||
return fu_fastboot_device_write_motorola(device, archive, progress, error);
|
||||
}
|
||||
|
||||
/* not supported */
|
||||
@ -675,15 +720,29 @@ fu_fastboot_device_set_quirk_kv(FuDevice *device,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_fastboot_device_attach(FuDevice *device, GError **error)
|
||||
fu_fastboot_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_fastboot_device_cmd(device, "reboot", FU_FASTBOOT_DEVICE_READ_FLAG_NONE, error))
|
||||
if (!fu_fastboot_device_cmd(device,
|
||||
"reboot",
|
||||
progress,
|
||||
FU_FASTBOOT_DEVICE_READ_FLAG_NONE,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_fastboot_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_fastboot_device_init(FuFastbootDevice *self)
|
||||
{
|
||||
@ -709,4 +768,5 @@ fu_fastboot_device_class_init(FuFastbootDeviceClass *klass)
|
||||
klass_device->set_quirk_kv = fu_fastboot_device_set_quirk_kv;
|
||||
klass_device->open = fu_fastboot_device_open;
|
||||
klass_device->close = fu_fastboot_device_close;
|
||||
klass_device->set_progress = fu_fastboot_device_set_progress;
|
||||
}
|
||||
|
@ -193,6 +193,17 @@ fu_flashrom_device_close(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
|
||||
{
|
||||
@ -203,4 +214,5 @@ fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
|
||||
klass_device->probe = fu_flashrom_device_probe;
|
||||
klass_device->open = fu_flashrom_device_open;
|
||||
klass_device->close = fu_flashrom_device_close;
|
||||
klass_device->set_progress = fu_flashrom_device_set_progress;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ fu_flashrom_internal_device_prepare(FuDevice *device, FwupdInstallFlags flags, G
|
||||
g_autofree gchar *firmware_orig = NULL;
|
||||
g_autofree gchar *localstatedir = NULL;
|
||||
g_autofree gchar *basename = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
/* if the original firmware doesn't exist, grab it now */
|
||||
basename = g_strdup_printf("flashrom-%s.bin", fu_device_get_id(device));
|
||||
@ -63,7 +64,6 @@ fu_flashrom_internal_device_prepare(FuDevice *device, FwupdInstallFlags flags, G
|
||||
struct flashrom_layout *layout;
|
||||
g_autofree guint8 *newcontents = g_malloc0(flash_size);
|
||||
g_autoptr(GBytes) buf = NULL;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
|
||||
if (flashrom_layout_read_from_ifd(&layout, flashctx, NULL, 0)) {
|
||||
g_set_error_literal(error,
|
||||
@ -85,6 +85,7 @@ fu_flashrom_internal_device_prepare(FuDevice *device, FwupdInstallFlags flags, G
|
||||
/* read region */
|
||||
flashrom_layout_set(flashctx, layout);
|
||||
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
if (flashrom_image_read(flashctx, newcontents, flash_size)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -103,6 +104,7 @@ fu_flashrom_internal_device_prepare(FuDevice *device, FwupdInstallFlags flags, G
|
||||
static gboolean
|
||||
fu_flashrom_internal_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -117,6 +119,12 @@ fu_flashrom_internal_device_write_firmware(FuDevice *device,
|
||||
if (blob_fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10);
|
||||
|
||||
/* Check if CMOS needs a reset */
|
||||
if (fu_device_has_private_flag(device, FU_FLASHROM_DEVICE_FLAG_RESET_CMOS)) {
|
||||
g_debug("Attempting CMOS Reset");
|
||||
@ -156,9 +164,6 @@ fu_flashrom_internal_device_write_firmware(FuDevice *device,
|
||||
(guint)flash_size);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_device_set_progress(device, 0); /* urgh */
|
||||
rc = flashrom_image_write(flashctx, (void *)buf, sz, NULL /* refbuffer */);
|
||||
if (rc != 0) {
|
||||
g_set_error(error,
|
||||
@ -168,12 +173,13 @@ fu_flashrom_internal_device_write_firmware(FuDevice *device,
|
||||
rc);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (flashrom_image_verify(flashctx, (void *)buf, sz)) {
|
||||
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "image verify failed");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
flashrom_layout_release(layout);
|
||||
|
||||
/* success */
|
||||
|
@ -226,7 +226,6 @@ fu_fresco_pd_device_panther_reset_device(FuFrescoPdDevice *self, GError **error)
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
g_debug("resetting target device");
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
|
||||
/* ignore when the device reset before completing the transaction */
|
||||
@ -246,6 +245,7 @@ fu_fresco_pd_device_panther_reset_device(FuFrescoPdDevice *self, GError **error)
|
||||
static gboolean
|
||||
fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -257,6 +257,15 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
guint8 start_symbols[2] = {0x0};
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* enable mtp write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 50); /* copy-mmio */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 46); /* customize */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* boot */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2);
|
||||
|
||||
/* get default blob, which we know is already bigger than FirmwareMin */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -277,7 +286,6 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
/* 0xA001<bit 2> = b'0
|
||||
* 0x6C00<bit 1> = b'0
|
||||
* 0x6C04 = 0x08 */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
g_debug("disable MCU, and enable mtp write");
|
||||
if (!fu_fresco_pd_device_and_byte(self, 0xa001, ~(1 << 2), error)) {
|
||||
g_prefix_error(error, "failed to disable MCU bit 2: ");
|
||||
@ -293,7 +301,6 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* fill safe code in the boot code */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint16 i = 0; i < 0x400; i += 3) {
|
||||
for (guint j = 0; j < 3; j++) {
|
||||
if (!fu_fresco_pd_device_read_byte(self,
|
||||
@ -328,6 +335,7 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
} else if (config[0] == 0x00 && config[1] == 0x00 && config[2] != 0x00)
|
||||
break;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* copy buf offset [0 - 0x3FFFF] to mmio address [0x2000 - 0x5FFF] */
|
||||
g_debug("fill firmware body");
|
||||
@ -337,8 +345,11 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
buf[byte_index],
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, (gsize)byte_index, 0x4000);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)byte_index + 1,
|
||||
0x4000);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write file buf 0x4200 ~ 0x4205, 6 bytes to internal address 0x6600 ~ 0x6605
|
||||
* write file buf 0x4210 ~ 0x4215, 6 bytes to internal address 0x6610 ~ 0x6615
|
||||
@ -364,6 +375,7 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
if (!fu_fresco_pd_device_set_byte(self, 0x6630, buf[0x4230], error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* overwrite firmware file's boot code area (0x4020 ~ 0x41ff) to the area on the device
|
||||
* marked by begin_addr example: if the begin_addr = 0x6420, then copy file buf [0x4020 ~
|
||||
@ -386,9 +398,26 @@ fu_fresco_pd_device_write_firmware(FuDevice *device,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* reset the device */
|
||||
return fu_fresco_pd_device_panther_reset_device(self, error);
|
||||
if (!fu_fresco_pd_device_panther_reset_device(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_fresco_pd_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -412,4 +441,5 @@ fu_fresco_pd_device_class_init(FuFrescoPdDeviceClass *klass)
|
||||
klass_device->setup = fu_fresco_pd_device_setup;
|
||||
klass_device->write_firmware = fu_fresco_pd_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_fresco_pd_device_prepare_firmware;
|
||||
klass_device->set_progress = fu_fresco_pd_device_set_progress;
|
||||
}
|
||||
|
@ -286,14 +286,13 @@ fu_goodixmoc_device_update_init(FuGoodixMocDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_goodixmoc_device_attach(FuDevice *device, GError **error)
|
||||
fu_goodixmoc_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuGoodixMocDevice *self = FU_GOODIXMOC_DEVICE(device);
|
||||
GxfpCmdResp rsp = {0};
|
||||
g_autoptr(GByteArray) req = g_byte_array_new();
|
||||
|
||||
/* reset device */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_goodixmoc_device_cmd_xfer(self,
|
||||
GX_CMD_RESET,
|
||||
0x03,
|
||||
@ -356,6 +355,7 @@ fu_goodixmoc_device_setup(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_goodixmoc_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -367,6 +367,12 @@ fu_goodixmoc_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* init */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 99);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -379,7 +385,6 @@ fu_goodixmoc_device_write_firmware(FuDevice *device,
|
||||
GX_FLASH_TRANSFER_BLOCK_SIZE);
|
||||
|
||||
/* don't auto-boot firmware */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_goodixmoc_device_update_init(self, &error_local)) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
@ -388,6 +393,7 @@ fu_goodixmoc_device_write_firmware(FuDevice *device,
|
||||
error_local->message);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write each block */
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
@ -429,13 +435,27 @@ fu_goodixmoc_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_goodixmoc_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_goodixmoc_device_init(FuGoodixMocDevice *self)
|
||||
{
|
||||
@ -461,4 +481,5 @@ fu_goodixmoc_device_class_init(FuGoodixMocDeviceClass *klass)
|
||||
klass_device->setup = fu_goodixmoc_device_setup;
|
||||
klass_device->attach = fu_goodixmoc_device_attach;
|
||||
klass_device->open = fu_goodixmoc_device_open;
|
||||
klass_device->set_progress = fu_goodixmoc_device_set_progress;
|
||||
}
|
||||
|
@ -19,13 +19,12 @@ struct _FuHailuckBlDevice {
|
||||
G_DEFINE_TYPE(FuHailuckBlDevice, fu_hailuck_bl_device, FU_TYPE_HID_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_hailuck_bl_device_attach(FuDevice *device, GError **error)
|
||||
fu_hailuck_bl_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint8 buf[6] = {
|
||||
FU_HAILUCK_REPORT_ID_SHORT,
|
||||
FU_HAILUCK_CMD_ATTACH,
|
||||
};
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_hid_device_set_report(FU_HID_DEVICE(device),
|
||||
buf[0],
|
||||
buf,
|
||||
@ -111,7 +110,7 @@ fu_hailuck_bl_device_read_block(FuHailuckBlDevice *self,
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_hailuck_bl_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_hailuck_bl_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuHailuckBlDevice *self = FU_HAILUCK_BL_DEVICE(device);
|
||||
gsize fwsz = fu_device_get_firmware_size_max(device);
|
||||
@ -119,7 +118,7 @@ fu_hailuck_bl_device_dump_firmware(FuDevice *device, GError **error)
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* tell device amount of data to send */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
if (!fu_hailuck_bl_device_read_block_start(self, fwsz, error))
|
||||
return NULL;
|
||||
|
||||
@ -133,7 +132,7 @@ fu_hailuck_bl_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_chunk_get_data_sz(chk),
|
||||
error))
|
||||
return NULL;
|
||||
fu_device_set_progress_full(device, i, chunks->len - 1);
|
||||
fu_progress_set_percentage_full(progress, i + 1, chunks->len);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -141,7 +140,7 @@ fu_hailuck_bl_device_dump_firmware(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_hailuck_bl_device_erase(FuHailuckBlDevice *self, GError **error)
|
||||
fu_hailuck_bl_device_erase(FuHailuckBlDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint8 buf[6] = {
|
||||
FU_HAILUCK_REPORT_ID_SHORT,
|
||||
@ -155,7 +154,7 @@ fu_hailuck_bl_device_erase(FuHailuckBlDevice *self, GError **error)
|
||||
FU_HID_DEVICE_FLAG_IS_FEATURE,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_sleep_with_progress(FU_DEVICE(self), 2);
|
||||
fu_progress_sleep(progress, 2000);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -225,6 +224,7 @@ fu_hailuck_bl_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_hailuck_bl_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -235,18 +235,25 @@ fu_hailuck_bl_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
g_autofree guint8 *chk0_data = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 80);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1); /* block 0 */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 9);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* erase all contents */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_hailuck_bl_device_erase(self, error))
|
||||
if (!fu_hailuck_bl_device_erase(self, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* tell device amount of data to expect */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_hailuck_bl_device_write_block_start(self, g_bytes_get_size(fw), error))
|
||||
return FALSE;
|
||||
|
||||
@ -270,8 +277,11 @@ fu_hailuck_bl_device_write_firmware(FuDevice *device,
|
||||
fu_chunk_get_data_sz(chk),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, i, chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 1,
|
||||
chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* retry write of first block */
|
||||
if (!fu_hailuck_bl_device_write_block_start(self, g_bytes_get_size(fw), error))
|
||||
@ -281,10 +291,11 @@ fu_hailuck_bl_device_write_firmware(FuDevice *device,
|
||||
fu_chunk_get_data_sz(chk0),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, chunks->len, chunks->len);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify */
|
||||
fw_new = fu_hailuck_bl_device_dump_firmware(device, error);
|
||||
fw_new = fu_hailuck_bl_device_dump_firmware(device, fu_progress_get_child(progress), error);
|
||||
fu_progress_step_done(progress);
|
||||
return fu_common_bytes_compare(fw, fw_new, error);
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,9 @@ struct _FuHailuckKbdDevice {
|
||||
G_DEFINE_TYPE(FuHailuckKbdDevice, fu_hailuck_kbd_device, FU_TYPE_HID_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_hailuck_kbd_device_detach(FuDevice *device, GError **error)
|
||||
fu_hailuck_kbd_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
guint8 buf[6] = {FU_HAILUCK_REPORT_ID_SHORT, FU_HAILUCK_CMD_DETACH};
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_hid_device_set_report(FU_HID_DEVICE(device),
|
||||
buf[0],
|
||||
buf,
|
||||
@ -62,6 +61,17 @@ fu_hailuck_kbd_device_probe(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_hailuck_kbd_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_hailuck_kbd_device_init(FuHailuckKbdDevice *self)
|
||||
{
|
||||
@ -81,4 +91,5 @@ fu_hailuck_kbd_device_class_init(FuHailuckKbdDeviceClass *klass)
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
klass_device->detach = fu_hailuck_kbd_device_detach;
|
||||
klass_device->probe = fu_hailuck_kbd_device_probe;
|
||||
klass_device->set_progress = fu_hailuck_kbd_device_set_progress;
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ fu_hailuck_tp_device_cmd_cb(FuDevice *device, gpointer user_data, GError **error
|
||||
static gboolean
|
||||
fu_hailuck_tp_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -101,22 +102,30 @@ fu_hailuck_tp_device_write_firmware(FuDevice *device,
|
||||
.success = 0xff,
|
||||
};
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 85);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* end-program */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 3);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* pass */
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* erase */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
req.type = FU_HAILUCK_CMD_I2C_ERASE;
|
||||
if (!fu_device_retry(device, fu_hailuck_tp_device_cmd_cb, 100, &req, error)) {
|
||||
g_prefix_error(error, "failed to erase: ");
|
||||
return FALSE;
|
||||
}
|
||||
g_usleep(10000);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(fw, 0x0, 0x0, block_size);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
@ -163,9 +172,12 @@ fu_hailuck_tp_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, i, chunks->len - 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 1,
|
||||
chunks->len);
|
||||
}
|
||||
g_usleep(50 * 1000);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* end-program */
|
||||
req.type = FU_HAILUCK_CMD_I2C_END_PROGRAM;
|
||||
@ -174,6 +186,7 @@ fu_hailuck_tp_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
g_usleep(50 * 1000);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify checksum */
|
||||
req.type = FU_HAILUCK_CMD_I2C_VERIFY_CHECKSUM;
|
||||
@ -182,6 +195,7 @@ fu_hailuck_tp_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
g_usleep(50 * 1000);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* signal that programming has completed */
|
||||
req.type = FU_HAILUCK_CMD_I2C_PROGRAMPASS;
|
||||
@ -190,11 +204,23 @@ fu_hailuck_tp_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to program: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_hailuck_tp_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_hailuck_tp_device_init(FuHailuckTpDevice *self)
|
||||
{
|
||||
@ -216,6 +242,7 @@ fu_hailuck_tp_device_class_init(FuHailuckTpDeviceClass *klass)
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
klass_device->write_firmware = fu_hailuck_tp_device_write_firmware;
|
||||
klass_device->probe = fu_hailuck_tp_device_probe;
|
||||
klass_device->set_progress = fu_hailuck_tp_device_set_progress;
|
||||
}
|
||||
|
||||
FuHailuckTpDevice *
|
||||
|
@ -78,7 +78,7 @@ fu_ifd_device_to_string(FuDevice *device, guint idt, GString *str)
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_ifd_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_ifd_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuIfdDevice *self = FU_IFD_DEVICE(device);
|
||||
FuIfdDevicePrivate *priv = GET_PRIVATE(self);
|
||||
@ -88,18 +88,19 @@ fu_ifd_device_dump_firmware(FuDevice *device, GError **error)
|
||||
device,
|
||||
priv->offset,
|
||||
total_size,
|
||||
progress,
|
||||
error);
|
||||
}
|
||||
|
||||
static FuFirmware *
|
||||
fu_ifd_device_read_firmware(FuDevice *device, GError **error)
|
||||
fu_ifd_device_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuIfdDevice *self = FU_IFD_DEVICE(device);
|
||||
FuIfdDevicePrivate *priv = GET_PRIVATE(self);
|
||||
g_autoptr(FuFirmware) firmware = fu_ifd_image_new();
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
blob = fu_ifd_device_dump_firmware(device, error);
|
||||
blob = fu_ifd_device_dump_firmware(device, progress, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
if (priv->region == FU_IFD_REGION_BIOS)
|
||||
|
@ -391,13 +391,14 @@ fu_intel_spi_device_dump(FuIntelSpiDevice *self,
|
||||
FuDevice *device,
|
||||
guint32 offset,
|
||||
guint32 length,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint8 block_len = 0x40;
|
||||
g_autoptr(GByteArray) buf = g_byte_array_sized_new(length);
|
||||
|
||||
/* set FDONE, FCERR, AEL */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_mmio_write16(self->spibar, ICH9_REG_HSFS, fu_mmio_read16(self->spibar, ICH9_REG_HSFS));
|
||||
for (guint32 addr = offset; addr < offset + length; addr += block_len) {
|
||||
guint16 hsfc;
|
||||
@ -426,7 +427,7 @@ fu_intel_spi_device_dump(FuIntelSpiDevice *self,
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_device_set_progress_full(device, addr - offset + block_len, length);
|
||||
fu_progress_set_percentage_full(progress, addr - offset + block_len, length);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -434,20 +435,26 @@ fu_intel_spi_device_dump(FuIntelSpiDevice *self,
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_intel_spi_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_intel_spi_device_dump_firmware2(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuIntelSpiDevice *self = FU_INTEL_SPI_DEVICE(device);
|
||||
guint64 total_size = fu_device_get_firmware_size_max(device);
|
||||
return fu_intel_spi_device_dump(self, device, 0x0, total_size, error);
|
||||
return fu_intel_spi_device_dump(self, device, 0x0, total_size, progress, error);
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_intel_spi_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
return fu_intel_spi_device_dump_firmware2(device, progress, error);
|
||||
}
|
||||
|
||||
static FuFirmware *
|
||||
fu_intel_spi_device_read_firmware(FuDevice *device, GError **error)
|
||||
fu_intel_spi_device_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(FuFirmware) firmware = fu_ifd_firmware_new();
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
blob = fu_intel_spi_device_dump_firmware(device, error);
|
||||
blob = fu_intel_spi_device_dump_firmware2(device, progress, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
if (!fu_firmware_parse(firmware, blob, FWUPD_INSTALL_FLAG_NONE, error))
|
||||
|
@ -16,4 +16,5 @@ fu_intel_spi_device_dump(FuIntelSpiDevice *self,
|
||||
FuDevice *device,
|
||||
guint32 offset,
|
||||
guint32 length,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
|
@ -53,6 +53,7 @@ fu_jabra_device_prepare(FuDevice *device, FwupdInstallFlags flags, GError **erro
|
||||
guint8 rep = 0x00;
|
||||
guint8 iface_hid;
|
||||
guint8 buf[33] = {0x00};
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* parse string and create magic packet */
|
||||
@ -110,7 +111,7 @@ fu_jabra_device_prepare(FuDevice *device, FwupdInstallFlags flags, GError **erro
|
||||
}
|
||||
|
||||
/* wait for device to re-appear and be added to the dfu plugin */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ fu_plugin_cleanup(FuPlugin *plugin, FuDevice *device, FwupdInstallFlags flags, G
|
||||
{
|
||||
GUsbDevice *usb_device;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* check for a property on the *dfu* FuDevice, which is also why we
|
||||
@ -35,7 +36,7 @@ fu_plugin_cleanup(FuPlugin *plugin, FuDevice *device, FwupdInstallFlags flags, G
|
||||
locker = fu_device_locker_new(device, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_RESTART);
|
||||
usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(device));
|
||||
if (!g_usb_device_reset(usb_device, &error_local)) {
|
||||
g_set_error(error,
|
||||
|
@ -418,6 +418,7 @@ fu_logitech_bulkcontroller_device_compute_hash(GBytes *data)
|
||||
static gboolean
|
||||
fu_logitech_bulkcontroller_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -428,6 +429,13 @@ fu_logitech_bulkcontroller_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -440,7 +448,6 @@ fu_logitech_bulkcontroller_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* transfer sent */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_byte_array_append_uint64(start_pkt, g_bytes_get_size(fw), G_LITTLE_ENDIAN);
|
||||
if (!fu_logitech_bulkcontroller_device_send_upd_cmd(self,
|
||||
CMD_START_TRANSFER,
|
||||
@ -449,6 +456,7 @@ fu_logitech_bulkcontroller_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "error in writing start transfer packet: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* each block */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw, 0x0, 0x0, PAYLOAD_SIZE);
|
||||
@ -463,8 +471,11 @@ fu_logitech_bulkcontroller_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to send data packet 0x%x: ", i);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(FU_DEVICE(self), i + 1, chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 1,
|
||||
chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* sending end transfer */
|
||||
base64hash = fu_logitech_bulkcontroller_device_compute_hash(fw);
|
||||
@ -485,6 +496,7 @@ fu_logitech_bulkcontroller_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "error in writing finish transfer packet: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
@ -683,6 +695,17 @@ fu_logitech_bulkcontroller_device_setup(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_logitech_bulkcontroller_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_logitech_bulkcontroller_device_init(FuLogitechBulkcontrollerDevice *self)
|
||||
{
|
||||
@ -701,4 +724,5 @@ fu_logitech_bulkcontroller_device_class_init(FuLogitechBulkcontrollerDeviceClass
|
||||
klass_device->setup = fu_logitech_bulkcontroller_device_setup;
|
||||
klass_device->open = fu_logitech_bulkcontroller_device_open;
|
||||
klass_device->close = fu_logitech_bulkcontroller_device_close;
|
||||
klass_device->set_progress = fu_logitech_bulkcontroller_device_set_progress;
|
||||
}
|
||||
|
@ -217,6 +217,7 @@ fu_logitech_hidpp_bootloader_nordic_erase(FuLogitechHidPpBootloader *self,
|
||||
static gboolean
|
||||
fu_logitech_hidpp_bootloader_nordic_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -226,25 +227,40 @@ fu_logitech_hidpp_bootloader_nordic_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) reqs = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
if (fu_device_has_private_flag(device, FU_LOGITECH_HIDPP_BOOTLOADER_FLAG_IS_SIGNED)) {
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 4);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 13);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1); /* block 0 */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 82); /* reset vector */
|
||||
} else {
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 22);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 72);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1); /* block 0 */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 6); /* reset vector */
|
||||
}
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* erase firmware pages up to the bootloader */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_ERASE);
|
||||
for (addr = fu_logitech_hidpp_bootloader_get_addr_lo(self);
|
||||
addr < fu_logitech_hidpp_bootloader_get_addr_hi(self);
|
||||
addr += fu_logitech_hidpp_bootloader_get_blocksize(self)) {
|
||||
if (!fu_logitech_hidpp_bootloader_nordic_erase(self, addr, error))
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* transfer payload */
|
||||
reqs = fu_logitech_hidpp_bootloader_parse_requests(self, fw, error);
|
||||
if (reqs == NULL)
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 1; i < reqs->len; i++) {
|
||||
gboolean res;
|
||||
payload = g_ptr_array_index(reqs, i);
|
||||
@ -265,8 +281,9 @@ fu_logitech_hidpp_bootloader_nordic_write_firmware(FuDevice *device,
|
||||
|
||||
if (!res)
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, i * 32, reqs->len * 32);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress), i + 1, reqs->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send the first managed packet last, excluding the reset vector */
|
||||
payload = g_ptr_array_index(reqs, 0);
|
||||
@ -276,12 +293,12 @@ fu_logitech_hidpp_bootloader_nordic_write_firmware(FuDevice *device,
|
||||
payload->data + 1,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* reset vector */
|
||||
if (!fu_logitech_hidpp_bootloader_nordic_write(self, 0x0000, 0x01, payload->data, error))
|
||||
return FALSE;
|
||||
|
||||
/* mark as complete */
|
||||
fu_device_set_progress_full(device, reqs->len * 32, reqs->len * 32);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
|
@ -115,6 +115,7 @@ fu_logitech_hidpp_bootloader_texas_clear_ram_buffer(FuLogitechHidPpBootloader *s
|
||||
static gboolean
|
||||
fu_logitech_hidpp_bootloader_texas_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -125,6 +126,20 @@ fu_logitech_hidpp_bootloader_texas_write_firmware(FuDevice *device,
|
||||
g_autoptr(FuLogitechHidPpBootloaderRequest) req =
|
||||
fu_logitech_hidpp_bootloader_request_new();
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
if (fu_device_has_private_flag(device, FU_LOGITECH_HIDPP_BOOTLOADER_FLAG_IS_SIGNED)) {
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 3);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 1); /* clear */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 18);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 79);
|
||||
} else {
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 11);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 1); /* clear */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 75);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 12);
|
||||
}
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -136,16 +151,16 @@ fu_logitech_hidpp_bootloader_texas_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* erase all flash pages */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_logitech_hidpp_bootloader_texas_erase_all(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* set existing RAM buffer to 0xff's */
|
||||
if (!fu_logitech_hidpp_bootloader_texas_clear_ram_buffer(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write to RAM buffer */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < reqs->len; i++) {
|
||||
payload = g_ptr_array_index(reqs, i);
|
||||
|
||||
@ -213,15 +228,14 @@ fu_logitech_hidpp_bootloader_texas_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, i * 32, reqs->len * 32);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress), i + 1, reqs->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* check CRC */
|
||||
if (!fu_logitech_hidpp_bootloader_texas_compute_and_test_crc(self, error))
|
||||
return FALSE;
|
||||
|
||||
/* mark as complete */
|
||||
fu_device_set_progress_full(device, reqs->len * 32, reqs->len * 32);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
|
@ -208,7 +208,7 @@ fu_logitech_hidpp_bootloader_get_blocksize(FuLogitechHidPpBootloader *self)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_bootloader_attach(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_bootloader_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuLogitechHidPpBootloader *self = FU_UNIFYING_BOOTLOADER(device);
|
||||
g_autoptr(FuLogitechHidPpBootloaderRequest) req =
|
||||
@ -252,10 +252,13 @@ fu_logitech_hidpp_bootloader_set_bl_version(FuLogitechHidPpBootloader *self, GEr
|
||||
}
|
||||
fu_device_set_version_bootloader(FU_DEVICE(self), version);
|
||||
|
||||
if ((major == 0x01 && minor >= 0x04) || (major == 0x03 && minor >= 0x02))
|
||||
if ((major == 0x01 && minor >= 0x04) || (major == 0x03 && minor >= 0x02)) {
|
||||
fu_device_add_private_flag(FU_DEVICE(self),
|
||||
FU_LOGITECH_HIDPP_BOOTLOADER_FLAG_IS_SIGNED);
|
||||
fu_device_add_protocol(FU_DEVICE(self), "com.logitech.unifyingsigned");
|
||||
else
|
||||
} else {
|
||||
fu_device_add_protocol(FU_DEVICE(self), "com.logitech.unifying");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -471,6 +474,9 @@ fu_logitech_hidpp_bootloader_init(FuLogitechHidPpBootloader *self)
|
||||
fu_device_set_name(FU_DEVICE(self), "Unifying Receiver");
|
||||
fu_device_set_summary(FU_DEVICE(self), "Miniaturised USB wireless receiver (bootloader)");
|
||||
fu_device_set_remove_delay(FU_DEVICE(self), FU_UNIFYING_DEVICE_TIMEOUT_MS);
|
||||
fu_device_register_private_flag(FU_DEVICE(self),
|
||||
FU_LOGITECH_HIDPP_BOOTLOADER_FLAG_IS_SIGNED,
|
||||
"is-signed");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -19,6 +19,15 @@ struct _FuLogitechHidPpBootloaderClass {
|
||||
FuHidDeviceClass parent_class;
|
||||
};
|
||||
|
||||
/**
|
||||
* FU_LOGITECH_HIDPP_BOOTLOADER_FLAG_IS_SIGNED:
|
||||
*
|
||||
* Device requires signed firmware.
|
||||
*
|
||||
* Since: 1.7.0
|
||||
*/
|
||||
#define FU_LOGITECH_HIDPP_BOOTLOADER_FLAG_IS_SIGNED (1 << 0)
|
||||
|
||||
typedef enum {
|
||||
FU_UNIFYING_BOOTLOADER_CMD_GENERAL_ERROR = 0x01,
|
||||
FU_UNIFYING_BOOTLOADER_CMD_READ = 0x10,
|
||||
|
@ -852,7 +852,7 @@ fu_logitech_hidpp_device_setup(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_device_detach(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuLogitechHidPpDevice *self = FU_HIDPP_DEVICE(device);
|
||||
FuLogitechHidPpDevicePrivate *priv = GET_PRIVATE(self);
|
||||
@ -887,7 +887,6 @@ fu_logitech_hidpp_device_detach(FuDevice *device, GError **error)
|
||||
msg->hidpp_version = priv->hidpp_version;
|
||||
msg->flags = FU_UNIFYING_HIDPP_MSG_FLAG_IGNORE_SUB_ID |
|
||||
FU_UNIFYING_HIDPP_MSG_FLAG_LONGER_TIMEOUT;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_logitech_hidpp_transfer(priv->io_channel, msg, &error_local)) {
|
||||
if (fu_device_has_private_flag(
|
||||
device,
|
||||
@ -1139,6 +1138,7 @@ fu_logitech_hidpp_device_write_firmware_pkt(FuLogitechHidPpDevice *self,
|
||||
static gboolean
|
||||
fu_logitech_hidpp_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1168,7 +1168,7 @@ fu_logitech_hidpp_device_write_firmware(FuDevice *device,
|
||||
g_warning("updating cached entity 0x%x with 0x%x", priv->cached_fw_entity, data[0]);
|
||||
priv->cached_fw_entity = data[0];
|
||||
}
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (gsize i = 0; i < sz / 16; i++) {
|
||||
/* send packet and wait for reply */
|
||||
if (g_getenv("FWUPD_LOGITECH_HIDPP") != NULL)
|
||||
@ -1186,7 +1186,7 @@ fu_logitech_hidpp_device_write_firmware(FuDevice *device,
|
||||
cmd = (cmd + 1) % 4;
|
||||
|
||||
/* update progress-bar */
|
||||
fu_device_set_progress_full(device, i * 16, sz);
|
||||
fu_progress_set_percentage_full(progress, (i + 1) * 16, sz);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1199,7 +1199,10 @@ fu_logitech_hidpp_device_reprobe_cb(FuDevice *device, gpointer user_data, GError
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_logitech_hidpp_device_attach(FuLogitechHidPpDevice *self, guint8 entity, GError **error)
|
||||
fu_logitech_hidpp_device_attach(FuLogitechHidPpDevice *self,
|
||||
guint8 entity,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuLogitechHidPpDevicePrivate *priv = GET_PRIVATE(self);
|
||||
FuDevice *device = FU_DEVICE(self);
|
||||
@ -1248,7 +1251,7 @@ fu_logitech_hidpp_device_attach(FuLogitechHidPpDevice *self, guint8 entity, GErr
|
||||
* Possible race condition: after the device is reset, Linux might enumerate it as
|
||||
* a different hidraw device depending on timing.
|
||||
*/
|
||||
fu_device_sleep_with_progress(device, 1); /* second */
|
||||
fu_progress_sleep(progress, 1000); /* ms */
|
||||
} else {
|
||||
/* device file hasn't been unbound/re-bound, just probe again */
|
||||
if (!fu_device_retry(device, fu_logitech_hidpp_device_reprobe_cb, 10, NULL, error))
|
||||
@ -1260,14 +1263,14 @@ fu_logitech_hidpp_device_attach(FuLogitechHidPpDevice *self, guint8 entity, GErr
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_device_attach_cached(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_device_attach_cached(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuLogitechHidPpDevice *self = FU_HIDPP_DEVICE(device);
|
||||
FuLogitechHidPpDevicePrivate *priv = GET_PRIVATE(self);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
if (fu_device_has_private_flag(device, FU_LOGITECH_HIDPP_DEVICE_FLAG_REBIND_ATTACH))
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return fu_logitech_hidpp_device_attach(self, priv->cached_fw_entity, error);
|
||||
return fu_logitech_hidpp_device_attach(self, priv->cached_fw_entity, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1286,6 +1289,17 @@ fu_logitech_hidpp_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_logitech_hidpp_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_logitech_hidpp_device_finalize(GObject *object)
|
||||
{
|
||||
@ -1327,6 +1341,7 @@ fu_logitech_hidpp_device_class_init(FuLogitechHidPpDeviceClass *klass)
|
||||
klass_device->probe = fu_logitech_hidpp_device_probe;
|
||||
klass_device->set_quirk_kv = fu_logitech_hidpp_device_set_quirk_kv;
|
||||
klass_device->cleanup = fu_logitech_hidpp_device_cleanup;
|
||||
klass_device->set_progress = fu_logitech_hidpp_device_set_progress;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -84,6 +84,9 @@ fu_logitech_hidpp_device_set_hidpp_pid(FuLogitechHidPpDevice *self, guint16 hidp
|
||||
const gchar *
|
||||
fu_logitech_hidpp_device_get_model_id(FuLogitechHidPpDevice *self);
|
||||
gboolean
|
||||
fu_logitech_hidpp_device_attach(FuLogitechHidPpDevice *self, guint8 entity, GError **error);
|
||||
fu_logitech_hidpp_device_attach(FuLogitechHidPpDevice *self,
|
||||
guint8 entity,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
FuLogitechHidPpDevice *
|
||||
fu_logitech_hidpp_device_new(FuUdevDevice *parent);
|
||||
|
@ -24,7 +24,7 @@ fu_logitech_hidpp_radio_to_string(FuDevice *device, guint idt, GString *str)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_radio_attach(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_radio_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuLogitechHidPpRadio *self = FU_HIDPP_RADIO(device);
|
||||
FuDevice *parent = fu_device_get_parent(device);
|
||||
@ -35,13 +35,15 @@ fu_logitech_hidpp_radio_attach(FuDevice *device, GError **error)
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
return fu_logitech_hidpp_device_attach(FU_HIDPP_DEVICE(parent), self->entity, error);
|
||||
return fu_logitech_hidpp_device_attach(FU_HIDPP_DEVICE(parent),
|
||||
self->entity,
|
||||
progress,
|
||||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_radio_detach(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_radio_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDevice *parent = fu_device_get_parent(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -51,16 +53,15 @@ fu_logitech_hidpp_radio_detach(FuDevice *device, GError **error)
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!fu_device_has_flag(parent, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_device_has_flag(parent, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
}
|
||||
return fu_device_detach(parent, error);
|
||||
return fu_device_detach(parent, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_radio_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -76,9 +77,7 @@ fu_logitech_hidpp_radio_write_firmware(FuDevice *device,
|
||||
locker = fu_device_locker_new(parent, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
return fu_device_write_firmware(parent, fw, flags, error);
|
||||
return fu_device_write_firmware(parent, fw, progress, flags, error);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -20,7 +20,7 @@ struct _FuLogitechHidPpRuntimeBolt {
|
||||
G_DEFINE_TYPE(FuLogitechHidPpRuntimeBolt, fu_logitech_hidpp_runtime_bolt, FU_TYPE_HIDPP_RUNTIME)
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_runtime_bolt_detach(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_runtime_bolt_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuLogitechHidPpRuntime *self = FU_HIDPP_RUNTIME(device);
|
||||
g_autoptr(FuLogitechHidPpHidppMsg) msg = fu_logitech_hidpp_msg_new();
|
||||
|
@ -20,7 +20,7 @@ G_DEFINE_TYPE(FuLogitechHidPpRuntimeUnifying,
|
||||
#define GET_PRIVATE(o) (fu_logitech_hidpp_runtime_unifying_get_instance_private(o))
|
||||
|
||||
static gboolean
|
||||
fu_logitech_hidpp_runtime_unifying_detach(FuDevice *device, GError **error)
|
||||
fu_logitech_hidpp_runtime_unifying_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuLogitechHidPpRuntime *self = FU_HIDPP_RUNTIME(device);
|
||||
g_autoptr(FuLogitechHidPpHidppMsg) msg = fu_logitech_hidpp_msg_new();
|
||||
@ -151,6 +151,16 @@ fu_logitech_hidpp_runtime_unifying_setup(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_logitech_hidpp_runtime_unifying_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 70); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 4); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 27); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_logitech_hidpp_runtime_unifying_class_init(FuLogitechHidPpRuntimeUnifyingClass *klass)
|
||||
{
|
||||
@ -158,6 +168,7 @@ fu_logitech_hidpp_runtime_unifying_class_init(FuLogitechHidPpRuntimeUnifyingClas
|
||||
|
||||
klass_device->detach = fu_logitech_hidpp_runtime_unifying_detach;
|
||||
klass_device->setup = fu_logitech_hidpp_runtime_unifying_setup;
|
||||
klass_device->set_progress = fu_logitech_hidpp_runtime_unifying_set_progress;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -49,10 +49,6 @@
|
||||
#define CONFIGURE_ZLP_AWARE_HOST 1
|
||||
#define CONFIGURE_SKIP_STORAGE_INIT 0
|
||||
|
||||
enum { SIGNAL_WRITE_PERCENTAGE, SIGNAL_LAST };
|
||||
|
||||
static guint signals[SIGNAL_LAST] = {0};
|
||||
|
||||
struct _FuFirehoseUpdater {
|
||||
GObject parent_instance;
|
||||
gchar *port;
|
||||
@ -755,6 +751,7 @@ fu_firehose_updater_run_actions(FuFirehoseUpdater *self,
|
||||
XbSilo *silo,
|
||||
GPtrArray *action_nodes,
|
||||
guint max_payload_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
gsize sent_bytes = 0;
|
||||
@ -777,10 +774,7 @@ fu_firehose_updater_run_actions(FuFirehoseUpdater *self,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
g_signal_emit(self,
|
||||
signals[SIGNAL_WRITE_PERCENTAGE],
|
||||
0,
|
||||
(guint)((100.0 * (gdouble)sent_bytes) / (gdouble)total_bytes));
|
||||
fu_progress_set_percentage_full(progress, sent_bytes, total_bytes);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -790,14 +784,13 @@ gboolean
|
||||
fu_firehose_updater_write(FuFirehoseUpdater *self,
|
||||
XbSilo *silo,
|
||||
GPtrArray *action_nodes,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint max_payload_size;
|
||||
gboolean result;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
g_signal_emit(self, signals[SIGNAL_WRITE_PERCENTAGE], 0, 0);
|
||||
|
||||
if (!fu_firehose_updater_initialize(self, error))
|
||||
return FALSE;
|
||||
|
||||
@ -805,7 +798,12 @@ fu_firehose_updater_write(FuFirehoseUpdater *self,
|
||||
if (max_payload_size == 0)
|
||||
return FALSE;
|
||||
|
||||
result = fu_firehose_updater_run_actions(self, silo, action_nodes, max_payload_size, error);
|
||||
result = fu_firehose_updater_run_actions(self,
|
||||
silo,
|
||||
action_nodes,
|
||||
max_payload_size,
|
||||
progress,
|
||||
error);
|
||||
|
||||
if (!fu_firehose_updater_reset(self, &error_local)) {
|
||||
if (result)
|
||||
@ -813,8 +811,6 @@ fu_firehose_updater_write(FuFirehoseUpdater *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_signal_emit(self, signals[SIGNAL_WRITE_PERCENTAGE], 0, 100);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -837,17 +833,6 @@ fu_firehose_updater_class_init(FuFirehoseUpdaterClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->finalize = fu_firehose_updater_finalize;
|
||||
|
||||
signals[SIGNAL_WRITE_PERCENTAGE] = g_signal_new("write-percentage",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_UINT);
|
||||
}
|
||||
|
||||
FuFirehoseUpdater *
|
||||
|
@ -23,6 +23,7 @@ gboolean
|
||||
fu_firehose_updater_write(FuFirehoseUpdater *self,
|
||||
XbSilo *silo,
|
||||
GPtrArray *action_nodes,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_firehose_updater_close(FuFirehoseUpdater *self, GError **error);
|
||||
|
@ -267,6 +267,7 @@ typedef struct {
|
||||
GPtrArray *chunks;
|
||||
guint chunk_sent;
|
||||
FuDevice *device;
|
||||
FuProgress *progress;
|
||||
} WriteContext;
|
||||
|
||||
static gboolean
|
||||
@ -302,10 +303,10 @@ fu_mbim_qdu_updater_file_write_ready(MbimDevice *device, GAsyncResult *res, gpoi
|
||||
return;
|
||||
}
|
||||
|
||||
fu_device_set_progress_full(FU_DEVICE(ctx->device),
|
||||
(gsize)ctx->chunk_sent,
|
||||
(gsize)ctx->chunks->len);
|
||||
ctx->chunk_sent++;
|
||||
fu_progress_set_percentage_full(ctx->progress,
|
||||
(gsize)ctx->chunk_sent,
|
||||
(gsize)ctx->chunks->len);
|
||||
if (ctx->chunk_sent < ctx->chunks->len) {
|
||||
FuChunk *chk = g_ptr_array_index(ctx->chunks, ctx->chunk_sent);
|
||||
g_autoptr(MbimMessage) request =
|
||||
@ -321,8 +322,7 @@ fu_mbim_qdu_updater_file_write_ready(MbimDevice *device, GAsyncResult *res, gpoi
|
||||
return;
|
||||
}
|
||||
|
||||
fu_device_set_progress(FU_DEVICE(ctx->device), 100);
|
||||
fu_device_set_status(FU_DEVICE(ctx->device), FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_DEVICE_RESTART);
|
||||
/* device will auto reboot right after update finish */
|
||||
g_timeout_add_seconds(10, fu_mbim_qdu_updater_reboot_timeout, ctx);
|
||||
}
|
||||
@ -462,6 +462,7 @@ fu_mbim_qdu_updater_write(FuMbimQduUpdater *self,
|
||||
const gchar *filename,
|
||||
GBytes *blob,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GMainLoop) mainloop = g_main_loop_new(NULL, FALSE);
|
||||
@ -476,6 +477,7 @@ fu_mbim_qdu_updater_write(FuMbimQduUpdater *self,
|
||||
.chunks = chunks,
|
||||
.chunk_sent = 0,
|
||||
.device = device,
|
||||
.progress = progress,
|
||||
};
|
||||
|
||||
fu_mbim_qdu_updater_set_update_session(self->mbim_device, &ctx);
|
||||
|
@ -23,6 +23,7 @@ fu_mbim_qdu_updater_write(FuMbimQduUpdater *self,
|
||||
const gchar *filename,
|
||||
GBytes *blob,
|
||||
FuDevice *device,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
gchar *
|
||||
fu_mbim_qdu_updater_check_ready(FuMbimQduUpdater *self, GError **error);
|
||||
|
@ -763,7 +763,7 @@ fu_mm_device_qcdm_switch_to_edl(FuDevice *device, GError **error)
|
||||
#endif /* MM_CHECK_VERSION(1,17,2) */
|
||||
|
||||
static gboolean
|
||||
fu_mm_device_detach(FuDevice *device, GError **error)
|
||||
fu_mm_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuMmDevice *self = FU_MM_DEVICE(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -1094,7 +1094,10 @@ fu_mm_device_writeln(const gchar *fn, const gchar *buf, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_mm_device_write_firmware_mbim_qdu(FuDevice *device, GBytes *fw, GError **error)
|
||||
fu_mm_device_write_firmware_mbim_qdu(FuDevice *device,
|
||||
GBytes *fw,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
GBytes *data;
|
||||
XbNode *part = NULL;
|
||||
@ -1162,12 +1165,12 @@ fu_mm_device_write_firmware_mbim_qdu(FuDevice *device, GBytes *fw, GError **erro
|
||||
if (!fu_mm_device_writeln(autosuspend_delay_filename, "10000", error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_mbim_qdu_updater_write(self->mbim_qdu_updater, filename, data, device, error);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_mbim_qdu_updater_write(self->mbim_qdu_updater, filename, data, device, progress, error);
|
||||
if (!fu_device_locker_close(locker, error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
fu_device_set_remove_delay(device, MAX_WAIT_TIME_SECS * 1000);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
version = fu_mm_device_get_firmware_version_mbim(device, error);
|
||||
@ -1200,32 +1203,21 @@ static gboolean
|
||||
fu_mm_device_firehose_write(FuMmDevice *self,
|
||||
XbSilo *rawprogram_silo,
|
||||
GPtrArray *rawprogram_actions,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
guint progress_signal_id;
|
||||
gboolean write_result;
|
||||
|
||||
locker = fu_device_locker_new_full(self,
|
||||
(FuDeviceLockerFunc)fu_mm_device_firehose_open,
|
||||
(FuDeviceLockerFunc)fu_mm_device_firehose_close,
|
||||
error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
|
||||
progress_signal_id = g_signal_connect_swapped(self->firehose_updater,
|
||||
"write-percentage",
|
||||
G_CALLBACK(fu_device_set_progress),
|
||||
self);
|
||||
|
||||
write_result = fu_firehose_updater_write(self->firehose_updater,
|
||||
rawprogram_silo,
|
||||
rawprogram_actions,
|
||||
error);
|
||||
|
||||
g_signal_handler_disconnect(self->firehose_updater, progress_signal_id);
|
||||
|
||||
return write_result;
|
||||
return fu_firehose_updater_write(self->firehose_updater,
|
||||
rawprogram_silo,
|
||||
rawprogram_actions,
|
||||
progress,
|
||||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1297,20 +1289,30 @@ fu_mm_restore_firmware_search_path(FuMmDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_mm_device_write_firmware_firehose(FuDevice *device, GBytes *fw, GError **error)
|
||||
fu_mm_device_write_firmware_firehose(FuDevice *device,
|
||||
GBytes *fw,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuMmDevice *self = FU_MM_DEVICE(device);
|
||||
|
||||
GBytes *firehose_rawprogram;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(FuArchive) archive = NULL;
|
||||
g_autoptr(XbSilo) firehose_rawprogram_silo = NULL;
|
||||
g_autoptr(GPtrArray) firehose_rawprogram_actions = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DECOMPRESSING, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
|
||||
/* decompress entire archive ahead of time */
|
||||
archive = fu_archive_new(fw, FU_ARCHIVE_FLAG_IGNORE_PATH, error);
|
||||
if (archive == NULL)
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* modify firmware search path and restore it before function returns */
|
||||
locker = fu_device_locker_new_full(self,
|
||||
@ -1325,9 +1327,6 @@ fu_mm_device_write_firmware_firehose(FuDevice *device, GBytes *fw, GError **erro
|
||||
if (!fu_mm_copy_firehose_prog(self, archive, error))
|
||||
return FALSE;
|
||||
|
||||
/* flag as restart because the QCDM and MHI/BHI operations switch the
|
||||
* device into FP execution environment */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_RESTART);
|
||||
/* switch to embedded downloader (EDL) execution environment */
|
||||
if (!fu_mm_device_qcdm_switch_to_edl(FU_DEVICE(self), error))
|
||||
return FALSE;
|
||||
@ -1344,20 +1343,19 @@ fu_mm_device_write_firmware_firehose(FuDevice *device, GBytes *fw, GError **erro
|
||||
g_prefix_error(error, "Invalid firehose rawprogram manifest: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* flag as write */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* download all files in the firehose-rawprogram manifest via Firehose */
|
||||
if (!fu_mm_device_firehose_write(self,
|
||||
firehose_rawprogram_silo,
|
||||
firehose_rawprogram_actions,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* flag as restart again, the module is switching to modem mode */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_RESTART);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1366,6 +1364,7 @@ fu_mm_device_write_firmware_firehose(FuDevice *device, GBytes *fw, GError **erro
|
||||
static gboolean
|
||||
fu_mm_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1393,13 +1392,13 @@ fu_mm_device_write_firmware(FuDevice *device,
|
||||
#if MM_CHECK_VERSION(1, 17, 1) && MBIM_CHECK_VERSION(1, 25, 3)
|
||||
/* mbim qdu write operation */
|
||||
if (self->update_methods & MM_MODEM_FIRMWARE_UPDATE_METHOD_MBIM_QDU)
|
||||
return fu_mm_device_write_firmware_mbim_qdu(device, fw, error);
|
||||
return fu_mm_device_write_firmware_mbim_qdu(device, fw, progress, error);
|
||||
|
||||
#endif /* MM_CHECK_VERSION(1,17,1) && MBIM_CHECK_VERSION(1,25,3) */
|
||||
#if MM_CHECK_VERSION(1, 17, 2)
|
||||
/* firehose operation */
|
||||
if (self->update_methods & MM_MODEM_FIRMWARE_UPDATE_METHOD_FIREHOSE)
|
||||
return fu_mm_device_write_firmware_firehose(device, fw, error);
|
||||
return fu_mm_device_write_firmware_firehose(device, fw, progress, error);
|
||||
#endif
|
||||
|
||||
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "unsupported update method");
|
||||
@ -1455,7 +1454,7 @@ fu_mm_device_attach_qmi_pdc_idle(gpointer user_data)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_mm_device_attach(FuDevice *device, GError **error)
|
||||
fu_mm_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuMmDevice *self = FU_MM_DEVICE(device);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -1478,6 +1477,17 @@ fu_mm_device_attach(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_mm_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_mm_device_init(FuMmDevice *self)
|
||||
{
|
||||
@ -1522,6 +1532,7 @@ fu_mm_device_class_init(FuMmDeviceClass *klass)
|
||||
klass_device->detach = fu_mm_device_detach;
|
||||
klass_device->write_firmware = fu_mm_device_write_firmware;
|
||||
klass_device->attach = fu_mm_device_attach;
|
||||
klass_device->set_progress = fu_mm_device_set_progress;
|
||||
|
||||
signals[SIGNAL_ATTACH_FINISHED] = g_signal_new("attach-finished",
|
||||
G_TYPE_FROM_CLASS(object_class),
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
@ -370,7 +371,7 @@ fu_plugin_destroy(FuPlugin *plugin)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_detach(FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
fu_plugin_detach(FuPlugin *plugin, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuPluginData *priv = fu_plugin_get_data(plugin);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -397,7 +398,7 @@ fu_plugin_detach(FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
/* reset */
|
||||
if (!fu_device_detach(device, error)) {
|
||||
if (!fu_device_detach(device, progress, error)) {
|
||||
fu_plugin_mm_uninhibit_device(plugin);
|
||||
return FALSE;
|
||||
}
|
||||
@ -414,7 +415,7 @@ fu_plugin_mm_device_attach_finished(gpointer user_data)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_attach(FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
fu_plugin_attach(FuPlugin *plugin, FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
|
||||
@ -434,7 +435,7 @@ fu_plugin_attach(FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
* so that engine can setup the device "waiting" logic before the actual
|
||||
* attach procedure happens (which will reset the module if it worked
|
||||
* properly) */
|
||||
if (!fu_device_attach(device, error))
|
||||
if (!fu_device_attach(device, progress, error))
|
||||
return FALSE;
|
||||
|
||||
/* this signal will always be emitted asynchronously */
|
||||
|
@ -318,6 +318,7 @@ fu_nvme_device_setup(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_nvme_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -327,6 +328,12 @@ fu_nvme_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
guint64 block_size = self->write_block_size > 0 ? self->write_block_size : 0x1000;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10); /* commit */
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -340,14 +347,11 @@ fu_nvme_device_write_firmware(FuDevice *device,
|
||||
fw2 = g_bytes_ref(fw);
|
||||
}
|
||||
|
||||
/* build packets */
|
||||
/* write each block */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw2,
|
||||
0x00, /* start_addr */
|
||||
0x00, /* page_sz */
|
||||
block_size); /* block size */
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
if (!fu_nvme_device_fw_download(self,
|
||||
@ -358,8 +362,11 @@ fu_nvme_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to write chunk %u: ", i);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len + 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* commit */
|
||||
if (!fu_nvme_device_fw_commit(self,
|
||||
@ -370,9 +377,9 @@ fu_nvme_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to commit to auto slot: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
fu_device_set_progress(device, 100);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -389,6 +396,16 @@ fu_nvme_device_set_quirk_kv(FuDevice *device, const gchar *key, const gchar *val
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_nvme_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_nvme_device_init(FuNvmeDevice *self)
|
||||
{
|
||||
@ -423,6 +440,7 @@ fu_nvme_device_class_init(FuNvmeDeviceClass *klass)
|
||||
klass_device->setup = fu_nvme_device_setup;
|
||||
klass_device->write_firmware = fu_nvme_device_write_firmware;
|
||||
klass_device->probe = fu_nvme_device_probe;
|
||||
klass_device->set_progress = fu_nvme_device_set_progress;
|
||||
}
|
||||
|
||||
FuNvmeDevice *
|
||||
|
@ -38,7 +38,7 @@ fu_optionrom_device_probe(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_optionrom_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_optionrom_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuUdevDevice *udev_device = FU_UDEV_DEVICE(device);
|
||||
guint number_reads = 0;
|
||||
|
@ -287,9 +287,9 @@ fu_parade_lspcon_flash_read(FuParadeLspconDevice *self,
|
||||
guint32 base_address,
|
||||
guint8 *data,
|
||||
const gsize len,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDevice *device = FU_DEVICE(self);
|
||||
FuI2cDevice *i2c_device = FU_I2C_DEVICE(self);
|
||||
gsize offset = 0;
|
||||
|
||||
@ -322,7 +322,7 @@ fu_parade_lspcon_flash_read(FuParadeLspconDevice *self,
|
||||
base_address += page_data_take;
|
||||
offset += page_data_take;
|
||||
|
||||
fu_device_set_progress_full(device, offset, len);
|
||||
fu_progress_set_percentage_full(progress, offset, len);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -417,9 +417,9 @@ static gboolean
|
||||
fu_parade_lspcon_flash_write(FuParadeLspconDevice *self,
|
||||
guint32 base_address,
|
||||
GBytes *data,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuDevice *device = FU_DEVICE(self);
|
||||
FuI2cDevice *i2c_device = FU_I2C_DEVICE(self);
|
||||
const guint8 unlock_writes[] = {0xaa, 0x55, 0x50, 0x41, 0x52, 0x44};
|
||||
gsize data_len = g_bytes_get_size(data);
|
||||
@ -477,7 +477,7 @@ fu_parade_lspcon_flash_write(FuParadeLspconDevice *self,
|
||||
if (!fu_i2c_device_write_full(i2c_device, write_data, chunk_size + 1, error))
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_progress_full(device, address - base_address, data_len);
|
||||
fu_progress_set_percentage_full(progress, address - base_address, data_len);
|
||||
}
|
||||
|
||||
/* re-lock map writes */
|
||||
@ -631,6 +631,7 @@ fu_parade_lspcon_device_reload(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_parade_lspcon_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -652,6 +653,15 @@ fu_parade_lspcon_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) blob_fw = NULL;
|
||||
g_autoptr(GBytes) flag_data_bytes = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 5);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 70);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 25);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 3); /* boot */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 2); /* boot */
|
||||
|
||||
blob_fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (blob_fw == NULL)
|
||||
return FALSE;
|
||||
@ -688,45 +698,62 @@ fu_parade_lspcon_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* erase entire target partition (one flash block) */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_parade_lspcon_flash_erase_block(self, target_address, bufsz, error)) {
|
||||
g_prefix_error(error, "failed to erase flash partition %d: ", target_partition);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write image */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_parade_lspcon_flash_write(self, target_address, blob_fw, error)) {
|
||||
if (!fu_parade_lspcon_flash_write(self,
|
||||
target_address,
|
||||
blob_fw,
|
||||
fu_progress_get_child(progress),
|
||||
error)) {
|
||||
g_prefix_error(error,
|
||||
"failed to write firmware to partition %d: ",
|
||||
target_partition);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* read back written image to verify */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
readback_buf = g_malloc0(bufsz);
|
||||
if (!fu_parade_lspcon_flash_read(self, target_address, readback_buf, bufsz, error))
|
||||
if (!fu_parade_lspcon_flash_read(self,
|
||||
target_address,
|
||||
readback_buf,
|
||||
bufsz,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
if (!fu_common_bytes_compare_raw(buf, bufsz, readback_buf, bufsz, error)) {
|
||||
g_prefix_error(error, "flash contents do not match: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* erase flag partition */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_parade_lspcon_flash_erase_block(self, 0, FLASH_BLOCK_SIZE, error))
|
||||
return FALSE;
|
||||
|
||||
/* write flag indicating device should boot the target partition */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
flag_data_bytes = g_bytes_new_static(flag_data, sizeof(flag_data));
|
||||
if (!fu_parade_lspcon_flash_write(self, 0, flag_data_bytes, error))
|
||||
if (!fu_parade_lspcon_flash_write(self,
|
||||
0,
|
||||
flag_data_bytes,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify flag partition */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!fu_parade_lspcon_flash_read(self, 0, readback_buf, sizeof(flag_data), error))
|
||||
if (!fu_parade_lspcon_flash_read(self,
|
||||
0,
|
||||
readback_buf,
|
||||
sizeof(flag_data),
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
if (!fu_common_bytes_compare_raw(flag_data,
|
||||
sizeof(flag_data),
|
||||
@ -748,6 +775,7 @@ fu_parade_lspcon_device_write_firmware(FuDevice *device,
|
||||
sizeof(write_sr_enable_bp),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* reassert /WP to flash */
|
||||
return fu_parade_lspcon_write_register(self, REG_ADDR_WR_PROTECT, 0, error);
|
||||
@ -765,21 +793,21 @@ fu_parade_lspcon_set_mpu_running(FuParadeLspconDevice *self, gboolean running, G
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_parade_lspcon_device_detach(FuDevice *device, GError **error)
|
||||
fu_parade_lspcon_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuParadeLspconDevice *self = FU_PARADE_LSPCON_DEVICE(device);
|
||||
return fu_parade_lspcon_set_mpu_running(self, FALSE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_parade_lspcon_device_attach(FuDevice *device, GError **error)
|
||||
fu_parade_lspcon_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuParadeLspconDevice *self = FU_PARADE_LSPCON_DEVICE(device);
|
||||
return fu_parade_lspcon_set_mpu_running(self, TRUE, error);
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_parade_lspcon_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_parade_lspcon_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuParadeLspconDevice *self = FU_PARADE_LSPCON_DEVICE(device);
|
||||
g_autofree guint8 *data = g_malloc0(FLASH_BLOCK_SIZE);
|
||||
@ -788,11 +816,23 @@ fu_parade_lspcon_device_dump_firmware(FuDevice *device, GError **error)
|
||||
self->active_partition * FLASH_BLOCK_SIZE,
|
||||
data,
|
||||
FLASH_BLOCK_SIZE,
|
||||
progress,
|
||||
error))
|
||||
return NULL;
|
||||
return g_bytes_new_take(g_steal_pointer(&data), FLASH_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_parade_lspcon_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_parade_lspcon_device_class_init(FuParadeLspconDeviceClass *klass)
|
||||
{
|
||||
@ -809,4 +849,5 @@ fu_parade_lspcon_device_class_init(FuParadeLspconDeviceClass *klass)
|
||||
klass_device->write_firmware = fu_parade_lspcon_device_write_firmware;
|
||||
klass_device->attach = fu_parade_lspcon_device_attach;
|
||||
klass_device->dump_firmware = fu_parade_lspcon_device_dump_firmware;
|
||||
klass_device->set_progress = fu_parade_lspcon_device_set_progress;
|
||||
}
|
||||
|
@ -284,7 +284,10 @@ fu_pxi_ble_device_fw_ota_check_retransmit(FuPxiBleDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_pxi_ble_device_check_support_resume(FuPxiBleDevice *self, FuFirmware *firmware, GError **error)
|
||||
fu_pxi_ble_device_check_support_resume(FuPxiBleDevice *self,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
@ -507,7 +510,6 @@ fu_pxi_ble_device_reset(FuPxiBleDevice *self, GError **error)
|
||||
fu_byte_array_append_uint8(req, PXI_HID_DEV_OTA_FEATURE_REPORT_ID);
|
||||
fu_byte_array_append_uint8(req, FU_PXI_DEVICE_CMD_FW_MCU_RESET); /* OTA reset command */
|
||||
fu_byte_array_append_uint8(req, OTA_RESET); /* OTA reset reason */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
if (!fu_pxi_ble_device_set_feature(self, req, error)) {
|
||||
g_prefix_error(error, "failed to reset: ");
|
||||
@ -572,7 +574,10 @@ fu_pxi_ble_device_fw_ota_init_new(FuPxiBleDevice *self, gsize bufsz, GError **er
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_pxi_ble_device_fw_upgrade(FuPxiBleDevice *self, FuFirmware *firmware, GError **error)
|
||||
fu_pxi_ble_device_fw_upgrade(FuPxiBleDevice *self,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *version;
|
||||
const guint8 *buf;
|
||||
@ -605,7 +610,6 @@ fu_pxi_ble_device_fw_upgrade(FuPxiBleDevice *self, FuFirmware *firmware, GError
|
||||
g_byte_array_append(req, fw_version, sizeof(fw_version));
|
||||
|
||||
/* send fw upgrade command */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!fu_pxi_ble_device_set_feature(self, req, error))
|
||||
return FALSE;
|
||||
|
||||
@ -637,6 +641,7 @@ fu_pxi_ble_device_fw_upgrade(FuPxiBleDevice *self, FuFirmware *firmware, GError
|
||||
static gboolean
|
||||
fu_pxi_ble_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -645,13 +650,21 @@ fu_pxi_ble_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 9); /* ota-init */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1);
|
||||
|
||||
/* get the default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* send fw ota retransmit command to reset status */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_pxi_ble_device_fw_ota_check_retransmit(self, error)) {
|
||||
g_prefix_error(error, "failed to OTA check retransmit: ");
|
||||
return FALSE;
|
||||
@ -661,30 +674,43 @@ fu_pxi_ble_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
if (!fu_pxi_ble_device_fw_ota_init_new(self, g_bytes_get_size(fw), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* prepare write fw into device */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw, 0x0, 0x0, FU_PXI_DEVICE_OBJECT_SIZE_MAX);
|
||||
if (!fu_pxi_ble_device_check_support_resume(self, firmware, &error_local)) {
|
||||
if (!fu_pxi_ble_device_check_support_resume(self,
|
||||
firmware,
|
||||
fu_progress_get_child(progress),
|
||||
&error_local)) {
|
||||
g_debug("do not resume: %s", error_local->message);
|
||||
self->fwstate.offset = 0;
|
||||
self->fwstate.checksum = 0;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write fw into device */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = self->fwstate.offset; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
if (!fu_pxi_ble_device_write_chunk(self, chk, error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)self->fwstate.offset + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* fw upgrade command */
|
||||
if (!fu_pxi_ble_device_fw_upgrade(self, firmware, error))
|
||||
if (!fu_pxi_ble_device_fw_upgrade(self, firmware, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send device reset command */
|
||||
return fu_pxi_ble_device_reset(self, error);
|
||||
if (!fu_pxi_ble_device_reset(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -855,6 +881,17 @@ fu_pxi_ble_device_setup(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_pxi_ble_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_pxi_ble_device_init(FuPxiBleDevice *self)
|
||||
{
|
||||
@ -884,4 +921,5 @@ fu_pxi_ble_device_class_init(FuPxiBleDeviceClass *klass)
|
||||
klass_device->to_string = fu_pxi_ble_device_to_string;
|
||||
klass_device->write_firmware = fu_pxi_ble_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_pxi_ble_device_prepare_firmware;
|
||||
klass_device->set_progress = fu_pxi_ble_device_set_progress;
|
||||
}
|
||||
|
@ -407,7 +407,10 @@ fu_pxi_receiver_device_write_chunk(FuDevice *device, FuChunk *chk, GError **erro
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_pxi_receiver_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError **error)
|
||||
fu_pxi_receiver_device_fw_upgrade(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuPxiReceiverDevice *self = FU_PXI_RECEIVER_DEVICE(device);
|
||||
const gchar *version;
|
||||
@ -421,6 +424,12 @@ fu_pxi_receiver_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError
|
||||
g_autoptr(GByteArray) receiver_device_cmd = g_byte_array_new();
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 5);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 95);
|
||||
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
@ -464,9 +473,8 @@ fu_pxi_receiver_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError
|
||||
ota_cmd,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* update device status */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_VERIFY);
|
||||
/* send ota fw upgrade command */
|
||||
if (!fu_pxi_receiver_device_set_feature(self,
|
||||
receiver_device_cmd->data,
|
||||
@ -491,6 +499,7 @@ fu_pxi_receiver_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError
|
||||
result);
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -520,9 +529,6 @@ fu_pxi_receiver_device_reset(FuDevice *device, GError **error)
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
/* update device status */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
/* send ota mcu reset command */
|
||||
return fu_pxi_receiver_device_set_feature(self,
|
||||
receiver_device_cmd->data,
|
||||
@ -545,6 +551,7 @@ fu_pxi_receiver_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_pxi_receiver_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -552,6 +559,13 @@ fu_pxi_receiver_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 9); /* ota-init */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1);
|
||||
|
||||
/* get the default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -563,6 +577,7 @@ fu_pxi_receiver_device_write_firmware(FuDevice *device,
|
||||
|
||||
if (!fu_pxi_receiver_device_fw_ota_ini_new_check(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
chunks = fu_chunk_array_new_from_bytes(fw, 0x0, 0x0, FU_PXI_DEVICE_OBJECT_SIZE_MAX);
|
||||
/* prepare write fw into device */
|
||||
@ -570,23 +585,34 @@ fu_pxi_receiver_device_write_firmware(FuDevice *device,
|
||||
self->fwstate.checksum = 0;
|
||||
|
||||
/* write fw into device */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = self->fwstate.offset; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
if (!fu_pxi_receiver_device_write_chunk(device, chk, error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + self->fwstate.offset + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* fw upgrade command */
|
||||
if (!fu_pxi_receiver_device_fw_upgrade(device, firmware, error))
|
||||
if (!fu_pxi_receiver_device_fw_upgrade(device,
|
||||
firmware,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* delay for wireless module device read command */
|
||||
g_usleep(5 * 1000);
|
||||
|
||||
/* send device reset command */
|
||||
return fu_pxi_receiver_device_reset(device, error);
|
||||
if (!fu_pxi_receiver_device_reset(device, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -836,6 +862,17 @@ fu_pxi_receiver_device_probe(FuDevice *device, GError **error)
|
||||
return fu_udev_device_set_physical_id(FU_UDEV_DEVICE(device), "hid", error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_pxi_receiver_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_pxi_receiver_device_init(FuPxiReceiverDevice *self)
|
||||
{
|
||||
@ -854,4 +891,5 @@ fu_pxi_receiver_device_class_init(FuPxiReceiverDeviceClass *klass)
|
||||
klass_device->probe = fu_pxi_receiver_device_probe;
|
||||
klass_device->write_firmware = fu_pxi_receiver_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_pxi_receiver_device_prepare_firmware;
|
||||
klass_device->set_progress = fu_pxi_receiver_device_set_progress;
|
||||
}
|
||||
|
@ -453,7 +453,10 @@ fu_pxi_wireless_device_fw_ota_ini_new_check(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_pxi_wireless_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError **error)
|
||||
fu_pxi_wireless_device_fw_upgrade(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuPxiReceiverDevice *parent;
|
||||
FuPxiWirelessDevice *self = FU_PXI_WIRELESS_DEVICE(device);
|
||||
@ -466,6 +469,12 @@ fu_pxi_wireless_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError
|
||||
g_autoptr(GByteArray) receiver_cmd = g_byte_array_new();
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 5);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 95);
|
||||
|
||||
/* proxy */
|
||||
parent = fu_pxi_wireless_device_get_parent(device, error);
|
||||
if (parent == NULL)
|
||||
@ -512,14 +521,16 @@ fu_pxi_wireless_device_fw_upgrade(FuDevice *device, FuFirmware *firmware, GError
|
||||
ota_cmd,
|
||||
error))
|
||||
return FALSE;
|
||||
/* update device status */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_VERIFY);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send ota fw upgrade command */
|
||||
return fu_pxi_wireless_device_set_feature(FU_DEVICE(parent),
|
||||
receiver_cmd->data,
|
||||
receiver_cmd->len,
|
||||
error);
|
||||
if (!fu_pxi_wireless_device_set_feature(FU_DEVICE(parent),
|
||||
receiver_cmd->data,
|
||||
receiver_cmd->len,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -553,7 +564,6 @@ fu_pxi_wireless_device_reset(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* send ota mcu reset command */
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_RESTART);
|
||||
return fu_pxi_wireless_device_set_feature(FU_DEVICE(parent),
|
||||
receiver_cmd->data,
|
||||
receiver_cmd->len,
|
||||
@ -575,6 +585,7 @@ fu_pxi_wireless_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_pxi_wireless_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -582,6 +593,13 @@ fu_pxi_wireless_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 9); /* ota-init */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1);
|
||||
|
||||
/* get the default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -592,6 +610,7 @@ fu_pxi_wireless_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
if (!fu_pxi_wireless_device_fw_ota_ini_new_check(device, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
chunks = fu_chunk_array_new_from_bytes(fw, 0x0, 0x0, FU_PXI_DEVICE_OBJECT_SIZE_MAX);
|
||||
/* prepare write fw into device */
|
||||
@ -599,21 +618,43 @@ fu_pxi_wireless_device_write_firmware(FuDevice *device,
|
||||
self->fwstate.checksum = 0;
|
||||
|
||||
/* write fw into device */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = self->fwstate.offset; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
if (!fu_pxi_wireless_device_write_chunk(device, chk, error))
|
||||
return FALSE;
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + self->fwstate.offset + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* fw upgrade command */
|
||||
if (!fu_pxi_wireless_device_fw_upgrade(device, firmware, error))
|
||||
if (!fu_pxi_wireless_device_fw_upgrade(device,
|
||||
firmware,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send device reset command */
|
||||
g_usleep(FU_PXI_WIRELESS_DEV_DELAY_US);
|
||||
return fu_pxi_wireless_device_reset(device, error);
|
||||
if (!fu_pxi_wireless_device_reset(device, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_pxi_wireless_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -633,6 +674,7 @@ fu_pxi_wireless_device_class_init(FuPxiWirelessDeviceClass *klass)
|
||||
klass_device->write_firmware = fu_pxi_wireless_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_pxi_wireless_device_prepare_firmware;
|
||||
klass_device->to_string = fu_pxi_wireless_device_to_string;
|
||||
klass_device->set_progress = fu_pxi_wireless_device_set_progress;
|
||||
}
|
||||
|
||||
FuPxiWirelessDevice *
|
||||
|
@ -550,6 +550,7 @@ flash_iface_read(FuRealtekMstDevice *self,
|
||||
guint32 address,
|
||||
guint8 *buf,
|
||||
const gsize buf_size,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
gsize bytes_read = 0;
|
||||
@ -591,7 +592,7 @@ flash_iface_read(FuRealtekMstDevice *self,
|
||||
return FALSE;
|
||||
|
||||
bytes_read += read_len;
|
||||
fu_device_set_progress_full(FU_DEVICE(self), bytes_read, buf_size);
|
||||
fu_progress_set_percentage_full(progress, bytes_read, buf_size);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -648,7 +649,11 @@ flash_iface_erase_block(FuRealtekMstDevice *self, guint32 address, GError **erro
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flash_iface_write(FuRealtekMstDevice *self, guint32 address, GBytes *data, GError **error)
|
||||
flash_iface_write(FuRealtekMstDevice *self,
|
||||
guint32 address,
|
||||
GBytes *data,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
gsize bytes_written = 0;
|
||||
gsize total_size = g_bytes_get_size(data);
|
||||
@ -704,14 +709,14 @@ flash_iface_write(FuRealtekMstDevice *self, guint32 address, GBytes *data, GErro
|
||||
}
|
||||
|
||||
bytes_written += chunk_size;
|
||||
fu_device_set_progress_full(FU_DEVICE(self), bytes_written, total_size);
|
||||
fu_progress_set_percentage_full(progress, i + 1, chunks->len);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_realtek_mst_device_detach(FuDevice *device, GError **error)
|
||||
fu_realtek_mst_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRealtekMstDevice *self = FU_REALTEK_MST_DEVICE(device);
|
||||
|
||||
@ -719,7 +724,6 @@ fu_realtek_mst_device_detach(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* Switch to programming mode (stops regular operation) */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!mst_write_register(self, REG_MCU_MODE, MCU_MODE_ISP, error))
|
||||
return FALSE;
|
||||
g_debug("wait for ISP mode ready");
|
||||
@ -733,7 +737,6 @@ fu_realtek_mst_device_detach(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER);
|
||||
fu_device_set_status(device, FWUPD_STATUS_IDLE);
|
||||
|
||||
/* Disable hardware write protect, assuming Flash ~WP is connected to
|
||||
* device pin 88, a GPIO. */
|
||||
@ -743,6 +746,7 @@ fu_realtek_mst_device_detach(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_realtek_mst_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -759,26 +763,45 @@ fu_realtek_mst_device_write_firmware(FuDevice *device,
|
||||
|
||||
g_return_val_if_fail(g_bytes_get_size(firmware_bytes) == FLASH_USER_SIZE, FALSE);
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 20);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 70);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 9);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* flag */
|
||||
|
||||
if (!mst_ensure_device_address(self, I2C_ADDR_ISP, error))
|
||||
return FALSE;
|
||||
|
||||
/* erase old image */
|
||||
g_debug("erase old image from %#x", base_addr);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
for (guint32 offset = 0; offset < FLASH_USER_SIZE; offset += FLASH_BLOCK_SIZE) {
|
||||
fu_device_set_progress_full(device, offset, FLASH_USER_SIZE);
|
||||
if (!flash_iface_erase_block(self, base_addr + offset, error))
|
||||
return FALSE;
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
offset + FLASH_BLOCK_SIZE,
|
||||
FLASH_USER_SIZE);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write new image */
|
||||
g_debug("write new image to %#x", base_addr);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!flash_iface_write(self, base_addr, firmware_bytes, error))
|
||||
if (!flash_iface_write(self,
|
||||
base_addr,
|
||||
firmware_bytes,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!flash_iface_read(self, base_addr, readback_buf, FLASH_USER_SIZE, error))
|
||||
/* verify */
|
||||
if (!flash_iface_read(self,
|
||||
base_addr,
|
||||
readback_buf,
|
||||
FLASH_USER_SIZE,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
if (memcmp(g_bytes_get_data(firmware_bytes, NULL), readback_buf, FLASH_USER_SIZE) != 0) {
|
||||
g_set_error(error,
|
||||
@ -787,22 +810,27 @@ fu_realtek_mst_device_write_firmware(FuDevice *device,
|
||||
"flash contents after write do not match firmware image");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* Erase old flag and write new one. The MST appears to modify the
|
||||
* flag value once booted, so we always write the same value here and
|
||||
* it picks up what we've updated. */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!flash_iface_erase_sector(self, flag_addr & ~(FLASH_SECTOR_SIZE - 1), error))
|
||||
return FALSE;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
return flash_iface_write(self,
|
||||
flag_addr,
|
||||
g_bytes_new_static(flag_data, sizeof(flag_data)),
|
||||
error);
|
||||
if (!flash_iface_write(self,
|
||||
flag_addr,
|
||||
g_bytes_new_static(flag_data, sizeof(flag_data)),
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static FuFirmware *
|
||||
fu_realtek_mst_device_read_firmware(FuDevice *device, GError **error)
|
||||
fu_realtek_mst_device_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRealtekMstDevice *self = FU_REALTEK_MST_DEVICE(device);
|
||||
guint32 bank_address;
|
||||
@ -824,30 +852,30 @@ fu_realtek_mst_device_read_firmware(FuDevice *device, GError **error)
|
||||
image_bytes = g_malloc0(FLASH_USER_SIZE);
|
||||
if (!mst_ensure_device_address(self, I2C_ADDR_ISP, error))
|
||||
return NULL;
|
||||
if (!flash_iface_read(self, bank_address, image_bytes, FLASH_USER_SIZE, error))
|
||||
if (!flash_iface_read(self, bank_address, image_bytes, FLASH_USER_SIZE, progress, error))
|
||||
return NULL;
|
||||
return fu_firmware_new_from_bytes(
|
||||
g_bytes_new_take(g_steal_pointer(&image_bytes), FLASH_USER_SIZE));
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_realtek_mst_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_realtek_mst_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRealtekMstDevice *self = FU_REALTEK_MST_DEVICE(device);
|
||||
g_autofree guint8 *flash_contents = g_malloc0(FLASH_SIZE);
|
||||
|
||||
if (!mst_ensure_device_address(self, I2C_ADDR_ISP, error))
|
||||
return NULL;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
if (!flash_iface_read(self, 0, flash_contents, FLASH_SIZE, error))
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
if (!flash_iface_read(self, 0, flash_contents, FLASH_SIZE, progress, error))
|
||||
return NULL;
|
||||
fu_device_set_status(device, FWUPD_STATUS_IDLE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_IDLE);
|
||||
|
||||
return g_bytes_new_take(g_steal_pointer(&flash_contents), FLASH_SIZE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_realtek_mst_device_attach(FuDevice *device, GError **error)
|
||||
fu_realtek_mst_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRealtekMstDevice *self = FU_REALTEK_MST_DEVICE(device);
|
||||
guint8 value;
|
||||
@ -865,7 +893,6 @@ fu_realtek_mst_device_attach(FuDevice *device, GError **error)
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
g_debug("resetting device to exit ISP mode");
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
|
||||
/* Set register EE bit 2 to request reset. This write can fail
|
||||
* spuriously, so we ignore the write result and verify the device is
|
||||
@ -895,10 +922,20 @@ fu_realtek_mst_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
fu_device_remove_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER);
|
||||
fu_device_set_status(device, FWUPD_STATUS_IDLE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_realtek_mst_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_realtek_mst_device_init(FuRealtekMstDevice *self)
|
||||
{
|
||||
@ -942,4 +979,5 @@ fu_realtek_mst_device_class_init(FuRealtekMstDeviceClass *klass)
|
||||
klass_device->read_firmware = fu_realtek_mst_device_read_firmware;
|
||||
/* dump whole flash */
|
||||
klass_device->dump_firmware = fu_realtek_mst_device_dump_firmware;
|
||||
klass_device->set_progress = fu_realtek_mst_device_set_progress;
|
||||
}
|
||||
|
@ -515,6 +515,7 @@ typedef struct {
|
||||
gchar *location;
|
||||
gboolean completed;
|
||||
GHashTable *messages_seen;
|
||||
FuProgress *progress;
|
||||
} FuRedfishDevicePollCtx;
|
||||
|
||||
static void
|
||||
@ -560,43 +561,43 @@ fu_redfish_device_poll_set_message_id(FuRedfishDevice *self,
|
||||
|
||||
/* set status */
|
||||
if (g_strcmp0(message_id, "Update.1.1.TargetDetermined") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_LOADING);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_LOADING);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "LenovoFirmwareUpdateRegistry.1.0.UpdateAssignment") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_LOADING);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_LOADING);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "LenovoFirmwareUpdateRegistry.1.0.PayloadApplyInProgress") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "LenovoFirmwareUpdateRegistry.1.0.PayloadApplyCompleted") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_IDLE);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_IDLE);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "LenovoFirmwareUpdateRegistry.1.0.UpdateVerifyInProgress") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_VERIFY);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "Update.1.1.TransferringToComponent") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_LOADING);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_LOADING);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "Update.1.1.VerifyingAtComponent") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_VERIFY);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "Update.1.1.UpdateInProgress") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "Update.1.1.UpdateSuccessful") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_IDLE);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_IDLE);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0(message_id, "Update.1.1.InstallingOnComponent") == 0) {
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(ctx->progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -622,7 +623,7 @@ fu_redfish_device_poll_task_once(FuRedfishDevice *self, FuRedfishDevicePollCtx *
|
||||
if (json_object_has_member(json_obj, "PercentComplete")) {
|
||||
gint64 pc = json_object_get_int_member(json_obj, "PercentComplete");
|
||||
if (pc >= 0 && pc <= 100)
|
||||
fu_device_set_progress(FU_DEVICE(self), (guint)pc);
|
||||
fu_progress_set_percentage(ctx->progress, (guint)pc);
|
||||
}
|
||||
|
||||
/* print all messages we've not seen yet */
|
||||
@ -685,12 +686,13 @@ fu_redfish_device_poll_task_once(FuRedfishDevice *self, FuRedfishDevicePollCtx *
|
||||
}
|
||||
|
||||
static FuRedfishDevicePollCtx *
|
||||
fu_redfish_device_poll_ctx_new(const gchar *location)
|
||||
fu_redfish_device_poll_ctx_new(FuProgress *progress, const gchar *location)
|
||||
{
|
||||
FuRedfishDevicePollCtx *ctx = g_new0(FuRedfishDevicePollCtx, 1);
|
||||
ctx->messages_seen = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
|
||||
ctx->location = g_strdup(location);
|
||||
ctx->error_code = FWUPD_ERROR_INTERNAL;
|
||||
ctx->progress = g_object_ref(progress);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@ -698,6 +700,7 @@ static void
|
||||
fu_redfish_device_poll_ctx_free(FuRedfishDevicePollCtx *ctx)
|
||||
{
|
||||
g_hash_table_unref(ctx->messages_seen);
|
||||
g_object_unref(ctx->progress);
|
||||
g_free(ctx->location);
|
||||
g_free(ctx);
|
||||
}
|
||||
@ -708,11 +711,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuRedfishDevicePollCtx, fu_redfish_device_poll_ctx
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
gboolean
|
||||
fu_redfish_device_poll_task(FuRedfishDevice *self, const gchar *location, GError **error)
|
||||
fu_redfish_device_poll_task(FuRedfishDevice *self,
|
||||
const gchar *location,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
const guint timeout = 2400;
|
||||
g_autoptr(GTimer) timer = g_timer_new();
|
||||
g_autoptr(FuRedfishDevicePollCtx) ctx = fu_redfish_device_poll_ctx_new(location);
|
||||
g_autoptr(FuRedfishDevicePollCtx) ctx = fu_redfish_device_poll_ctx_new(progress, location);
|
||||
|
||||
/* sleep and then reprobe hardware */
|
||||
do {
|
||||
|
@ -45,4 +45,7 @@ struct _FuRedfishDeviceClass {
|
||||
FuRedfishBackend *
|
||||
fu_redfish_device_get_backend(FuRedfishDevice *self);
|
||||
gboolean
|
||||
fu_redfish_device_poll_task(FuRedfishDevice *self, const gchar *location, GError **error);
|
||||
fu_redfish_device_poll_task(FuRedfishDevice *self,
|
||||
const gchar *location,
|
||||
FuProgress *progress,
|
||||
GError **error);
|
||||
|
@ -18,7 +18,7 @@ struct _FuRedfishLegacyDevice {
|
||||
G_DEFINE_TYPE(FuRedfishLegacyDevice, fu_redfish_legacy_device, FU_TYPE_REDFISH_DEVICE)
|
||||
|
||||
static gboolean
|
||||
fu_redfish_legacy_device_detach(FuDevice *dev, GError **error)
|
||||
fu_redfish_legacy_device_detach(FuDevice *dev, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRedfishLegacyDevice *self = FU_REDFISH_LEGACY_DEVICE(dev);
|
||||
FuRedfishBackend *backend = fu_redfish_device_get_backend(FU_REDFISH_DEVICE(self));
|
||||
@ -44,7 +44,7 @@ fu_redfish_legacy_device_detach(FuDevice *dev, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_redfish_legacy_device_attach(FuDevice *dev, GError **error)
|
||||
fu_redfish_legacy_device_attach(FuDevice *dev, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRedfishLegacyDevice *self = FU_REDFISH_LEGACY_DEVICE(dev);
|
||||
FuRedfishBackend *backend = fu_redfish_device_get_backend(FU_REDFISH_DEVICE(self));
|
||||
@ -71,6 +71,7 @@ fu_redfish_legacy_device_attach(FuDevice *dev, GError **error)
|
||||
static gboolean
|
||||
fu_redfish_legacy_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -93,7 +94,7 @@ fu_redfish_legacy_device_write_firmware(FuDevice *device,
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, g_bytes_get_data(fw, NULL));
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)g_bytes_get_size(fw));
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_redfish_request_perform(request,
|
||||
fu_redfish_backend_get_push_uri_path(backend),
|
||||
FU_REDFISH_REQUEST_PERFORM_FLAG_LOAD_JSON,
|
||||
@ -111,7 +112,17 @@ fu_redfish_legacy_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
location = json_object_get_string_member(json_obj, "@odata.id");
|
||||
return fu_redfish_device_poll_task(FU_REDFISH_DEVICE(self), location, error);
|
||||
return fu_redfish_device_poll_task(FU_REDFISH_DEVICE(self), location, progress, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_redfish_legacy_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -127,4 +138,5 @@ fu_redfish_legacy_device_class_init(FuRedfishLegacyDeviceClass *klass)
|
||||
klass_device->attach = fu_redfish_legacy_device_attach;
|
||||
klass_device->detach = fu_redfish_legacy_device_detach;
|
||||
klass_device->write_firmware = fu_redfish_legacy_device_write_firmware;
|
||||
klass_device->set_progress = fu_redfish_legacy_device_set_progress;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ fu_redfish_multipart_device_get_parameters(FuRedfishMultipartDevice *self)
|
||||
static gboolean
|
||||
fu_redfish_multipart_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -94,7 +95,7 @@ fu_redfish_multipart_device_write_firmware(FuDevice *device,
|
||||
curl_mime_filedata(part, filename);
|
||||
curl_mime_data(part, g_bytes_get_data(fw, NULL), g_bytes_get_size(fw));
|
||||
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_redfish_request_perform(request,
|
||||
fu_redfish_backend_get_push_uri_path(backend),
|
||||
FU_REDFISH_REQUEST_PERFORM_FLAG_LOAD_JSON,
|
||||
@ -127,7 +128,17 @@ fu_redfish_multipart_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
location = json_object_get_string_member(json_obj, "@odata.id");
|
||||
return fu_redfish_device_poll_task(FU_REDFISH_DEVICE(self), location, error);
|
||||
return fu_redfish_device_poll_task(FU_REDFISH_DEVICE(self), location, progress, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_redfish_multipart_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 100); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -141,4 +152,5 @@ fu_redfish_multipart_device_class_init(FuRedfishMultipartDeviceClass *klass)
|
||||
{
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
klass_device->write_firmware = fu_redfish_multipart_device_write_firmware;
|
||||
klass_device->set_progress = fu_redfish_multipart_device_set_progress;
|
||||
}
|
||||
|
@ -296,6 +296,7 @@ fu_test_redfish_update_func(gconstpointer user_data)
|
||||
gboolean ret;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GBytes) blob_fw = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
|
||||
devices = fu_plugin_get_devices(self->plugin);
|
||||
g_assert_nonnull(devices);
|
||||
@ -311,6 +312,7 @@ fu_test_redfish_update_func(gconstpointer user_data)
|
||||
ret = fu_plugin_runner_write_firmware(self->plugin,
|
||||
dev,
|
||||
blob_fw,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_no_error(error);
|
||||
@ -321,6 +323,7 @@ fu_test_redfish_update_func(gconstpointer user_data)
|
||||
ret = fu_plugin_runner_write_firmware(self->plugin,
|
||||
dev,
|
||||
blob_fw,
|
||||
progress,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_error(error, FWUPD_ERROR, FWUPD_ERROR_WRITE);
|
||||
|
@ -126,7 +126,7 @@ fu_rts54hid_device_write_flash(FuRts54HidDevice *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_rts54hid_device_verify_update_fw(FuRts54HidDevice *self, GError **error)
|
||||
fu_rts54hid_device_verify_update_fw(FuRts54HidDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
const FuRts54HidCmdBuffer cmd_buffer = {
|
||||
.cmd = FU_RTS54HID_CMD_WRITE_DATA,
|
||||
@ -150,7 +150,7 @@ fu_rts54hid_device_verify_update_fw(FuRts54HidDevice *self, GError **error)
|
||||
FU_HID_DEVICE_FLAG_NONE,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_device_sleep_with_progress(FU_DEVICE(self), 4); /* seconds */
|
||||
fu_progress_sleep(progress, 4000);
|
||||
if (!fu_hid_device_get_report(FU_HID_DEVICE(self),
|
||||
0x0,
|
||||
buf,
|
||||
@ -285,6 +285,7 @@ fu_rts54hid_device_close(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_rts54hid_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -292,6 +293,13 @@ fu_rts54hid_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 46);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 52);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* reset */
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -302,18 +310,15 @@ fu_rts54hid_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* erase spare flash bank only if it is not empty */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_rts54hid_device_erase_spare_bank(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* build packets */
|
||||
/* write each block */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
0x00, /* start addr */
|
||||
0x00, /* page_sz */
|
||||
FU_RTS54HID_TRANSFER_BLOCK_SIZE);
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
/* write chunk */
|
||||
@ -325,21 +330,37 @@ fu_rts54hid_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len * 2);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* get device to authenticate the firmware */
|
||||
if (!fu_rts54hid_device_verify_update_fw(self, error))
|
||||
if (!fu_rts54hid_device_verify_update_fw(self, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send software reset to run available flash code */
|
||||
if (!fu_rts54hid_device_reset_to_flash(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_rts54hid_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 62); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 38); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_rts54hid_device_init(FuRts54HidDevice *self)
|
||||
{
|
||||
@ -355,4 +376,5 @@ fu_rts54hid_device_class_init(FuRts54HidDeviceClass *klass)
|
||||
klass_device->to_string = fu_rts54hid_device_to_string;
|
||||
klass_device->setup = fu_rts54hid_device_setup;
|
||||
klass_device->close = fu_rts54hid_device_close;
|
||||
klass_device->set_progress = fu_rts54hid_device_set_progress;
|
||||
}
|
||||
|
@ -209,6 +209,7 @@ fu_rts54hid_module_set_quirk_kv(FuDevice *device,
|
||||
static gboolean
|
||||
fu_rts54hid_module_write_firmware(FuDevice *module,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -235,7 +236,7 @@ fu_rts54hid_module_write_firmware(FuDevice *module,
|
||||
}
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(module, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
|
||||
@ -247,7 +248,7 @@ fu_rts54hid_module_write_firmware(FuDevice *module,
|
||||
return FALSE;
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(module, (gsize)i, (gsize)chunks->len * 2);
|
||||
fu_progress_set_percentage_full(progress, (gsize)i + 1, (gsize)chunks->len);
|
||||
}
|
||||
|
||||
/* success! */
|
||||
|
@ -427,6 +427,7 @@ fu_rts54hub_device_close(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_rts54hub_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -434,6 +435,13 @@ fu_rts54hub_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 46);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 52);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 1);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -449,9 +457,9 @@ fu_rts54hub_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* erase spare flash bank only if it is not empty */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_ERASE);
|
||||
if (!fu_rts54hub_device_erase_flash(self, 1, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* set MCU clock to high clock mode */
|
||||
if (!fu_rts54hub_device_highclockmode(self, 0x0001, error)) {
|
||||
@ -465,14 +473,11 @@ fu_rts54hub_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* build packets */
|
||||
/* write each block */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
0x00, /* start addr */
|
||||
0x00, /* page_sz */
|
||||
FU_RTS54HUB_DEVICE_BLOCK_SIZE);
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
|
||||
@ -485,18 +490,21 @@ fu_rts54hub_device_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len - 1);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* get device to authenticate the firmware */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_VERIFY);
|
||||
if (!fu_rts54hub_device_flash_authentication(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send software reset to run available flash code */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_rts54hub_device_reset_flash(self, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* don't reset the vendor command enable, the device will be rebooted */
|
||||
self->vendor_cmd = FU_RTS54HUB_VENDOR_CMD_NONE;
|
||||
@ -528,6 +536,16 @@ fu_rts54hub_device_prepare_firmware(FuDevice *device,
|
||||
return fu_firmware_new_from_bytes(fw);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_rts54hub_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 62); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 38); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_rts54hub_device_init(FuRts54HubDevice *self)
|
||||
{
|
||||
@ -544,4 +562,5 @@ fu_rts54hub_device_class_init(FuRts54HubDeviceClass *klass)
|
||||
klass_device->to_string = fu_rts54hub_device_to_string;
|
||||
klass_device->prepare_firmware = fu_rts54hub_device_prepare_firmware;
|
||||
klass_device->close = fu_rts54hub_device_close;
|
||||
klass_device->set_progress = fu_rts54hub_device_set_progress;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ fu_rts54hub_rtd21xx_background_detach_cb(FuDevice *device, gpointer user_data, G
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_rts54hub_rtd21xx_background_detach(FuDevice *device, GError **error)
|
||||
fu_rts54hub_rtd21xx_background_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRts54HubDevice *parent = FU_RTS54HUB_DEVICE(fu_device_get_parent(device));
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -127,7 +127,7 @@ fu_rts54hub_rtd21xx_background_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_rts54hub_rtd21xx_background_attach(FuDevice *device, GError **error)
|
||||
fu_rts54hub_rtd21xx_background_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRts54HubDevice *parent = FU_RTS54HUB_DEVICE(fu_device_get_parent(device));
|
||||
FuRts54hubRtd21xxDevice *self = FU_RTS54HUB_RTD21XX_DEVICE(device);
|
||||
@ -147,7 +147,7 @@ fu_rts54hub_rtd21xx_background_attach(FuDevice *device, GError **error)
|
||||
g_prefix_error(error, "failed to attach: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_sleep_with_progress(device, 1);
|
||||
fu_progress_sleep(progress, 1000);
|
||||
|
||||
/* success */
|
||||
fu_device_remove_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER);
|
||||
@ -190,6 +190,7 @@ fu_rts54hub_rtd21xx_background_reload(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -204,6 +205,13 @@ fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* setup */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 5); /* exit */
|
||||
|
||||
/* open device */
|
||||
locker = fu_device_locker_new(self, error);
|
||||
if (locker == NULL)
|
||||
@ -217,7 +225,6 @@ fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
|
||||
/* get project ID address */
|
||||
write_buf[0] = ISP_CMD_GET_PROJECT_ID_ADDR;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
if (!fu_rts54hub_rtd21xx_device_i2c_write(FU_RTS54HUB_RTD21XX_DEVICE(self),
|
||||
UC_ISP_SLAVE_ADDR,
|
||||
UC_BACKGROUND_OPCODE,
|
||||
@ -263,7 +270,6 @@ fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to write project ID from 0x%04x: ", project_addr);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_rts54hub_rtd21xx_device_i2c_write(FU_RTS54HUB_RTD21XX_DEVICE(self),
|
||||
UC_ISP_SLAVE_ADDR,
|
||||
UC_BACKGROUND_OPCODE,
|
||||
@ -288,9 +294,9 @@ fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to send fw update start cmd: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send data */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
0x00, /* start addr */
|
||||
0x00, /* page_sz */
|
||||
@ -314,11 +320,13 @@ fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* update finish command */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_rts54hub_rtd21xx_device_read_status(FU_RTS54HUB_RTD21XX_DEVICE(self), NULL, error))
|
||||
return FALSE;
|
||||
write_buf[0] = ISP_CMD_FW_UPDATE_ISP_DONE;
|
||||
@ -333,10 +341,9 @@ fu_rts54hub_rtd21xx_background_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* exit fw mode */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_set_progress(device, 0);
|
||||
if (!fu_rts54hub_rtd21xx_device_read_status(FU_RTS54HUB_RTD21XX_DEVICE(self), NULL, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
|
@ -113,7 +113,7 @@ fu_rts54hub_rtd21xx_foreground_detach_cb(FuDevice *device, gpointer user_data, G
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_rts54hub_rtd21xx_foreground_detach(FuDevice *device, GError **error)
|
||||
fu_rts54hub_rtd21xx_foreground_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRts54HubDevice *parent = FU_RTS54HUB_DEVICE(fu_device_get_parent(device));
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -126,7 +126,7 @@ fu_rts54hub_rtd21xx_foreground_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_rts54hub_rtd21xx_foreground_attach(FuDevice *device, GError **error)
|
||||
fu_rts54hub_rtd21xx_foreground_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuRts54HubDevice *parent = FU_RTS54HUB_DEVICE(fu_device_get_parent(device));
|
||||
FuRts54hubRtd21xxForeground *self = FU_RTS54HUB_RTD21XX_FOREGROUND(device);
|
||||
@ -139,8 +139,6 @@ fu_rts54hub_rtd21xx_foreground_attach(FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* exit fw mode */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_set_progress(device, 0);
|
||||
if (!fu_rts54hub_rtd21xx_device_read_status(FU_RTS54HUB_RTD21XX_DEVICE(self), NULL, error))
|
||||
return FALSE;
|
||||
if (!fu_rts54hub_rtd21xx_device_i2c_write(FU_RTS54HUB_RTD21XX_DEVICE(self),
|
||||
@ -155,7 +153,7 @@ fu_rts54hub_rtd21xx_foreground_attach(FuDevice *device, GError **error)
|
||||
|
||||
/* the device needs some time to restart with the new firmware before
|
||||
* it can be queried again */
|
||||
fu_device_sleep_with_progress(device, 60);
|
||||
fu_progress_sleep(progress, 60000);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -224,6 +222,7 @@ fu_rts54hub_rtd21xx_foreground_reload(FuDevice *device, GError **error)
|
||||
static gboolean
|
||||
fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -238,6 +237,13 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* setup */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* finish */
|
||||
|
||||
/* open device */
|
||||
locker = fu_device_locker_new(self, error);
|
||||
if (locker == NULL)
|
||||
@ -252,7 +258,6 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
/* enable ISP high priority */
|
||||
write_buf[0] = ISP_CMD_ENTER_FW_UPDATE;
|
||||
write_buf[1] = 0x01;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_rts54hub_rtd21xx_device_i2c_write(FU_RTS54HUB_RTD21XX_DEVICE(self),
|
||||
UC_ISP_SLAVE_ADDR,
|
||||
UC_FOREGROUND_OPCODE,
|
||||
@ -267,7 +272,6 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
|
||||
/* get project ID address */
|
||||
write_buf[0] = ISP_CMD_GET_PROJECT_ID_ADDR;
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
if (!fu_rts54hub_rtd21xx_device_i2c_write(FU_RTS54HUB_RTD21XX_DEVICE(self),
|
||||
UC_ISP_SLAVE_ADDR,
|
||||
UC_FOREGROUND_OPCODE,
|
||||
@ -313,7 +317,6 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to write project ID from 0x%04x: ", project_addr);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_rts54hub_rtd21xx_device_i2c_write(FU_RTS54HUB_RTD21XX_DEVICE(self),
|
||||
UC_ISP_SLAVE_ADDR,
|
||||
UC_FOREGROUND_OPCODE,
|
||||
@ -338,9 +341,9 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed to send fw update start cmd: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* send data */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
chunks = fu_chunk_array_new_from_bytes(fw,
|
||||
0x00, /* start addr */
|
||||
0x00, /* page_sz */
|
||||
@ -364,11 +367,13 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* update finish command */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_BUSY);
|
||||
if (!fu_rts54hub_rtd21xx_device_read_status(FU_RTS54HUB_RTD21XX_DEVICE(self), NULL, error))
|
||||
return FALSE;
|
||||
write_buf[0] = ISP_CMD_FW_UPDATE_ISP_DONE;
|
||||
@ -381,6 +386,7 @@ fu_rts54hub_rtd21xx_foreground_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "failed update finish cmd: ");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
|
@ -423,7 +423,6 @@ fu_solokey_device_verify(FuSolokeyDevice *self, GBytes *fw_sig, GError **error)
|
||||
g_autoptr(GByteArray) res = NULL;
|
||||
g_autoptr(GByteArray) sig = g_byte_array_new();
|
||||
|
||||
fu_device_set_status(FU_DEVICE(self), FWUPD_STATUS_DEVICE_VERIFY);
|
||||
fu_byte_array_append_bytes(sig, fw_sig);
|
||||
fu_solokey_device_exchange(req, SOLO_BOOTLOADER_DONE, 0x00, sig);
|
||||
res = fu_solokey_device_packet(self, SOLO_BOOTLOADER_HID_CMD_BOOT, req, error);
|
||||
@ -447,6 +446,7 @@ fu_solokey_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_solokey_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -455,6 +455,12 @@ fu_solokey_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw_sig = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 10);
|
||||
|
||||
/* build packets */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
@ -465,7 +471,6 @@ fu_solokey_device_write_firmware(FuDevice *device,
|
||||
2048);
|
||||
|
||||
/* write each block */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < chunks->len; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
g_autoptr(GByteArray) buf = g_byte_array_new();
|
||||
@ -490,14 +495,33 @@ fu_solokey_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* update progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)chunks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify the signature and reboot back to runtime */
|
||||
fw_sig = fu_firmware_get_image_by_id_bytes(firmware, FU_FIRMWARE_ID_SIGNATURE, error);
|
||||
if (fw_sig == NULL)
|
||||
return FALSE;
|
||||
return fu_solokey_device_verify(self, fw_sig, error);
|
||||
if (!fu_solokey_device_verify(self, fw_sig, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_solokey_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -522,4 +546,5 @@ fu_solokey_device_class_init(FuSolokeyDeviceClass *klass)
|
||||
klass_device->setup = fu_solokey_device_setup;
|
||||
klass_device->open = fu_solokey_device_open;
|
||||
klass_device->close = fu_solokey_device_close;
|
||||
klass_device->set_progress = fu_solokey_device_set_progress;
|
||||
}
|
||||
|
@ -472,6 +472,17 @@ fu_superio_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_superio_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_superio_device_init(FuSuperioDevice *self)
|
||||
{
|
||||
@ -517,4 +528,5 @@ fu_superio_device_class_init(FuSuperioDeviceClass *klass)
|
||||
klass_device->probe = fu_superio_device_probe;
|
||||
klass_device->setup = fu_superio_device_setup;
|
||||
klass_device->prepare_firmware = fu_superio_device_prepare_firmware;
|
||||
klass_device->set_progress = fu_superio_device_set_progress;
|
||||
}
|
||||
|
@ -174,13 +174,6 @@ fu_superio_it55_device_setup(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_superio_it55_device_progress_cb(goffset current, goffset total, gpointer user_data)
|
||||
{
|
||||
FuDevice *device = FU_DEVICE(user_data);
|
||||
fu_device_set_progress_full(device, (gsize)current, (gsize)total);
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_plugin_superio_patch_autoload(FuDevice *device, GBytes *fw, GError **error)
|
||||
{
|
||||
@ -234,9 +227,7 @@ fu_plugin_superio_patch_autoload(FuDevice *device, GBytes *fw, GError **error)
|
||||
/* progress callback is optional to not affect device progress during writing
|
||||
* firmware */
|
||||
static GBytes *
|
||||
fu_superio_it55_device_get_firmware(FuDevice *device,
|
||||
GFileProgressCallback progress_cb,
|
||||
GError **error)
|
||||
fu_superio_it55_device_get_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
guint64 fwsize = fu_device_get_firmware_size_min(device);
|
||||
@ -254,8 +245,7 @@ fu_superio_it55_device_get_firmware(FuDevice *device,
|
||||
if (!fu_superio_device_ec_read_data(self, &buf[offset], error))
|
||||
return NULL;
|
||||
|
||||
if (progress_cb != NULL)
|
||||
progress_cb(offset, (goffset)fwsize, self);
|
||||
fu_progress_set_percentage_full(progress, (gsize)i + 1, (gsize)block_count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +253,7 @@ fu_superio_it55_device_get_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_superio_it55_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_superio_it55_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
|
||||
@ -275,14 +265,12 @@ fu_superio_it55_device_dump_firmware(FuDevice *device, GError **error)
|
||||
if (locker == NULL)
|
||||
return NULL;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
return fu_superio_it55_device_get_firmware(device,
|
||||
fu_superio_it55_device_progress_cb,
|
||||
error);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
return fu_superio_it55_device_get_firmware(device, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it55_device_attach(FuDevice *device, GError **error)
|
||||
fu_superio_it55_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
|
||||
@ -299,7 +287,7 @@ fu_superio_it55_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it55_device_detach(FuDevice *device, GError **error)
|
||||
fu_superio_it55_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
|
||||
@ -338,20 +326,30 @@ fu_superio_it55_device_erase(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it55_device_write_attempt(FuDevice *device, GBytes *firmware, GError **error)
|
||||
fu_superio_it55_device_write_attempt(FuDevice *device,
|
||||
GBytes *firmware,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
gsize fwsize = g_bytes_get_size(firmware);
|
||||
guint64 total = (fwsize + CHUNK_SIZE - 1) / CHUNK_SIZE;
|
||||
const guint8 *fw_data = NULL;
|
||||
g_autoptr(GBytes) erased_fw = NULL;
|
||||
g_autoptr(GBytes) written_fw = NULL;
|
||||
g_autoptr(GPtrArray) blocks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 80);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1); /* block 0 */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 9);
|
||||
|
||||
if (!fu_superio_it55_device_erase(device, error))
|
||||
return FALSE;
|
||||
|
||||
erased_fw = fu_superio_it55_device_get_firmware(device, NULL, error);
|
||||
erased_fw =
|
||||
fu_superio_it55_device_get_firmware(device, fu_progress_get_child(progress), error);
|
||||
if (erased_fw == NULL) {
|
||||
g_prefix_error(error, "failed to read erased firmware");
|
||||
return FALSE;
|
||||
@ -363,6 +361,7 @@ fu_superio_it55_device_write_attempt(FuDevice *device, GBytes *firmware, GError
|
||||
"firmware was not erased");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* write everything but the first kilobyte */
|
||||
blocks = fu_chunk_array_new_from_bytes(firmware, 0x00, 0x00, BLOCK_SIZE);
|
||||
@ -381,12 +380,9 @@ fu_superio_it55_device_write_attempt(FuDevice *device, GBytes *firmware, GError
|
||||
return FALSE;
|
||||
|
||||
for (guint j = 0; j < CHUNKS_IN_BLOCK; ++j) {
|
||||
gsize progress = i * CHUNKS_IN_BLOCK + j;
|
||||
|
||||
if (first && j < CHUNKS_IN_KBYTE) {
|
||||
offset += CHUNK_SIZE;
|
||||
bytes_left -= CHUNK_SIZE;
|
||||
fu_device_set_progress_full(device, progress, (gsize)total);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -403,10 +399,12 @@ fu_superio_it55_device_write_attempt(FuDevice *device, GBytes *firmware, GError
|
||||
++offset;
|
||||
--bytes_left;
|
||||
}
|
||||
|
||||
fu_device_set_progress_full(device, progress, (gsize)total);
|
||||
}
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)blocks->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* now write the first kilobyte */
|
||||
if (!fu_superio_device_ec_write_cmd(self, SIO_CMD_EC_WRITE_1ST_KBYTE, error))
|
||||
@ -415,27 +413,30 @@ fu_superio_it55_device_write_attempt(FuDevice *device, GBytes *firmware, GError
|
||||
for (guint i = 0; i < CHUNK_SIZE * CHUNKS_IN_KBYTE; ++i)
|
||||
if (!fu_superio_device_ec_write_data(self, fw_data[i], error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
g_usleep(1000);
|
||||
|
||||
written_fw = fu_superio_it55_device_get_firmware(device, NULL, error);
|
||||
written_fw =
|
||||
fu_superio_it55_device_get_firmware(device, fu_progress_get_child(progress), error);
|
||||
if (written_fw == NULL) {
|
||||
g_prefix_error(error, "failed to read erased firmware");
|
||||
g_prefix_error(error, "failed to read firmware");
|
||||
return FALSE;
|
||||
}
|
||||
if (!fu_common_bytes_compare(written_fw, firmware, error)) {
|
||||
g_prefix_error(error, "firmware verification");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
fu_device_set_progress(device, 100);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it55_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -444,6 +445,11 @@ fu_superio_it55_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw_patched = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 10);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
|
||||
/* require detach -> attach */
|
||||
locker = fu_device_locker_new_full(device,
|
||||
(FuDeviceLockerFunc)fu_device_detach,
|
||||
@ -466,14 +472,16 @@ fu_superio_it55_device_write_firmware(FuDevice *device,
|
||||
fw_patched = fu_plugin_superio_patch_autoload(device, fw, error);
|
||||
if (fw_patched == NULL)
|
||||
return FALSE;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* try this many times; the failure-to-flash case leaves you without a
|
||||
* keyboard and future boot may completely fail */
|
||||
for (guint i = 1;; ++i) {
|
||||
g_autoptr(GError) error_chk = NULL;
|
||||
if (fu_superio_it55_device_write_attempt(device, fw_patched, &error_chk))
|
||||
if (fu_superio_it55_device_write_attempt(device,
|
||||
fw_patched,
|
||||
fu_progress_get_child(progress),
|
||||
&error_chk))
|
||||
break;
|
||||
|
||||
if (i == MAX_FLASHING_ATTEMPTS) {
|
||||
@ -483,6 +491,7 @@ fu_superio_it55_device_write_firmware(FuDevice *device,
|
||||
|
||||
g_warning("failure %u: %s", i, error_chk->message);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
|
@ -223,7 +223,7 @@ static GBytes *
|
||||
fu_superio_it89_device_read_addr(FuSuperioDevice *self,
|
||||
guint32 addr,
|
||||
guint size,
|
||||
GFileProgressCallback progress_cb,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree guint8 *buf = NULL;
|
||||
@ -261,8 +261,7 @@ fu_superio_it89_device_read_addr(FuSuperioDevice *self,
|
||||
return NULL;
|
||||
|
||||
/* update progress */
|
||||
if (progress_cb != NULL)
|
||||
progress_cb((goffset)i, (goffset)size, self);
|
||||
fu_progress_set_percentage_full(progress, (goffset)i, (goffset)size);
|
||||
}
|
||||
|
||||
/* check again... */
|
||||
@ -273,13 +272,6 @@ fu_superio_it89_device_read_addr(FuSuperioDevice *self,
|
||||
return g_bytes_new_take(g_steal_pointer(&buf), size);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_superio_it89_device_progress_cb(goffset current, goffset total, gpointer user_data)
|
||||
{
|
||||
FuDevice *device = FU_DEVICE(user_data);
|
||||
fu_device_set_progress_full(device, (gsize)current, (gsize)total);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_write_addr(FuSuperioDevice *self, guint addr, GBytes *fw, GError **error)
|
||||
{
|
||||
@ -409,7 +401,7 @@ fu_plugin_superio_fix_signature(FuSuperioDevice *self, GBytes *fw, GError **erro
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_superio_it89_device_dump_firmware(FuDevice *device, GError **error)
|
||||
fu_superio_it89_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
guint64 fwsize = fu_device_get_firmware_size_min(device);
|
||||
@ -423,28 +415,24 @@ fu_superio_it89_device_dump_firmware(FuDevice *device, GError **error)
|
||||
if (locker == NULL)
|
||||
return NULL;
|
||||
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_READ);
|
||||
return fu_superio_it89_device_read_addr(self,
|
||||
0x0,
|
||||
fwsize,
|
||||
fu_superio_it89_device_progress_cb,
|
||||
error);
|
||||
fu_progress_set_status(progress, FWUPD_STATUS_DEVICE_READ);
|
||||
return fu_superio_it89_device_read_addr(self, 0x0, fwsize, progress, error);
|
||||
}
|
||||
|
||||
static FuFirmware *
|
||||
fu_superio_it89_device_read_firmware(FuDevice *device, GError **error)
|
||||
fu_superio_it89_device_read_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
|
||||
blob = fu_superio_it89_device_dump_firmware(device, error);
|
||||
blob = fu_superio_it89_device_dump_firmware(device, progress, error);
|
||||
fw = fu_plugin_superio_fix_signature(self, blob, error);
|
||||
return fu_firmware_new_from_bytes(fw);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_attach(FuDevice *device, GError **error)
|
||||
fu_superio_it89_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
|
||||
@ -458,7 +446,7 @@ fu_superio_it89_device_attach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_detach(FuDevice *device, GError **error)
|
||||
fu_superio_it89_device_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE(device);
|
||||
guint8 tmp = 0x00;
|
||||
@ -483,14 +471,14 @@ fu_superio_it89_device_detach(FuDevice *device, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_check_eflash(FuSuperioDevice *self, GError **error)
|
||||
fu_superio_it89_device_check_eflash(FuSuperioDevice *self, FuProgress *progress, GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
const guint64 fwsize = fu_device_get_firmware_size_min(FU_DEVICE(self));
|
||||
const guint sigsz = 16;
|
||||
|
||||
/* last 16 bytes of eeprom */
|
||||
fw = fu_superio_it89_device_read_addr(self, fwsize - sigsz, sigsz, NULL, error);
|
||||
fw = fu_superio_it89_device_read_addr(self, fwsize - sigsz, sigsz, progress, error);
|
||||
if (fw == NULL) {
|
||||
g_prefix_error(error, "failed to read signature bytes: ");
|
||||
return FALSE;
|
||||
@ -518,12 +506,22 @@ fu_superio_it89_device_check_eflash(FuSuperioDevice *self, GError **error)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_write_chunk(FuSuperioDevice *self, FuChunk *chk, GError **error)
|
||||
fu_superio_it89_device_write_chunk(FuSuperioDevice *self,
|
||||
FuChunk *chk,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) fw1 = NULL;
|
||||
g_autoptr(GBytes) fw2 = NULL;
|
||||
g_autoptr(GBytes) fw3 = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 1);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 21);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 59);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_VERIFY, 20);
|
||||
|
||||
/* erase page */
|
||||
if (!fu_superio_it89_device_erase_addr(self, fu_chunk_get_address(chk), error)) {
|
||||
g_prefix_error(error,
|
||||
@ -531,12 +529,13 @@ fu_superio_it89_device_write_chunk(FuSuperioDevice *self, FuChunk *chk, GError *
|
||||
(guint)fu_chunk_get_address(chk));
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* check erased */
|
||||
fw1 = fu_superio_it89_device_read_addr(self,
|
||||
fu_chunk_get_address(chk),
|
||||
fu_chunk_get_data_sz(chk),
|
||||
NULL,
|
||||
fu_progress_get_child(progress),
|
||||
error);
|
||||
if (fw1 == NULL) {
|
||||
g_prefix_error(error,
|
||||
@ -548,11 +547,14 @@ fu_superio_it89_device_write_chunk(FuSuperioDevice *self, FuChunk *chk, GError *
|
||||
g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_READ, "sector was not erased");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* skip empty page */
|
||||
fw2 = g_bytes_new_static(fu_chunk_get_data(chk), fu_chunk_get_data_sz(chk));
|
||||
if (fu_common_bytes_is_empty(fw2))
|
||||
if (fu_common_bytes_is_empty(fw2)) {
|
||||
fu_progress_finished(progress);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* write page */
|
||||
if (!fu_superio_it89_device_write_addr(self, fu_chunk_get_address(chk), fw2, error)) {
|
||||
@ -561,12 +563,13 @@ fu_superio_it89_device_write_chunk(FuSuperioDevice *self, FuChunk *chk, GError *
|
||||
(guint)fu_chunk_get_address(chk));
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* verify page */
|
||||
fw3 = fu_superio_it89_device_read_addr(self,
|
||||
fu_chunk_get_address(chk),
|
||||
fu_chunk_get_data_sz(chk),
|
||||
NULL,
|
||||
fu_progress_get_child(progress),
|
||||
error);
|
||||
if (fw3 == NULL) {
|
||||
g_prefix_error(error,
|
||||
@ -581,6 +584,7 @@ fu_superio_it89_device_write_chunk(FuSuperioDevice *self, FuChunk *chk, GError *
|
||||
(guint)fu_chunk_get_address(chk));
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -609,9 +613,47 @@ fu_superio_it89_device_get_jedec_id(FuSuperioDevice *self, guint8 *id, GError **
|
||||
return fu_superio_device_ec_write_cmd(self, SIO_EC_PMC_PM1DISCI, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_write_chunks(FuSuperioDevice *self,
|
||||
GPtrArray *chunks,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_set_steps(progress, chunks->len - 1);
|
||||
for (guint i = 0; i < chunks->len - 1; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
|
||||
/* try this many times; the failure-to-flash case leaves you
|
||||
* without a keyboard and future boot may completely fail */
|
||||
for (guint j = 0;; j++) {
|
||||
g_autoptr(GError) error_chk = NULL;
|
||||
if (fu_superio_it89_device_write_chunk(self,
|
||||
chk,
|
||||
fu_progress_get_child(progress),
|
||||
&error_chk))
|
||||
break;
|
||||
if (j > 5) {
|
||||
g_propagate_error(error, g_steal_pointer(&error_chk));
|
||||
return FALSE;
|
||||
}
|
||||
g_warning("failure %u: %s", j, error_chk->message);
|
||||
fu_progress_reset(fu_progress_get_child(progress));
|
||||
}
|
||||
|
||||
/* set progress */
|
||||
fu_progress_step_done(progress);
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_superio_it89_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -621,6 +663,12 @@ fu_superio_it89_device_write_firmware(FuDevice *device,
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GPtrArray) chunks = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* check e-flash */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 95);
|
||||
|
||||
/* check JEDEC ID */
|
||||
if (!fu_superio_it89_device_get_jedec_id(self, id, error)) {
|
||||
g_prefix_error(error, "failed to get JEDEC ID: ");
|
||||
@ -639,8 +687,9 @@ fu_superio_it89_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
|
||||
/* check eflash is writable */
|
||||
if (!fu_superio_it89_device_check_eflash(self, error))
|
||||
if (!fu_superio_it89_device_check_eflash(self, fu_progress_get_child(progress), error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* get default image */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
@ -658,29 +707,14 @@ fu_superio_it89_device_write_firmware(FuDevice *device,
|
||||
|
||||
/* chunks of 1kB, skipping the final chunk */
|
||||
chunks = fu_chunk_array_new_from_bytes(fw_fixed, 0x00, 0x00, 0x400);
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < chunks->len - 1; i++) {
|
||||
FuChunk *chk = g_ptr_array_index(chunks, i);
|
||||
|
||||
/* try this many times; the failure-to-flash case leaves you
|
||||
* without a keyboard and future boot may completely fail */
|
||||
for (guint j = 0;; j++) {
|
||||
g_autoptr(GError) error_chk = NULL;
|
||||
if (fu_superio_it89_device_write_chunk(self, chk, &error_chk))
|
||||
break;
|
||||
if (j > 5) {
|
||||
g_propagate_error(error, g_steal_pointer(&error_chk));
|
||||
return FALSE;
|
||||
}
|
||||
g_warning("failure %u: %s", j, error_chk->message);
|
||||
}
|
||||
|
||||
/* set progress */
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)chunks->len);
|
||||
}
|
||||
if (!fu_superio_it89_device_write_chunks(self,
|
||||
chunks,
|
||||
fu_progress_get_child(progress),
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
fu_device_set_progress(device, 100);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -612,6 +612,7 @@ fu_synaptics_cxaudio_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -619,6 +620,14 @@ fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
GPtrArray *records = fu_srec_firmware_get_records(FU_SREC_FIRMWARE(firmware));
|
||||
FuSynapticsCxaudioFileKind file_kind;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 3); /* park */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* init */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* invalidate */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1); /* unpark */
|
||||
|
||||
/* check if a patch file fits completely into the EEPROM */
|
||||
for (guint i = 0; i < records->len; i++) {
|
||||
FuSrecFirmwareRecord *rcd = g_ptr_array_index(records, i);
|
||||
@ -645,6 +654,7 @@ fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
error))
|
||||
return FALSE;
|
||||
g_usleep(10 * 1000);
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* initialize layout signature and version to 0 if transitioning from
|
||||
* EEPROM layout version 1 => 0 */
|
||||
@ -681,9 +691,9 @@ fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
}
|
||||
g_debug("initialized layout signature");
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* perform the actual write */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
for (guint i = 0; i < records->len; i++) {
|
||||
FuSrecFirmwareRecord *rcd = g_ptr_array_index(records, i);
|
||||
if (rcd->kind != FU_FIRMWARE_SREC_RECORD_KIND_S3_DATA_32)
|
||||
@ -704,8 +714,11 @@ fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
rcd->buf->len);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_progress_full(device, (gsize)i, (gsize)records->len);
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
(gsize)i + 1,
|
||||
(gsize)records->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* in case of a full FW upgrade invalidate the old FW patch (if any)
|
||||
* as it may have not been done by the S37 file */
|
||||
@ -740,6 +753,7 @@ fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
g_debug("invalidated old FW patch for CX2070x (RAM) device");
|
||||
}
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* unpark the FW */
|
||||
if (!fu_synaptics_cxaudio_device_register_clear_bit(
|
||||
@ -748,13 +762,14 @@ fu_synaptics_cxaudio_device_write_firmware(FuDevice *device,
|
||||
7,
|
||||
error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_synaptics_cxaudio_device_attach(FuDevice *device, GError **error)
|
||||
fu_synaptics_cxaudio_device_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuSynapticsCxaudioDevice *self = FU_SYNAPTICS_CXAUDIO_DEVICE(device);
|
||||
guint8 tmp = 1 << 6;
|
||||
@ -765,7 +780,6 @@ fu_synaptics_cxaudio_device_attach(FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
|
||||
/* wait for re-enumeration */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
|
||||
/* this fails on success */
|
||||
@ -816,6 +830,17 @@ fu_synaptics_cxaudio_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_cxaudio_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_cxaudio_device_init(FuSynapticsCxaudioDevice *self)
|
||||
{
|
||||
@ -839,4 +864,5 @@ fu_synaptics_cxaudio_device_class_init(FuSynapticsCxaudioDeviceClass *klass)
|
||||
klass_device->write_firmware = fu_synaptics_cxaudio_device_write_firmware;
|
||||
klass_device->attach = fu_synaptics_cxaudio_device_attach;
|
||||
klass_device->prepare_firmware = fu_synaptics_cxaudio_device_prepare_firmware;
|
||||
klass_device->set_progress = fu_synaptics_cxaudio_device_set_progress;
|
||||
}
|
||||
|
@ -119,13 +119,14 @@ gboolean
|
||||
fu_plugin_write_firmware(FuPlugin *plugin,
|
||||
FuDevice *device,
|
||||
GBytes *blob_fw,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = fu_device_locker_new(device, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
if (!fu_device_write_firmware(device, blob_fw, flags, error))
|
||||
if (!fu_device_write_firmware(device, blob_fw, progress, flags, error))
|
||||
return FALSE;
|
||||
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_SKIPS_RESTART))
|
||||
fu_plugin_device_remove(plugin, device);
|
||||
|
@ -295,6 +295,7 @@ fu_synaptics_mst_device_set_flash_sector_erase(FuSynapticsMstDevice *self,
|
||||
static gboolean
|
||||
fu_synaptics_mst_device_update_esm(FuSynapticsMstDevice *self,
|
||||
const guint8 *payload_data,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint32 checksum = 0;
|
||||
@ -360,9 +361,9 @@ fu_synaptics_mst_device_update_esm(FuSynapticsMstDevice *self,
|
||||
}
|
||||
write_offset += unit_sz;
|
||||
write_idx += unit_sz;
|
||||
fu_device_set_progress_full(FU_DEVICE(self),
|
||||
(goffset)i * 100,
|
||||
(goffset)(write_loops - 1) * 100);
|
||||
fu_progress_set_percentage_full(progress,
|
||||
(goffset)i + 1,
|
||||
(goffset)write_loops);
|
||||
}
|
||||
|
||||
/* check ESM checksum */
|
||||
@ -404,6 +405,7 @@ static gboolean
|
||||
fu_synaptics_mst_device_update_tesla_leaf_firmware(FuSynapticsMstDevice *self,
|
||||
guint32 payload_len,
|
||||
const guint8 *payload_data,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FuSynapticsMstConnection) connection = NULL;
|
||||
@ -460,9 +462,9 @@ fu_synaptics_mst_device_update_tesla_leaf_firmware(FuSynapticsMstDevice *self,
|
||||
}
|
||||
offset += length;
|
||||
data_to_write -= length;
|
||||
fu_device_set_progress_full(FU_DEVICE(self),
|
||||
(goffset)i * 100,
|
||||
(goffset)(write_loops - 1) * 100);
|
||||
fu_progress_set_percentage_full(progress,
|
||||
(goffset)i + 1,
|
||||
(goffset)write_loops);
|
||||
}
|
||||
|
||||
/* check data just written */
|
||||
@ -526,6 +528,7 @@ static gboolean
|
||||
fu_synaptics_mst_device_update_panamera_firmware(FuSynapticsMstDevice *self,
|
||||
guint32 payload_len,
|
||||
const guint8 *payload_data,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
guint16 crc_tmp = 0;
|
||||
@ -613,9 +616,9 @@ fu_synaptics_mst_device_update_panamera_firmware(FuSynapticsMstDevice *self,
|
||||
|
||||
write_offset += unit_sz;
|
||||
write_idx += unit_sz;
|
||||
fu_device_set_progress_full(FU_DEVICE(self),
|
||||
(goffset)i * 100,
|
||||
(goffset)(write_loops - 1) * 100);
|
||||
fu_progress_set_percentage_full(progress,
|
||||
(goffset)i + 1,
|
||||
(goffset)write_loops);
|
||||
}
|
||||
|
||||
/* verify CRC */
|
||||
@ -853,6 +856,7 @@ static gboolean
|
||||
fu_synaptics_mst_device_update_cayenne_firmware(FuSynapticsMstDevice *self,
|
||||
guint32 payload_len,
|
||||
const guint8 *payload_data,
|
||||
FuProgress *progress,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FuSynapticsMstConnection) connection = NULL;
|
||||
@ -910,9 +914,9 @@ fu_synaptics_mst_device_update_cayenne_firmware(FuSynapticsMstDevice *self,
|
||||
}
|
||||
offset += length;
|
||||
data_to_write -= length;
|
||||
fu_device_set_progress_full(FU_DEVICE(self),
|
||||
(goffset)i * 100,
|
||||
(goffset)(write_loops - 1) * 100);
|
||||
fu_progress_set_percentage_full(progress,
|
||||
(goffset)i * 100,
|
||||
(goffset)(write_loops - 1) * 100);
|
||||
}
|
||||
|
||||
/* verify CRC */
|
||||
@ -1031,6 +1035,7 @@ fu_synaptics_mst_device_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_synaptics_mst_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -1040,13 +1045,18 @@ fu_synaptics_mst_device_write_firmware(FuDevice *device,
|
||||
gsize payload_len;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 10);
|
||||
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
payload_data = g_bytes_get_data(fw, &payload_len);
|
||||
|
||||
/* enable remote control and disable on exit */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_WRITE);
|
||||
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_SKIPS_RESTART)) {
|
||||
locker =
|
||||
fu_device_locker_new_full(self,
|
||||
@ -1072,6 +1082,7 @@ fu_synaptics_mst_device_write_firmware(FuDevice *device,
|
||||
if (!fu_synaptics_mst_device_update_tesla_leaf_firmware(self,
|
||||
payload_len,
|
||||
payload_data,
|
||||
progress,
|
||||
error)) {
|
||||
g_prefix_error(error, "Firmware update failed: ");
|
||||
return FALSE;
|
||||
@ -1082,13 +1093,14 @@ fu_synaptics_mst_device_write_firmware(FuDevice *device,
|
||||
g_prefix_error(error, "Failed to prepare for write: ");
|
||||
return FALSE;
|
||||
}
|
||||
if (!fu_synaptics_mst_device_update_esm(self, payload_data, error)) {
|
||||
if (!fu_synaptics_mst_device_update_esm(self, payload_data, progress, error)) {
|
||||
g_prefix_error(error, "ESM update failed: ");
|
||||
return FALSE;
|
||||
}
|
||||
if (!fu_synaptics_mst_device_update_panamera_firmware(self,
|
||||
payload_len,
|
||||
payload_data,
|
||||
progress,
|
||||
error)) {
|
||||
g_prefix_error(error, "Firmware update failed: ");
|
||||
return FALSE;
|
||||
@ -1099,6 +1111,7 @@ fu_synaptics_mst_device_write_firmware(FuDevice *device,
|
||||
if (!fu_synaptics_mst_device_update_cayenne_firmware(self,
|
||||
payload_len,
|
||||
payload_data,
|
||||
progress,
|
||||
error)) {
|
||||
g_prefix_error(error, "Firmware update failed: ");
|
||||
return FALSE;
|
||||
@ -1111,10 +1124,11 @@ fu_synaptics_mst_device_write_firmware(FuDevice *device,
|
||||
"Unsupported chip family");
|
||||
return FALSE;
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* wait for flash clear to settle */
|
||||
fu_device_set_status(device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_sleep_with_progress(device, 2);
|
||||
fu_progress_sleep(fu_progress_get_child(progress), 2000);
|
||||
fu_progress_step_done(progress);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1465,6 +1479,17 @@ fu_synaptics_mst_device_set_quirk_kv(FuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_mst_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_synaptics_mst_device_class_init(FuSynapticsMstDeviceClass *klass)
|
||||
{
|
||||
@ -1477,4 +1502,5 @@ fu_synaptics_mst_device_class_init(FuSynapticsMstDeviceClass *klass)
|
||||
klass_device->write_firmware = fu_synaptics_mst_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_synaptics_mst_device_prepare_firmware;
|
||||
klass_device->probe = fu_synaptics_mst_device_probe;
|
||||
klass_device->set_progress = fu_synaptics_mst_device_set_progress;
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ fu_synaprom_config_setup(FuDevice *device, GError **error)
|
||||
g_autofree gchar *version = NULL;
|
||||
g_autoptr(GByteArray) reply = NULL;
|
||||
g_autoptr(GByteArray) request = NULL;
|
||||
g_autoptr(FuProgress) progress = fu_progress_new(G_STRLOC);
|
||||
g_autofree gchar *devid = NULL;
|
||||
|
||||
/* get IOTA */
|
||||
@ -84,7 +85,12 @@ fu_synaprom_config_setup(FuDevice *device, GError **error)
|
||||
request = fu_synaprom_request_new(FU_SYNAPROM_CMD_IOTA_FIND, &cmd, sizeof(cmd));
|
||||
reply = fu_synaprom_reply_new(sizeof(FuSynapromReplyIotaFindHdr) +
|
||||
FU_SYNAPROM_MAX_IOTA_READ_SIZE);
|
||||
if (!fu_synaprom_device_cmd_send(FU_SYNAPROM_DEVICE(parent), request, reply, 5000, error))
|
||||
if (!fu_synaprom_device_cmd_send(FU_SYNAPROM_DEVICE(parent),
|
||||
request,
|
||||
reply,
|
||||
progress,
|
||||
5000,
|
||||
error))
|
||||
return FALSE;
|
||||
if (reply->len < sizeof(hdr) + sizeof(cfg)) {
|
||||
g_set_error(error,
|
||||
@ -213,6 +219,7 @@ fu_synaprom_config_prepare_firmware(FuDevice *device,
|
||||
static gboolean
|
||||
fu_synaprom_config_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
@ -225,7 +232,7 @@ fu_synaprom_config_write_firmware(FuDevice *device,
|
||||
return FALSE;
|
||||
|
||||
/* I assume the CFG/MFW difference is detected in the device...*/
|
||||
return fu_synaprom_device_write_fw(FU_SYNAPROM_DEVICE(parent), fw, error);
|
||||
return fu_synaprom_device_write_fw(FU_SYNAPROM_DEVICE(parent), fw, progress, error);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -259,17 +266,17 @@ fu_synaprom_config_constructed(GObject *obj)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_synaprom_config_attach(FuDevice *device, GError **error)
|
||||
fu_synaprom_config_attach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDevice *parent = fu_device_get_parent(device);
|
||||
return fu_device_attach(parent, error);
|
||||
return fu_device_attach(parent, progress, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_synaprom_config_detach(FuDevice *device, GError **error)
|
||||
fu_synaprom_config_detach(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuDevice *parent = fu_device_get_parent(device);
|
||||
return fu_device_detach(parent, error);
|
||||
return fu_device_detach(parent, progress, error);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user