system76-launch: Prompt for unlock keypress if reset command is blocked

This commit is contained in:
Jeremy Soller 2021-02-25 10:23:07 -07:00 committed by Mario Limonciello
parent 0b6c67a3e3
commit 9beb12ad97
2 changed files with 43 additions and 29 deletions

View File

@ -20,58 +20,71 @@ struct _FuSystem76LaunchDevice {
G_DEFINE_TYPE (FuSystem76LaunchDevice, fu_system76_launch_device, FU_TYPE_USB_DEVICE) G_DEFINE_TYPE (FuSystem76LaunchDevice, fu_system76_launch_device, FU_TYPE_USB_DEVICE)
static gboolean static gboolean
fu_system76_launch_device_setup (FuDevice *device, GError **error) fu_system76_launch_device_command (FuDevice *device, guint8 *data, gsize len, GError **error)
{ {
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
const guint8 ep_in = 0x82; const guint8 ep_in = 0x82;
const guint8 ep_out = 0x03; const guint8 ep_out = 0x03;
guint8 data[32] = { 0 };
gsize actual_len = 0; gsize actual_len = 0;
g_autofree gchar *version = NULL;
/* send version command */ /* send command */
data[0] = SYSTEM76_LAUNCH_CMD_VERSION;
if (!g_usb_device_interrupt_transfer (usb_device, if (!g_usb_device_interrupt_transfer (usb_device,
ep_out, ep_out,
data, data,
sizeof(data), len,
&actual_len, &actual_len,
SYSTEM76_LAUNCH_TIMEOUT, SYSTEM76_LAUNCH_TIMEOUT,
NULL, NULL,
error)) { error)) {
g_prefix_error (error, "failed to send version command: "); g_prefix_error (error, "failed to send command: ");
return FALSE; return FALSE;
} }
if (actual_len < sizeof(data)) { if (actual_len < len) {
g_set_error (error, g_set_error (error,
G_IO_ERROR, G_IO_ERROR,
G_IO_ERROR_INVALID_DATA, G_IO_ERROR_INVALID_DATA,
"version command truncated: sent %" G_GSIZE_FORMAT " bytes", "command truncated: sent %" G_GSIZE_FORMAT " bytes",
actual_len); actual_len);
return FALSE; return FALSE;
} }
/* receive version response */ /* receive response */
if (!g_usb_device_interrupt_transfer (usb_device, if (!g_usb_device_interrupt_transfer (usb_device,
ep_in, ep_in,
data, data,
sizeof(data), len,
&actual_len, &actual_len,
SYSTEM76_LAUNCH_TIMEOUT, SYSTEM76_LAUNCH_TIMEOUT,
NULL, NULL,
error)) { error)) {
g_prefix_error (error, "failed to read version response: "); g_prefix_error (error, "failed to read response: ");
return FALSE; return FALSE;
} }
if (actual_len < sizeof(data)) { if (actual_len < len) {
g_set_error (error, g_set_error (error,
G_IO_ERROR, G_IO_ERROR,
G_IO_ERROR_INVALID_DATA, G_IO_ERROR_INVALID_DATA,
"version response truncated: received %" G_GSIZE_FORMAT " bytes", "response truncated: received %" G_GSIZE_FORMAT " bytes",
actual_len); actual_len);
return FALSE; return FALSE;
} }
return TRUE;
}
static gboolean
fu_system76_launch_device_setup (FuDevice *device, GError **error)
{
guint8 data[32] = { 0 };
g_autofree gchar *version = NULL;
/* execute version command */
data[0] = SYSTEM76_LAUNCH_CMD_VERSION;
if (!fu_system76_launch_device_command (device, data, sizeof(data), error)) {
g_prefix_error (error, "failed to execute version command: ");
return FALSE;
}
version = g_strdup_printf ("%s", &data[2]); version = g_strdup_printf ("%s", &data[2]);
fu_device_set_version (device, version); fu_device_set_version (device, version);
@ -81,27 +94,27 @@ fu_system76_launch_device_setup (FuDevice *device, GError **error)
static gboolean static gboolean
fu_system76_launch_device_detach (FuDevice *device, GError **error) fu_system76_launch_device_detach (FuDevice *device, GError **error)
{ {
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
const guint8 ep_out = 0x03;
guint8 data[32] = { 0 }; guint8 data[32] = { 0 };
gsize actual_len = 0;
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART); /* execute reset command */
/* send reset command, should result in bootloader device appearing */
data[0] = SYSTEM76_LAUNCH_CMD_RESET; data[0] = SYSTEM76_LAUNCH_CMD_RESET;
if (!g_usb_device_interrupt_transfer (usb_device, if (!fu_system76_launch_device_command (device, data, sizeof(data), error)) {
ep_out, g_prefix_error (error, "failed to execute reset command: ");
data,
sizeof(data),
&actual_len,
SYSTEM76_LAUNCH_TIMEOUT,
NULL,
error)) {
g_prefix_error (error, "failed to send reset command: ");
return FALSE; return FALSE;
} }
/* prompt for unlock if reset was blocked */
if (data[1] != 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NEEDS_USER_ACTION,
"To ensure you have physical access, %s needs to be manually unlocked. "
"Please press Fn+Esc to unlock and re-run the update.",
fu_device_get_name (device));
return FALSE;
}
fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART);
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
return TRUE; return TRUE;

View File

@ -19,6 +19,7 @@ shared_module('fu_plugin_system76_launch',
install : true, install : true,
install_dir: plugin_dir, install_dir: plugin_dir,
link_with : [ link_with : [
fwupd,
fwupdplugin, fwupdplugin,
], ],
c_args : cargs, c_args : cargs,