diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-02 09:34:57 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-07-02 09:38:07 +0100 |
commit | 282507af8e932e49b31d5f20958a61c137df590d (patch) | |
tree | b54c68b053ea2176f63ed4d835070eb7dd39a521 /src/intel_device.c | |
parent | 24a7bec7faa7dcc4393ef7f66939ae0fb8acdf36 (diff) |
intel: Move the validation of the KMS device into the open routine
Currently we leak the fd should we open the device node and decide that
is not a GEM/KMS kernel driver. The simplest way to perform the cleanup
upon failure is to move the checking for GEM/KMS into the device open
routine.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/intel_device.c')
-rw-r--r-- | src/intel_device.c | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/src/intel_device.c b/src/intel_device.c index da4d21e0..c5f0a38d 100644 --- a/src/intel_device.c +++ b/src/intel_device.c @@ -38,6 +38,7 @@ #include <xf86drm.h> #include <xf86drmMode.h> #include <xf86_OSproc.h> +#include <i915_drm.h> #include "intel_driver.h" @@ -63,6 +64,45 @@ static inline void intel_set_device(ScrnInfoPtr scrn, struct intel_device *dev) xf86GetEntityPrivate(scrn->entityList[0], intel_device_key)->ptr = dev; } +static Bool is_i915_device(int fd) +{ + drm_version_t version; + char name[5] = ""; + + memset(&version, 0, sizeof(version)); + version.name_len = 4; + version.name = name; + + if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) + return FALSE; + + return strcmp("i915", name) == 0; +} + +static int __intel_check_device(int fd) +{ + int ret; + + /* Confirm that this is a i915.ko device with GEM/KMS enabled */ + ret = is_i915_device(fd); + if (ret) { + struct drm_i915_getparam gp; + gp.param = I915_PARAM_HAS_GEM; + gp.value = &ret; + if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) + ret = FALSE; + } + if (ret) { + struct drm_mode_card_res res; + + memset(&res, 0, sizeof(res)); + if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) + ret = FALSE; + } + + return ret; +} + static int fd_set_cloexec(int fd) { int flags; @@ -145,14 +185,14 @@ int intel_open_device(int entity_num, fd = __intel_open_device(pci, &local_path); if (fd == -1) - return -1; + goto err_path; + + if (!__intel_check_device(fd)) + goto err_close; dev = malloc(sizeof(*dev)); - if (dev == NULL) { - free(local_path); - close(fd); - return -1; - } + if (dev == NULL) + goto err_close; dev->path = local_path; dev->fd = fd; @@ -162,6 +202,12 @@ int intel_open_device(int entity_num, xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev; return fd; + +err_close: + close(fd); +err_path: + free(local_path); + return -1; } int intel_get_device(ScrnInfoPtr scrn) |