From ce71b580fc1e722d93c09cefaaeaf41e4ec6e545 Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Wed, 4 May 2022 13:52:59 +0200 Subject: filter: add vendor id/subsystem vendor id filter Some PCI modems prefer customizing the subsytem vendor ID, instead of the vendor ID. Add a filter for the couple vendor/subsystem vendor IDs. --- src/mm-plugin.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'src/mm-plugin.c') diff --git a/src/mm-plugin.c b/src/mm-plugin.c index 354caf09..f4d84ad4 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -74,6 +74,7 @@ struct _MMPluginPrivate { gchar **forbidden_drivers; guint16 *vendor_ids; mm_uint16_pair *product_ids; + mm_uint16_pair *subsystem_vendor_ids; mm_uint16_pair *forbidden_product_ids; gchar **udev_tags; @@ -114,6 +115,7 @@ enum { PROP_FORBIDDEN_DRIVERS, PROP_ALLOWED_VENDOR_IDS, PROP_ALLOWED_PRODUCT_IDS, + PROP_ALLOWED_SUBSYSTEM_VENDOR_IDS, PROP_FORBIDDEN_PRODUCT_IDS, PROP_ALLOWED_VENDOR_STRINGS, PROP_ALLOWED_PRODUCT_STRINGS, @@ -170,6 +172,12 @@ mm_plugin_get_allowed_product_ids (MMPlugin *self) return self->priv->product_ids; } +const mm_uint16_pair * +mm_plugin_get_allowed_subsystem_vendor_ids (MMPlugin *self) +{ + return self->priv->subsystem_vendor_ids; +} + gboolean mm_plugin_is_generic (MMPlugin *self) { @@ -243,8 +251,10 @@ apply_pre_probing_filters (MMPlugin *self, { guint16 vendor; guint16 product; + guint16 subsystem_vendor; gboolean product_filtered = FALSE; gboolean vendor_filtered = FALSE; + gboolean subsystem_vendor_filtered = FALSE; guint i; *need_vendor_probing = FALSE; @@ -350,6 +360,7 @@ apply_pre_probing_filters (MMPlugin *self, vendor = mm_device_get_vendor (device); product = mm_device_get_product (device); + subsystem_vendor = mm_device_get_subsystem_vendor (device); /* The plugin may specify that only some vendor IDs are supported. If that * is the case, filter by vendor ID. */ @@ -394,12 +405,30 @@ apply_pre_probing_filters (MMPlugin *self, product_filtered = FALSE; } - /* If we got filtered by vendor or product IDs; mark it as unsupported only if: + /* The plugin may specify that a set of vendor IDs is valid only when going + * with a specific subsystem vendor IDs (PCI modems). + * If that is the case, filter by vendor+subsystem vendor ID pair */ + if (subsystem_vendor && self->priv->subsystem_vendor_ids) { + for (i = 0; self->priv->subsystem_vendor_ids[i].l; i++) + if (vendor == self->priv->subsystem_vendor_ids[i].l && + subsystem_vendor == self->priv->subsystem_vendor_ids[i].r) { + /* If device was filtered by vendor, we override that value, since + * we want to give priority to vendor/subsystem vendor match */ + vendor_filtered = FALSE; + break; + } + + /* If we didn't match any vendor/subsystem vendor: filtered */ + if (!self->priv->subsystem_vendor_ids[i].l) + subsystem_vendor_filtered = TRUE; + } + + /* If we got filtered by vendor/product/subsystem IDs; mark it as unsupported only if: * a) we do not have vendor or product strings to compare with (i.e. plugin * doesn't have explicit vendor/product strings * b) the port is NOT an AT port which we can use for AT probing */ - if ((vendor_filtered || product_filtered) && + if ((vendor_filtered || product_filtered || subsystem_vendor_filtered) && ((!self->priv->vendor_strings && !self->priv->product_strings && !self->priv->forbidden_product_strings) || @@ -430,7 +459,8 @@ apply_pre_probing_filters (MMPlugin *self, * already had vendor/product ID filters and we actually passed those. */ if ((!self->priv->vendor_ids && !self->priv->product_ids) || vendor_filtered || - product_filtered) { + product_filtered || + subsystem_vendor_filtered) { /* If product strings related filters around, we need to probe for both * vendor and product strings */ if (self->priv->product_strings || @@ -1172,6 +1202,10 @@ set_property (GObject *object, /* Construct only */ self->priv->product_ids = g_value_dup_boxed (value); break; + case PROP_ALLOWED_SUBSYSTEM_VENDOR_IDS: + /* Construct only */ + self->priv->subsystem_vendor_ids = g_value_dup_boxed (value); + break; case PROP_FORBIDDEN_PRODUCT_IDS: /* Construct only */ self->priv->forbidden_product_ids = g_value_dup_boxed (value); @@ -1292,6 +1326,9 @@ get_property (GObject *object, case PROP_ALLOWED_PRODUCT_IDS: g_value_set_boxed (value, self->priv->product_ids); break; + case PROP_ALLOWED_SUBSYSTEM_VENDOR_IDS: + g_value_set_boxed (value, self->priv->subsystem_vendor_ids); + break; case PROP_FORBIDDEN_PRODUCT_IDS: g_value_set_boxed (value, self->priv->forbidden_product_ids); break; @@ -1375,6 +1412,7 @@ finalize (GObject *object) _g_boxed_free0 (G_TYPE_STRV, self->priv->forbidden_drivers); _g_boxed_free0 (MM_TYPE_UINT16_ARRAY, self->priv->vendor_ids); _g_boxed_free0 (MM_TYPE_UINT16_PAIR_ARRAY, self->priv->product_ids); + _g_boxed_free0 (MM_TYPE_UINT16_PAIR_ARRAY, self->priv->subsystem_vendor_ids); _g_boxed_free0 (MM_TYPE_UINT16_PAIR_ARRAY, self->priv->forbidden_product_ids); _g_boxed_free0 (G_TYPE_STRV, self->priv->udev_tags); _g_boxed_free0 (G_TYPE_STRV, self->priv->vendor_strings); @@ -1467,6 +1505,15 @@ mm_plugin_class_init (MMPluginClass *klass) MM_TYPE_UINT16_PAIR_ARRAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, PROP_ALLOWED_SUBSYSTEM_VENDOR_IDS, + g_param_spec_boxed (MM_PLUGIN_ALLOWED_SUBSYSTEM_VENDOR_IDS, + "Allowed subsystem vendor IDs", + "List of vendor+subsystem vendor ID pairs this plugin can support, " + "should be an array of mm_uint16_pair finished with '0,0'", + MM_TYPE_UINT16_PAIR_ARRAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_FORBIDDEN_PRODUCT_IDS, g_param_spec_boxed (MM_PLUGIN_FORBIDDEN_PRODUCT_IDS, -- cgit v1.2.3-70-g09d2