summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2010-04-16 10:19:19 -0700
committerAaron Plattner <aplattner@nvidia.com>2010-04-16 12:53:05 -0700
commit17ab5dbea69e690cbf78c25040db518471e0887f (patch)
tree62785716af1c986a643419381dd88ba3291518a2
parent250a3a7cee1a4bbfc432ab6da5b986e889207526 (diff)
Refuse to bind to a device which has kernel modesetting active.
Touching directly the hardware while kernel modesetting is active breaks console output. Patch almost entrirely based on VESA patch by Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Tested-by: Aaron Plattner <aplattner@nvidia.com> Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
-rw-r--r--configure.ac11
-rw-r--r--src/Makefile.am2
-rw-r--r--src/nv_driver.c33
3 files changed, 45 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index d717805..c51ab4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -134,6 +134,17 @@ AC_SUBST([modes_dir])
AC_SUBST([XORG_CFLAGS])
AC_SUBST([moduledir])
+if test "x$XSERVER_LIBPCIACCESS" = xyes; then
+ PKG_CHECK_MODULES(LIBDRM, [libdrm > 2.4.3 xf86driproto], HAVE_KMS="yes", HAVE_KMS="no")
+ if test "x$HAVE_KMS" = xyes; then
+ AC_DEFINE(HAVE_KMS, 1, [Have kernel modesetting])
+ else
+ AC_MSG_WARN(Support for detecting kernel modesetting drivers is not available.)
+ AC_MSG_WARN(This driver can cause display problems in the presence of kernel modesetting.)
+ AC_MSG_WARN(Please install libdrm > 2.4.3 and xf86driproto to enable KMS detection.)
+ fi
+fi
+
DRIVER_NAME=nv
AC_SUBST([DRIVER_NAME])
diff --git a/src/Makefile.am b/src/Makefile.am
index 2677d9c..5d57010 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@
+AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ $(LIBDRM_CFLAGS)
nv_drv_la_LTLIBRARIES = nv_drv.la
nv_drv_la_LDFLAGS = -module -avoid-version
nv_drv_ladir = @moduledir@/drivers
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 0d017f9..e10ae0c 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -33,6 +33,11 @@
#include "xf86int10.h"
#include "vbeModes.h"
+#ifdef HAVE_KMS
+#include <xf86drmMode.h>
+#include <dri.h>
+#endif
+
const OptionInfoRec * RivaAvailableOptions(int chipid, int busid);
Bool RivaGetScrnInfoRec(PciChipsets *chips, int chip);
Bool G80GetScrnInfoRec(PciChipsets *chips, int chip);
@@ -830,6 +835,26 @@ NVIsSupported(CARD32 id)
return FALSE;
}
+#ifdef HAVE_KMS
+static Bool NVKernelModesettingEnabled(struct pci_device *device)
+{
+ char *busIdString;
+ int ret;
+
+ if (!xf86LoaderCheckSymbol("DRICreatePCIBusID"))
+ return FALSE;
+
+ busIdString = DRICreatePCIBusID(device);
+
+ ret = drmCheckModesettingSupported(busIdString);
+ xfree(busIdString);
+
+ return (ret == 0);
+}
+#else
+static inline Bool NVKernelModesettingEnabled(struct pci_device *device) { return FALSE; }
+#endif //HAVE_KMS
+
/* Mandatory */
#if XSERVER_LIBPCIACCESS
static Bool
@@ -864,6 +889,14 @@ NVPciProbe(DriverPtr drv, int entity, struct pci_device *dev, intptr_t data)
NV_NAME ": Found NVIDIA %s at %2.2x@%2.2x:%2.2x:%1.1x\n",
name, dev->bus, dev->domain, dev->dev, dev->func);
+ /* Trying to bring up a NV mode while kernel modesetting is enabled
+ results in badness */
+ if (NVKernelModesettingEnabled(dev)) {
+ xf86Msg(X_ERROR,
+ NV_NAME ": Kernel modesetting driver in use, refusing to load\n");
+ return FALSE;
+ }
+
if(NVIsG80(id))
return G80GetScrnInfoRec(NULL, entity);
else if(dev->vendor_id == PCI_VENDOR_NVIDIA_SGS)