From 185856133af4d723b719a4ad5395e32153deb98b Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Fri, 18 Oct 2019 11:37:17 +0200 Subject: [PATCH 1/3] qmi-device: support and detect smdpkt managed QMI control ports https://gitlab.freedesktop.org/mobile-broadband/libqmi/issues/20 https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge_requests/72 https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge_requests/101 (cherry picked from commit e3851c8d456f32553324beaab1b7c48bbffa2892) (cherry picked from commit 6fc07ae25a7c3e2375f02f7ab65c92073303e8d0) --- .../libqmi-glib/libqmi-glib-common.sections | 2 + src/libqmi-glib/qmi-device.c | 68 ++++++++--------- src/libqmi-glib/qmi-utils.c | 73 ++++++++++++++++--- src/libqmi-glib/qmi-utils.h | 11 ++- 4 files changed, 107 insertions(+), 47 deletions(-) diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections index eb6cbeded2ba..75a13653416a 100644 --- a/docs/reference/libqmi-glib/libqmi-glib-common.sections +++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections @@ -1403,6 +1403,8 @@ QmiEndian qmi_utils_get_traces_enabled qmi_utils_set_traces_enabled + +__QmiTransportType
diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 1e7d8cd1a9d2..7af4f4cd43b6 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -1942,68 +1942,68 @@ device_create_endpoint (QmiDevice *self, } static gboolean -device_setup_open_flags_by_driver (QmiDevice *self, - DeviceOpenContext *ctx, - GError **error) -{ - gchar *driver; - GError *inner_error = NULL; - - driver = __qmi_utils_get_driver (qmi_file_get_path (self->priv->file), &inner_error); - if (driver) - g_debug ("[%s] loaded driver of cdc-wdm port: %s", qmi_file_get_path_display (self->priv->file), driver); - else if (!self->priv->no_file_check) - g_warning ("[%s] couldn't load driver of cdc-wdm port: %s", qmi_file_get_path_display (self->priv->file), inner_error->message); +device_setup_open_flags_by_transport (QmiDevice *self, + DeviceOpenContext *ctx, + GError **error) +{ + __QmiTransportType transport; + GError *inner_error = NULL; + + transport = __qmi_utils_get_transport_type (qmi_file_get_path (self->priv->file), &inner_error); + if ((transport == __QMI_TRANSPORT_TYPE_UNKNOWN) && !self->priv->no_file_check) + g_warning ("[%s] couldn't detect transport type of port: %s", qmi_file_get_path_display (self->priv->file), inner_error->message); g_clear_error (&inner_error); #if defined MBIM_QMUX_ENABLED /* Auto mode requested? */ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_AUTO) { - if (!g_strcmp0 (driver, "cdc_mbim")) { + switch (transport) { + case __QMI_TRANSPORT_TYPE_MBIM: g_debug ("[%s] automatically selecting MBIM mode", qmi_file_get_path_display (self->priv->file)); ctx->flags |= QMI_DEVICE_OPEN_FLAGS_MBIM; - goto out; - } - if (!g_strcmp0 (driver, "qmi_wwan")) { + break; + case __QMI_TRANSPORT_TYPE_QMUX: g_debug ("[%s] automatically selecting QMI mode", qmi_file_get_path_display (self->priv->file)); ctx->flags &= ~QMI_DEVICE_OPEN_FLAGS_MBIM; - goto out; + break; + case __QMI_TRANSPORT_TYPE_UNKNOWN: + g_set_error (&inner_error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED, + "Cannot automatically select QMI/MBIM mode"); + break; } - g_set_error (&inner_error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "Cannot automatically select QMI/MBIM mode: driver %s", - driver ? driver : "unknown"); goto out; } /* MBIM mode requested? */ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { - if (g_strcmp0 (driver, "cdc_mbim") && !self->priv->no_file_check) - g_warning ("[%s] requested MBIM mode but unexpected driver found: %s", qmi_file_get_path_display (self->priv->file), driver); + if ((transport != __QMI_TRANSPORT_TYPE_MBIM) && !self->priv->no_file_check) + g_warning ("[%s] requested MBIM mode but unexpected transport type found", qmi_file_get_path_display (self->priv->file)); goto out; } #else - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_AUTO) + /* Auto mode requested? */ + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_AUTO) { g_warning ("[%s] requested auto mode but no MBIM QMUX support available", qmi_file_get_path_display (self->priv->file)); - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) + goto out; + } + + /* MBIM mode requested? */ + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { g_warning ("[%s] requested MBIM mode but no MBIM QMUX support available", qmi_file_get_path_display (self->priv->file)); + goto out; + } #endif /* MBIM_QMUX_ENABLED */ /* QMI mode requested? */ - if (g_strcmp0 (driver, "qmi_wwan") && !self->priv->no_file_check) - g_warning ("[%s] requested QMI mode but unexpected driver found: %s", - qmi_file_get_path_display (self->priv->file), driver ? driver : "unknown"); + if ((transport != __QMI_TRANSPORT_TYPE_QMUX) && !self->priv->no_file_check) + g_warning ("[%s] requested QMI mode but unexpected transport type found", + qmi_file_get_path_display (self->priv->file)); -#if defined MBIM_QMUX_ENABLED out: -#endif - - g_free (driver); if (inner_error) { g_propagate_error (error, inner_error); @@ -2029,7 +2029,7 @@ device_open_step (GTask *task) /* Fall through */ case DEVICE_OPEN_CONTEXT_STEP_DRIVER: - if (!device_setup_open_flags_by_driver (self, ctx, &error)) { + if (!device_setup_open_flags_by_transport (self, ctx, &error)) { g_task_return_error (task, error); g_object_unref (task); return; diff --git a/src/libqmi-glib/qmi-utils.c b/src/libqmi-glib/qmi-utils.c index df2420cf5c1f..084dba51d011 100644 --- a/src/libqmi-glib/qmi-utils.c +++ b/src/libqmi-glib/qmi-utils.c @@ -120,18 +120,13 @@ __qmi_user_allowed (uid_t uid, /*****************************************************************************/ -gchar * -__qmi_utils_get_driver (const gchar *cdc_wdm_path, - GError **error) +static gchar * +utils_get_driver (const gchar *device_basename, + GError **error) { static const gchar *subsystems[] = { "usbmisc", "usb" }; - guint i; - gchar *device_basename; - gchar *driver = NULL; - - device_basename = __qmi_utils_get_devname (cdc_wdm_path, error); - if (!device_basename) - return NULL; + guint i; + gchar *driver = NULL; for (i = 0; !driver && i < G_N_ELEMENTS (subsystems); i++) { gchar *tmp; @@ -153,9 +148,65 @@ __qmi_utils_get_driver (const gchar *cdc_wdm_path, g_free (path); } + if (!driver) + g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED, + "couldn't detect device driver"); + return driver; +} + +__QmiTransportType +__qmi_utils_get_transport_type (const gchar *path, + GError **error) +{ + __QmiTransportType transport = __QMI_TRANSPORT_TYPE_UNKNOWN; + gchar *device_basename = NULL; + gchar *driver = NULL; + gchar *sysfs_path = NULL; + GError *inner_error = NULL; + + device_basename = __qmi_utils_get_devname (path, &inner_error); + if (!device_basename) + goto out; + + driver = utils_get_driver (device_basename, &inner_error); + + /* On Android systems we get access to the QMI control port through + * virtual smdcntl devices in the smdpkt subsystem. */ + if (!driver) { + path = g_strdup_printf ("/sys/devices/virtual/smdpkt/%s", device_basename); + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + g_clear_error (&inner_error); + transport = __QMI_TRANSPORT_TYPE_QMUX; + } + goto out; + } + + if (!g_strcmp0 (driver, "cdc_mbim")) { + transport = __QMI_TRANSPORT_TYPE_MBIM; + goto out; + } + + if (!g_strcmp0 (driver, "qmi_wwan")) { + transport = __QMI_TRANSPORT_TYPE_QMUX; + goto out; + } + + g_set_error (&inner_error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED, + "unexpected driver detected: %s", driver); + + out: + g_free (device_basename); + g_free (driver); + g_free (sysfs_path); - return driver; + if (inner_error) { + g_assert (transport == __QMI_TRANSPORT_TYPE_UNKNOWN); + g_propagate_error (error, inner_error); + } else + g_assert (transport != __QMI_TRANSPORT_TYPE_UNKNOWN); + + return transport; } gchar * diff --git a/src/libqmi-glib/qmi-utils.h b/src/libqmi-glib/qmi-utils.h index b83bf23c184d..8a1c712dfad0 100644 --- a/src/libqmi-glib/qmi-utils.h +++ b/src/libqmi-glib/qmi-utils.h @@ -84,9 +84,16 @@ gchar *__qmi_utils_str_hex (gconstpointer mem, G_GNUC_INTERNAL gboolean __qmi_user_allowed (uid_t uid, GError **error); + +typedef enum { + __QMI_TRANSPORT_TYPE_UNKNOWN, + __QMI_TRANSPORT_TYPE_QMUX, + __QMI_TRANSPORT_TYPE_MBIM, +} __QmiTransportType; + G_GNUC_INTERNAL -gchar *__qmi_utils_get_driver (const gchar *cdc_wdm_path, - GError **error); +__QmiTransportType __qmi_utils_get_transport_type (const gchar *path, + GError **error); G_GNUC_INTERNAL gchar *__qmi_utils_get_devname (const gchar *cdc_wdm_path, -- 2.31.1 From 00502d0353d7e056b3348514033001e0a71bbd83 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Fri, 18 Oct 2019 11:41:49 +0200 Subject: [PATCH 2/3] qmi-device: when MBIM/QMUX support not enabled ignore AUTO warnings https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/issues/20 https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge_requests/72 (cherry picked from commit 99e320c76dc41bc4b4cb0a5b55c06a825cd9224c) --- src/libqmi-glib/qmi-device.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 7af4f4cd43b6..7e93fad079a4 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -1984,18 +1984,14 @@ device_setup_open_flags_by_transport (QmiDevice *self, #else - /* Auto mode requested? */ - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_AUTO) { - g_warning ("[%s] requested auto mode but no MBIM QMUX support available", qmi_file_get_path_display (self->priv->file)); - goto out; - } - /* MBIM mode requested? */ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { g_warning ("[%s] requested MBIM mode but no MBIM QMUX support available", qmi_file_get_path_display (self->priv->file)); goto out; } + /* Treat AUTO as QMI mode, without warnings */ + #endif /* MBIM_QMUX_ENABLED */ /* QMI mode requested? */ -- 2.31.1 From dc013e2e3fee3583f93961900b45d6b2fc59871c Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 21 Oct 2019 21:05:28 +0200 Subject: [PATCH 3/3] qmi-device: detect rpmsg control ports and adjust the path to check for smdpkt nodes https://gitlab.freedesktop.org/mobile-broadband/libqmi/issues/20 https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge_requests/73 https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/merge_requests/101 (cherry picked from commit c2ceb25d6e95e37e9f3394937fd9b9b524207224) (cherry picked from commit 816c36f9a1d24ac1b2a4c46d04cb2ca47d9c0a4e) --- src/libqmi-glib/qmi-utils.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libqmi-glib/qmi-utils.c b/src/libqmi-glib/qmi-utils.c index 084dba51d011..cb29c91c64b4 100644 --- a/src/libqmi-glib/qmi-utils.c +++ b/src/libqmi-glib/qmi-utils.c @@ -170,11 +170,19 @@ __qmi_utils_get_transport_type (const gchar *path, driver = utils_get_driver (device_basename, &inner_error); - /* On Android systems we get access to the QMI control port through - * virtual smdcntl devices in the smdpkt subsystem. */ if (!driver) { - path = g_strdup_printf ("/sys/devices/virtual/smdpkt/%s", device_basename); - if (g_file_test (path, G_FILE_TEST_EXISTS)) { + /* On Android systems we get access to the QMI control port through + * virtual smdcntl devices in the smdpkt subsystem. */ + sysfs_path = g_strdup_printf ("/sys/class/smdpkt/%s", device_basename); + if (g_file_test (sysfs_path, G_FILE_TEST_EXISTS)) { + g_clear_error (&inner_error); + transport = __QMI_TRANSPORT_TYPE_QMUX; + goto out; + } + g_free (sysfs_path); + /* On mainline kernels this control port is provided by rpmsg */ + sysfs_path = g_strdup_printf ("/sys/class/rpmsg/%s", device_basename); + if (g_file_test (sysfs_path, G_FILE_TEST_EXISTS)) { g_clear_error (&inner_error); transport = __QMI_TRANSPORT_TYPE_QMUX; } -- 2.31.1