summaryrefslogtreecommitdiff
path: root/src/intel_device.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-07-02 09:34:57 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-07-02 09:38:07 +0100
commit282507af8e932e49b31d5f20958a61c137df590d (patch)
treeb54c68b053ea2176f63ed4d835070eb7dd39a521 /src/intel_device.c
parent24a7bec7faa7dcc4393ef7f66939ae0fb8acdf36 (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.c58
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)