[libcamera-devel] [PATCH] cam: drm: Support /dev/dri cards other than 0

Eric Curtin ecurtin at redhat.com
Wed Jun 1 17:23:45 CEST 2022


Existing code is hardcoded to card0. Since recent fedora upgrades, we
have noticed on more than one machine that card1 is present as the
lowest numbered device, could theoretically be higher. This technique
tries every file starting with card and continue only when we have
successfully opened one. These devices with card1 as the lowest device
were simply failing when they do not see a /dev/dri/card0 file present.

Reported-by: Ian Mullins <imullins at redhat.com>
Signed-off-by: Eric Curtin <ecurtin at redhat.com>
---
 src/cam/drm.cpp | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/cam/drm.cpp b/src/cam/drm.cpp
index 42c5a3b1..5a322819 100644
--- a/src/cam/drm.cpp
+++ b/src/cam/drm.cpp
@@ -8,6 +8,7 @@
 #include "drm.h"
 
 #include <algorithm>
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <iostream>
@@ -393,8 +394,10 @@ Device::~Device()
 
 int Device::init()
 {
-	constexpr size_t NODE_NAME_MAX = sizeof("/dev/dri/card255");
-	char name[NODE_NAME_MAX];
+	constexpr size_t DIR_NAME_MAX = sizeof("/dev/dri/");
+	constexpr size_t BASE_NAME_MAX = sizeof("card255");
+	constexpr size_t NODE_NAME_MAX = DIR_NAME_MAX + BASE_NAME_MAX - 1;
+	char name[NODE_NAME_MAX] = "/dev/dri/";
 	int ret;
 
 	/*
@@ -404,14 +407,28 @@ int Device::init()
 	 * from drmOpen() is of no practical use as any modern system will
 	 * handle that through udev or an equivalent component.
 	 */
-	snprintf(name, sizeof(name), "/dev/dri/card%u", 0);
-	fd_ = open(name, O_RDWR | O_CLOEXEC);
-	if (fd_ < 0) {
-		ret = -errno;
-		std::cerr
-			<< "Failed to open DRM/KMS device " << name << ": "
-			<< strerror(-ret) << std::endl;
-		return ret;
+	DIR *folder = opendir(name);
+	if (folder) {
+		for (struct dirent *res; (res = readdir(folder));) {
+			if (strlen(res->d_name) > 4 &&
+			    !strncmp(res->d_name, "card", 4)) {
+				memcpy(name + DIR_NAME_MAX - 1, res->d_name,
+				       BASE_NAME_MAX);
+				fd_ = open(name, O_RDWR | O_CLOEXEC);
+				if (fd_ < 0) {
+					ret = -errno;
+					std::cerr
+						<< "Failed to open DRM/KMS device "
+						<< name << ": "
+						<< strerror(-ret) << std::endl;
+					continue;
+				}
+
+				break;
+			}
+		}
+
+		closedir(folder);
 	}
 
 	/*
-- 
2.35.3



More information about the libcamera-devel mailing list