summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-05-13 13:35:12 +1000
committerDave Airlie <airlied@redhat.com>2013-05-13 13:48:16 +1000
commitd3b52efe959f255784f5ead16d7276ca0fb4cdb1 (patch)
treea96d2246d21ffd98f403a96bfbe31a8a504ae32e
parent50426ac83f9f077791e4df8c04fc0ecefc06e8ab (diff)
downloadxorg-driver-xf86-video-nouveau-d3b52efe959f255784f5ead16d7276ca0fb4cdb1.tar.gz
nouveau: attempt to fix zaphod since dri1 code removal
j_v on #nouveau bisected b1a630b48210d6a3c44994fce1b73273000ace5c has breaking zaphod, on review it was trying to open the drm fd a second time which was unnecessary. Avoid the problem by storing the nv fd in an entity and have share it between the two scrn info recs. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/nv_driver.c42
-rw-r--r--src/nv_type.h5
2 files changed, 47 insertions, 0 deletions
diff --git a/src/nv_driver.c b/src/nv_driver.c
index ece5e91..470f70d 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -80,6 +80,7 @@ static Bool NVPlatformProbe(DriverPtr driver,
intptr_t dev_match_data);
#endif
+_X_EXPORT int NVEntityIndex = -1;
/*
* This contains the functions needed by the server after loading the
* driver module. It must be supplied, and gets added the driver list by
@@ -228,6 +229,8 @@ NVDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
static void
NVInitScrn(ScrnInfoPtr pScrn, int entity_num)
{
+ DevUnion *pPriv;
+
pScrn->driverVersion = NV_VERSION;
pScrn->driverName = NV_DRIVER_NAME;
pScrn->name = NV_NAME;
@@ -242,6 +245,15 @@ NVInitScrn(ScrnInfoPtr pScrn, int entity_num)
pScrn->FreeScreen = NVFreeScreen;
xf86SetEntitySharable(entity_num);
+ if (NVEntityIndex == -1)
+ NVEntityIndex = xf86AllocateEntityPrivateIndex();
+
+ pPriv = xf86GetEntityPrivate(entity_num,
+ NVEntityIndex);
+ if (!pPriv->ptr) {
+ pPriv->ptr = xnfcalloc(sizeof(NVEntRec), 1);
+ }
+
xf86SetEntityInstanceForScreen(pScrn, entity_num,
xf86GetNumEntityInstances(entity_num) - 1);
}
@@ -683,15 +695,44 @@ nouveau_setup_capabilities(ScrnInfoPtr pScrn)
#endif
}
+extern _X_EXPORT int NVEntityIndex;
+
+static int getNVEntityIndex(void)
+{
+ return NVEntityIndex;
+}
+
+NVEntPtr NVEntPriv(ScrnInfoPtr pScrn)
+{
+ DevUnion *pPriv;
+ NVPtr pNv = NVPTR(pScrn);
+ pPriv = xf86GetEntityPrivate(pNv->pEnt->index,
+ getNVEntityIndex());
+ return pPriv->ptr;
+}
+
static Bool NVOpenDRMMaster(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
+ NVEntPtr pNVEnt = NVEntPriv(pScrn);
struct pci_device *dev = pNv->PciInfo;
char *busid;
drmSetVersion sv;
int err;
int ret;
+ if (pNVEnt->fd) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " reusing fd for second head\n");
+ ret = nouveau_device_wrap(pNVEnt->fd, 0, &pNv->dev);
+ if (ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] error creating device\n");
+ return FALSE;
+ }
+ return TRUE;
+ }
+
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
dev->domain, dev->bus, dev->dev, dev->func);
@@ -721,6 +762,7 @@ static Bool NVOpenDRMMaster(ScrnInfoPtr pScrn)
nouveau_device_del(&pNv->dev);
return FALSE;
}
+ pNVEnt->fd = pNv->dev->fd;
return TRUE;
}
diff --git a/src/nv_type.h b/src/nv_type.h
index 8aabe77..9c403b5 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -31,6 +31,11 @@
/* NV50 */
typedef struct _NVRec *NVPtr;
+
+typedef struct {
+ int fd;
+} NVEntRec, *NVEntPtr;
+
typedef struct _NVRec {
uint32_t Architecture;
EntityInfoPtr pEnt;