#include <fcntl.h>
#include <errno.h>
#include <xf86drm.h>
+#include <xf86drmMode.h>
#include <pthread.h>
#include <hal-common.h>
#include <hal-tbm-types.h>
};
static int
-_tbm_dumb_open_drm()
+_tbm_dumb_is_kms(struct udev_device *device)
{
- struct udev *udev = NULL;
- struct udev_enumerate *e = NULL;
- struct udev_list_entry *entry = NULL;
- struct udev_device *device = NULL, *drm_device = NULL, *pci = NULL;
- const char *filepath, *id;
- struct stat s;
- int fd = -1;
- int ret;
+ 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;
+
+ TBM_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) {
+ TBM_BACKEND_ERR("Cannot 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 *
+_tbm_dumb_find_primary_gpu(void)
+{
+ struct udev *udev;
+ struct udev_enumerate *e;
+ struct udev_list_entry *entry;
+ const char *path, *id;
+ struct udev_device *device, *drm_device, *pci;
udev = udev_new();
if (!udev) {
- TBM_BACKEND_ERR("udev_new() failed.\n");
- return -1;
+ TBM_BACKEND_ERR("fail to initialize udev context\n");
+ return NULL;
}
e = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(e, "drm");
udev_enumerate_add_match_sysname(e, "card[0-9]*");
- udev_enumerate_scan_devices(e);
+ udev_enumerate_scan_devices(e);
drm_device = NULL;
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
- filepath = udev_list_entry_get_name(entry);
- device = udev_device_new_from_syspath(udev, filepath);
+ int is_boot_vga;
+
+ path = udev_list_entry_get_name(entry);
+ device = udev_device_new_from_syspath(udev, path);
if (!device)
continue;
- pci = udev_device_get_parent_with_subsystem_devtype(device, "pci", NULL);
+ pci = udev_device_get_parent_with_subsystem_devtype(device,
+ "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 (!_tbm_dumb_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);
- /* Get device file path. */
- filepath = udev_device_get_devnode(drm_device);
- if (!filepath) {
- TBM_BACKEND_ERR("udev_device_get_devnode() failed.\n");
- udev_device_unref(drm_device);
- udev_unref(udev);
- return -1;
+ return drm_device;
+}
+
+static int
+_tbm_dumb_open_drm(void)
+{
+ int fd = -1;
+ struct udev_device *drm_device = NULL;
+ const char *file_name;
+
+ drm_device = _tbm_dumb_find_primary_gpu();
+ if (!drm_device) {
+ TBM_BACKEND_ERR("fail to find drm device");
+ goto ret;
}
- /* Open DRM device file and check validity. */
- fd = open(filepath, O_RDWR | O_CLOEXEC);
- if (fd < 0) {
- TBM_BACKEND_ERR("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
- udev_device_unref(drm_device);
- udev_unref(udev);
- return -1;
+ file_name = udev_device_get_devnode(drm_device);
+ if (!file_name) {
+ TBM_BACKEND_ERR("fail to get devnode");
+ goto ret;
}
- ret = fstat(fd, &s);
- if (ret) {
- TBM_BACKEND_ERR("fstat() failed %s.\n");
- close(fd);
- udev_device_unref(drm_device);
- udev_unref(udev);
- return -1;
+ fd = open(file_name, O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ TBM_BACKEND_ERR("Cannot open drm device(%s)", file_name);
+ goto ret;
}
- udev_device_unref(drm_device);
- udev_unref(udev);
+ TBM_BACKEND_INFO("open drm device (name:%s, fd:%d)", file_name, fd);
+ret:
+ if (drm_device) udev_device_unref(drm_device);
return fd;
}