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.
This commit is contained in:
Aleksander Morgado
2012-08-21 11:32:24 +02:00
parent 8cb021293c
commit 494a70a8ff
6 changed files with 32 additions and 15 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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;

View File

@@ -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),

View File

@@ -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 */

View File

@@ -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;