summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c11
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h1
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c69
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h5
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h7
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c10
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c16
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h1
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c12
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h2
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c7
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c3
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c11
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h1
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h13
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h52
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h118
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h112
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h130
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h11
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h154
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h6
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c21
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h21
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h12
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c26
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h10
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c11
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c33
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h13
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h9
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h6
38 files changed, 740 insertions, 256 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
index a1247ab5e..5d55ad114 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
@@ -737,10 +737,10 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
/* Check the DRI version */
DRIQueryVersion(&major, &minor, &patch);
- if (major != 3 || minor != 0 || patch < 0) {
+ if (major != 4 || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"R128DRIScreenInit failed "
- "(DRI version = %d.%d.%d, expected 3.0.x). "
+ "(DRI version = %d.%d.%d, expected 4.0.x). "
"Disabling DRI.\n",
major, minor, patch);
return FALSE;
@@ -819,6 +819,9 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->MoveBuffers = R128DRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n");
xfree(pDRIInfo->devPrivate);
@@ -832,8 +835,7 @@ Bool R128DRIScreenInit(ScreenPtr pScreen)
version = drmGetVersion(info->drmFD);
if (version) {
if (version->version_major != 2 ||
- version->version_minor != 1 ||
- version->version_patchlevel < 0) {
+ version->version_minor < 1) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"R128DRIScreenInit failed "
@@ -956,6 +958,7 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen)
pR128DRI->agpTexMapSize = info->agpTexMapSize;
pR128DRI->log2AGPTexGran = info->log2AGPTexGran;
pR128DRI->agpTexOffset = info->agpTexStart;
+ pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
return TRUE;
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h
index 5aa4f5056..01857a0e3 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h
@@ -96,6 +96,7 @@ typedef struct {
drmSize agpTexMapSize;
int log2AGPTexGran;
int agpTexOffset;
+ unsigned int sarea_priv_offset;
} R128DRIRec, *R128DRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
index 7a2285200..911122b21 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
@@ -366,6 +366,10 @@ typedef struct {
CARD32 re_width_height;
CARD32 aux_sc_cntl;
+
+#ifdef PER_CONTEXT_SAREA
+ int perctx_sarea_size;
+#endif
#endif
XF86VideoAdaptorPtr adaptor;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
index cad22ad8b..704041d91 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
@@ -244,7 +244,36 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual,
drmContext hwContext, void *pVisualConfigPriv,
DRIContextType contextStore)
{
- /* Nothing yet */
+#ifdef PER_CONTEXT_SAREA
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONDRIContextPtr ctx_info;
+
+ ctx_info = (RADEONDRIContextPtr)contextStore;
+ if (!ctx_info) return FALSE;
+
+ if (drmAddMap(info->drmFD, 0,
+ info->perctx_sarea_size,
+ DRM_SHM,
+ DRM_REMOVABLE,
+ &ctx_info->sarea_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[DRI] could not create private sarea for ctx id (%d)\n",
+ (int)hwContext);
+ return FALSE;
+ }
+
+ if (drmAddContextPrivateMapping(info->drmFD, hwContext,
+ ctx_info->sarea_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[DRI] could not associate private sarea to ctx id (%d)\n",
+ (int)hwContext);
+ drmRmMap(info->drmFD, ctx_info->sarea_handle);
+ return FALSE;
+ }
+
+ ctx_info->ctx_id = hwContext;
+#endif
return TRUE;
}
@@ -252,7 +281,20 @@ static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual,
static void RADEONDestroyContext(ScreenPtr pScreen, drmContext hwContext,
DRIContextType contextStore)
{
- /* Nothing yet */
+#ifdef PER_CONTEXT_SAREA
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONDRIContextPtr ctx_info;
+
+ ctx_info = (RADEONDRIContextPtr) contextStore;
+ if (!ctx_info) return;
+
+ if (drmRmMap(info->drmFD, ctx_info->sarea_handle) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[DRI] could not remove private sarea for ctx id (%d)\n",
+ (int)hwContext);
+ }
+#endif
}
/* Called when the X server is woken up to allow the last client's
@@ -1145,10 +1187,10 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
/* Check the DRI version */
DRIQueryVersion(&major, &minor, &patch);
- if (major != 3 || minor != 0 || patch < 0) {
+ if (major != 4 || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"RADEONDRIScreenInit failed "
- "(DRI version = %d.%d.%d, expected 3.0.x). "
+ "(DRI version = %d.%d.%d, expected 4.0.x). "
"Disabling DRI.\n",
major, minor, patch);
return FALSE;
@@ -1192,6 +1234,11 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
< RADEON_MAX_DRAWABLES
? SAREA_MAX_DRAWABLES
: RADEON_MAX_DRAWABLES);
+#ifdef PER_CONTEXT_SAREA
+ /* This is only here for testing per-context SAREAs. When used, the
+ magic number below would be properly defined in a header file. */
+ info->perctx_sarea_size = 64 * 1024;
+#endif
#ifdef NOT_DONE
/* FIXME: Need to extend DRI protocol to pass this size back to
@@ -1227,6 +1274,9 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n");
xfree(pDRIInfo->devPrivate);
@@ -1240,8 +1290,7 @@ Bool RADEONDRIScreenInit(ScreenPtr pScreen)
version = drmGetVersion(info->drmFD);
if (version) {
if (version->version_major != 1 ||
- version->version_minor != 0 ||
- version->version_patchlevel < 0) {
+ version->version_minor < 0) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"RADEONDRIScreenInit failed "
@@ -1335,6 +1384,7 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
/* Initialize the SAREA private data structure */
pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen);
memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
+
RADEONDRISAREAInit(pScreen, pSAREAPriv);
pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate;
@@ -1369,6 +1419,13 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran;
pRADEONDRI->agpTexOffset = info->agpTexStart;
+ pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+#ifdef PER_CONTEXT_SAREA
+ /* Set per-context SAREA size */
+ pRADEONDRI->perctx_sarea_size = info->perctx_sarea_size;
+#endif
+
return TRUE;
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h
index 27d5be961..bfbc07b40 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h
@@ -96,6 +96,11 @@ typedef struct {
drmSize agpTexMapSize;
int log2AGPTexGran;
int agpTexOffset;
+ unsigned int sarea_priv_offset;
+
+#ifdef PER_CONTEXT_SAREA
+ drmSize perctx_sarea_size;
+#endif
} RADEONDRIRec, *RADEONDRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h
index 9225c5cda..ffbd869c5 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h
@@ -38,6 +38,8 @@
#define _RADEON_DRIPRIV_H_
#include "GL/glxint.h"
+#include "xf86drm.h"
+#include "xf86drmRadeon.h"
#define RADEON_MAX_DRAWABLES 256
@@ -50,8 +52,13 @@ typedef struct {
} RADEONConfigPrivRec, *RADEONConfigPrivPtr;
typedef struct {
+#ifdef PER_CONTEXT_SAREA
+ drmContext ctx_id;
+ drmHandle sarea_handle;
+#else
/* Nothing here yet */
int dummy;
+#endif
} RADEONDRIContextRec, *RADEONDRIContextPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
index 57eb82299..6cf4650f2 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
@@ -351,9 +351,9 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
{
int major, minor, patch;
DRIQueryVersion(&major, &minor, &patch);
- if (major != 3 || minor != 0 || patch < 0) {
+ if (major != 4 || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
- "GLINTDRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n",
+ "GLINTDRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n",
major, minor, patch);
return FALSE;
}
@@ -425,6 +425,9 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->MoveBuffers = GLINTDRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if (!DRIScreenInit(pScreen, pDRIInfo, &(pGlint->drmSubFD))) {
DRIDestroyInfoRec(pGlint->pDRIInfo);
xfree(pGlintDRI);
@@ -436,8 +439,7 @@ GLINTDRIScreenInit(ScreenPtr pScreen)
drmVersionPtr version = drmGetVersion(pGlint->drmSubFD);
if (version) {
if (version->version_major != 1 ||
- version->version_minor != 0 ||
- version->version_patchlevel < 0) {
+ version->version_minor < 0) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"GLINTDRIScreenInit failed (DRM version = %d.%d.%d, expected 1.0.x). Disabling DRI.\n",
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
index 92fbdc925..03ec81480 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c
@@ -68,14 +68,15 @@ Bool I810InitDma(ScrnInfoPtr pScrn)
{
I810Ptr pI810 = I810PTR(pScrn);
I810RingBuffer *ring = &(pI810->LpRing);
+ I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate;
drmI810Init info;
Bool ret_val;
info.start = ring->mem.Start;
info.end = ring->mem.End;
info.size = ring->mem.Size;
- info.ring_map_idx = 6;
- info.buffer_map_idx = 5;
+ info.mmio_offset = (unsigned int)pI810DRI->regs;
+ info.buffers_offset = (unsigned int)pI810->buffer_map;
info.sarea_off = sizeof(XF86DRISAREARec);
info.front_offset = 0;
@@ -203,7 +204,6 @@ static unsigned int mylog2(unsigned int n)
return log2;
}
-
Bool I810DRIScreenInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -240,9 +240,9 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
{
int major, minor, patch;
DRIQueryVersion(&major, &minor, &patch);
- if (major != 3 || minor != 0 || patch < 0) {
+ if (major != 4 || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
- "I810DRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n",
+ "I810DRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n",
major, minor, patch);
return FALSE;
}
@@ -310,6 +310,8 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->MoveBuffers = I810DRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
/* This adds the framebuffer as a drm map *before* we have asked agp
* to allocate it. Scary stuff, hold on...
@@ -328,8 +330,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
drmVersionPtr version = drmGetVersion(pI810->drmSubFD);
if (version) {
if (version->version_major != 1 ||
- version->version_minor != 1 ||
- version->version_patchlevel < 0) {
+ version->version_minor < 1) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"I810DRIScreenInit failed (DRM version = %d.%d.%d, expected 1.0.x). Disabling DRI.\n",
@@ -734,6 +735,7 @@ Bool I810DRIScreenInit(ScreenPtr pScreen)
pI810DRI->auxPitch = pI810->auxPitch;
pI810DRI->auxPitchBits = pI810->auxPitchBits;
+ pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
if (!(I810InitVisualConfigs(pScreen))) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "I810InitVisualConfigs failed\n");
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h
index bbb0cc927..70a32f594 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.h
@@ -50,6 +50,7 @@ typedef struct {
drmBufMapPtr drmBufs;
int irq;
+ unsigned int sarea_priv_offset;
} I810DRIRec, *I810DRIPtr;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
index d6699eb09..73fbb11bd 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c
@@ -927,10 +927,10 @@ Bool MGADRIScreenInit( ScreenPtr pScreen )
{
int major, minor, patch;
DRIQueryVersion( &major, &minor, &patch );
- if ( major != 3 || minor != 0 || patch < 0 ) {
+ if ( major != 4 || minor < 0) {
xf86DrvMsg( pScreen->myNum, X_ERROR,
"[drm] MGADRIScreenInit failed "
- "(DRI version = %d.%d.%d, expected 3.0.x). "
+ "(DRI version = %d.%d.%d, expected 4.0.x). "
"Disabling DRI.\n",
major, minor, patch );
return FALSE;
@@ -973,6 +973,9 @@ Bool MGADRIScreenInit( ScreenPtr pScreen )
pDRIInfo->wrap.ValidateTree = NULL;
pDRIInfo->wrap.PostValidateTree = NULL;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if ( SAREA_MAX_DRAWABLES < MGA_MAX_DRAWABLES ) {
pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
} else {
@@ -1062,8 +1065,7 @@ Bool MGADRIScreenInit( ScreenPtr pScreen )
drmVersionPtr version = drmGetVersion(pMga->drmFD);
if ( version ) {
if ( version->version_major != 3 ||
- version->version_minor != 0 ||
- version->version_patchlevel < 0 ) {
+ version->version_minor < 0) {
/* incompatible drm version */
xf86DrvMsg( pScreen->myNum, X_ERROR,
"[drm] MGADRIScreenInit failed "
@@ -1193,7 +1195,7 @@ Bool MGADRIFinishScreenInit( ScreenPtr pScreen )
pMGADRI->primary.size = pMGADRIServer->primary.size;
pMGADRI->buffers.handle = pMGADRIServer->buffers.handle;
pMGADRI->buffers.size = pMGADRIServer->buffers.size;
-
+ pMGADRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
return TRUE;
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
index b3e72d46f..7e6794348 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.h
@@ -115,7 +115,7 @@ typedef struct {
drmRegion status;
drmRegion primary;
drmRegion buffers;
-
+ unsigned int sarea_priv_offset;
} MGADRIRec, *MGADRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c
index 79cb34251..9dc2feb48 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.c
@@ -194,9 +194,9 @@ Bool SISDRIScreenInit(ScreenPtr pScreen)
{
int major, minor, patch;
DRIQueryVersion(&major, &minor, &patch);
- if (major != 3 || minor != 0 || patch < 0) {
+ if (major != 4 || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] SISDRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n",
+ "[drm] SISDRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n",
major, minor, patch);
return FALSE;
}
@@ -262,6 +262,9 @@ Bool SISDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->MoveBuffers = SISDRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if (!DRIScreenInit(pScreen, pDRIInfo, &pSIS->drmSubFD)) {
xfree(pDRIInfo->devPrivate);
pDRIInfo->devPrivate=0;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c
index b10dd018d..af7d6a1cb 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_dri.c
@@ -260,6 +260,9 @@ FFBDRIScreenInit(ScreenPtr pScreen)
/* Our InitBuffers depends heavily on this setting. */
pDRIInfo->bufferRequests = DRI_3D_WINDOWS_ONLY;
+ pDRIInfo->createDummyCtx = TRUE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if (!DRIScreenInit(pScreen, pDRIInfo, &(pFfb->drmSubFD))) {
DRIDestroyInfoRec(pFfb->pDRIInfo);
xfree(pFfbDRI);
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
index 0ce50455a..5d160998d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
@@ -300,9 +300,9 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen)
{
int major, minor, patch;
DRIQueryVersion(&major, &minor, &patch);
- if (major != 3 || minor != 0 || patch < 0) {
+ if (major != 4 || minor < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
- "TDFXDRIScreenInit failed (DRI version = %d.%d.%d, expected 3.0.x). Disabling DRI.\n",
+ "TDFXDRIScreenInit failed (DRI version = %d.%d.%d, expected 4.0.x). Disabling DRI.\n",
major, minor, patch);
return FALSE;
}
@@ -381,6 +381,9 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->TransitionTo3d = TDFXDRITransitionTo3d;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->createDummyCtx = FALSE;
+ pDRIInfo->createDummyCtxPriv = FALSE;
+
if (!DRIScreenInit(pScreen, pDRIInfo, &pTDFX->drmSubFD)) {
xfree(pDRIInfo->devPrivate);
pDRIInfo->devPrivate=0;
@@ -396,8 +399,7 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen)
drmVersionPtr version = drmGetVersion(pTDFX->drmSubFD);
if (version) {
if (version->version_major != 1 ||
- version->version_minor != 0 ||
- version->version_patchlevel < 0) {
+ version->version_minor < 0) {
/* incompatible drm version */
xf86DrvMsg(pScreen->myNum, X_ERROR,
"TDFXDRIScreenInit failed (DRM version = %d.%d.%d, expected 1.0.x). Disabling DRI.\n",
@@ -489,6 +491,7 @@ TDFXDRIFinishScreenInit(ScreenPtr pScreen)
pTDFXDRI->fbOffset=pTDFX->fbOffset;
pTDFXDRI->backOffset=pTDFX->backOffset;
pTDFXDRI->depthOffset=pTDFX->depthOffset;
+ pTDFXDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
return DRIFinishScreenInit(pScreen);
}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h
index 7da92b83a..96fa44c99 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h
@@ -22,6 +22,7 @@ typedef struct {
int depthOffset;
int textureOffset;
int textureSize;
+ unsigned int sarea_priv_offset;
} TDFXDRIRec, *TDFXDRIPtr;
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
index 30b75e1e3..ddabc2771 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
@@ -138,9 +138,15 @@ typedef enum drm_map_flags {
_DRM_LOCKED = 0x04, /* shared, cached, locked */
_DRM_KERNEL = 0x08, /* kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
- _DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
+ _DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */
+ _DRM_REMOVABLE = 0x40 /* Removable mapping */
} drm_map_flags_t;
+typedef struct drm_ctx_priv_map {
+ unsigned int ctx_id; /* Context requesting private mapping */
+ void *handle; /* Handle of map */
+} drm_ctx_priv_map_t;
+
typedef struct drm_map {
unsigned long offset; /* Requested physical address (0 for SAREA)*/
unsigned long size; /* Requested physical size (bytes) */
@@ -365,6 +371,11 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
+#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
+
+#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t)
+#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t)
+
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
index 4032689a2..a7e4d5732 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h
@@ -73,6 +73,7 @@
#if LINUX_VERSION_CODE < 0x020400
#include "compat-pre24.h"
#endif
+#include <asm/pgalloc.h>
#include "drm.h"
/* DRM template customization defaults
@@ -329,16 +330,19 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
DRM(ioremapfree)( (map)->handle, (map)->size ); \
} while (0)
-#define DRM_FIND_MAP(map, o) \
- do { \
- int i; \
- for ( i = 0 ; i < dev->map_count ; i++ ) { \
- if ( dev->maplist[i]->offset == o ) { \
- map = dev->maplist[i]; \
- break; \
- } \
- } \
- } while (0)
+#define DRM_FIND_MAP(_map, _o) \
+do { \
+ struct list_head *_list; \
+ list_for_each(_list, &dev->maplist->head) { \
+ drm_map_list_t *_r_list; \
+ _r_list = (drm_map_list_t *)_list; \
+ if(_r_list->map && \
+ _r_list->map->offset == (_o)) { \
+ (_map) = _r_list->map; \
+ break; \
+ } \
+ } \
+} while(0)
/* Internal types and structures */
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
@@ -349,6 +353,10 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
+#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
+ (_map) = (_dev)->context_sareas[_ctx]; \
+} while(0)
+
typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@@ -577,6 +585,11 @@ typedef struct drm_sigdata {
drm_hw_lock_t *lock;
} drm_sigdata_t;
+typedef struct drm_map_list {
+ struct list_head head;
+ drm_map_t *map;
+} drm_map_list_t;
+
typedef struct drm_device {
const char *name; /* Simple driver name */
char *unique; /* Unique identifier: e.g., busid */
@@ -609,9 +622,12 @@ typedef struct drm_device {
drm_magic_head_t magiclist[DRM_HASH_SIZE];
/* Memory management */
- drm_map_t **maplist; /* Vector of pointers to regions */
+ drm_map_list_t *maplist; /* Linked list of regions */
int map_count; /* Number of mappable regions */
+ drm_map_t **context_sareas;
+ int max_context;
+
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
drm_lock_data_t lock; /* Information on hardware lock */
@@ -700,9 +716,6 @@ extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long address,
int write_access);
-extern unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access);
extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address,
int write_access);
@@ -714,15 +727,13 @@ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long address,
int write_access);
-extern struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access);
extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address,
int write_access);
#endif
extern void DRM(vm_open)(struct vm_area_struct *vma);
extern void DRM(vm_close)(struct vm_area_struct *vma);
+extern void DRM(vm_shm_close)(struct vm_area_struct *vma);
extern int DRM(mmap_dma)(struct file *filp,
struct vm_area_struct *vma);
extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
@@ -788,6 +799,11 @@ extern int DRM(ctxbitmap_init)( drm_device_t *dev );
extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
#endif
+extern int DRM(setsareactx)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int DRM(getsareactx)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+
/* Drawable IOCTL support (drm_drawable.h) */
extern int DRM(adddraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
@@ -830,6 +846,8 @@ extern int DRM(notifier)(void *priv);
extern int DRM(order)( unsigned long size );
extern int DRM(addmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+extern int DRM(rmmap)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
#if __HAVE_DMA
extern int DRM(addbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h
index b7e27d172..1d5403225 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_bufs.h
@@ -69,6 +69,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t *map;
+ drm_map_list_t *list;
if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
@@ -81,6 +82,14 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
return -EFAULT;
}
+ /* Only allow shared memory to be removable since we only keep enough
+ * book keeping information about shared memory to allow for removal
+ * when processes fork.
+ */
+ if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
+ DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
+ return -EINVAL;
+ }
DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
map->offset, map->size, map->type );
if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
@@ -100,7 +109,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
return -EINVAL;
}
#endif
-#ifdef CONFIG_MTRR
+#ifdef __REALLY_HAVE_MTRR
if ( map->type == _DRM_FRAME_BUFFER ||
(map->flags & _DRM_WRITE_COMBINING) ) {
map->mtrr = mtrr_add( map->offset, map->size,
@@ -111,9 +120,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
break;
case _DRM_SHM:
- map->handle = (void *)DRM(alloc_pages)( DRM(order)( map->size )
- - PAGE_SHIFT,
- DRM_MEM_SAREA );
+ map->handle = vmalloc_32(map->size);
DRM_DEBUG( "%ld %d %p\n",
map->size, DRM(order)( map->size ), map->handle );
if ( !map->handle ) {
@@ -136,22 +143,17 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
return -EINVAL;
}
- down( &dev->struct_sem );
- if ( dev->maplist ) {
- ++dev->map_count;
- dev->maplist = DRM(realloc)( dev->maplist,
- (dev->map_count-1)
- * sizeof(*dev->maplist),
- dev->map_count
- * sizeof(*dev->maplist),
- DRM_MEM_MAPS );
- } else {
- dev->map_count = 1;
- dev->maplist = DRM(alloc)( dev->map_count*sizeof(*dev->maplist),
- DRM_MEM_MAPS );
+ list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
+ if(!list) {
+ DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
}
- dev->maplist[dev->map_count-1] = map;
- up( &dev->struct_sem );
+ memset(list, 0, sizeof(*list));
+ list->map = map;
+
+ down(&dev->struct_sem);
+ list_add(&list->head, &dev->maplist->head);
+ up(&dev->struct_sem);
if ( copy_to_user( (drm_map_t *)arg, map, sizeof(*map) ) )
return -EFAULT;
@@ -164,6 +166,84 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
return 0;
}
+
+/* Remove a map private from list and deallocate resources if the mapping
+ * isn't in use.
+ */
+
+int DRM(rmmap)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ struct list_head *list;
+ drm_map_list_t *r_list;
+ drm_vma_entry_t *pt, *prev;
+ drm_map_t *map;
+ drm_map_t request;
+ int found_maps = 0;
+
+ if (copy_from_user(&request, (drm_map_t *)arg,
+ sizeof(request))) {
+ return -EFAULT;
+ }
+
+ down(&dev->struct_sem);
+ list = &dev->maplist->head;
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *) list;
+
+ if(r_list->map &&
+ r_list->map->handle == request.handle &&
+ r_list->map->flags & _DRM_REMOVABLE) break;
+ }
+
+ /* List has wrapped around to the head pointer, or its empty we didn't
+ * find anything.
+ */
+ if(list == (&dev->maplist->head)) {
+ up(&dev->struct_sem);
+ return -EINVAL;
+ }
+ map = r_list->map;
+ list_del(list);
+ DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
+
+ for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+#if LINUX_VERSION_CODE >= 0x020300
+ if (pt->vma->vm_private_data == map) found_maps++;
+#else
+ if (pt->vma->vm_pte == map) found_maps++;
+#endif
+ }
+
+ if(!found_maps) {
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef __REALLY_HAVE_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ DRM(ioremapfree)(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ vfree(map->handle);
+ break;
+ case _DRM_AGP:
+ break;
+ }
+ DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ up(&dev->struct_sem);
+ return 0;
+}
+
#if __HAVE_DMA
#if __REALLY_HAVE_AGP
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h
index e2b6170a8..4ac896ef5 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_context.h
@@ -41,9 +41,13 @@
void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
{
if ( ctx_handle < 0 ) goto failed;
+ if ( !dev->ctx_bitmap ) goto failed;
if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
+ down(&dev->struct_sem);
clear_bit( ctx_handle, dev->ctx_bitmap );
+ dev->context_sareas[ctx_handle] = NULL;
+ up(&dev->struct_sem);
return;
}
failed:
@@ -56,12 +60,37 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
{
int bit;
+ if(!dev->ctx_bitmap) return -1;
+
+ down(&dev->struct_sem);
bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
if ( bit < DRM_MAX_CTXBITMAP ) {
set_bit( bit, dev->ctx_bitmap );
DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
+ if((bit+1) > dev->max_context) {
+ dev->max_context = (bit+1);
+ if(dev->context_sareas) {
+ dev->context_sareas = DRM(realloc)(
+ dev->context_sareas,
+ (dev->max_context - 1) *
+ sizeof(*dev->context_sareas),
+ dev->max_context *
+ sizeof(*dev->context_sareas),
+ DRM_MEM_MAPS);
+ dev->context_sareas[bit] = NULL;
+ } else {
+ /* max_context == 1 at this point */
+ dev->context_sareas = DRM(alloc)(
+ dev->max_context *
+ sizeof(*dev->context_sareas),
+ DRM_MEM_MAPS);
+ dev->context_sareas[bit] = NULL;
+ }
+ }
+ up(&dev->struct_sem);
return bit;
}
+ up(&dev->struct_sem);
return -1;
}
@@ -70,12 +99,18 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
int i;
int temp;
+ down(&dev->struct_sem);
dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
DRM_MEM_CTXBITMAP );
if ( dev->ctx_bitmap == NULL ) {
+ up(&dev->struct_sem);
return -ENOMEM;
}
memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
+ dev->context_sareas = NULL;
+ dev->max_context = -1;
+ up(&dev->struct_sem);
+
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
temp = DRM(ctxbitmap_next)( dev );
DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
@@ -86,9 +121,86 @@ int DRM(ctxbitmap_init)( drm_device_t *dev )
void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
{
+ down(&dev->struct_sem);
+ if( dev->context_sareas ) DRM(free)( dev->context_sareas,
+ sizeof(*dev->context_sareas) *
+ dev->max_context,
+ DRM_MEM_MAPS );
DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
+ up(&dev->struct_sem);
+}
+
+/* ================================================================
+ * Per Context SAREA Support
+ */
+
+int DRM(getsareactx)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_priv_map_t request;
+ drm_map_t *map;
+
+ if (copy_from_user(&request,
+ (drm_ctx_priv_map_t *)arg,
+ sizeof(request)))
+ return -EFAULT;
+
+ down(&dev->struct_sem);
+ if ((int)request.ctx_id >= dev->max_context) {
+ up(&dev->struct_sem);
+ return -EINVAL;
+ }
+
+ map = dev->context_sareas[request.ctx_id];
+ up(&dev->struct_sem);
+
+ request.handle = map->handle;
+ if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request)))
+ return -EFAULT;
+ return 0;
}
+int DRM(setsareactx)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_priv_map_t request;
+ drm_map_t *map = NULL;
+ drm_map_list_t *r_list;
+ struct list_head *list;
+
+ if (copy_from_user(&request,
+ (drm_ctx_priv_map_t *)arg,
+ sizeof(request)))
+ return -EFAULT;
+
+ down(&dev->struct_sem);
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *)list;
+ if(r_list->map &&
+ r_list->map->handle == request.handle) break;
+ }
+ if (list == &(dev->maplist->head)) {
+ up(&dev->struct_sem);
+ return -EINVAL;
+ }
+ map = r_list->map;
+ up(&dev->struct_sem);
+
+ if (!map) return -EINVAL;
+
+ down(&dev->struct_sem);
+ if ((int)request.ctx_id >= dev->max_context) {
+ up(&dev->struct_sem);
+ return -EINVAL;
+ }
+ dev->context_sareas[request.ctx_id] = map;
+ up(&dev->struct_sem);
+ return 0;
+}
/* ================================================================
* The actual DRM context handling routines
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
index c19b63983..7447ca6d4 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
@@ -118,60 +118,64 @@ static struct file_operations DRM(fops) = {
};
-static drm_ioctl_desc_t DRM(ioctls)[] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 },
+static drm_ioctl_desc_t DRM(ioctls)[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { DRM(rmmap), 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 },
#if __HAVE_DMA
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 },
/* The DRM_IOCTL_DMA ioctl should be defined by the driver.
*/
#if __HAVE_DMA_IRQ
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 },
#endif
#endif
#if __REALLY_HAVE_AGP
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
#endif
DRIVER_IOCTLS
@@ -262,8 +266,14 @@ static int DRM(setup)( drm_device_t *dev )
dev->magiclist[i].head = NULL;
dev->magiclist[i].tail = NULL;
}
- dev->maplist = NULL;
+
+ dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ if(dev->maplist == NULL) return -ENOMEM;
+ memset(dev->maplist, 0, sizeof(*dev->maplist));
+ INIT_LIST_HEAD(&dev->maplist->head);
dev->map_count = 0;
+
dev->vmalist = NULL;
dev->lock.hw_lock = NULL;
init_waitqueue_head( &dev->lock.lock_queue );
@@ -307,6 +317,8 @@ static int DRM(takedown)( drm_device_t *dev )
{
drm_magic_entry_t *pt, *next;
drm_map_t *map;
+ drm_map_list_t *r_list;
+ struct list_head *list;
drm_vma_entry_t *vma, *vma_next;
int i;
@@ -373,10 +385,13 @@ static int DRM(takedown)( drm_device_t *dev )
dev->vmalist = NULL;
}
- /* Clear map area and mtrr information */
- if ( dev->maplist ) {
- for ( i = 0 ; i < dev->map_count ; i++ ) {
- map = dev->maplist[i];
+ if( dev->maplist ) {
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *)list;
+ map = r_list->map;
+ DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
+ if(!map) continue;
+
switch ( map->type ) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
@@ -392,25 +407,20 @@ static int DRM(takedown)( drm_device_t *dev )
DRM(ioremapfree)( map->handle, map->size );
break;
case _DRM_SHM:
- DRM(free_pages)( (unsigned long)map->handle,
- DRM(order)( map->size )
- - PAGE_SHIFT,
- DRM_MEM_SAREA );
+ vfree(map->handle);
break;
+
case _DRM_AGP:
/* Do nothing here, because this is all
* handled in the AGP/GART driver.
*/
break;
}
- DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
- }
- DRM(free)( dev->maplist,
- dev->map_count * sizeof(*dev->maplist),
- DRM_MEM_MAPS );
+ DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
dev->maplist = NULL;
- dev->map_count = 0;
- }
+ }
#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES
if ( dev->queuelist ) {
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h
index ce6ac2e68..2fba6b0c2 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_ioctl.h
@@ -105,22 +105,40 @@ int DRM(getmap)( struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t map;
+ drm_map_list_t *r_list = NULL;
+ struct list_head *list;
int idx;
+ int i;
if (copy_from_user(&map, (drm_map_t *)arg, sizeof(map)))
return -EFAULT;
idx = map.offset;
+
down(&dev->struct_sem);
if (idx < 0 || idx >= dev->map_count) {
up(&dev->struct_sem);
return -EINVAL;
}
- map.offset = dev->maplist[idx]->offset;
- map.size = dev->maplist[idx]->size;
- map.type = dev->maplist[idx]->type;
- map.flags = dev->maplist[idx]->flags;
- map.handle = dev->maplist[idx]->handle;
- map.mtrr = dev->maplist[idx]->mtrr;
+
+ i = 0;
+ list_for_each(list, &dev->maplist->head) {
+ if(i == idx) {
+ r_list = (drm_map_list_t *)list;
+ break;
+ }
+ i++;
+ }
+ if(!r_list || !r_list->map) {
+ up(&dev->struct_sem);
+ return -EINVAL;
+ }
+
+ map.offset = r_list->map->offset;
+ map.size = r_list->map->size;
+ map.type = r_list->map->type;
+ map.flags = r_list->map->flags;
+ map.handle = r_list->map->handle;
+ map.mtrr = r_list->map->mtrr;
up(&dev->struct_sem);
if (copy_to_user((drm_map_t *)arg, &map, sizeof(map))) return -EFAULT;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h
index ee9c0cbc8..f65f42b71 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_proc.h
@@ -165,6 +165,9 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
drm_map_t *map;
+ drm_map_list_t *r_list;
+ struct list_head *list;
+
/* Hardcoded from _DRM_FRAME_BUFFER,
_DRM_REGISTERS, _DRM_SHM, and
_DRM_AGP. */
@@ -182,8 +185,11 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
DRM_PROC_PRINT("slot offset size type flags "
"address mtrr\n\n");
- for (i = 0; i < dev->map_count; i++) {
- map = dev->maplist[i];
+ i = 0;
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *)list;
+ map = r_list->map;
+ if(!map) continue;
if (map->type < 0 || map->type > 3) type = "??";
else type = types[map->type];
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
@@ -198,6 +204,7 @@ static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
} else {
DRM_PROC_PRINT("%4d\n", map->mtrr);
}
+ i++;
}
if (len > request + offset) return request;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h
index 347816ac3..123eea299 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_vm.h
@@ -41,13 +41,7 @@ struct vm_operations_struct drm_vm_ops = {
struct vm_operations_struct drm_vm_shm_ops = {
nopage: DRM(vm_shm_nopage),
open: DRM(vm_open),
- close: DRM(vm_close),
-};
-
-struct vm_operations_struct drm_vm_shm_lock_ops = {
- nopage: DRM(vm_shm_nopage_lock),
- open: DRM(vm_open),
- close: DRM(vm_close),
+ close: DRM(vm_shm_close),
};
struct vm_operations_struct drm_vm_dma_ops = {
@@ -88,12 +82,26 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
#endif
unsigned long physical;
unsigned long offset;
+ unsigned long i;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map) return NOPAGE_OOM; /* Nothing allocated */
offset = address - vma->vm_start;
- physical = (unsigned long)map->handle + offset;
+ i = (unsigned long)map->handle + offset;
+ /* We have to walk page tables here because we need large SAREA's, and
+ * they need to be virtually contigious in kernel space.
+ */
+ pgd = pgd_offset_k( i );
+ if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
+ pmd = pmd_offset( pgd, i );
+ if( !pmd_present( *pmd ) ) return NOPAGE_OOM;
+ pte = pte_offset( pmd, i );
+ if( !pte_present( *pte ) ) return NOPAGE_OOM;
+ physical = (unsigned long)pte_page( *pte )->virtual;
atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
@@ -104,37 +112,87 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
#endif
}
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access)
-#else
- /* Return type changed in 2.3.23 */
-struct page *DRM(vm_shm_nopage_lock)(struct vm_area_struct *vma,
- unsigned long address,
- int write_access)
-#endif
+/* Special close routine which deletes map information if we are the last
+ * person to close a mapping and its not in the global maplist.
+ */
+
+void DRM(vm_shm_close)(struct vm_area_struct *vma)
{
- drm_file_t *priv = vma->vm_file->private_data;
- drm_device_t *dev = priv->dev;
- unsigned long physical;
- unsigned long offset;
- unsigned long page;
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_vma_entry_t *pt, *prev;
+ drm_map_t *map;
+ drm_map_list_t *r_list;
+ struct list_head *list;
+ int found_maps = 0;
- if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
- if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */
+ DRM_DEBUG("0x%08lx,0x%08lx\n",
+ vma->vm_start, vma->vm_end - vma->vm_start);
+#if LINUX_VERSION_CODE < 0x020333
+ MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+ atomic_dec(&dev->vma_count);
- offset = address - vma->vm_start;
- page = offset >> PAGE_SHIFT;
- physical = (unsigned long)dev->lock.hw_lock + offset;
- atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+#if LINUX_VERSION_CODE >= 0x020300
+ map = vma->vm_private_data;
+#else
+ map = vma->vm_pte;
+#endif
- DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
-#if LINUX_VERSION_CODE < 0x020317
- return physical;
+ down(&dev->struct_sem);
+ for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+#if LINUX_VERSION_CODE >= 0x020300
+ if (pt->vma->vm_private_data == map) found_maps++;
#else
- return virt_to_page(physical);
+ if (pt->vma->vm_pte == map) found_maps++;
#endif
+ if (pt->vma == vma) {
+ if (prev) {
+ prev->next = pt->next;
+ } else {
+ dev->vmalist = pt->next;
+ }
+ DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
+ }
+ }
+ /* We were the only map that was found */
+ if(found_maps == 1 &&
+ map->flags & _DRM_REMOVABLE) {
+ /* Check to see if we are in the maplist, if we are not, then
+ * we delete this mappings information.
+ */
+ found_maps = 0;
+ list = &dev->maplist->head;
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *) list;
+ if (r_list->map == map) found_maps++;
+ }
+
+ if(!found_maps) {
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef __REALLY_HAVE_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ DRM(ioremapfree)(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ vfree(map->handle);
+ break;
+ case _DRM_AGP:
+ break;
+ }
+ DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ }
+ up(&dev->struct_sem);
}
#if LINUX_VERSION_CODE < 0x020317
@@ -176,9 +234,7 @@ void DRM(vm_open)(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
-#if DRM_DEBUG_CODE
drm_vma_entry_t *vma_entry;
-#endif
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
@@ -188,8 +244,6 @@ void DRM(vm_open)(struct vm_area_struct *vma)
MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
#endif
-
-#if DRM_DEBUG_CODE
vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
if (vma_entry) {
down(&dev->struct_sem);
@@ -199,16 +253,13 @@ void DRM(vm_open)(struct vm_area_struct *vma)
dev->vmalist = vma_entry;
up(&dev->struct_sem);
}
-#endif
}
void DRM(vm_close)(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
-#if DRM_DEBUG_CODE
drm_vma_entry_t *pt, *prev;
-#endif
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
@@ -217,7 +268,6 @@ void DRM(vm_close)(struct vm_area_struct *vma)
#endif
atomic_dec(&dev->vma_count);
-#if DRM_DEBUG_CODE
down(&dev->struct_sem);
for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
if (pt->vma == vma) {
@@ -231,7 +281,6 @@ void DRM(vm_close)(struct vm_area_struct *vma)
}
}
up(&dev->struct_sem);
-#endif
}
int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma)
@@ -272,7 +321,8 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t *map = NULL;
- int i;
+ drm_map_list_t *r_list;
+ struct list_head *list;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
@@ -286,12 +336,13 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
once, so it doesn't have to be optimized
for performance, even if the list was a
bit longer. */
- for (i = 0; i < dev->map_count; i++) {
- map = dev->maplist[i];
+ list_for_each(list, &dev->maplist->head) {
+ r_list = (drm_map_list_t *)list;
+ map = r_list->map;
+ if (!map) continue;
if (map->offset == VM_OFFSET(vma)) break;
}
- if (i >= dev->map_count) return -EINVAL;
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
@@ -339,17 +390,12 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
- if (map->flags & _DRM_CONTAINS_LOCK)
- vma->vm_ops = &drm_vm_shm_lock_ops;
- else {
- vma->vm_ops = &drm_vm_shm_ops;
+ vma->vm_ops = &drm_vm_shm_ops;
#if LINUX_VERSION_CODE >= 0x020300
- vma->vm_private_data = (void *)map;
+ vma->vm_private_data = (void *)map;
#else
- vma->vm_pte = (unsigned long)map;
+ vma->vm_pte = (unsigned long)map;
#endif
- }
-
/* Don't let this area swap. Change when
DRM_KERNEL advisory is supported. */
vma->vm_flags |= VM_LOCKED;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h
index 383c54af5..232ed018b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h
@@ -68,17 +68,23 @@
#define __HAVE_DMA_IRQ 1
#define __HAVE_DMA_IRQ_BH 1
#define DRIVER_PREINSTALL() do { \
+ drm_gamma_private_t *dev_priv = \
+ (drm_gamma_private_t *)dev->dev_private;\
GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \
} while (0)
#define DRIVER_POSTINSTALL() do { \
+ drm_gamma_private_t *dev_priv = \
+ (drm_gamma_private_t *)dev->dev_private;\
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \
} while (0)
#define DRIVER_UNINSTALL() do { \
+ drm_gamma_private_t *dev_priv = \
+ (drm_gamma_private_t *)dev->dev_private;\
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c
index 2238d1268..d3a9414d7 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c
@@ -41,6 +41,9 @@
static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
unsigned long length)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address));
while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
;
@@ -49,6 +52,9 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
void gamma_dma_quiescent_single(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
while (GAMMA_READ(GAMMA_DMACOUNT))
;
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
@@ -65,6 +71,9 @@ void gamma_dma_quiescent_single(drm_device_t *dev)
void gamma_dma_quiescent_dual(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
while (GAMMA_READ(GAMMA_DMACOUNT))
;
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
@@ -90,19 +99,27 @@ void gamma_dma_quiescent_dual(drm_device_t *dev)
void gamma_dma_ready(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
while (GAMMA_READ(GAMMA_DMACOUNT))
;
}
static inline int gamma_dma_is_ready(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
return !GAMMA_READ(GAMMA_DMACOUNT);
}
void gamma_dma_service(int irq, void *device, struct pt_regs *regs)
{
- drm_device_t *dev = (drm_device_t *)device;
- drm_device_dma_t *dma = dev->dma;
+ drm_device_t *dev = (drm_device_t *)device;
+ drm_device_dma_t *dma = dev->dma;
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */
GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h
index d8cca6676..68b520700 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h
@@ -35,6 +35,10 @@
typedef struct drm_gamma_private {
drm_map_t *buffers;
+ drm_map_t *mmio0;
+ drm_map_t *mmio1;
+ drm_map_t *mmio2;
+ drm_map_t *mmio3;
} drm_gamma_private_t;
#define LOCK_TEST_WITH_RETURN( dev ) \
@@ -60,16 +64,6 @@ extern int gamma_find_devices(void);
extern int gamma_found(void);
-/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the
- kernel must be specified here. Currently, the number is 2. This must
- match the order the X server uses for instantiating register regions ,
- or must be passed in a new ioctl. */
-#define GAMMA_REG(reg) \
- (2 \
- + ((reg < 0x1000) \
- ? 0 \
- : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3))))
-
#define GAMMA_OFF(reg) \
((reg < 0x1000) \
? reg \
@@ -79,7 +73,12 @@ extern int gamma_found(void);
? (reg - 0x10000) \
: (reg - 0x11000))))
-#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle)
+#define GAMMA_BASE(reg) ((unsigned long) \
+ ((reg < 0x1000) ? dev_priv->mmio0->handle : \
+ ((reg < 0x10000) ? dev_priv->mmio1->handle : \
+ ((reg < 0x11000) ? dev_priv->mmio2->handle : \
+ dev_priv->mmio3->handle))))
+
#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg))
#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
#define GAMMA_READ(reg) GAMMA_DEREF(reg)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h
index 303ddd5ee..ed25b2a99 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h
@@ -63,6 +63,8 @@
#define __HAVE_DMA_IRQ 1
#define __HAVE_DMA_IRQ_BH 1
#define DRIVER_PREINSTALL() do { \
+ drm_i810_private_t *dev_priv = \
+ (drm_i810_private_t *)dev->dev_private; \
u16 tmp; \
tmp = I810_READ16( I810REG_HWSTAM ); \
tmp = tmp & 0x6000; \
@@ -77,6 +79,8 @@
} while (0)
#define DRIVER_POSTINSTALL() do { \
+ drm_i810_private_t *dev_priv = \
+ (drm_i810_private_t *)dev->dev_private; \
u16 tmp; \
tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
tmp = tmp & 0x6000; \
@@ -85,6 +89,8 @@
} while (0)
#define DRIVER_UNINSTALL() do { \
+ drm_i810_private_t *dev_priv = \
+ (drm_i810_private_t *)dev->dev_private; \
u16 tmp; \
tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \
tmp = tmp & ~(0x6000); /* Clear all interrupts */ \
@@ -101,10 +107,6 @@
#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t
#define DRIVER_AGP_BUFFERS_MAP( dev ) \
-({ \
- drm_i810_private_t *dev_priv = (dev)->dev_private; \
- drm_map_t *map = (dev)->maplist[dev_priv->buffer_map_idx]; \
- map; \
-})
+ ((drm_i810_private_t *)((dev)->dev_private))->buffer_map
#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
index e27406a62..4c90496a7 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c
@@ -396,23 +396,26 @@ static int i810_dma_initialize(drm_device_t *dev,
drm_i810_private_t *dev_priv,
drm_i810_init_t *init)
{
- drm_map_t *sarea_map;
+ struct list_head *list;
dev->dev_private = (void *) dev_priv;
memset(dev_priv, 0, sizeof(drm_i810_private_t));
- if (init->ring_map_idx >= dev->map_count ||
- init->buffer_map_idx >= dev->map_count) {
- i810_dma_cleanup(dev);
- DRM_ERROR("ring_map or buffer_map are invalid\n");
- return -EINVAL;
- }
+ list_for_each(list, &dev->maplist->head) {
+ drm_map_list_t *r_list = (drm_map_list_t *)list;
+ if( r_list->map &&
+ r_list->map->type == _DRM_SHM &&
+ r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+ dev_priv->sarea_map = r_list->map;
+ break;
+ }
+ }
+
+ DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset );
+ DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset );
- dev_priv->ring_map_idx = init->ring_map_idx;
- dev_priv->buffer_map_idx = init->buffer_map_idx;
- sarea_map = dev->maplist[0];
dev_priv->sarea_priv = (drm_i810_sarea_t *)
- ((u8 *)sarea_map->handle +
+ ((u8 *)dev_priv->sarea_map->handle +
init->sarea_priv_offset);
atomic_set(&dev_priv->flush_done, 0);
@@ -865,6 +868,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
void i810_dma_service(int irq, void *device, struct pt_regs *regs)
{
drm_device_t *dev = (drm_device_t *)device;
+ drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
u16 temp;
atomic_inc(&dev->counts[_DRM_STAT_IRQ]);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
index c5f51c9ad..cee189b7b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm.h
@@ -98,8 +98,8 @@ typedef struct _drm_i810_init {
I810_INIT_DMA = 0x01,
I810_CLEANUP_DMA = 0x02
} func;
- int ring_map_idx;
- int buffer_map_idx;
+ unsigned int mmio_offset;
+ unsigned int buffers_offset;
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
index 43d44e028..e1b17148e 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h
@@ -54,11 +54,12 @@ typedef struct _drm_i810_ring_buffer{
} drm_i810_ring_buffer_t;
typedef struct drm_i810_private {
- int ring_map_idx;
- int buffer_map_idx;
+ drm_map_t *sarea_map;
+ drm_map_t *buffer_map;
+ drm_map_t *mmio_map;
- drm_i810_ring_buffer_t ring;
drm_i810_sarea_t *sarea_priv;
+ drm_i810_ring_buffer_t ring;
unsigned long hw_status_page;
unsigned long counter;
@@ -108,9 +109,8 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-#define I810_REG(reg) 2
#define I810_BASE(reg) ((unsigned long) \
- dev->maplist[I810_REG(reg)]->handle)
+ dev_priv->mmio_map->handle)
#define I810_ADDR(reg) (I810_BASE(reg) + reg)
#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
#define I810_READ(reg) I810_DEREF(reg)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
index c76e54eb4..ec80fb417 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c
@@ -436,6 +436,7 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
{
drm_mga_private_t *dev_priv;
+ struct list_head *list;
int ret;
DRM_DEBUG( "%s\n", __FUNCTION__ );
@@ -467,7 +468,15 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
dev_priv->depth_offset = init->depth_offset;
dev_priv->depth_pitch = init->depth_pitch;
- dev_priv->sarea = dev->maplist[0];
+ list_for_each(list, &dev->maplist->head) {
+ drm_map_list_t *r_list = (drm_map_list_t *)list;
+ if( r_list->map &&
+ r_list->map->type == _DRM_SHM &&
+ r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+ dev_priv->sarea = r_list->map;
+ break;
+ }
+ }
DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
index 5c67bec9f..c0e20c213 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c
@@ -344,7 +344,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
{
drm_r128_private_t *dev_priv;
- int i;
+ struct list_head *list;
dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
if ( dev_priv == NULL )
@@ -451,15 +451,15 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
(dev_priv->span_offset >> 5));
- /* FIXME: We want multiple shared areas, including one shared
- * only by the X Server and kernel module.
- */
- for ( i = 0 ; i < dev->map_count ; i++ ) {
- if ( dev->maplist[i]->type == _DRM_SHM ) {
- dev_priv->sarea = dev->maplist[i];
- break;
- }
- }
+ list_for_each(list, &dev->maplist->head) {
+ drm_map_list_t *r_list = (drm_map_list_t *)list;
+ if( r_list->map &&
+ r_list->map->type == _DRM_SHM &&
+ r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+ dev_priv->sarea = r_list->map;
+ break;
+ }
+ }
DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
index cea8c327a..ed8b1bbca 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
@@ -601,7 +601,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
{
drm_radeon_private_t *dev_priv;
- int i;
+ struct list_head *list;
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
if ( dev_priv == NULL )
@@ -710,15 +710,15 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
RADEON_ROUND_MODE_TRUNC |
RADEON_ROUND_PREC_8TH_PIX);
- /* FIXME: We want multiple shared areas, including one shared
- * only by the X Server and kernel module.
- */
- for ( i = 0 ; i < dev->map_count ; i++ ) {
- if ( dev->maplist[i]->type == _DRM_SHM ) {
- dev_priv->sarea = dev->maplist[i];
- break;
- }
- }
+ list_for_each(list, &dev->maplist->head) {
+ drm_map_list_t *r_list = (drm_map_list_t *)list;
+ if( r_list->map &&
+ r_list->map->type == _DRM_SHM &&
+ r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+ dev_priv->sarea = r_list->map;
+ break;
+ }
+ }
DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
index 73a083e38..a640d5987 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
@@ -513,6 +513,16 @@ int drmAddMap(int fd,
return 0;
}
+int drmRmMap(int fd, drmHandle handle)
+{
+ drm_map_t map;
+
+ map.handle = (void *)handle;
+
+ if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno;
+ return 0;
+}
+
int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
int agp_offset)
{
@@ -1088,6 +1098,29 @@ void *drmGetContextTag(int fd, drmContext context)
return value;
}
+int drmAddContextPrivateMapping(int fd, drmContext ctx_id, drmHandle handle)
+{
+ drm_ctx_priv_map_t map;
+
+ map.ctx_id = ctx_id;
+ map.handle = (void *)handle;
+
+ if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno;
+ return 0;
+}
+
+int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle)
+{
+ drm_ctx_priv_map_t map;
+
+ map.ctx_id = ctx_id;
+
+ if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno;
+ if (handle) *handle = (drmHandle)map.handle;
+
+ return 0;
+}
+
int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size,
drmMapType *type, drmMapFlags *flags, drmHandle *handle,
int *mtrr)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
index d5a7e2263..fb632a481 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmI810.c
@@ -70,8 +70,8 @@ Bool drmI810InitDma(int driSubFD, drmI810Init *info)
memset(&init, 0, sizeof(drm_i810_init_t));
init.func = I810_INIT_DMA;
- init.ring_map_idx = info->ring_map_idx;
- init.buffer_map_idx = info->buffer_map_idx;
+ init.mmio_offset = info->mmio_offset;
+ init.buffers_offset = info->buffers_offset;
init.ring_start = info->start;
init.ring_end = info->end;
init.ring_size = info->size;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
index 30b75e1e3..ddabc2771 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h
@@ -138,9 +138,15 @@ typedef enum drm_map_flags {
_DRM_LOCKED = 0x04, /* shared, cached, locked */
_DRM_KERNEL = 0x08, /* kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
- _DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
+ _DRM_CONTAINS_LOCK = 0x20, /* SHM page that contains lock */
+ _DRM_REMOVABLE = 0x40 /* Removable mapping */
} drm_map_flags_t;
+typedef struct drm_ctx_priv_map {
+ unsigned int ctx_id; /* Context requesting private mapping */
+ void *handle; /* Handle of map */
+} drm_ctx_priv_map_t;
+
typedef struct drm_map {
unsigned long offset; /* Requested physical address (0 for SAREA)*/
unsigned long size; /* Requested physical size (bytes) */
@@ -365,6 +371,11 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
+#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
+
+#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t)
+#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t)
+
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
index 83753c90c..180e15844 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -102,7 +102,8 @@ typedef enum {
DRM_LOCKED = 0x0004, /* Physical pages locked */
DRM_KERNEL = 0x0008, /* Kernel requires access */
DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */
- DRM_CONTAINS_LOCK = 0x0020 /* SHM page that contains lock */
+ DRM_CONTAINS_LOCK = 0x0020, /* SHM page that contains lock */
+ DRM_REMOVABLE = 0x0040 /* Removable mapping */
} drmMapFlags;
typedef enum { /* These values *MUST* match drm.h */
@@ -425,6 +426,10 @@ extern int drmAddMap(int fd,
drmMapType type,
drmMapFlags flags,
drmHandlePtr handle);
+extern int drmRmMap(int fd, drmHandle handle);
+extern int drmAddContextPrivateMapping(int fd, drmContext ctx_id,
+ drmHandle handle);
+
extern int drmAddBufs(int fd, int count, int size,
drmBufDescFlags flags,
int agp_offset);
@@ -467,6 +472,8 @@ extern int drmGetLock(int fd,
drmLockFlags flags);
extern int drmUnlock(int fd, drmContext context);
extern int drmFinish(int fd, int context, drmLockFlags flags);
+extern int drmGetContextPrivateMapping(int fd, drmContext ctx_id,
+ drmHandlePtr handle);
/* AGP/GART support: X server (root) only */
extern int drmAgpAcquire(int fd);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
index 6c11b7a10..32927453b 100644
--- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmI810.h
@@ -25,9 +25,9 @@
typedef struct _drmI810Init {
unsigned int start;
unsigned int end;
- unsigned int size;
- int ring_map_idx;
- int buffer_map_idx;
+ unsigned int size;
+ unsigned int mmio_offset;
+ unsigned int buffers_offset;
int sarea_off;
unsigned int front_offset;