summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-05-09 13:58:37 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-06-02 08:32:11 +0100
commitd27c948a4382c4024ce5e76f1ea82103fc8e9d66 (patch)
tree53b7c10a2f59d69e288d62c3117904694c02ce1e /src
parent8a02886a24c8699374a39a9363e72bec0e7bbe30 (diff)
intel: Add common routines and configure probing for DRI3
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/intel_device.c84
-rw-r--r--src/intel_driver.h1
-rw-r--r--src/intel_options.c1
-rw-r--r--src/intel_options.h1
4 files changed, 72 insertions, 15 deletions
diff --git a/src/intel_device.c b/src/intel_device.c
index 43372284..7140bebd 100644
--- a/src/intel_device.c
+++ b/src/intel_device.c
@@ -104,7 +104,7 @@ 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)
+static int is_i915_device(int fd)
{
drm_version_t version;
char name[5] = "";
@@ -114,30 +114,40 @@ static Bool is_i915_device(int fd)
version.name = name;
if (drmIoctl(fd, DRM_IOCTL_VERSION, &version))
- return FALSE;
+ return 0;
return strcmp("i915", name) == 0;
}
-static int __intel_check_device(int fd)
+static int is_i915_gem(int fd)
{
- int ret;
+ int ret = is_i915_device(fd);
- /* 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;
+ ret = 0;
}
+
+ return ret;
+}
+
+static int __intel_check_device(int fd)
+{
+ int ret;
+
+ /* Confirm that this is a i915.ko device with GEM/KMS enabled */
+ ret = is_i915_gem(fd);
if (ret && !hosted()) {
struct drm_mode_card_res res;
memset(&res, 0, sizeof(res));
if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
- ret = FALSE;
+ ret = 0;
}
return ret;
@@ -203,20 +213,25 @@ static char *find_master_node(int fd)
return drmGetDeviceNameFromFd(fd);
}
+static int is_render_node(int fd, struct stat *st)
+{
+ if (fstat(fd, st))
+ return 0;
+
+ if (!S_ISCHR(st->st_mode))
+ return 0;
+
+ return st->st_rdev & 0x80;
+}
+
static char *find_render_node(int fd)
{
#if defined(USE_RENDERNODE)
struct stat master, render;
char buf[128];
- if (fstat(fd, &master))
- return NULL;
-
- if (!S_ISCHR(master.st_mode))
- return NULL;
-
/* Are we a render-node ourselves? */
- if (master.st_rdev & 0x80)
+ if (is_render_node(fd, &master))
return NULL;
sprintf(buf, "/dev/dri/renderD%d", (int)((master.st_rdev | 0x80) & 0xbf));
@@ -400,6 +415,45 @@ const char *intel_get_client_name(ScrnInfoPtr scrn)
return dev->render_node;
}
+static int authorise(struct intel_device *dev, int fd)
+{
+ struct stat st;
+ drm_magic_t magic;
+
+ assert(is_i915_gem(fd));
+
+ if (is_render_node(fd, &st)) /* restricted authority, do not elevate */
+ return 1;
+
+ return drmGetMagic(fd, &magic) == 0 && drmAuthMagic(dev->fd, magic) == 0;
+}
+
+int intel_get_client_fd(ScrnInfoPtr scrn)
+{
+ struct intel_device *dev;
+ int fd = -1;
+
+ dev = intel_device(scrn);
+ assert(dev);
+ assert(dev->fd != -1);
+ assert(dev->render_node);
+
+#ifdef O_CLOEXEC
+ fd = open(dev->render_node, O_RDWR | O_CLOEXEC);
+#endif
+ if (fd < 0)
+ fd = fd_set_cloexec(open(dev->render_node, O_RDWR));
+ if (fd < 0)
+ return -BadAlloc;
+
+ if (!authorise(dev, fd)) {
+ close(fd);
+ return -BadMatch;
+ }
+
+ return fd;
+}
+
int intel_get_device_id(ScrnInfoPtr scrn)
{
struct intel_device *dev = intel_device(scrn);
diff --git a/src/intel_driver.h b/src/intel_driver.h
index 182a30eb..3dc640cf 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -127,6 +127,7 @@ int intel_open_device(int entity_num,
struct xf86_platform_device *dev);
int intel_get_device(ScrnInfoPtr scrn);
const char *intel_get_client_name(ScrnInfoPtr scrn);
+int intel_get_client_fd(ScrnInfoPtr scrn);
int intel_get_device_id(ScrnInfoPtr scrn);
int intel_get_master(ScrnInfoPtr scrn);
int intel_put_master(ScrnInfoPtr scrn);
diff --git a/src/intel_options.c b/src/intel_options.c
index 51d5462d..ff8541a4 100644
--- a/src/intel_options.c
+++ b/src/intel_options.c
@@ -9,6 +9,7 @@ const OptionInfoRec intel_options[] = {
{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, 0},
{OPTION_BACKLIGHT, "Backlight", OPTV_STRING, {0}, 0},
{OPTION_DRI, "DRI", OPTV_STRING, {0}, 0},
+ {OPTION_PRESENT, "Present", OPTV_BOOLEAN, {0}, 1},
{OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, 0},
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, 0},
{OPTION_TILING_2D, "Tiling", OPTV_BOOLEAN, {0}, 1},
diff --git a/src/intel_options.h b/src/intel_options.h
index 6873a6dd..7e2cbd9b 100644
--- a/src/intel_options.h
+++ b/src/intel_options.h
@@ -16,6 +16,7 @@ enum intel_options {
OPTION_ACCEL_METHOD,
OPTION_BACKLIGHT,
OPTION_DRI,
+ OPTION_PRESENT,
OPTION_VIDEO_KEY,
OPTION_COLOR_KEY,
OPTION_TILING_2D,