summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tdm_backend_drm.c117
1 files changed, 90 insertions, 27 deletions
diff --git a/src/tdm_backend_drm.c b/src/tdm_backend_drm.c
index d6e420e..931fda6 100644
--- a/src/tdm_backend_drm.c
+++ b/src/tdm_backend_drm.c
@@ -43,8 +43,52 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define TDM_DRM_NAME "vigs"
#ifdef HAVE_UDEV
+static int
+_tdm_drm_is_kms(struct udev_device *device)
+{
+ drmModeRes *res;
+ int fd = -1, id = -1;
+ const char *file_name;
+ const char *sys_num;
+
+ file_name = udev_device_get_devnode(device);
+ if (!file_name) return 0;
+
+ TDM_BACKEND_INFO("check kms device:%s", file_name);
+
+ sys_num = udev_device_get_sysnum(device);
+ if (!sys_num) return 0;
+
+ id = atoi(sys_num);
+ if (id < 0) return 0;
+
+ fd = open(file_name, O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ TDM_BACKEND_ERR("fail to open drm device(%s)", file_name);
+ return 0;
+ }
+
+ res = drmModeGetResources(fd);
+ if (!res) goto fail;
+
+ if ((res->count_crtcs <= 0) || (res->count_connectors <= 0) ||
+ (res->count_encoders <= 0))
+ goto fail;
+
+ close(fd);
+ drmModeFreeResources(res);
+
+ return 1;
+
+fail:
+ if (fd >= 0) close(fd);
+ if (res) drmModeFreeResources(res);
+
+ return 0;
+}
+
static struct udev_device *
-_tdm_find_primary_gpu(void)
+_tdm_drm_find_primary_gpu(void)
{
struct udev *udev;
struct udev_enumerate *e;
@@ -65,6 +109,8 @@ _tdm_find_primary_gpu(void)
udev_enumerate_scan_devices(e);
drm_device = NULL;
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
+ int is_boot_vga;
+
path = udev_list_entry_get_name(entry);
device = udev_device_new_from_syspath(udev, path);
if (!device)
@@ -74,21 +120,32 @@ _tdm_find_primary_gpu(void)
"pci", NULL);
if (pci) {
id = udev_device_get_sysattr_value(pci, "boot_vga");
- if (id && !strcmp(id, "1")) {
- if (drm_device)
- udev_device_unref(drm_device);
- drm_device = device;
- break;
- }
+ if (id && !strcmp(id, "1"))
+ is_boot_vga = 1;
}
- if (!drm_device)
- drm_device = device;
- else
+ if (!is_boot_vga && drm_device) {
+ udev_device_unref(device);
+ continue;
+ }
+
+ if (!_tdm_drm_is_kms(device)) {
udev_device_unref(device);
+ continue;
+ }
+
+ if (is_boot_vga) {
+ if (drm_device)
+ udev_device_unref(drm_device);
+ drm_device = device;
+ break;
+ }
+
+ drm_device = device;
}
udev_enumerate_unref(e);
+
return drm_device;
}
@@ -190,31 +247,37 @@ _tdm_drm_open_drm(void)
fd = drmOpen(TDM_DRM_NAME, NULL);
if (fd < 0)
- TDM_BACKEND_WRN("Cannot open '%s' drm", TDM_DRM_NAME);
+ TDM_BACKEND_WRN("fail to open '%s' drm", TDM_DRM_NAME);
#ifdef HAVE_UDEV
+ struct udev_device *drm_device = NULL;
+ const char *file_name;
+
if (fd < 0) {
- struct udev_device *drm_device = NULL;
- const char *filename;
- TDM_BACKEND_WRN("Cannot open drm device.. search by udev");
-
- drm_device = _tdm_find_primary_gpu();
- if (drm_device == NULL) {
- TDM_BACKEND_ERR("fail to find drm device\n");
- goto close_l;
- }
+ TDM_BACKEND_WRN("fail to open drm device.. search by udev");
- filename = udev_device_get_devnode(drm_device);
+ drm_device = _tdm_drm_find_primary_gpu();
+ if (!drm_device) {
+ TDM_BACKEND_ERR("fail to find drm device");
+ goto ret;
+ }
- fd = open(filename, O_RDWR | O_CLOEXEC);
- if (fd < 0)
- TDM_BACKEND_ERR("Cannot open drm device(%s)\n", filename);
+ file_name = udev_device_get_devnode(drm_device);
+ if (!file_name) {
+ TDM_BACKEND_ERR("fail to get devnode");
+ goto ret;
+ }
- TDM_BACKEND_DBG("open drm device (name:%s, fd:%d)", filename, fd);
+ fd = open(file_name, O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ TDM_BACKEND_ERR("fail to open drm device(%s)", file_name);
+ goto ret;
+ }
- udev_device_unref(drm_device);
+ TDM_BACKEND_INFO("open drm device (name:%s fd:%d)", file_name, fd);
}
-close_l:
+ret:
+ if (drm_device) udev_device_unref(drm_device);
#endif
return fd;
}