drm/i915: Expand force_probe to block probe of devices as well.
authorjsg <jsg@openbsd.org>
Thu, 15 Jun 2023 02:44:18 +0000 (02:44 +0000)
committerjsg <jsg@openbsd.org>
Thu, 15 Jun 2023 02:44:18 +0000 (02:44 +0000)
From Rodrigo Vivi
36fa6187753a9b52f2bbf2f3ba628f6bad314510 in linux-6.1.y/6.1.30
157821fb3e9aaa07cf408686b08d117bf27b7de1 in mainline linux

sys/dev/pci/drm/i915/i915_params.c
sys/dev/pci/drm/i915/i915_pci.c

index d1e4d52..5b24dd5 100644 (file)
@@ -122,7 +122,7 @@ i915_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400,
        "Default: 0");
 
 i915_param_named_unsafe(force_probe, charp, 0400,
-       "Force probe the driver for specified devices. "
+       "Force probe options for specified supported devices. "
        "See CONFIG_DRM_I915_FORCE_PROBE for details.");
 
 i915_param_named_unsafe(disable_power_well, int, 0400,
index 6dedad5..ef72617 100644 (file)
@@ -1253,7 +1253,7 @@ static void i915_pci_remove(struct pci_dev *pdev)
 }
 
 /* is device_id present in comma separated list of ids */
-static bool force_probe(u16 device_id, const char *devices)
+static bool device_id_in_list(u16 device_id, const char *devices, bool negative)
 {
        char *s, *p, *tok;
        bool ret;
@@ -1262,7 +1262,9 @@ static bool force_probe(u16 device_id, const char *devices)
                return false;
 
        /* match everything */
-       if (strcmp(devices, "*") == 0)
+       if (negative && strcmp(devices, "!*") == 0)
+               return true;
+       if (!negative && strcmp(devices, "*") == 0)
                return true;
 
        s = kstrdup(devices, GFP_KERNEL);
@@ -1272,6 +1274,12 @@ static bool force_probe(u16 device_id, const char *devices)
        for (p = s, ret = false; (tok = strsep(&p, ",")) != NULL; ) {
                u16 val;
 
+               if (negative && tok[0] == '!')
+                       tok++;
+               else if ((negative && tok[0] != '!') ||
+                        (!negative && tok[0] == '!'))
+                       continue;
+
                if (kstrtou16(tok, 16, &val) == 0 && val == device_id) {
                        ret = true;
                        break;
@@ -1283,6 +1291,16 @@ static bool force_probe(u16 device_id, const char *devices)
        return ret;
 }
 
+static bool id_forced(u16 device_id)
+{
+       return device_id_in_list(device_id, i915_modparams.force_probe, false);
+}
+
+static bool id_blocked(u16 device_id)
+{
+       return device_id_in_list(device_id, i915_modparams.force_probe, true);
+}
+
 bool i915_pci_resource_valid(struct pci_dev *pdev, int bar)
 {
        if (!pci_resource_flags(pdev, bar))
@@ -1310,10 +1328,9 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                (struct intel_device_info *) ent->driver_data;
        int err;
 
-       if (intel_info->require_force_probe &&
-           !force_probe(pdev->device, i915_modparams.force_probe)) {
+       if (intel_info->require_force_probe && !id_forced(pdev->device)) {
                dev_info(&pdev->dev,
-                        "Your graphics device %04x is not properly supported by the driver in this\n"
+                        "Your graphics device %04x is not properly supported by i915 in this\n"
                         "kernel version. To force driver probe anyway, use i915.force_probe=%04x\n"
                         "module parameter or CONFIG_DRM_I915_FORCE_PROBE=%04x configuration option,\n"
                         "or (recommended) check for kernel updates.\n",
@@ -1321,6 +1338,12 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                return -ENODEV;
        }
 
+       if (id_blocked(pdev->device)) {
+               dev_info(&pdev->dev, "I915 probe blocked for Device ID %04x.\n",
+                        pdev->device);
+               return -ENODEV;
+       }
+
        /* Only bind to function 0 of the device. Early generations
         * used function 1 as a placeholder for multi-head. This causes
         * us confusion instead, especially on the systems where both