summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2018-01-18 18:07:29 -0800
committerKeith Packard <keithp@keithp.com>2018-01-24 10:51:08 +1100
commitaead4a60c29857047a3493eadee4b6bf3e997b72 (patch)
tree8205867e56798f09dbd5a885700593849ea41acf
parent9e8d2a9450c69f86024d62d3ed0525c744c0717e (diff)
modesetting: Allow a DRM fd to be passed through XF86_VIDEO_MODESETTING_FDdrm-lease-v2
This lets an application open a suitable DRM device and pass the file descriptor to the mode setting driver through an environment variable. There's a companion application, xlease, which creates a DRM master by leasing an output from another X server. That is available at git clone git://people.freedesktop.org/~keithp/xlease Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c29
-rw-r--r--hw/xfree86/drivers/modesetting/driver.h1
2 files changed, 29 insertions, 1 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 2e4c43b5b..1181effe7 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -195,10 +195,27 @@ modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn)
}
static int
+get_passed_fd(void)
+{
+ char *fdstr = getenv("XF86_VIDEO_MODESETTING_FD");
+
+ if (fdstr) {
+ char *endptr;
+ int fd = strtol(fdstr, &endptr, 10);
+ if (endptr != fdstr && *endptr == '\0')
+ return dup(fd);
+ }
+ return -1;
+}
+
+static int
open_hw(const char *dev)
{
int fd;
+ if ((fd = get_passed_fd()) >= 0)
+ return fd;
+
if (dev)
fd = open(dev, O_RDWR, 0);
else {
@@ -822,6 +839,12 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn)
return TRUE;
}
+ ms->fd_passed = FALSE;
+ if ((ms->fd = get_passed_fd()) >= 0) {
+ ms->fd_passed = TRUE;
+ return TRUE;
+ }
+
#ifdef XSERVER_PLATFORM_BUS
if (pEnt->location.type == BUS_PLATFORM) {
if (pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)
@@ -1494,6 +1517,9 @@ SetMaster(ScrnInfoPtr pScrn)
(ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD))
return TRUE;
+ if (ms->fd_passed)
+ return TRUE;
+
ret = drmSetMaster(ms->fd);
if (ret)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
@@ -1745,7 +1771,8 @@ LeaveVT(ScrnInfoPtr pScrn)
(ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD))
return;
- drmDropMaster(ms->fd);
+ if (!ms->fd_passed)
+ drmDropMaster(ms->fd);
}
/*
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index fe835918b..6be51e01b 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -84,6 +84,7 @@ struct ms_drm_queue {
typedef struct _modesettingRec {
int fd;
+ Bool fd_passed;
int Chipset;
EntityInfoPtr pEnt;