synapticsmst: Add a reboot at end of flash cycle

This makes sure the MST hub jumps to the new active firmware after
completion.
This commit is contained in:
Mario Limonciello 2018-07-20 11:53:43 -05:00 committed by Mario Limonciello
parent 801cca6dc3
commit 2b4013562d
3 changed files with 38 additions and 4 deletions

View File

@ -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));

View File

@ -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,

View File

@ -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) {