summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2022-03-16 15:44:46 +0100
committerAleksander Morgado <aleksander@aleksander.es>2022-03-18 10:19:23 +0100
commit8fa701a945260dd716197f0d9ad5d2ac26d4d02e (patch)
tree789f1fea1e1a54239f83401e9965184782c4f761 /src
parent3cc7e7e31bd0c01d4177787dc2e0f13cb631c440 (diff)
downloadlibqmi-8fa701a945260dd716197f0d9ad5d2ac26d4d02e.tar.gz
qmi-firmware-update: always validate type of TTY before using it
When listing TTYs or waiting for TTYs, always explicitly specify the exact mode the modem should be in, so that we don't get the wrong device. E.g. after a reset request, always wait for a TTY with the device in download mode. The modem mode is automatically detected based on the amount of USB interfaces the device exposes. If the device has a single USB interface, then it's in download mode, otherwise it's in modem mode. A vid:pid match could also be possible, but it would be harder to maintain. Let's use this approach for now and see how it goes.
Diffstat (limited to 'src')
-rw-r--r--src/qmi-firmware-update/qfu-device-selection.c26
-rw-r--r--src/qmi-firmware-update/qfu-device-selection.h9
-rw-r--r--src/qmi-firmware-update/qfu-helpers-sysfs.c105
-rw-r--r--src/qmi-firmware-update/qfu-helpers-sysfs.h18
-rw-r--r--src/qmi-firmware-update/qfu-helpers-udev.c84
-rw-r--r--src/qmi-firmware-update/qfu-helpers-udev.h2
-rw-r--r--src/qmi-firmware-update/qfu-helpers.c16
-rw-r--r--src/qmi-firmware-update/qfu-helpers.h13
-rw-r--r--src/qmi-firmware-update/qfu-reseter.c2
-rw-r--r--src/qmi-firmware-update/qfu-updater.c11
10 files changed, 187 insertions, 99 deletions
diff --git a/src/qmi-firmware-update/qfu-device-selection.c b/src/qmi-firmware-update/qfu-device-selection.c
index 138e813f..21e490d8 100644
--- a/src/qmi-firmware-update/qfu-device-selection.c
+++ b/src/qmi-firmware-update/qfu-device-selection.c
@@ -54,7 +54,8 @@ struct _QfuDeviceSelectionPrivate {
static GFile *
device_selection_get_single (QfuDeviceSelection *self,
- QfuHelpersDeviceType device_type)
+ QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode)
{
GFile *first_selection = NULL;
GFile *preferred_selection = NULL;
@@ -65,7 +66,7 @@ device_selection_get_single (QfuDeviceSelection *self,
qfu_helpers_device_type_to_string (device_type),
self->priv->sysfs_path);
- list = qfu_helpers_list_devices (device_type, self->priv->sysfs_path);
+ list = qfu_helpers_list_devices (device_type, device_mode, self->priv->sysfs_path);
for (l = list; l; l = g_list_next (l)) {
path = g_file_get_path (G_FILE (l->data));
g_debug ("[qfu,device-selection] device found: %s", path);
@@ -100,20 +101,22 @@ device_selection_get_single (QfuDeviceSelection *self,
GFile *
qfu_device_selection_get_single_cdc_wdm (QfuDeviceSelection *self)
{
- return device_selection_get_single (self, QFU_HELPERS_DEVICE_TYPE_CDC_WDM);
+ return device_selection_get_single (self, QFU_HELPERS_DEVICE_TYPE_CDC_WDM, QFU_HELPERS_DEVICE_MODE_MODEM);
}
GFile *
-qfu_device_selection_get_single_tty (QfuDeviceSelection *self)
+qfu_device_selection_get_single_tty (QfuDeviceSelection *self,
+ QfuHelpersDeviceMode mode)
{
- return device_selection_get_single (self, QFU_HELPERS_DEVICE_TYPE_TTY);
+ return device_selection_get_single (self, QFU_HELPERS_DEVICE_TYPE_TTY, mode);
}
/******************************************************************************/
static GList *
device_selection_get_multiple (QfuDeviceSelection *self,
- QfuHelpersDeviceType device_type)
+ QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode)
{
GFile *preferred_selection = NULL;
GList *list, *l;
@@ -123,7 +126,7 @@ device_selection_get_multiple (QfuDeviceSelection *self,
qfu_helpers_device_type_to_string (device_type),
self->priv->sysfs_path);
- list = qfu_helpers_list_devices (device_type, self->priv->sysfs_path);
+ list = qfu_helpers_list_devices (device_type, device_mode, self->priv->sysfs_path);
for (l = list; l; l = g_list_next (l)) {
path = g_file_get_path (G_FILE (l->data));
g_debug ("[qfu,device-selection] device found: %s", path);
@@ -149,9 +152,10 @@ device_selection_get_multiple (QfuDeviceSelection *self,
}
GList *
-qfu_device_selection_get_multiple_ttys (QfuDeviceSelection *self)
+qfu_device_selection_get_multiple_ttys (QfuDeviceSelection *self,
+ QfuHelpersDeviceMode mode)
{
- return device_selection_get_multiple (self, QFU_HELPERS_DEVICE_TYPE_TTY);
+ return device_selection_get_multiple (self, QFU_HELPERS_DEVICE_TYPE_TTY, mode);
}
/******************************************************************************/
@@ -198,6 +202,7 @@ qfu_device_selection_wait_for_cdc_wdm (QfuDeviceSelection *self,
task = g_task_new (self, cancellable, callback, user_data);
qfu_helpers_wait_for_device (QFU_HELPERS_DEVICE_TYPE_CDC_WDM,
+ QFU_HELPERS_DEVICE_MODE_MODEM,
self->priv->sysfs_path,
self->priv->peer_port,
cancellable,
@@ -207,6 +212,7 @@ qfu_device_selection_wait_for_cdc_wdm (QfuDeviceSelection *self,
void
qfu_device_selection_wait_for_tty (QfuDeviceSelection *self,
+ QfuHelpersDeviceMode mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -215,6 +221,7 @@ qfu_device_selection_wait_for_tty (QfuDeviceSelection *self,
task = g_task_new (self, cancellable, callback, user_data);
qfu_helpers_wait_for_device (QFU_HELPERS_DEVICE_TYPE_TTY,
+ mode,
self->priv->sysfs_path,
self->priv->peer_port,
cancellable,
@@ -266,7 +273,6 @@ qfu_device_selection_new (const gchar *preferred_cdc_wdm,
self->priv->preferred_busnum = preferred_busnum;
self->priv->preferred_devnum = preferred_devnum;
-
/* Initialize sysfs path from inputs */
if (preferred_vid || preferred_devnum)
self->priv->sysfs_path = qfu_helpers_find_by_device_info (preferred_vid, preferred_pid, preferred_busnum, preferred_devnum, error);
diff --git a/src/qmi-firmware-update/qfu-device-selection.h b/src/qmi-firmware-update/qfu-device-selection.h
index 1f9991a9..e91a5729 100644
--- a/src/qmi-firmware-update/qfu-device-selection.h
+++ b/src/qmi-firmware-update/qfu-device-selection.h
@@ -25,6 +25,8 @@
#include <glib-object.h>
#include <gio/gio.h>
+#include "qfu-helpers.h"
+
G_BEGIN_DECLS
#define QFU_TYPE_DEVICE_SELECTION (qfu_device_selection_get_type ())
@@ -67,9 +69,12 @@ GFile *qfu_device_selection_wait_for_cdc_wdm_finish (QfuDeviceSelection *self,
GAsyncResult *res,
GError **error);
-GFile *qfu_device_selection_get_single_tty (QfuDeviceSelection *self);
-GList *qfu_device_selection_get_multiple_ttys (QfuDeviceSelection *self);
+GFile *qfu_device_selection_get_single_tty (QfuDeviceSelection *self,
+ QfuHelpersDeviceMode mode);
+GList *qfu_device_selection_get_multiple_ttys (QfuDeviceSelection *self,
+ QfuHelpersDeviceMode mode);
void qfu_device_selection_wait_for_tty (QfuDeviceSelection *self,
+ QfuHelpersDeviceMode mode,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/src/qmi-firmware-update/qfu-helpers-sysfs.c b/src/qmi-firmware-update/qfu-helpers-sysfs.c
index 6e8b9118..0629ec8a 100644
--- a/src/qmi-firmware-update/qfu-helpers-sysfs.c
+++ b/src/qmi-firmware-update/qfu-helpers-sysfs.c
@@ -89,13 +89,14 @@ read_sysfs_attribute_link_basename (const gchar *path,
}
static gboolean
-get_device_details (const gchar *port_sysfs_path,
- gchar **out_sysfs_path,
- guint16 *out_vid,
- guint16 *out_pid,
- guint *out_busnum,
- guint *out_devnum,
- GError **error)
+get_device_details (const gchar *port_sysfs_path,
+ gchar **out_sysfs_path,
+ QfuHelpersDeviceMode *out_device_mode,
+ guint16 *out_vid,
+ guint16 *out_pid,
+ guint *out_busnum,
+ guint *out_devnum,
+ GError **error)
{
g_autofree gchar *iter = NULL;
g_autofree gchar *physdev_sysfs_path = NULL;
@@ -111,6 +112,8 @@ get_device_details (const gchar *port_sysfs_path,
*out_devnum = 0;
if (out_sysfs_path)
*out_sysfs_path = NULL;
+ if (out_device_mode)
+ *out_device_mode = QFU_HELPERS_DEVICE_MODE_UNKNOWN;
iter = realpath (port_sysfs_path, NULL);
@@ -134,6 +137,15 @@ get_device_details (const gchar *port_sysfs_path,
return FALSE;
}
+ if (out_device_mode) {
+ aux = read_sysfs_attribute_as_num (physdev_sysfs_path, "bNumInterfaces", 10);
+ /* QDL download mode has exactly one single USB interface */
+ if (aux == 1)
+ *out_device_mode = QFU_HELPERS_DEVICE_MODE_DOWNLOAD;
+ else if (aux > 1)
+ *out_device_mode = QFU_HELPERS_DEVICE_MODE_MODEM;
+ }
+
if (out_vid) {
aux = read_sysfs_attribute_as_num (physdev_sysfs_path, "idVendor", 16);
if (aux <= G_MAXUINT16)
@@ -213,7 +225,7 @@ qfu_helpers_sysfs_find_by_file (GFile *file,
g_autofree gchar *physdev_sysfs_path = NULL;
g_autofree gchar *found_port_sysfs_path = NULL;
g_autofree gchar *basename = NULL;
- guint i;
+ guint i;
basename = g_file_get_basename (file);
if (!basename) {
@@ -247,7 +259,7 @@ qfu_helpers_sysfs_find_by_file (GFile *file,
}
if (!get_device_details (found_port_sysfs_path,
- &physdev_sysfs_path, NULL, NULL, NULL, NULL,
+ &physdev_sysfs_path, NULL, NULL, NULL, NULL, NULL,
error))
return NULL;
@@ -272,12 +284,12 @@ device_already_added (GPtrArray *ptr,
}
static GPtrArray *
-find_by_device_info_in_subsystem (GPtrArray *sysfs_paths,
- const gchar *subsystem,
- guint16 vid,
- guint16 pid,
- guint busnum,
- guint devnum)
+find_by_device_info_in_subsystem (GPtrArray *sysfs_paths,
+ const gchar *subsystem,
+ guint16 vid,
+ guint16 pid,
+ guint busnum,
+ guint devnum)
{
g_autofree gchar *subsys_sysfs_path = NULL;
g_autoptr(GFile) subsys_sysfs_file = NULL;
@@ -292,14 +304,14 @@ find_by_device_info_in_subsystem (GPtrArray *sysfs_paths,
NULL);
if (direnum) {
while (TRUE) {
- GFileInfo *info = NULL;
- g_autoptr(GFile) child = NULL;
- g_autofree gchar *child_path = NULL;
- guint16 device_vid = 0;
- guint16 device_pid = 0;
- guint device_busnum = 0;
- guint device_devnum = 0;
- g_autofree gchar *device_sysfs_path = NULL;
+ GFileInfo *info = NULL;
+ g_autoptr(GFile) child = NULL;
+ g_autofree gchar *child_path = NULL;
+ guint16 device_vid = 0;
+ guint16 device_pid = 0;
+ guint device_busnum = 0;
+ guint device_devnum = 0;
+ g_autofree gchar *device_sysfs_path = NULL;
if (!g_file_enumerator_iterate (direnum, &info, NULL, NULL, NULL) || !info)
break;
@@ -308,6 +320,7 @@ find_by_device_info_in_subsystem (GPtrArray *sysfs_paths,
child_path = g_file_get_path (child);
if (get_device_details (child_path,
&device_sysfs_path,
+ NULL,
&device_vid,
&device_pid,
&device_busnum,
@@ -383,18 +396,20 @@ qfu_helpers_sysfs_find_by_device_info (guint16 vid,
/******************************************************************************/
static GFile *
-device_matches_sysfs_and_type (GFile *file,
- const gchar *sysfs_path,
- QfuHelpersDeviceType type)
+device_matches (GFile *file,
+ QfuHelpersDeviceType type,
+ QfuHelpersDeviceMode mode,
+ const gchar *sysfs_path)
{
- g_autofree gchar *port_sysfs_path = NULL;
- g_autofree gchar *device_sysfs_path = NULL;
- g_autofree gchar *device_driver = NULL;
- g_autofree gchar *device_path = NULL;
+ g_autofree gchar *port_sysfs_path = NULL;
+ g_autofree gchar *device_sysfs_path = NULL;
+ g_autofree gchar *device_driver = NULL;
+ g_autofree gchar *device_path = NULL;
+ QfuHelpersDeviceMode device_mode = QFU_HELPERS_DEVICE_MODE_UNKNOWN;
port_sysfs_path = g_file_get_path (file);
if (!get_device_details (port_sysfs_path,
- &device_sysfs_path, NULL, NULL, NULL, NULL,
+ &device_sysfs_path, &device_mode, NULL, NULL, NULL, NULL,
NULL))
return NULL;
@@ -404,6 +419,9 @@ device_matches_sysfs_and_type (GFile *file,
if (g_strcmp0 (device_sysfs_path, sysfs_path) != 0)
return NULL;
+ if (device_mode != mode)
+ return NULL;
+
if (!get_interface_details (port_sysfs_path, &device_driver, NULL))
return NULL;
@@ -427,6 +445,7 @@ device_matches_sysfs_and_type (GFile *file,
GList *
qfu_helpers_sysfs_list_devices (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path)
{
const gchar **subsys_list = NULL;
@@ -469,7 +488,7 @@ qfu_helpers_sysfs_list_devices (QfuHelpersDeviceType device_type,
break;
child = g_file_enumerator_get_child (direnum, info);
- devfile = device_matches_sysfs_and_type (child, sysfs_path, device_type);
+ devfile = device_matches (child, device_type, device_mode, sysfs_path);
if (devfile)
files = g_list_prepend (files, g_steal_pointer (&devfile));
}
@@ -488,6 +507,7 @@ qfu_helpers_sysfs_list_devices (QfuHelpersDeviceType device_type,
typedef struct {
QfuHelpersDeviceType device_type;
+ QfuHelpersDeviceMode device_mode;
gchar *sysfs_path;
gchar *peer_port;
guint check_attempts;
@@ -515,13 +535,14 @@ qfu_helpers_sysfs_wait_for_device_finish (GAsyncResult *res,
static GFile *
wait_for_device_lookup (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path,
const gchar *peer_port)
{
GList *devices;
GFile *file;
- devices = qfu_helpers_sysfs_list_devices (device_type, sysfs_path);
+ devices = qfu_helpers_sysfs_list_devices (device_type, device_mode, sysfs_path);
if (!devices) {
g_autofree gchar *tmp = NULL;
g_autofree gchar *path = NULL;
@@ -534,7 +555,7 @@ wait_for_device_lookup (QfuHelpersDeviceType device_type,
path = realpath (tmp, NULL);
if (path) {
g_debug ("[qfu-sysfs] peer lookup: %s => %s", peer_port, path);
- devices = qfu_helpers_sysfs_list_devices (device_type, path);
+ devices = qfu_helpers_sysfs_list_devices (device_type, device_mode, path);
if (!devices)
return NULL;
}
@@ -561,7 +582,7 @@ wait_for_device_check (GTask *task)
ctx = (WaitForDeviceContext *) g_task_get_task_data (task);
/* Check devices matching */
- device = wait_for_device_lookup (ctx->device_type, ctx->sysfs_path, ctx->peer_port);
+ device = wait_for_device_lookup (ctx->device_type, ctx->device_mode, ctx->sysfs_path, ctx->peer_port);
if (!device) {
/* No devices found */
if (ctx->check_attempts == WAIT_FOR_DEVICE_CHECK_ATTEMPTS) {
@@ -625,18 +646,20 @@ wait_for_device_cancelled (GCancellable *cancellable,
}
void
-qfu_helpers_sysfs_wait_for_device (QfuHelpersDeviceType device_type,
- const gchar *sysfs_path,
- const gchar *peer_port,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+qfu_helpers_sysfs_wait_for_device (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
+ const gchar *sysfs_path,
+ const gchar *peer_port,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GTask *task;
WaitForDeviceContext *ctx;
ctx = g_slice_new0 (WaitForDeviceContext);
ctx->device_type = device_type;
+ ctx->device_mode = device_mode;
ctx->sysfs_path = g_strdup (sysfs_path);
ctx->peer_port = g_strdup (peer_port);
diff --git a/src/qmi-firmware-update/qfu-helpers-sysfs.h b/src/qmi-firmware-update/qfu-helpers-sysfs.h
index 39790e68..3f1162da 100644
--- a/src/qmi-firmware-update/qfu-helpers-sysfs.h
+++ b/src/qmi-firmware-update/qfu-helpers-sysfs.h
@@ -30,20 +30,20 @@
G_BEGIN_DECLS
-gchar *qfu_helpers_sysfs_find_by_file (GFile *file,
- GError **error);
-gchar *qfu_helpers_sysfs_find_by_file_path (const gchar *path,
- GError **error);
-gchar *qfu_helpers_sysfs_find_by_device_info (guint16 vid,
- guint16 pid,
- guint busnum,
- guint devnum,
- GError **error);
+gchar *qfu_helpers_sysfs_find_by_file (GFile *file,
+ GError **error);
+gchar *qfu_helpers_sysfs_find_by_device_info (guint16 vid,
+ guint16 pid,
+ guint busnum,
+ guint devnum,
+ GError **error);
GList *qfu_helpers_sysfs_list_devices (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path);
void qfu_helpers_sysfs_wait_for_device (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path,
const gchar *peer_port,
GCancellable *cancellable,
diff --git a/src/qmi-firmware-update/qfu-helpers-udev.c b/src/qmi-firmware-update/qfu-helpers-udev.c
index 667ce038..bda91061 100644
--- a/src/qmi-firmware-update/qfu-helpers-udev.c
+++ b/src/qmi-firmware-update/qfu-helpers-udev.c
@@ -39,13 +39,14 @@ static const gchar *tty_subsys_list[] = { "tty", NULL };
static const gchar *cdc_wdm_subsys_list[] = { "usbmisc", "usb", NULL };
static gboolean
-udev_helper_get_udev_device_details (GUdevDevice *device,
- gchar **out_sysfs_path,
- guint16 *out_vid,
- guint16 *out_pid,
- guint *out_busnum,
- guint *out_devnum,
- GError **error)
+get_device_details (GUdevDevice *device,
+ gchar **out_sysfs_path,
+ QfuHelpersDeviceMode *out_device_mode,
+ guint16 *out_vid,
+ guint16 *out_pid,
+ guint *out_busnum,
+ guint *out_devnum,
+ GError **error)
{
GUdevDevice *parent;
gulong aux;
@@ -60,6 +61,8 @@ udev_helper_get_udev_device_details (GUdevDevice *device,
*out_busnum = 0;
if (out_devnum)
*out_devnum = 0;
+ if (out_device_mode)
+ *out_device_mode = QFU_HELPERS_DEVICE_MODE_UNKNOWN;
/* We need to look for the parent GUdevDevice which has a "usb_device"
* devtype. */
@@ -85,6 +88,15 @@ udev_helper_get_udev_device_details (GUdevDevice *device,
if (out_sysfs_path)
*out_sysfs_path = g_strdup (g_udev_device_get_sysfs_path (parent));
+ if (out_device_mode) {
+ aux = strtoul (g_udev_device_get_sysfs_attr (parent, "bNumInterfaces"), NULL, 10);
+ /* QDL download mode has exactly one single USB interface */
+ if (aux == 1)
+ *out_device_mode = QFU_HELPERS_DEVICE_MODE_DOWNLOAD;
+ else if (aux > 1)
+ *out_device_mode = QFU_HELPERS_DEVICE_MODE_MODEM;
+ }
+
if (out_vid) {
aux = strtoul (g_udev_device_get_property (parent, "ID_VENDOR_ID"), NULL, 16);
if (aux <= G_MAXUINT16)
@@ -186,9 +198,9 @@ qfu_helpers_udev_find_by_file (GFile *file,
goto out;
}
- if (!udev_helper_get_udev_device_details (device,
- &sysfs_path, NULL, NULL, NULL, NULL,
- error))
+ if (!get_device_details (device,
+ &sysfs_path, NULL, NULL, NULL, NULL, NULL,
+ error))
goto out;
g_debug ("[qfu-udev] sysfs path for '%s' found: %s", basename, sysfs_path);
@@ -239,13 +251,14 @@ udev_helper_find_by_device_info_in_subsystem (GPtrArray *sysfs_paths,
device = G_UDEV_DEVICE (iter->data);
- if (udev_helper_get_udev_device_details (device,
- &device_sysfs_path,
- &device_vid,
- &device_pid,
- &device_busnum,
- &device_devnum,
- NULL)) {
+ if (get_device_details (device,
+ &device_sysfs_path,
+ NULL,
+ &device_vid,
+ &device_pid,
+ &device_busnum,
+ &device_devnum,
+ NULL)) {
if ((vid == 0 || vid == device_vid) &&
(pid == 0 || pid == device_pid) &&
(busnum == 0 || busnum == device_busnum) &&
@@ -332,18 +345,20 @@ out:
/******************************************************************************/
static GFile *
-device_matches_sysfs_and_type (GUdevDevice *device,
- const gchar *sysfs_path,
- QfuHelpersDeviceType type)
+device_matches (GUdevDevice *device,
+ QfuHelpersDeviceType type,
+ QfuHelpersDeviceMode mode,
+ const gchar *sysfs_path)
{
- GFile *file = NULL;
- gchar *device_sysfs_path = NULL;
- gchar *device_driver = NULL;
- gchar *device_path = NULL;
-
- if (!udev_helper_get_udev_device_details (device,
- &device_sysfs_path, NULL, NULL, NULL, NULL,
- NULL))
+ GFile *file = NULL;
+ gchar *device_sysfs_path = NULL;
+ gchar *device_driver = NULL;
+ gchar *device_path = NULL;
+ QfuHelpersDeviceMode device_mode = QFU_HELPERS_DEVICE_MODE_UNKNOWN;
+
+ if (!get_device_details (device,
+ &device_sysfs_path, &device_mode, NULL, NULL, NULL, NULL,
+ NULL))
goto out;
if (!device_sysfs_path)
@@ -352,6 +367,9 @@ device_matches_sysfs_and_type (GUdevDevice *device,
if (g_strcmp0 (device_sysfs_path, sysfs_path) != 0)
goto out;
+ if (device_mode != mode)
+ return NULL;
+
if (!udev_helper_get_udev_interface_details (device,
&device_driver,
NULL))
@@ -383,6 +401,7 @@ out:
GList *
qfu_helpers_udev_list_devices (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path)
{
GUdevClient *udev;
@@ -411,7 +430,7 @@ qfu_helpers_udev_list_devices (QfuHelpersDeviceType device_type,
for (iter = devices; iter; iter = g_list_next (iter)) {
GFile *file;
- file = device_matches_sysfs_and_type (G_UDEV_DEVICE (iter->data), sysfs_path, device_type);
+ file = device_matches (G_UDEV_DEVICE (iter->data), device_type, device_mode, sysfs_path);
if (file)
files = g_list_prepend (files, file);
g_object_unref (G_OBJECT (iter->data));
@@ -429,6 +448,7 @@ qfu_helpers_udev_list_devices (QfuHelpersDeviceType device_type,
typedef struct {
QfuHelpersDeviceType device_type;
+ QfuHelpersDeviceMode device_mode;
GUdevClient *udev;
gchar *sysfs_path;
gchar *peer_port;
@@ -471,7 +491,7 @@ handle_uevent (GUdevClient *client,
if (!g_str_equal (action, "add") && !g_str_equal (action, "move") && !g_str_equal (action, "change"))
return;
- file = device_matches_sysfs_and_type (device, ctx->sysfs_path, ctx->device_type);
+ file = device_matches (device, ctx->device_type, ctx->device_mode, ctx->sysfs_path);
if (!file && ctx->peer_port) {
gchar *tmp, *path;
@@ -481,7 +501,7 @@ handle_uevent (GUdevClient *client,
if (!path)
return;
- file = device_matches_sysfs_and_type (device, path, ctx->device_type);
+ file = device_matches (device, ctx->device_type, ctx->device_mode, path);
g_debug ("[qfu-udev] peer lookup for %s: %s => %s", g_udev_device_get_name (device), ctx->peer_port, path);
g_free (path);
}
@@ -555,6 +575,7 @@ wait_for_device_cancelled (GCancellable *cancellable,
void
qfu_helpers_udev_wait_for_device (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path,
const gchar *peer_port,
GCancellable *cancellable,
@@ -566,6 +587,7 @@ qfu_helpers_udev_wait_for_device (QfuHelpersDeviceType device_type,
ctx = g_slice_new0 (WaitForDeviceContext);
ctx->device_type = device_type;
+ ctx->device_mode = device_mode;
ctx->sysfs_path = g_strdup (sysfs_path);
ctx->peer_port = g_strdup (peer_port);
diff --git a/src/qmi-firmware-update/qfu-helpers-udev.h b/src/qmi-firmware-update/qfu-helpers-udev.h
index 9ee7d0ff..020e152d 100644
--- a/src/qmi-firmware-update/qfu-helpers-udev.h
+++ b/src/qmi-firmware-update/qfu-helpers-udev.h
@@ -42,9 +42,11 @@ gchar *qfu_helpers_udev_find_by_device_info (guint16 vid,
GError **error);
GList *qfu_helpers_udev_list_devices (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path);
void qfu_helpers_udev_wait_for_device (QfuHelpersDeviceType device_type,
+ QfuHelpersDeviceMode device_mode,
const gchar *sysfs_path,
const gchar *peer_port,
GCancellable *cancellable,
diff --git a/src/qmi-firmware-update/qfu-helpers.c b/src/qmi-firmware-update/qfu-helpers.c
index 2ed15dca..2af69b02 100644
--- a/src/qmi-firmware-update/qfu-helpers.c
+++ b/src/qmi-firmware-update/qfu-helpers.c
@@ -40,6 +40,22 @@ qfu_helpers_device_type_to_string (QfuHelpersDeviceType type)
/******************************************************************************/
+static const gchar *device_mode_str[] = {
+ [QFU_HELPERS_DEVICE_MODE_UNKNOWN] = "unknown",
+ [QFU_HELPERS_DEVICE_MODE_MODEM] = "modem",
+ [QFU_HELPERS_DEVICE_MODE_DOWNLOAD] = "download",
+};
+
+G_STATIC_ASSERT (G_N_ELEMENTS (device_mode_str) == QFU_HELPERS_DEVICE_MODE_LAST);
+
+const gchar *
+qfu_helpers_device_mode_to_string (QfuHelpersDeviceMode mode)
+{
+ return device_mode_str[mode];
+}
+
+/******************************************************************************/
+
gchar *
qfu_helpers_find_by_file_path (const gchar *path,
GError **error)
diff --git a/src/qmi-firmware-update/qfu-helpers.h b/src/qmi-firmware-update/qfu-helpers.h
index 5a25a37c..4df73f29 100644
--- a/src/qmi-firmware-update/qfu-helpers.h
+++ b/src/qmi-firmware-update/qfu-helpers.h
@@ -28,6 +28,8 @@
G_BEGIN_DECLS
+/******************************************************************************/
+
typedef enum {
QFU_HELPERS_DEVICE_TYPE_TTY,
QFU_HELPERS_DEVICE_TYPE_CDC_WDM,
@@ -38,6 +40,17 @@ const gchar *qfu_helpers_device_type_to_string (QfuHelpersDeviceType type);
/******************************************************************************/
+typedef enum {
+ QFU_HELPERS_DEVICE_MODE_UNKNOWN,
+ QFU_HELPERS_DEVICE_MODE_MODEM,
+ QFU_HELPERS_DEVICE_MODE_DOWNLOAD,
+ QFU_HELPERS_DEVICE_MODE_LAST
+} QfuHelpersDeviceMode;
+
+const gchar *qfu_helpers_device_mode_to_string (QfuHelpersDeviceMode mode);
+
+/******************************************************************************/
+
gchar *qfu_helpers_find_by_file_path (const gchar *path,
GError **error);
gchar *qfu_helpers_find_peer_port (const gchar *sysfs_path,
diff --git a/src/qmi-firmware-update/qfu-reseter.c b/src/qmi-firmware-update/qfu-reseter.c
index 979294a3..3bd5dcc5 100644
--- a/src/qmi-firmware-update/qfu-reseter.c
+++ b/src/qmi-firmware-update/qfu-reseter.c
@@ -360,7 +360,7 @@ qfu_reseter_run (QfuReseter *self,
/* List devices to use */
if (!self->priv->qmi_client)
ctx->cdc_wdm = qfu_device_selection_get_single_cdc_wdm (self->priv->device_selection);
- ctx->ttys = qfu_device_selection_get_multiple_ttys (self->priv->device_selection);
+ ctx->ttys = qfu_device_selection_get_multiple_ttys (self->priv->device_selection, QFU_HELPERS_DEVICE_MODE_MODEM);
if (!ctx->ttys && !ctx->cdc_wdm && !self->priv->qmi_client) {
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
diff --git a/src/qmi-firmware-update/qfu-updater.c b/src/qmi-firmware-update/qfu-updater.c
index 15d85ad3..f860c1b0 100644
--- a/src/qmi-firmware-update/qfu-updater.c
+++ b/src/qmi-firmware-update/qfu-updater.c
@@ -876,14 +876,14 @@ wait_for_tty_ready (QfuDeviceSelection *device_selection,
g_assert (!ctx->serial_file);
ctx->serial_file = qfu_device_selection_wait_for_tty_finish (device_selection, res, &error);
if (!ctx->serial_file) {
- g_prefix_error (&error, "error waiting for TTY: ");
+ g_prefix_error (&error, "error waiting for serial device in download mode: ");
g_task_return_error (task, error);
g_object_unref (task);
return;
}
path = g_file_get_path (ctx->serial_file);
- g_debug ("[qfu-updater] TTY device found: %s", path);
+ g_debug ("[qfu-updater] serial device in download mode found: %s", path);
g_free (path);
g_print ("download mode detected\n");
@@ -901,8 +901,9 @@ run_context_step_wait_for_tty (GTask *task)
g_print ("rebooting in download mode...\n");
- g_debug ("[qfu-updater] reset requested, now waiting for TTY device...");
+ g_debug ("[qfu-updater] reset requested, now waiting for serial device...");
qfu_device_selection_wait_for_tty (self->priv->device_selection,
+ QFU_HELPERS_DEVICE_MODE_DOWNLOAD,
g_task_get_cancellable (task),
(GAsyncReadyCallback) wait_for_tty_ready,
task);
@@ -1530,10 +1531,10 @@ qfu_updater_run (QfuUpdater *self,
break;
case UPDATER_TYPE_DOWNLOAD:
ctx->step = RUN_CONTEXT_STEP_SELECT_DEVICE;
- ctx->serial_file = qfu_device_selection_get_single_tty (self->priv->device_selection);
+ ctx->serial_file = qfu_device_selection_get_single_tty (self->priv->device_selection, QFU_HELPERS_DEVICE_MODE_DOWNLOAD);
if (!ctx->serial_file) {
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- "No serial device found to run QDL update operation");
+ "No serial device in download mode found to run QDL update operation");
g_object_unref (task);
return;
}