Add a flag to open and close with the parent device

This is a common pattern that is used in lots of plugins, so move the
logic into common code.
This commit is contained in:
Richard Hughes 2021-07-11 14:30:23 +01:00
parent df297d3ee2
commit 0cc06f032c
8 changed files with 57 additions and 155 deletions

View File

@ -234,6 +234,8 @@ fu_device_internal_flag_to_string (FuDeviceInternalFlags flag)
return "inhibit-children";
if (flag == FU_DEVICE_INTERNAL_FLAG_NO_AUTO_REMOVE_CHILDREN)
return "no-auto-remove-children";
if (flag == FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN)
return "use-parent-for-open";
return NULL;
}
@ -282,6 +284,8 @@ fu_device_internal_flag_from_string (const gchar *flag)
return FU_DEVICE_INTERNAL_FLAG_INHIBIT_CHILDREN;
if (g_strcmp0 (flag, "no-auto-remove-children") == 0)
return FU_DEVICE_INTERNAL_FLAG_NO_AUTO_REMOVE_CHILDREN;
if (g_strcmp0 (flag, "use-parent-for-open") == 0)
return FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN;
return FU_DEVICE_INTERNAL_FLAG_UNKNOWN;
}
@ -3755,39 +3759,12 @@ fu_device_open_cb (FuDevice *self, gpointer user_data, GError **error)
return klass->open (self, error);
}
/**
* fu_device_open:
* @self: a #FuDevice
* @error: (nullable): optional return location for an error
*
* Opens a device, optionally running a object-specific vfunc.
*
* Plugins can call fu_device_open() multiple times without calling
* fu_device_close(), but only the first call will actually invoke the vfunc.
*
* It is expected that plugins issue the same number of fu_device_open() and
* fu_device_close() methods when using a specific @self.
*
* If the `->probe()`, `->open()` and `->setup()` actions all complete
* successfully the internal device flag %FU_DEVICE_INTERNAL_FLAG_IS_OPEN will
* be set.
*
* NOTE: It is important to still call fu_device_close() even if this function
* fails as the device may still be partially initialized.
*
* Returns: %TRUE for success
*
* Since: 1.1.2
**/
gboolean
fu_device_open (FuDevice *self, GError **error)
static gboolean
fu_device_open_internal (FuDevice *self, GError **error)
{
FuDeviceClass *klass = FU_DEVICE_GET_CLASS (self);
FuDevicePrivate *priv = GET_PRIVATE (self);
g_return_val_if_fail (FU_IS_DEVICE (self), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* already open */
g_atomic_int_inc (&priv->open_refcount);
if (priv->open_refcount > 1)
@ -3828,6 +3805,49 @@ fu_device_open (FuDevice *self, GError **error)
return TRUE;
}
/**
* fu_device_open:
* @self: a #FuDevice
* @error: (nullable): optional return location for an error
*
* Opens a device, optionally running a object-specific vfunc.
*
* Plugins can call fu_device_open() multiple times without calling
* fu_device_close(), but only the first call will actually invoke the vfunc.
*
* It is expected that plugins issue the same number of fu_device_open() and
* fu_device_close() methods when using a specific @self.
*
* If the `->probe()`, `->open()` and `->setup()` actions all complete
* successfully the internal device flag %FU_DEVICE_INTERNAL_FLAG_IS_OPEN will
* be set.
*
* NOTE: It is important to still call fu_device_close() even if this function
* fails as the device may still be partially initialized.
*
* Returns: %TRUE for success
*
* Since: 1.1.2
**/
gboolean
fu_device_open (FuDevice *self, GError **error)
{
g_return_val_if_fail (FU_IS_DEVICE (self), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (fu_device_has_internal_flag (self, FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN)) {
FuDevice *parent = fu_device_get_parent (self);
if (parent == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"no parent device");
return FALSE;
}
return fu_device_open_internal (parent, error);
}
return fu_device_open_internal (self, error);
}
/**
* fu_device_close:
* @self: a #FuDevice

View File

@ -239,6 +239,7 @@ FuDevice *fu_device_new (void);
* @FU_DEVICE_INTERNAL_FLAG_ATTACH_EXTRA_RESET: Device needs resetting twice for attach after the firmware update
* @FU_DEVICE_INTERNAL_FLAG_INHIBIT_CHILDREN: Children of the device are inhibited by the parent
* @FU_DEVICE_INTERNAL_FLAG_NO_AUTO_REMOVE_CHILDREN: Do not auto-remove clildren in the device list
* @FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN: Use parent to open and close the device
*
* The device internal flags.
**/
@ -260,6 +261,7 @@ typedef enum {
FU_DEVICE_INTERNAL_FLAG_ATTACH_EXTRA_RESET = (1llu << 13), /* Since: 1.6.2 */
FU_DEVICE_INTERNAL_FLAG_INHIBIT_CHILDREN = (1llu << 14), /* Since: 1.6.2 */
FU_DEVICE_INTERNAL_FLAG_NO_AUTO_REMOVE_CHILDREN = (1llu << 15), /* Since: 1.6.2 */
FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN = (1llu << 16), /* Since: 1.6.2 */
/*< private >*/
FU_DEVICE_INTERNAL_FLAG_UNKNOWN = G_MAXUINT64,
} FuDeviceInternalFlags;

View File

@ -36,20 +36,6 @@ fu_hailuck_tp_device_probe (FuDevice *device, GError **error)
return TRUE;
}
static gboolean
fu_hailuck_tp_device_open (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
return fu_device_open (parent, error);
}
static gboolean
fu_hailuck_tp_device_close (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
return fu_device_close (parent, error);
}
typedef struct {
guint8 type;
guint8 success; /* if 0xff, then cmd-0x10 */
@ -206,6 +192,7 @@ fu_hailuck_tp_device_init (FuHailuckTpDevice *self)
fu_device_set_name (FU_DEVICE (self), "Touchpad");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
fu_device_add_icon (FU_DEVICE (self), "input-touchpad");
fu_device_set_remove_delay (FU_DEVICE (self),
FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
@ -216,8 +203,6 @@ 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->open = fu_hailuck_tp_device_open;
klass_device->close = fu_hailuck_tp_device_close;
klass_device->probe = fu_hailuck_tp_device_probe;
}

View File

@ -59,18 +59,6 @@ fu_ifd_device_set_access (FuIfdDevice *self, FuIfdRegion region, FuIfdAccess acc
priv->access[region] = access;
}
static gboolean
fu_ifd_device_open (FuDevice *device, GError **error)
{
return fu_device_open (fu_device_get_parent (device), error);
}
static gboolean
fu_ifd_device_close (FuDevice *device, GError **error)
{
return fu_device_close (fu_device_get_parent (device), error);
}
static void
fu_ifd_device_to_string (FuDevice *device, guint idt, GString *str)
{
@ -131,6 +119,7 @@ fu_ifd_device_init (FuIfdDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
fu_device_add_icon (FU_DEVICE (self), "computer");
}
@ -141,8 +130,6 @@ fu_ifd_device_class_init (FuIfdDeviceClass *klass)
klass_device->to_string = fu_ifd_device_to_string;
klass_device->dump_firmware = fu_ifd_device_dump_firmware;
klass_device->read_firmware = fu_ifd_device_read_firmware;
klass_device->open = fu_ifd_device_open;
klass_device->close = fu_ifd_device_close;
}
FuDevice *

View File

@ -96,24 +96,6 @@ fu_pxi_wireless_device_get_parent (FuDevice *self, GError **error)
return FU_PXI_RECEIVER_DEVICE (FU_UDEV_DEVICE (parent));
}
static gboolean
fu_pxi_wireless_device_open (FuDevice *device, GError **error)
{
FuPxiReceiverDevice *parent = fu_pxi_wireless_device_get_parent (device, error);
if (parent == NULL)
return FALSE;
return fu_device_open (FU_DEVICE (parent), error);
}
static gboolean
fu_pxi_wireless_device_close (FuDevice *device, GError **error)
{
FuPxiReceiverDevice *parent = fu_pxi_wireless_device_get_parent (device, error);
if (parent == NULL)
return FALSE;
return fu_device_close (FU_DEVICE (parent), error);
}
static gboolean
fu_pxi_wireless_device_get_cmd_response (FuPxiWirelessDevice *device,
guint8 *buf, guint bufsz,
@ -612,6 +594,7 @@ static void
fu_pxi_wireless_device_init (FuPxiWirelessDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_add_vendor_id (FU_DEVICE (self), "USB:0x093A");
fu_device_add_protocol (FU_DEVICE (self), "com.pixart.rf");
@ -621,8 +604,6 @@ static void
fu_pxi_wireless_device_class_init (FuPxiWirelessDeviceClass *klass)
{
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
klass_device->open = fu_pxi_wireless_device_open;
klass_device->close = fu_pxi_wireless_device_close;
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;

View File

@ -193,34 +193,6 @@ fu_rts54hid_module_set_quirk_kv (FuDevice *device,
}
static gboolean
fu_rts54hid_module_open (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
if (parent == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"no parent device");
return FALSE;
}
return fu_device_open (parent, error);
}
static gboolean
fu_rts54hid_module_close (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
if (parent == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"no parent device");
return FALSE;
}
return fu_device_close (parent, error);
}
static gboolean
fu_rts54hid_module_write_firmware (FuDevice *module,
FuFirmware *firmware,
@ -272,6 +244,7 @@ fu_rts54hid_module_write_firmware (FuDevice *module,
static void
fu_rts54hid_module_init (FuRts54HidModule *self)
{
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
}
static void
@ -281,8 +254,6 @@ fu_rts54hid_module_class_init (FuRts54HidModuleClass *klass)
klass_device->write_firmware = fu_rts54hid_module_write_firmware;
klass_device->to_string = fu_rts54hid_module_to_string;
klass_device->set_quirk_kv = fu_rts54hid_module_set_quirk_kv;
klass_device->open = fu_rts54hid_module_open;
klass_device->close = fu_rts54hid_module_close;
}
FuRts54HidModule *

View File

@ -217,34 +217,6 @@ fu_rts54hub_rtd21xx_device_read_status (FuRts54hubRtd21xxDevice *self,
4200, status, error);
}
static gboolean
fu_rts54hub_rtd21xx_device_open (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
if (parent == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"no parent device");
return FALSE;
}
return fu_device_open (parent, error);
}
static gboolean
fu_rts54hub_rtd21xx_device_close (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
if (parent == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"no parent device");
return FALSE;
}
return fu_device_close (parent, error);
}
static void
fu_rts54hub_rtd21xx_device_init (FuRts54hubRtd21xxDevice *self)
{
@ -252,6 +224,7 @@ fu_rts54hub_rtd21xx_device_init (FuRts54hubRtd21xxDevice *self)
fu_device_add_protocol (FU_DEVICE (self), "com.realtek.rts54.i2c");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_DUAL_IMAGE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
fu_device_set_install_duration (FU_DEVICE (self), 100); /* seconds */
fu_device_set_logical_id (FU_DEVICE (self), "I2C");
@ -264,6 +237,4 @@ fu_rts54hub_rtd21xx_device_class_init (FuRts54hubRtd21xxDeviceClass *klass)
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
klass_device->to_string = fu_rts54hub_rtd21xx_device_to_string;
klass_device->set_quirk_kv = fu_rts54hub_rtd21xx_device_set_quirk_kv;
klass_device->open = fu_rts54hub_rtd21xx_device_open;
klass_device->close = fu_rts54hub_rtd21xx_device_close;
}

