diff --git a/plugins/vli/fu-vli-usbhub-device.c b/plugins/vli/fu-vli-usbhub-device.c index 64f8bc3b1..b8f96b9e7 100644 --- a/plugins/vli/fu-vli-usbhub-device.c +++ b/plugins/vli/fu-vli-usbhub-device.c @@ -498,43 +498,22 @@ fu_vli_usbhub_device_probe (FuDevice *device, GError **error) static gboolean fu_vli_usbhub_device_pd_setup (FuVliUsbhubDevice *self, GError **error) { - FuVliPdHdr hdr = { 0x0 }; g_autoptr(FuDevice) dev = NULL; g_autoptr(GError) error_local = NULL; - /* legacy location */ - if (!fu_vli_device_spi_read_block (FU_VLI_DEVICE (self), - VLI_USBHUB_FLASHMAP_ADDR_PD_LEGACY + - VLI_USBHUB_PD_FLASHMAP_ADDR_LEGACY, - (guint8 *) &hdr, sizeof(hdr), error)) { - g_prefix_error (error, "failed to read legacy PD header"); - return FALSE; - } - - /* new location */ - if (GUINT16_FROM_LE (hdr.vid) != 0x2109) { - g_debug ("PD VID was 0x%04x trying new location", - GUINT16_FROM_LE (hdr.vid)); - if (!fu_vli_device_spi_read_block (FU_VLI_DEVICE (self), - VLI_USBHUB_FLASHMAP_ADDR_PD + - VLI_USBHUB_PD_FLASHMAP_ADDR, - (guint8 *) &hdr, sizeof(hdr), error)) { - g_prefix_error (error, "failed to read PD header"); - return FALSE; - } - } - - /* just empty space */ - if (hdr.fwver == G_MAXUINT32) { - g_debug ("no PD device header found"); - return TRUE; - } - /* add child */ - dev = fu_vli_usbhub_pd_device_new (&hdr); - fu_device_set_quirks (dev, fu_device_get_quirks (FU_DEVICE (self))); - if (!fu_device_probe (dev, &error_local)) { - g_warning ("cannot create PD device: %s", error_local->message); + dev = fu_vli_usbhub_pd_device_new (self); + if (!fu_device_probe (dev, error)) + return FALSE; + if (!fu_device_setup (dev, &error_local)) { + if (g_error_matches (error_local, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND)) { + g_debug ("%s", error_local->message); + } else { + g_warning ("cannot create PD device: %s", + error_local->message); + } return TRUE; } fu_device_add_child (FU_DEVICE (self), dev); diff --git a/plugins/vli/fu-vli-usbhub-pd-device.c b/plugins/vli/fu-vli-usbhub-pd-device.c index ba470c77d..684be5560 100644 --- a/plugins/vli/fu-vli-usbhub-pd-device.c +++ b/plugins/vli/fu-vli-usbhub-pd-device.c @@ -19,7 +19,6 @@ struct _FuVliUsbhubPdDevice { FuDevice parent_instance; - FuVliPdHdr hdr; FuVliDeviceKind device_kind; }; @@ -38,10 +37,11 @@ fu_vli_usbhub_pd_device_to_string (FuDevice *device, guint idt, GString *str) } static gboolean -fu_vli_usbhub_pd_device_probe (FuDevice *device, GError **error) +fu_vli_usbhub_pd_device_setup (FuDevice *device, GError **error) { + FuVliPdHdr hdr = { 0x0 }; FuVliUsbhubPdDevice *self = FU_VLI_USBHUB_PD_DEVICE (device); - + FuVliUsbhubDevice *parent = FU_VLI_USBHUB_DEVICE (fu_device_get_parent (device)); guint32 fwver; g_autofree gchar *fwver_str = NULL; g_autofree gchar *instance_id0 = NULL; @@ -49,8 +49,39 @@ fu_vli_usbhub_pd_device_probe (FuDevice *device, GError **error) g_autofree gchar *instance_id2 = NULL; g_autofree gchar *instance_id3 = NULL; + /* legacy location */ + if (!fu_vli_device_spi_read_block (FU_VLI_DEVICE (parent), + VLI_USBHUB_FLASHMAP_ADDR_PD_LEGACY + + VLI_USBHUB_PD_FLASHMAP_ADDR_LEGACY, + (guint8 *) &hdr, sizeof(hdr), error)) { + g_prefix_error (error, "failed to read legacy PD header"); + return FALSE; + } + + /* new location */ + if (GUINT16_FROM_LE (hdr.vid) != 0x2109) { + g_debug ("PD VID was 0x%04x trying new location", + GUINT16_FROM_LE (hdr.vid)); + if (!fu_vli_device_spi_read_block (FU_VLI_DEVICE (parent), + VLI_USBHUB_FLASHMAP_ADDR_PD + + VLI_USBHUB_PD_FLASHMAP_ADDR, + (guint8 *) &hdr, sizeof(hdr), error)) { + g_prefix_error (error, "failed to read PD header"); + return FALSE; + } + } + + /* just empty space */ + if (hdr.fwver == G_MAXUINT32) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND, + "no PD device header found"); + return FALSE; + } + /* get version */ - fwver = GUINT32_FROM_BE (self->hdr.fwver); + fwver = GUINT32_FROM_BE (hdr.fwver); self->device_kind = fu_vli_pd_common_guess_device_kind (fwver); if (self->device_kind == FU_VLI_DEVICE_KIND_UNKNOWN) { g_set_error (error, @@ -66,23 +97,23 @@ fu_vli_usbhub_pd_device_probe (FuDevice *device, GError **error) fwver_str = fu_common_version_from_uint32 (fwver, FWUPD_VERSION_FORMAT_QUAD); fu_device_set_version (device, fwver_str); instance_id0 = g_strdup_printf ("USB\\VID_%04X&PID_%04X&APP_%02X", - GUINT16_FROM_LE (self->hdr.vid), - GUINT16_FROM_LE (self->hdr.pid), + GUINT16_FROM_LE (hdr.vid), + GUINT16_FROM_LE (hdr.pid), fwver & 0xff); fu_device_add_instance_id (device, instance_id0); instance_id1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X&DEV_%s", - GUINT16_FROM_LE (self->hdr.vid), - GUINT16_FROM_LE (self->hdr.pid), + GUINT16_FROM_LE (hdr.vid), + GUINT16_FROM_LE (hdr.pid), fu_vli_common_device_kind_to_string (self->device_kind)); fu_device_add_instance_id (device, instance_id1); /* add standard GUIDs in order of priority */ instance_id2 = g_strdup_printf ("USB\\VID_%04X&PID_%04X", - GUINT16_FROM_LE (self->hdr.vid), - GUINT16_FROM_LE (self->hdr.pid)); + GUINT16_FROM_LE (hdr.vid), + GUINT16_FROM_LE (hdr.pid)); fu_device_add_instance_id (device, instance_id2); instance_id3 = g_strdup_printf ("USB\\VID_%04X", - GUINT16_FROM_LE (self->hdr.vid)); + GUINT16_FROM_LE (hdr.vid)); fu_device_add_instance_id_full (device, instance_id3, FU_DEVICE_INSTANCE_FLAG_ONLY_QUIRKS); @@ -94,6 +125,19 @@ fu_vli_usbhub_pd_device_probe (FuDevice *device, GError **error) return TRUE; } +static gboolean +fu_vli_usbhub_pd_device_reload (FuDevice *device, GError **error) +{ + FuVliUsbhubDevice *parent = FU_VLI_USBHUB_DEVICE (fu_device_get_parent (device)); + g_autoptr(FuDeviceLocker) locker = NULL; + + /* open parent device */ + locker = fu_device_locker_new (parent, error); + if (locker == NULL) + return FALSE; + return fu_vli_usbhub_pd_device_setup (device, error); +} + static FuFirmware * fu_vli_usbhub_pd_device_prepare_firmware (FuDevice *device, GBytes *fw, @@ -215,7 +259,8 @@ fu_vli_usbhub_pd_device_class_init (FuVliUsbhubPdDeviceClass *klass) { FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); klass_device->to_string = fu_vli_usbhub_pd_device_to_string; - klass_device->probe = fu_vli_usbhub_pd_device_probe; + klass_device->setup = fu_vli_usbhub_pd_device_setup; + klass_device->reload = fu_vli_usbhub_pd_device_reload; klass_device->attach = fu_vli_usbhub_pd_device_attach; klass_device->dump_firmware = fu_vli_usbhub_pd_device_dump_firmware; klass_device->write_firmware = fu_vli_usbhub_pd_device_write_firmware; @@ -223,9 +268,10 @@ fu_vli_usbhub_pd_device_class_init (FuVliUsbhubPdDeviceClass *klass) } FuDevice * -fu_vli_usbhub_pd_device_new (FuVliPdHdr *hdr) +fu_vli_usbhub_pd_device_new (FuVliUsbhubDevice *parent) { - FuVliUsbhubPdDevice *self = g_object_new (FU_TYPE_VLI_USBHUB_PD_DEVICE, NULL); - memcpy (&self->hdr, hdr, sizeof(self->hdr)); + FuVliUsbhubPdDevice *self = g_object_new (FU_TYPE_VLI_USBHUB_PD_DEVICE, + "parent", parent, + NULL); return FU_DEVICE (self); } diff --git a/plugins/vli/fu-vli-usbhub-pd-device.h b/plugins/vli/fu-vli-usbhub-pd-device.h index 61280f328..cceb4c2c3 100644 --- a/plugins/vli/fu-vli-usbhub-pd-device.h +++ b/plugins/vli/fu-vli-usbhub-pd-device.h @@ -8,8 +8,6 @@ #include "fu-plugin.h" -#include "fu-vli-pd-common.h" - #define FU_TYPE_VLI_USBHUB_PD_DEVICE (fu_vli_usbhub_pd_device_get_type ()) G_DECLARE_FINAL_TYPE (FuVliUsbhubPdDevice, fu_vli_usbhub_pd_device, FU, VLI_USBHUB_PD_DEVICE, FuDevice) @@ -18,4 +16,4 @@ struct _FuVliUsbhubPdDeviceClass FuDeviceClass parent_class; }; -FuDevice *fu_vli_usbhub_pd_device_new (FuVliPdHdr *hdr); +FuDevice *fu_vli_usbhub_pd_device_new (FuVliUsbhubDevice *parent);