aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-08-21 11:32:24 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-29 17:26:46 +0200
commit494a70a8ffff4a50d0a00e99e964165054ff36aa (patch)
tree1e4c4ff6bc9f484b0e4fac4ab06743d8dd108de9
parent8cb021293ce0aa316028339c8f213c0bf72c9158 (diff)
core: handle the 'usb'->'usbmisc' subsystem rename in the kernel
We'll try to cope with getting devices being reported in either 'usb' or 'usbmisc', trying to avoid the need of checking kernel version during runtime.
-rw-r--r--src/80-mm-candidate.rules1
-rw-r--r--src/mm-base-modem.c4
-rw-r--r--src/mm-device.c4
-rw-r--r--src/mm-manager.c22
-rw-r--r--src/mm-plugin.c4
-rw-r--r--src/mm-port-probe.c12
6 files changed, 32 insertions, 15 deletions
diff --git a/src/80-mm-candidate.rules b/src/80-mm-candidate.rules
index 01ba9123..2e938d7a 100644
--- a/src/80-mm-candidate.rules
+++ b/src/80-mm-candidate.rules
@@ -12,5 +12,6 @@ ACTION!="add|change|move", GOTO="mm_candidate_end"
SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1"
SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1"
KERNEL=="cdc-wdm*", SUBSYSTEM=="usb", ENV{ID_MM_CANDIDATE}="1"
+KERNEL=="cdc-wdm*", SUBSYSTEM=="usbmisc", ENV{ID_MM_CANDIDATE}="1"
LABEL="mm_candidate_end"
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 642201aa..7bb24257 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -165,7 +165,7 @@ mm_base_modem_grab_port (MMBaseModem *self,
/* Only allow 'tty', 'net' and 'cdc-wdm' ports */
if (!g_str_equal (subsys, "net") &&
!g_str_equal (subsys, "tty") &&
- !(g_str_equal (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm"))) {
+ !(g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm"))) {
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_UNSUPPORTED,
@@ -234,7 +234,7 @@ mm_base_modem_grab_port (MMBaseModem *self,
NULL));
}
/* QMI ports... */
- else if (g_str_equal (subsys, "usb") &&
+ else if (g_str_has_prefix (subsys, "usb") &&
g_str_has_prefix (name, "cdc-wdm")) {
port = MM_PORT (mm_qmi_port_new (name));
} else
diff --git a/src/mm-device.c b/src/mm-device.c
index faf7c942..06755722 100644
--- a/src/mm-device.c
+++ b/src/mm-device.c
@@ -140,8 +140,8 @@ get_device_ids (GUdevDevice *device,
/* Platform devices don't usually have a VID/PID */
success = TRUE;
goto out;
- } else if (!strcmp (parent_subsys, "usb") &&
- !strcmp (g_udev_device_get_driver (parent), "qmi_wwan")) {
+ } else if (g_str_has_prefix (parent_subsys, "usb") &&
+ g_str_equal (g_udev_device_get_driver (parent), "qmi_wwan")) {
/* Need to look for vendor/product in the parent of the QMI device */
GUdevDevice *qmi_parent;
diff --git a/src/mm-manager.c b/src/mm-manager.c
index 23ef8e68..c5185b31 100644
--- a/src/mm-manager.c
+++ b/src/mm-manager.c
@@ -167,7 +167,7 @@ find_physical_device (GUdevDevice *child)
while (iter && i++ < 8) {
subsys = g_udev_device_get_subsystem (iter);
if (subsys) {
- if (is_usb || !strcmp (subsys, "usb")) {
+ if (is_usb || g_str_has_prefix (subsys, "usb")) {
is_usb = TRUE;
type = g_udev_device_get_devtype (iter);
if (type && !strcmp (type, "usb_device")) {
@@ -329,7 +329,7 @@ device_removed (MMManager *self,
subsys = g_udev_device_get_subsystem (udev_device);
name = g_udev_device_get_name (udev_device);
- if (!g_str_equal (subsys, "usb") ||
+ if (!g_str_has_prefix (subsys, "usb") ||
(name && g_str_has_prefix (name, "cdc-wdm"))) {
/* Handle tty/net/wdm port removal */
device = find_device_by_port (self, udev_device);
@@ -386,14 +386,14 @@ handle_uevent (GUdevClient *client,
/* A bit paranoid */
subsys = g_udev_device_get_subsystem (device);
g_return_if_fail (subsys != NULL);
- g_return_if_fail (g_str_equal (subsys, "tty") || g_str_equal (subsys, "net") || g_str_equal (subsys, "usb"));
+ g_return_if_fail (g_str_equal (subsys, "tty") || g_str_equal (subsys, "net") || g_str_has_prefix (subsys, "usb"));
/* 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
*/
name = g_udev_device_get_name (device);
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"))))
+ && (!g_str_has_prefix (subsys, "usb") || (name && g_str_has_prefix (name, "cdc-wdm"))))
device_added (self, device);
else if (g_str_equal (action, "remove"))
device_removed (self, device);
@@ -434,6 +434,18 @@ mm_manager_start (MMManager *manager)
}
g_list_free (devices);
+ /* Newer kernels report 'usbmisc' subsystem */
+ devices = g_udev_client_query_by_subsystem (manager->priv->udev, "usbmisc");
+ 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...");
}
@@ -672,7 +684,7 @@ static void
mm_manager_init (MMManager *manager)
{
MMManagerPrivate *priv;
- const char *subsys[4] = { "tty", "net", "usb", NULL };
+ const gchar *subsys[5] = { "tty", "net", "usb", "usbmisc", NULL };
/* Setup private data */
manager->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE ((manager),
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 8948e96c..a1a1c33f 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -188,6 +188,10 @@ apply_pre_probing_filters (MMPlugin *self,
for (i = 0; self->priv->subsystems[i]; i++) {
if (g_str_equal (subsys, self->priv->subsystems[i]))
break;
+ /* New kernels may report as 'usbmisc' the subsystem */
+ else if (g_str_equal (self->priv->subsystems[i], "usb") &&
+ g_str_equal (subsys, "usbmisc"))
+ break;
}
/* If we didn't match any subsystem: unsupported */
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index 6572707a..04a1bf8b 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -1119,7 +1119,7 @@ mm_port_probe_is_at (MMPortProbe *self)
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 (subsys, "usb") &&
g_str_has_prefix (name, "cdc-wdm")))
return FALSE;
@@ -1154,7 +1154,7 @@ mm_port_probe_is_qcdm (MMPortProbe *self)
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 (subsys, "usb") &&
g_str_has_prefix (name, "cdc-wdm")))
return FALSE;
@@ -1173,7 +1173,7 @@ mm_port_probe_is_qmi (MMPortProbe *self)
subsys = g_udev_device_get_subsystem (self->priv->port);
name = g_udev_device_get_name (self->priv->port);
- if (!g_str_equal (subsys, "usb") ||
+ if (!g_str_has_prefix (subsys, "usb") ||
!name ||
!g_str_has_prefix (name, "cdc-wdm"))
return FALSE;
@@ -1208,7 +1208,7 @@ mm_port_probe_get_port_type (MMPortProbe *self)
if (g_str_equal (subsys, "net"))
return MM_PORT_TYPE_NET;
- if (g_str_equal (subsys, "usb") &&
+ if (g_str_has_prefix (subsys, "usb") &&
g_str_has_prefix (name, "cdc-wdm") &&
self->priv->is_qmi)
return MM_PORT_TYPE_QMI;
@@ -1267,7 +1267,7 @@ mm_port_probe_get_vendor (MMPortProbe *self)
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 (subsys, "usb") &&
g_str_has_prefix (name, "cdc-wdm")))
return NULL;
@@ -1287,7 +1287,7 @@ mm_port_probe_get_product (MMPortProbe *self)
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 (subsys, "usb") &&
g_str_has_prefix (name, "cdc-wdm")))
return NULL;