static void device_added (MMBaseManager *manager, GUdevDevice *port, gboolean hotplugged, gboolean manual_scan) { MMDevice *device; const char *subsys, *name, *physdev_path, *physdev_subsys; gboolean is_candidate; GUdevDevice *physdev = NULL; g_return_if_fail (port != NULL); subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); /* ignore VTs */ if (strncmp (name, "tty", 3) == 0 && isdigit (name[3])) return; /* Ignore devices that aren't completely configured by udev yet. If * ModemManager is started in parallel with udev, explicitly requesting * devices may return devices for which not all udev rules have yet been * applied (a bug in udev/gudev). Since we often need those rules to match * the device to a specific ModemManager driver, we need to ensure that all * rules have been processed before handling a device. */ is_candidate = g_udev_device_get_property_as_boolean (port, "ID_MM_CANDIDATE"); if (!is_candidate) { /* This could mean that device changed, loosing its ID_MM_CANDIDATE * flags (such as Bluetooth RFCOMM devices upon disconnect. * Try to forget it. */ if (hotplugged && !manual_scan) device_removed (manager, port); return; } if (find_device_by_port (manager, port)) return; /* Find the port's physical device's sysfs path. This is the kernel device * that "owns" all the ports of the device, like the USB device or the PCI * device the provides each tty or network port. */ physdev = find_physical_device (port); if (!physdev) { /* Warn about it, but filter out some common ports that we know don't have * anything to do with mobile broadband. */ if ( strcmp (name, "console") && strcmp (name, "ptmx") && strcmp (name, "lo") && strcmp (name, "tty") && !strstr (name, "virbr")) mm_dbg ("(%s/%s): could not get port's parent device", subsys, name); goto out; } /* Is the device blacklisted? */ if (g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_IGNORE")) { mm_dbg ("(%s/%s): port's parent device is blacklisted", subsys, name); goto out; } /* Is the device in the manual-only greylist? If so, return if this is an * automatic scan. */ if (!manual_scan && g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_MANUAL_SCAN_ONLY")) { mm_dbg ("(%s/%s): port probed only in manual scan", subsys, name); goto out; } /* If the physdev is a 'platform' or 'pnp' device that's not whitelisted, ignore it */ physdev_subsys = g_udev_device_get_subsystem (physdev); if ( physdev_subsys && ( g_str_equal (physdev_subsys, "platform") || g_str_equal (physdev_subsys, "pnp")) && !g_udev_device_get_property_as_boolean (physdev, "ID_MM_PLATFORM_DRIVER_PROBE")) { mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name); goto out; } physdev_path = g_udev_device_get_sysfs_path (physdev); if (!physdev_path) { mm_dbg ("(%s/%s): could not get port's parent device sysfs path", subsys, name); goto out; } /* See if we already created an object to handle ports in this device */ device = find_device_by_sysfs_path (manager, physdev_path); if (!device) { FindDeviceSupportContext *ctx; /* Keep the device listed in the Manager */ device = mm_device_new (physdev, hotplugged); g_hash_table_insert (manager->priv->devices, g_strdup (physdev_path), device); /* Launch device support check */ ctx = g_slice_new (FindDeviceSupportContext); ctx->self = g_object_ref (manager); ctx->device = g_object_ref (device); mm_plugin_manager_device_support_check ( manager->priv->plugin_manager, device, (GAsyncReadyCallback) device_support_check_ready, ctx); } /* Grab the port in the existing device. */ mm_device_grab_port (device, port); out: if (physdev) g_object_unref (physdev); }
static void device_added (MMManager *manager, GUdevDevice *device) { const char *subsys, *name, *physdev_path, *physdev_subsys; gboolean is_candidate; GUdevDevice *physdev = NULL; MMPlugin *plugin; MMBaseModem *existing; g_return_if_fail (device != NULL); subsys = g_udev_device_get_subsystem (device); name = g_udev_device_get_name (device); /* ignore VTs */ if (strncmp (name, "tty", 3) == 0 && isdigit (name[3])) return; /* Ignore devices that aren't completely configured by udev yet. If * ModemManager is started in parallel with udev, explicitly requesting * devices may return devices for which not all udev rules have yet been * applied (a bug in udev/gudev). Since we often need those rules to match * the device to a specific ModemManager driver, we need to ensure that all * rules have been processed before handling a device. */ is_candidate = g_udev_device_get_property_as_boolean (device, "ID_MM_CANDIDATE"); if (!is_candidate) return; if (find_modem_for_port (manager, subsys, name)) return; /* Find the port's physical device's sysfs path. This is the kernel device * that "owns" all the ports of the device, like the USB device or the PCI * device the provides each tty or network port. */ physdev = find_physical_device (device); if (!physdev) { /* Warn about it, but filter out some common ports that we know don't have * anything to do with mobile broadband. */ if ( strcmp (name, "console") && strcmp (name, "ptmx") && strcmp (name, "lo") && strcmp (name, "tty") && !strstr (name, "virbr")) mm_dbg ("(%s/%s): could not get port's parent device", subsys, name); goto out; } /* Is the device blacklisted? */ if (g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_IGNORE")) { mm_dbg ("(%s/%s): port's parent device is blacklisted", subsys, name); goto out; } /* If the physdev is a 'platform' device that's not whitelisted, ignore it */ physdev_subsys = g_udev_device_get_subsystem (physdev); if ( physdev_subsys && !strcmp (physdev_subsys, "platform") && !g_udev_device_get_property_as_boolean (physdev, "ID_MM_PLATFORM_DRIVER_PROBE")) { mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name); goto out; } physdev_path = g_udev_device_get_sysfs_path (physdev); if (!physdev_path) { mm_dbg ("(%s/%s): could not get port's parent device sysfs path", subsys, name); goto out; } /* Already launched the same port support check? */ if (mm_plugin_manager_is_finding_port_support (manager->priv->plugin_manager, subsys, name, physdev_path)) { mm_dbg ("(%s/%s): support check already requested in port", subsys, name); goto out; } /* If this port's physical modem is already owned by a plugin, don't bother * asking all plugins whether they support this port, just let the owning * plugin check if it supports the port. */ existing = find_modem_for_device (manager, physdev_path); plugin = (existing ? MM_PLUGIN (g_object_get_data (G_OBJECT (existing), MANAGER_PLUGIN_TAG)) : NULL); /* Launch supports check in the Plugin Manager */ mm_plugin_manager_find_port_support ( manager->priv->plugin_manager, subsys, name, physdev_path, plugin, existing, (GAsyncReadyCallback)find_port_support_ready_cb, find_port_support_context_new (manager, device, physdev)); out: if (physdev) g_object_unref (physdev); }