mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-14 14:22:13 +00:00
vli: Fix VL103 reboot from ROM mode to FW mode
The logic was wrong; we should have been using command 0xB0 for attach back to FW mode for both VL10x and VL103. Using a generic reset on VL103 always reset the device back into bootloader mode as the ROM signatures were being written by command 0xC0. As now attach and detach have different code paths, there's no point having a `FuVliDevice->reset()` vfunc, and so we can make everything a little simpler at the same time.
This commit is contained in:
parent
df2ae010d5
commit
aebd90baad
@ -73,19 +73,6 @@ fu_vli_device_get_spi_cmd (FuVliDevice *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_vli_device_reset (FuVliDevice *self, GError **error)
|
||||
{
|
||||
FuVliDeviceClass *klass = FU_VLI_DEVICE_GET_CLASS (self);
|
||||
if (klass->reset != NULL) {
|
||||
if (!klass->reset (self, error)) {
|
||||
g_prefix_error (error, "failed to reset device: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_device_spi_write_enable (FuVliDevice *self, GError **error)
|
||||
{
|
||||
@ -584,32 +571,6 @@ fu_vli_device_setup (FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_device_attach (FuDevice *device, GError **error)
|
||||
{
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* replug, and ignore the device going away */
|
||||
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
if (!fu_vli_device_reset (FU_VLI_DEVICE (device), &error_local)) {
|
||||
if (g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_NO_DEVICE) ||
|
||||
g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_FAILED)) {
|
||||
g_debug ("ignoring %s", error_local->message);
|
||||
} else {
|
||||
g_propagate_prefixed_error (error,
|
||||
g_steal_pointer (&error_local),
|
||||
"failed to restart device: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_device_set_quirk_kv (FuDevice *device,
|
||||
const gchar *key,
|
||||
@ -682,5 +643,4 @@ fu_vli_device_class_init (FuVliDeviceClass *klass)
|
||||
klass_device->to_string = fu_vli_device_to_string;
|
||||
klass_device->set_quirk_kv = fu_vli_device_set_quirk_kv;
|
||||
klass_device->setup = fu_vli_device_setup;
|
||||
klass_device->attach = fu_vli_device_attach;
|
||||
}
|
||||
|
@ -21,8 +21,6 @@ struct _FuVliDeviceClass
|
||||
void (*to_string) (FuVliDevice *self,
|
||||
guint idt,
|
||||
GString *str);
|
||||
gboolean (*reset) (FuVliDevice *self,
|
||||
GError **error);
|
||||
gboolean (*spi_chip_erase) (FuVliDevice *self,
|
||||
GError **error);
|
||||
gboolean (*spi_sector_erase) (FuVliDevice *self,
|
||||
@ -69,8 +67,6 @@ void fu_vli_device_set_spi_auto_detect (FuVliDevice *self,
|
||||
gboolean spi_auto_detect);
|
||||
FuVliDeviceKind fu_vli_device_get_kind (FuVliDevice *self);
|
||||
guint32 fu_vli_device_get_offset (FuVliDevice *self);
|
||||
gboolean fu_vli_device_reset (FuVliDevice *self,
|
||||
GError **error);
|
||||
gboolean fu_vli_device_get_spi_cmd (FuVliDevice *self,
|
||||
FuVliDeviceSpiReq req,
|
||||
guint8 *cmd,
|
||||
|
@ -216,32 +216,6 @@ fu_vli_pd_device_spi_write_data (FuVliDevice *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_pd_device_reset (FuVliDevice *device, GError **error)
|
||||
{
|
||||
return g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
0xb0, 0x0000, 0x0000,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_pd_device_reset_vl103 (FuVliDevice *device, GError **error)
|
||||
{
|
||||
return g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
0xc0, 0x0000, 0x0000,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_pd_device_parade_setup (FuVliPdDevice *self, GError **error)
|
||||
{
|
||||
@ -277,7 +251,6 @@ fu_vli_pd_device_setup (FuVliDevice *device, GError **error)
|
||||
guint8 verbuf[4] = { 0x0 };
|
||||
guint8 tmp = 0;
|
||||
g_autofree gchar *version_str = NULL;
|
||||
FuVliDeviceClass *klass = FU_VLI_DEVICE_GET_CLASS (device);
|
||||
|
||||
/* get version */
|
||||
if (!g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (self)),
|
||||
@ -323,10 +296,6 @@ fu_vli_pd_device_setup (FuVliDevice *device, GError **error)
|
||||
}
|
||||
}
|
||||
|
||||
/* handle this in a different way */
|
||||
if (fu_vli_device_get_kind (device) == FU_VLI_DEVICE_KIND_VL103)
|
||||
klass->reset = fu_vli_pd_device_reset_vl103;
|
||||
|
||||
/* get bootloader mode */
|
||||
if (!fu_vli_pd_device_read_reg (self, 0x00F7, &tmp, error))
|
||||
return FALSE;
|
||||
@ -459,11 +428,16 @@ fu_vli_pd_device_write_firmware (FuDevice *device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define VL10X_CMD1_SET_ROM_SIG 0xa0 /* all VL10x */
|
||||
#define VL10X_CMD2_CHIP_RESET 0xb0 /* all VL10x */
|
||||
#define VL10X_CMD3_SET_ROM_SIG_AND_RESET 0xc0 /* VL103 only */
|
||||
|
||||
static gboolean
|
||||
fu_vli_pd_device_detach (FuDevice *device, GError **error)
|
||||
{
|
||||
FuVliPdDevice *self = FU_VLI_PD_DEVICE (device);
|
||||
guint8 tmp = 0;
|
||||
guint8 cmd = VL10X_CMD2_CHIP_RESET;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* write GPIOs */
|
||||
@ -482,12 +456,19 @@ fu_vli_pd_device_detach (FuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
if (!fu_vli_pd_device_write_reg (self, 0x2AE5, 0x87, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* VL103 CMD1 does not work, so use CMD3 whose function is CMD1+CMD2 */
|
||||
if (fu_vli_device_get_kind (FU_VLI_DEVICE (device)) == FU_VLI_DEVICE_KIND_VL103) {
|
||||
cmd = VL10X_CMD3_SET_ROM_SIG_AND_RESET;
|
||||
} else {
|
||||
/* set ROM sig */
|
||||
if (!g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
0xa0, 0x0000, 0x0000,
|
||||
VL10X_CMD1_SET_ROM_SIG,
|
||||
0x0000, 0x0000,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, error))
|
||||
@ -496,7 +477,14 @@ fu_vli_pd_device_detach (FuDevice *device, GError **error)
|
||||
|
||||
/* reset from SPI_Code into ROM_Code */
|
||||
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
if (!fu_vli_device_reset (FU_VLI_DEVICE (device), &error_local)) {
|
||||
if (!g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
cmd, 0x0000, 0x0000,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, &error_local)) {
|
||||
if (g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_FAILED)) {
|
||||
@ -512,6 +500,43 @@ fu_vli_pd_device_detach (FuDevice *device, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
fu_vli_pd_device_attach (FuDevice *device, GError **error)
|
||||
{
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* replug, and ignore the device going away */
|
||||
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
|
||||
/* CMD2 works for VL10x *and* VL103 */
|
||||
if (!g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
VL10X_CMD2_CHIP_RESET,
|
||||
0x0000, 0x0000,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, &error_local)) {
|
||||
if (g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_NO_DEVICE) ||
|
||||
g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_FAILED)) {
|
||||
g_debug ("ignoring %s", error_local->message);
|
||||
} else {
|
||||
g_propagate_prefixed_error (error,
|
||||
g_steal_pointer (&error_local),
|
||||
"failed to restart device: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_vli_pd_device_init (FuVliPdDevice *self)
|
||||
{
|
||||
@ -533,9 +558,9 @@ fu_vli_pd_device_class_init (FuVliPdDeviceClass *klass)
|
||||
klass_device->read_firmware = fu_vli_pd_device_read_firmware;
|
||||
klass_device->write_firmware = fu_vli_pd_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_vli_pd_device_prepare_firmware;
|
||||
klass_device->attach = fu_vli_pd_device_attach;
|
||||
klass_device->detach = fu_vli_pd_device_detach;
|
||||
klass_vli_device->setup = fu_vli_pd_device_setup;
|
||||
klass_vli_device->reset = fu_vli_pd_device_reset;
|
||||
klass_vli_device->spi_chip_erase = fu_vli_pd_device_spi_chip_erase;
|
||||
klass_vli_device->spi_sector_erase = fu_vli_pd_device_spi_sector_erase;
|
||||
klass_vli_device->spi_read_data = fu_vli_pd_device_spi_read_data;
|
||||
|
@ -325,16 +325,36 @@ fu_vli_usbhub_device_spi_write_data (FuVliDevice *self,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_vli_usbhub_device_reset (FuVliDevice *device, GError **error)
|
||||
fu_vli_usbhub_device_attach (FuDevice *device, GError **error)
|
||||
{
|
||||
return g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
0xf6, 0x0040, 0x0002,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, error);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* replug, and ignore the device going away */
|
||||
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
|
||||
if (!g_usb_device_control_transfer (fu_usb_device_get_dev (FU_USB_DEVICE (device)),
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||
G_USB_DEVICE_RECIPIENT_DEVICE,
|
||||
0xf6, 0x0040, 0x0002,
|
||||
NULL, 0x0, NULL,
|
||||
FU_VLI_DEVICE_TIMEOUT,
|
||||
NULL, &error_local)) {
|
||||
if (g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_NO_DEVICE) ||
|
||||
g_error_matches (error_local,
|
||||
G_USB_DEVICE_ERROR,
|
||||
G_USB_DEVICE_ERROR_FAILED)) {
|
||||
g_debug ("ignoring %s", error_local->message);
|
||||
} else {
|
||||
g_propagate_prefixed_error (error,
|
||||
g_steal_pointer (&error_local),
|
||||
"failed to restart device: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* disable hub sleep states -- not really required by 815~ hubs */
|
||||
@ -995,9 +1015,9 @@ fu_vli_usbhub_device_class_init (FuVliUsbhubDeviceClass *klass)
|
||||
klass_device->read_firmware = fu_vli_usbhub_device_read_firmware;
|
||||
klass_device->write_firmware = fu_vli_usbhub_device_write_firmware;
|
||||
klass_device->prepare_firmware = fu_vli_usbhub_device_prepare_firmware;
|
||||
klass_device->attach = fu_vli_usbhub_device_attach;
|
||||
klass_vli_device->to_string = fu_vli_usbhub_device_to_string;
|
||||
klass_vli_device->setup = fu_vli_usbhub_device_setup;
|
||||
klass_vli_device->reset = fu_vli_usbhub_device_reset;
|
||||
klass_vli_device->spi_chip_erase = fu_vli_usbhub_device_spi_chip_erase;
|
||||
klass_vli_device->spi_sector_erase = fu_vli_usbhub_device_spi_sector_erase;
|
||||
klass_vli_device->spi_read_data = fu_vli_usbhub_device_spi_read_data;
|
||||
|
Loading…
Reference in New Issue
Block a user