core: allow grabbing QMI ports
This commit is contained in:
@@ -11,6 +11,6 @@ ACTION!="add|change|move", GOTO="mm_candidate_end"
|
|||||||
|
|
||||||
SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1"
|
SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1"
|
||||||
SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1"
|
SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1"
|
||||||
|
KERNEL=="cdc-wdm*", SUBSYSTEM=="usb", DRIVERS=="qmi_wwan", ENV{ID_MM_CANDIDATE}="1"
|
||||||
|
|
||||||
LABEL="mm_candidate_end"
|
LABEL="mm_candidate_end"
|
||||||
|
|
||||||
|
@@ -161,7 +161,8 @@ mm_base_modem_grab_port (MMBaseModem *self,
|
|||||||
|
|
||||||
/* Only allow 'tty' and 'net' ports */
|
/* Only allow 'tty' and 'net' ports */
|
||||||
if (!g_str_equal (subsys, "net") &&
|
if (!g_str_equal (subsys, "net") &&
|
||||||
!g_str_equal (subsys, "tty")) {
|
!g_str_equal (subsys, "tty") &&
|
||||||
|
!(g_str_equal (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm"))) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
MM_CORE_ERROR,
|
MM_CORE_ERROR,
|
||||||
MM_CORE_ERROR_UNSUPPORTED,
|
MM_CORE_ERROR_UNSUPPORTED,
|
||||||
@@ -228,8 +229,17 @@ mm_base_modem_grab_port (MMBaseModem *self,
|
|||||||
MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET,
|
MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET,
|
||||||
MM_PORT_TYPE, MM_PORT_TYPE_NET,
|
MM_PORT_TYPE, MM_PORT_TYPE_NET,
|
||||||
NULL));
|
NULL));
|
||||||
|
}
|
||||||
|
/* QMI ports... */
|
||||||
|
else if (g_str_equal (subsys, "usb") &&
|
||||||
|
g_str_has_prefix (name, "cdc-wdm")) {
|
||||||
|
port = MM_PORT (g_object_new (MM_TYPE_PORT,
|
||||||
|
MM_PORT_DEVICE, name,
|
||||||
|
MM_PORT_SUBSYS, MM_PORT_SUBSYS_USB,
|
||||||
|
MM_PORT_TYPE, MM_PORT_TYPE_QMI,
|
||||||
|
NULL));
|
||||||
} else
|
} else
|
||||||
/* We already filter out before all non-tty, non-net ports */
|
/* We already filter out before all non-tty, non-net, non-wdm ports */
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
mm_dbg ("(%s) type '%s' claimed by %s",
|
mm_dbg ("(%s) type '%s' claimed by %s",
|
||||||
|
@@ -140,6 +140,17 @@ get_device_ids (GUdevDevice *device,
|
|||||||
/* Platform devices don't usually have a VID/PID */
|
/* Platform devices don't usually have a VID/PID */
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
goto out;
|
goto out;
|
||||||
|
} else if (!strcmp (parent_subsys, "usb") &&
|
||||||
|
!strcmp (g_udev_device_get_driver (parent), "qmi_wwan")) {
|
||||||
|
/* Need to look for vendor/product in the parent of the QMI device */
|
||||||
|
GUdevDevice *qmi_parent;
|
||||||
|
|
||||||
|
qmi_parent = g_udev_device_get_parent (parent);
|
||||||
|
if (qmi_parent) {
|
||||||
|
vid = g_udev_device_get_property (qmi_parent, "ID_VENDOR_ID");
|
||||||
|
pid = g_udev_device_get_property (qmi_parent, "ID_MODEL_ID");
|
||||||
|
g_object_unref (qmi_parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -321,16 +321,22 @@ device_removed (MMManager *self,
|
|||||||
GUdevDevice *udev_device)
|
GUdevDevice *udev_device)
|
||||||
{
|
{
|
||||||
MMDevice *device;
|
MMDevice *device;
|
||||||
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
g_return_if_fail (udev_device != NULL);
|
g_return_if_fail (udev_device != NULL);
|
||||||
|
|
||||||
if (!g_str_equal (g_udev_device_get_subsystem (udev_device), "usb")) {
|
subsys = g_udev_device_get_subsystem (udev_device);
|
||||||
/* Handle tty/net port removal */
|
name = g_udev_device_get_name (udev_device);
|
||||||
|
|
||||||
|
if (!g_str_equal (subsys, "usb") ||
|
||||||
|
(name && g_str_has_prefix (name, "cdc-wdm"))) {
|
||||||
|
/* Handle tty/net/wdm port removal */
|
||||||
device = find_device_by_port (self, udev_device);
|
device = find_device_by_port (self, udev_device);
|
||||||
if (device) {
|
if (device) {
|
||||||
mm_info ("(%s/%s): released by modem %s",
|
mm_info ("(%s/%s): released by modem %s",
|
||||||
g_udev_device_get_subsystem (udev_device),
|
subsys,
|
||||||
g_udev_device_get_name (udev_device),
|
name,
|
||||||
g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
|
g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
|
||||||
mm_device_release_port (device, udev_device);
|
mm_device_release_port (device, udev_device);
|
||||||
|
|
||||||
@@ -372,22 +378,24 @@ handle_uevent (GUdevClient *client,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MMManager *self = MM_MANAGER (user_data);
|
MMManager *self = MM_MANAGER (user_data);
|
||||||
const char *subsys;
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
g_return_if_fail (action != NULL);
|
g_return_if_fail (action != NULL);
|
||||||
|
|
||||||
/* A bit paranoid */
|
/* A bit paranoid */
|
||||||
subsys = g_udev_device_get_subsystem (device);
|
subsys = g_udev_device_get_subsystem (device);
|
||||||
g_return_if_fail (subsys != NULL);
|
g_return_if_fail (subsys != NULL);
|
||||||
g_return_if_fail (!strcmp (subsys, "tty") || !strcmp (subsys, "net") || !strcmp (subsys, "usb"));
|
g_return_if_fail (g_str_equal (subsys, "tty") || g_str_equal (subsys, "net") || g_str_equal (subsys, "usb"));
|
||||||
|
|
||||||
/* We only care about tty/net devices when adding modem ports,
|
/* We only care about tty/net and usb/cdc-wdm devices when adding modem ports,
|
||||||
* but for remove, also handle usb parent device remove events
|
* but for remove, also handle usb parent device remove events
|
||||||
*/
|
*/
|
||||||
if ( (!strcmp (action, "add") || !strcmp (action, "move") || !strcmp (action, "change"))
|
name = g_udev_device_get_name (device);
|
||||||
&& (strcmp (subsys, "usb") != 0))
|
if ( (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change"))
|
||||||
|
&& (!g_str_equal (subsys, "usb") || (name && g_str_has_prefix (name, "cdc-wdm"))))
|
||||||
device_added (self, device);
|
device_added (self, device);
|
||||||
else if (!strcmp (action, "remove"))
|
else if (g_str_equal (action, "remove"))
|
||||||
device_removed (self, device);
|
device_removed (self, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,6 +423,17 @@ mm_manager_start (MMManager *manager)
|
|||||||
}
|
}
|
||||||
g_list_free (devices);
|
g_list_free (devices);
|
||||||
|
|
||||||
|
devices = g_udev_client_query_by_subsystem (manager->priv->udev, "usb");
|
||||||
|
for (iter = devices; iter; iter = g_list_next (iter)) {
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
|
name = g_udev_device_get_name (G_UDEV_DEVICE (iter->data));
|
||||||
|
if (name && g_str_has_prefix (name, "cdc-wdm"))
|
||||||
|
device_added (manager, G_UDEV_DEVICE (iter->data));
|
||||||
|
g_object_unref (G_OBJECT (iter->data));
|
||||||
|
}
|
||||||
|
g_list_free (devices);
|
||||||
|
|
||||||
mm_dbg ("Finished device scan...");
|
mm_dbg ("Finished device scan...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -589,9 +589,10 @@ mm_plugin_supports_port (MMPlugin *self,
|
|||||||
g_udev_device_get_subsystem (port),
|
g_udev_device_get_subsystem (port),
|
||||||
g_udev_device_get_name (port));
|
g_udev_device_get_name (port));
|
||||||
|
|
||||||
/* Before launching any probing, check if the port is a net device (which
|
/* Before launching any probing, check if the port is a net OR a wdm device
|
||||||
* cannot be probed). */
|
* (which cannot be probed). */
|
||||||
if (g_str_equal (g_udev_device_get_subsystem (port), "net")) {
|
if (g_str_equal (g_udev_device_get_subsystem (port), "net") ||
|
||||||
|
g_str_equal (g_udev_device_get_subsystem (port), "cdc-wdm")) {
|
||||||
g_simple_async_result_set_op_res_gpointer (
|
g_simple_async_result_set_op_res_gpointer (
|
||||||
async_result,
|
async_result,
|
||||||
GUINT_TO_POINTER (MM_PLUGIN_SUPPORTS_PORT_DEFER_UNTIL_SUGGESTED),
|
GUINT_TO_POINTER (MM_PLUGIN_SUPPORTS_PORT_DEFER_UNTIL_SUGGESTED),
|
||||||
|
@@ -1006,9 +1006,16 @@ mm_port_probe_run (MMPortProbe *self,
|
|||||||
gboolean
|
gboolean
|
||||||
mm_port_probe_is_at (MMPortProbe *self)
|
mm_port_probe_is_at (MMPortProbe *self)
|
||||||
{
|
{
|
||||||
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
||||||
|
|
||||||
if (g_str_equal (g_udev_device_get_subsystem (self->priv->port), "net"))
|
subsys = g_udev_device_get_subsystem (self->priv->port);
|
||||||
|
name = g_udev_device_get_name (self->priv->port);
|
||||||
|
if (g_str_equal (subsys, "net") ||
|
||||||
|
(g_str_equal (subsys, "usb") &&
|
||||||
|
g_str_has_prefix (name, "cdc-wdm")))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return (self->priv->flags & MM_PORT_PROBE_AT ?
|
return (self->priv->flags & MM_PORT_PROBE_AT ?
|
||||||
@@ -1034,9 +1041,16 @@ mm_port_probe_list_has_at_port (GList *list)
|
|||||||
gboolean
|
gboolean
|
||||||
mm_port_probe_is_qcdm (MMPortProbe *self)
|
mm_port_probe_is_qcdm (MMPortProbe *self)
|
||||||
{
|
{
|
||||||
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
||||||
|
|
||||||
if (g_str_equal (g_udev_device_get_subsystem (self->priv->port), "net"))
|
subsys = g_udev_device_get_subsystem (self->priv->port);
|
||||||
|
name = g_udev_device_get_name (self->priv->port);
|
||||||
|
if (g_str_equal (subsys, "net") ||
|
||||||
|
(g_str_equal (subsys, "usb") &&
|
||||||
|
g_str_has_prefix (name, "cdc-wdm")))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return (self->priv->flags & MM_PORT_PROBE_QCDM ?
|
return (self->priv->flags & MM_PORT_PROBE_QCDM ?
|
||||||
@@ -1047,11 +1061,21 @@ mm_port_probe_is_qcdm (MMPortProbe *self)
|
|||||||
MMPortType
|
MMPortType
|
||||||
mm_port_probe_get_port_type (MMPortProbe *self)
|
mm_port_probe_get_port_type (MMPortProbe *self)
|
||||||
{
|
{
|
||||||
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
||||||
|
|
||||||
if (g_str_equal (g_udev_device_get_subsystem (self->priv->port), "net"))
|
subsys = g_udev_device_get_subsystem (self->priv->port);
|
||||||
|
name = g_udev_device_get_name (self->priv->port);
|
||||||
|
|
||||||
|
if (g_str_equal (subsys, "net"))
|
||||||
return MM_PORT_TYPE_NET;
|
return MM_PORT_TYPE_NET;
|
||||||
|
|
||||||
|
if (g_str_equal (subsys, "usb") &&
|
||||||
|
g_str_has_prefix (name, "cdc-wdm"))
|
||||||
|
return MM_PORT_TYPE_QMI;
|
||||||
|
|
||||||
if (self->priv->flags & MM_PORT_PROBE_QCDM &&
|
if (self->priv->flags & MM_PORT_PROBE_QCDM &&
|
||||||
self->priv->is_qcdm)
|
self->priv->is_qcdm)
|
||||||
return MM_PORT_TYPE_QCDM;
|
return MM_PORT_TYPE_QCDM;
|
||||||
@@ -1098,9 +1122,16 @@ mm_port_probe_get_port (MMPortProbe *self)
|
|||||||
const gchar *
|
const gchar *
|
||||||
mm_port_probe_get_vendor (MMPortProbe *self)
|
mm_port_probe_get_vendor (MMPortProbe *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (MM_IS_PORT_PROBE (self), NULL);
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
if (g_str_equal (g_udev_device_get_subsystem (self->priv->port), "net"))
|
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
||||||
|
|
||||||
|
subsys = g_udev_device_get_subsystem (self->priv->port);
|
||||||
|
name = g_udev_device_get_name (self->priv->port);
|
||||||
|
if (g_str_equal (subsys, "net") ||
|
||||||
|
(g_str_equal (subsys, "usb") &&
|
||||||
|
g_str_has_prefix (name, "cdc-wdm")))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (self->priv->flags & MM_PORT_PROBE_AT_VENDOR ?
|
return (self->priv->flags & MM_PORT_PROBE_AT_VENDOR ?
|
||||||
@@ -1111,9 +1142,16 @@ mm_port_probe_get_vendor (MMPortProbe *self)
|
|||||||
const gchar *
|
const gchar *
|
||||||
mm_port_probe_get_product (MMPortProbe *self)
|
mm_port_probe_get_product (MMPortProbe *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (MM_IS_PORT_PROBE (self), NULL);
|
const gchar *subsys;
|
||||||
|
const gchar *name;
|
||||||
|
|
||||||
if (g_str_equal (g_udev_device_get_subsystem (self->priv->port), "net"))
|
g_return_val_if_fail (MM_IS_PORT_PROBE (self), FALSE);
|
||||||
|
|
||||||
|
subsys = g_udev_device_get_subsystem (self->priv->port);
|
||||||
|
name = g_udev_device_get_name (self->priv->port);
|
||||||
|
if (g_str_equal (subsys, "net") ||
|
||||||
|
(g_str_equal (subsys, "usb") &&
|
||||||
|
g_str_has_prefix (name, "cdc-wdm")))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (self->priv->flags & MM_PORT_PROBE_AT_PRODUCT ?
|
return (self->priv->flags & MM_PORT_PROBE_AT_PRODUCT ?
|
||||||
|
@@ -23,8 +23,9 @@ typedef enum { /*< underscore_name=mm_port_subsys >*/
|
|||||||
MM_PORT_SUBSYS_UNKNOWN = 0x0,
|
MM_PORT_SUBSYS_UNKNOWN = 0x0,
|
||||||
MM_PORT_SUBSYS_TTY,
|
MM_PORT_SUBSYS_TTY,
|
||||||
MM_PORT_SUBSYS_NET,
|
MM_PORT_SUBSYS_NET,
|
||||||
|
MM_PORT_SUBSYS_USB,
|
||||||
|
|
||||||
MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_NET /*< skip >*/
|
MM_PORT_SUBSYS_LAST = MM_PORT_SUBSYS_USB /*< skip >*/
|
||||||
} MMPortSubsys;
|
} MMPortSubsys;
|
||||||
|
|
||||||
typedef enum { /*< underscore_name=mm_port_type >*/
|
typedef enum { /*< underscore_name=mm_port_type >*/
|
||||||
@@ -34,8 +35,9 @@ typedef enum { /*< underscore_name=mm_port_type >*/
|
|||||||
MM_PORT_TYPE_AT,
|
MM_PORT_TYPE_AT,
|
||||||
MM_PORT_TYPE_QCDM,
|
MM_PORT_TYPE_QCDM,
|
||||||
MM_PORT_TYPE_GPS,
|
MM_PORT_TYPE_GPS,
|
||||||
|
MM_PORT_TYPE_QMI,
|
||||||
|
|
||||||
MM_PORT_TYPE_LAST = MM_PORT_TYPE_GPS /*< skip >*/
|
MM_PORT_TYPE_LAST = MM_PORT_TYPE_QMI /*< skip >*/
|
||||||
} MMPortType;
|
} MMPortType;
|
||||||
|
|
||||||
#define MM_TYPE_PORT (mm_port_get_type ())
|
#define MM_TYPE_PORT (mm_port_get_type ())
|
||||||
|
Reference in New Issue
Block a user