- struct udev *udev = NULL;
- struct udev_device *device = NULL, *parent;
- const char *pci_id;
- UDEV_SYMBOL(struct udev *, udev_new, (void));
- UDEV_SYMBOL(struct udev_device *, udev_device_get_parent,
- (struct udev_device *));
- UDEV_SYMBOL(const char *, udev_device_get_property_value,
- (struct udev_device *, const char *));
- UDEV_SYMBOL(struct udev_device *, udev_device_unref,
- (struct udev_device *));
- UDEV_SYMBOL(struct udev *, udev_unref, (struct udev *));
-
- *chip_id = -1;
-
- if (dlsym_failed)
- return 0;
-
- udev = udev_new();
- device = udev_device_new_from_fd(udev, fd);
- if (!device)
- goto out;
-
- parent = udev_device_get_parent(device);
- if (parent == NULL) {
- log_(_LOADER_WARNING, "MESA-LOADER: could not get parent device\n");
- goto out;
+/* Arbitrary "maximum" value of drm devices. */
+#define MAX_DRM_DEVICES 32
+ const char *dri_prime = getenv("DRI_PRIME");
+ char *default_tag, *prime = NULL;
+ drmDevicePtr devices[MAX_DRM_DEVICES];
+ int i, num_devices, fd;
+ bool found = false;
+
+ if (dri_prime)
+ prime = strdup(dri_prime);
+#ifdef USE_DRICONF
+ else
+ prime = loader_get_dri_config_device_id();
+#endif
+
+ if (prime == NULL) {
+ *different_device = false;
+ return default_fd;
+ }
+
+ default_tag = drm_get_id_path_tag_for_fd(default_fd);
+ if (default_tag == NULL)
+ goto err;
+
+ num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
+ if (num_devices < 0)
+ goto err;
+
+ /* two format are supported:
+ * "1": choose any other card than the card used by default.
+ * id_path_tag: (for example "pci-0000_02_00_0") choose the card
+ * with this id_path_tag.
+ */
+ if (!strcmp(prime,"1")) {
+ /* Hmm... detection for 2-7 seems to be broken. Oh well ...
+ * Pick the first render device that is not our own.
+ */
+ for (i = 0; i < num_devices; i++) {
+ if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
+ !drm_device_matches_tag(devices[i], default_tag)) {
+
+ found = true;
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < num_devices; i++) {
+ if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
+ drm_device_matches_tag(devices[i], prime)) {
+
+ found = true;
+ break;
+ }
+ }