View File

@ -218,6 +218,7 @@ fu_synaprom_config_init (FuSynapromConfig *self)
{
fu_device_add_protocol (FU_DEVICE (self), "com.synaptics.prometheus.config");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_USE_PARENT_FOR_OPEN);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_set_logical_id (FU_DEVICE (self), "cfg");
fu_device_set_name (FU_DEVICE (self), "Prometheus IOTA Config");
@ -241,20 +242,6 @@ fu_synaprom_config_constructed (GObject *obj)
G_OBJECT_CLASS (fu_synaprom_config_parent_class)->constructed (obj);
}
static gboolean
fu_synaprom_config_open (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
return fu_device_open (parent, error);
}
static gboolean
fu_synaprom_config_close (FuDevice *device, GError **error)
{
FuDevice *parent = fu_device_get_parent (device);
return fu_device_close (parent, error);
}
static gboolean
fu_synaprom_config_attach (FuDevice *device, GError **error)
{
@ -277,8 +264,6 @@ fu_synaprom_config_class_init (FuSynapromConfigClass *klass)
object_class->constructed = fu_synaprom_config_constructed;
klass_device->write_firmware = fu_synaprom_config_write_firmware;
klass_device->prepare_firmware = fu_synaprom_config_prepare_firmware;
klass_device->open = fu_synaprom_config_open;
klass_device->close = fu_synaprom_config_close;
klass_device->setup = fu_synaprom_config_setup;
klass_device->reload = fu_synaprom_config_setup;
klass_device->attach = fu_synaprom_config_attach;