diff options
Diffstat (limited to 'src/tdm_backend_drm.c')
-rw-r--r-- | src/tdm_backend_drm.c | 117 |
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; } |