diff --git a/plugins/synapticsmst/fu-plugin-synapticsmst.c b/plugins/synapticsmst/fu-plugin-synapticsmst.c index 1487c9460..d9840df4d 100644 --- a/plugins/synapticsmst/fu-plugin-synapticsmst.c +++ b/plugins/synapticsmst/fu-plugin-synapticsmst.c @@ -15,6 +15,7 @@ #include "fu-device-metadata.h" #define SYNAPTICS_FLASH_MODE_DELAY 3 +#define SYNAPTICS_UPDATE_ENUMERATE_TRIES 3 #define HWID_DELL_INC "85d38fda-fc0e-5c6f-808f-076984ae7978" #define DELL_DOCK_FLASH_GUID "e7ca1f36-bf73-4574-afe6-a4ccacabf479" @@ -348,9 +349,24 @@ fu_plugin_update (FuPlugin *plugin, /* Re-run device enumeration to find the new device version */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_RESTART); - if (!synapticsmst_device_enumerate_device (device, - data->system_type, error)) { - return FALSE; + for (guint i = 1; i <= SYNAPTICS_UPDATE_ENUMERATE_TRIES; i++) { + g_autoptr(GError) error_local = NULL; + g_usleep (SYNAPTICS_FLASH_MODE_DELAY * 1000000); + if (!synapticsmst_device_enumerate_device (device, + data->system_type, + &error_local)) { + g_warning ("Unable to find device after %u seconds: %s", + SYNAPTICS_FLASH_MODE_DELAY * i, + error_local->message); + if (i == SYNAPTICS_UPDATE_ENUMERATE_TRIES) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_INTERNAL, + "%s", + error_local->message); + return FALSE; + } + } } fu_device_set_version (dev, synapticsmst_device_get_version (device)); diff --git a/plugins/synapticsmst/synapticsmst-common.h b/plugins/synapticsmst/synapticsmst-common.h index 29fbdaf52..6ab87d6b4 100644 --- a/plugins/synapticsmst/synapticsmst-common.h +++ b/plugins/synapticsmst/synapticsmst-common.h @@ -52,6 +52,7 @@ typedef enum { UPDC_CAL_EEPROM_CHECK_CRC8 = 0X16, UPDC_CAL_EEPROM_CHECK_CRC16, UPDC_WRITE_TO_EEPROM = 0X20, + UPDC_WRITE_TO_MEMORY = 0x21, UPDC_WRITE_TO_TX_DPCD = 0x22, UPDC_READ_FROM_EEPROM = 0x30, UPDC_READ_FROM_TX_DPCD = 0x32, diff --git a/plugins/synapticsmst/synapticsmst-device.c b/plugins/synapticsmst/synapticsmst-device.c index 8d4ac8fa0..92e8c4d35 100644 --- a/plugins/synapticsmst/synapticsmst-device.c +++ b/plugins/synapticsmst/synapticsmst-device.c @@ -541,6 +541,23 @@ synapticsmst_device_get_flash_checksum (SynapticsMSTDevice *device, } } +static gboolean +synapticsmst_device_restart (SynapticsMSTDevice *device, + GError **error) +{ + g_autoptr(SynapticsMSTConnection) connection = NULL; + SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); + guint8 dwData[4] = {0xF5, 0, 0 ,0}; + + /* issue the reboot command, ignore return code (triggers before returning) */ + connection = synapticsmst_common_new (priv->fd, priv->layer, priv->rad); + synapticsmst_common_rc_set_command (connection, + UPDC_WRITE_TO_MEMORY, + 4, (gint) 0x2000FC, (guint8*) &dwData); + + return TRUE; +} + gboolean synapticsmst_device_write_firmware (SynapticsMSTDevice *device, GBytes *fw, @@ -757,7 +774,7 @@ synapticsmst_device_write_firmware (SynapticsMSTDevice *device, } /* disable remote control and close aux node */ - if (!synapticsmst_device_disable_remote_control (device, error)) + if (!synapticsmst_device_restart (device, error)) return FALSE; if (rc) {