? drm_internal.h
? size
Index: drmP.h
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drmP.h,v
retrieving revision 1.28
diff -u -b -r1.28 drmP.h
--- drmP.h	9 Jun 2008 06:49:55 -0000	1.28
+++ drmP.h	17 Jun 2008 20:48:44 -0000
@@ -59,6 +59,7 @@
 #include <sys/param.h>
 #include <sys/queue.h>
 #include <sys/malloc.h>
+#include <sys/extent.h>
 #include <sys/kernel.h>
 #ifdef __FreeBSD__
 #include <sys/module.h>
@@ -136,6 +137,7 @@
 #include "drm.h"
 #include "drm_linux_list.h"
 #include "drm_atomic.h"
+#include "drm_netbsd.h"
 
 #if defined(__FreeBSD__) || defined(__NetBSD__)
 #if defined(_KERNEL_OPT)
@@ -238,13 +240,17 @@
 #define DRM_STRUCTPROC		struct proc
 #define DRM_STRUCTCDEVPROC	struct lwp
 #define DRM_SPINTYPE		kmutex_t
-#define DRM_SPININIT(l,name)	mutex_init(l, MUTEX_DEFAULT, IPL_VM)
+#define DRM_SPININIT(l,name)	mutex_init(l, MUTEX_DEFAULT, IPL_NONE)
 #define DRM_SPINUNINIT(l)	mutex_destroy(l)
 #define DRM_SPINLOCK(l)		mutex_enter(l)
 #define DRM_SPINUNLOCK(u)	mutex_exit(u)
-#define DRM_SPINLOCK_ASSERT(l)	mutex_owned(l)
-#define DRM_LOCK()		DRM_SPINLOCK(&dev->dev_lock)
-#define DRM_UNLOCK() 		DRM_SPINUNLOCK(&dev->dev_lock)
+#ifdef LOCKDEBUG
+#define DRM_SPINLOCK_ASSERT(l)	KASSERT(mutex_owned(l))
+#else
+#define DRM_SPINLOCK_ASSERT(l)	do {} while (0)
+#endif
+#define DRM_LOCK()		mutex_enter(&dev->dev_lock)
+#define DRM_UNLOCK() 		mutex_exit(&dev->dev_lock)
 #define DRM_CURRENTPID		curproc->p_pid
 #define DRM_SYSCTL_HANDLER_ARGS	(SYSCTLFN_ARGS)
 #else
@@ -515,11 +521,11 @@
 #define DRM_WAIT_ON( ret, queue, timeout, condition )		\
 for ( ret = 0 ; !ret && !(condition) ; ) {			\
 	DRM_UNLOCK();						\
-	mutex_enter(&dev->irq_lock);				\
+	mutex_spin_enter(&dev->irq_lock);			\
 	if (!(condition))					\
 	   ret = mtsleep(&(queue), PZERO | PCATCH, 		\
 			 "drmwtq", (timeout), &dev->irq_lock);	\
-	mutex_exit(&dev->irq_lock);				\
+	mutex_spin_exit(&dev->irq_lock);			\
 	DRM_LOCK();						\
 }
 #else
@@ -614,13 +620,10 @@
 typedef struct drm_dma_handle {
 	void *vaddr;
 	bus_addr_t busaddr;
-	bus_dma_tag_t dmat;
-	bus_dmamap_t map;
-	bus_dma_segment_t segs[1];
+
 	size_t size;
-	void *addr;
+	struct drm_dmamem	*mem;
 } drm_dma_handle_t;
-#define DRM_PCI_DMAADDR(p)   ((p)->map->dm_segs[0].ds_addr)
 
 typedef struct drm_buf_entry {
 	int		  buf_size;
@@ -702,7 +705,11 @@
 	void            *virtual;
 	int             pages;
 	dma_addr_t	*busaddr;
-	drm_dma_handle_t *dmah;	/* Handle to PCI memory for ATI PCIGART table */
+/*
+ * Handle to PCI memory for GART table
+ */
+	drm_dma_handle_t 	*dmah;
+	struct drm_dmamem 	*mem;
 } drm_sg_mem_t;
 
 typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t;
@@ -726,6 +733,8 @@
 #ifdef __NetBSD__
 	int		*cnt;
 	bus_size_t	mapsize;
+	u_long		cookie;   /* mmap cookie */
+	struct drm_dmamem *mem;
 #endif
 	TAILQ_ENTRY(drm_local_map) link;
 } drm_local_map_t;
@@ -934,6 +943,10 @@
 	void		  *dev_private;
 	unsigned int	  agp_buffer_token;
 	drm_local_map_t   *agp_buffer_map;
+
+#if defined(__NetBSD__)
+	struct extent	  *ex;	/* Extent map for mmap cookies */
+#endif
 };
 
 extern int	drm_debug_flag;
@@ -979,8 +992,14 @@
 #endif /* __NetBSD__ || __OpenBSD__ */
 
 /* Memory management support (drm_memory.c) */
-void	drm_mem_init(void);
-void	drm_mem_uninit(void);
+
+/*
+ * XXX The drm_mem_init/uninit functions originally took void arguments.
+ *     However, these are sensible places to create/destroy the mmap cookie
+ *     extent map, and so they now take a pointer to the "drm device".
+ */
+void	drm_mem_init(struct drm_device *);
+void	drm_mem_uninit(struct drm_device *);
 void	*drm_alloc(size_t size, int area);
 void	*drm_calloc(size_t nmemb, size_t size, int area);
 void	*drm_realloc(void *oldpt, size_t oldsize, size_t size,
@@ -1154,9 +1173,12 @@
 {
 	drm_local_map_t *map;
 
+	/* NOTE: this code must be remain in harmony with related code
+	 *  in drm_mmap(), drm_addmap_ioctl(), and/or drm_rmmap().
+	 */ 
 	DRM_SPINLOCK_ASSERT(&dev->dev_lock);
 	TAILQ_FOREACH(map, &dev->maplist, link) {
-		if (map->offset == offset)
+		if (map->cookie == offset)
 			return map;
 	}
 	return NULL;
Index: drm_auth.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_auth.c,v
retrieving revision 1.4
diff -u -b -r1.4 drm_auth.c
--- drm_auth.c	11 Dec 2007 11:17:31 -0000	1.4
+++ drm_auth.c	17 Jun 2008 20:48:44 -0000
@@ -79,7 +79,6 @@
 	entry->priv  = priv;
 	entry->next  = NULL;
 
-	DRM_LOCK();
 	if (dev->magiclist[hash].tail) {
 		dev->magiclist[hash].tail->next = entry;
 		dev->magiclist[hash].tail	= entry;
@@ -87,7 +86,6 @@
 		dev->magiclist[hash].head	= entry;
 		dev->magiclist[hash].tail	= entry;
 	}
-	DRM_UNLOCK();
 
 	return 0;
 }
Index: drm_bufs.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_bufs.c,v
retrieving revision 1.7
diff -u -b -r1.7 drm_bufs.c
--- drm_bufs.c	4 May 2008 20:09:32 -0000	1.7
+++ drm_bufs.c	17 Jun 2008 20:48:45 -0000
@@ -139,8 +139,10 @@
 	 * initialization necessary.
 	 */
 	map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT);
-	if ( !map )
+	if ( !map ) {
+		DRM_LOCK();
 		return DRM_ERR(ENOMEM);
+	}
 
 	map->offset = offset;
 	map->size = size;
@@ -148,6 +150,20 @@
 	map->flags = flags;
 	map->cnt = NULL;	/* cnt, mapsize added for NetBSD port */
 	map->mapsize = 0;
+	map->cookie = 0;
+
+	/* XXX We're not managing any actual address space here; we simply
+	 *     need to assign unique and sane cookies as to not offend
+	 *     the device pager.
+	 */
+	extent_alloc(dev->ex, map->size, PAGE_SIZE, 0, EX_FAST|EX_WAITOK,
+		&map->cookie);
+	if (map->cookie == 0) {
+		DRM_DEBUG("could not allocate entry for mmap cookie in extent map!\n");
+		free(map, M_DRM);
+		DRM_LOCK();
+		return DRM_ERR(ENOMEM);
+	}
 
 	switch ( map->type ) {
 	case _DRM_REGISTERS:
@@ -162,20 +178,22 @@
 #endif
 		break;
 	case _DRM_SHM:
-		map->handle = malloc(map->size, M_DRM, M_NOWAIT);
+		map->mem = drm_dmamem_pgalloc(dev, btop(map->size));
 		DRM_DEBUG( "%lu %d %p\n",
 			   map->size, drm_order(map->size), map->handle );
-		if ( !map->handle ) {
+		if ( map->mem == NULL ) {
 			free(map, M_DRM);
+			DRM_LOCK();
 			return DRM_ERR(ENOMEM);
 		}
-		map->offset = (unsigned long)map->handle;
+		map->handle = map->mem->dd_kva;
+		map->offset = map->mem->dd_dmam->dm_segs[0].ds_addr;
 		if ( map->flags & _DRM_CONTAINS_LOCK ) {
 			/* Prevent a 2nd X Server from creating a 2nd lock */
 			DRM_LOCK();
 			if (dev->lock.hw_lock != NULL) {
 				DRM_UNLOCK();
-				free(map->handle, M_DRM);
+				drm_dmamem_free(map->mem);
 				free(map, M_DRM);
 				return DRM_ERR(EBUSY);
 			}
@@ -197,15 +215,18 @@
 		}
 		if (!valid) {
 			free(map, M_DRM);
+			DRM_LOCK();
 			return DRM_ERR(EACCES);
 		}*/
 		break;
 	case _DRM_SCATTER_GATHER:
 		if (!dev->sg) {
 			free(map, M_DRM);
+			DRM_LOCK();
 			return DRM_ERR(EINVAL);
 		}
 		map->offset = map->offset + dev->sg->handle;
+		map->mem = dev->sg->mem;
 		break;
 	case _DRM_CONSISTENT:
 		/* Unfortunately, we don't get any alignment specification from
@@ -220,14 +241,17 @@
 		map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful);
 		if (map->dmah == NULL) {
 			free(map, M_DRM);
+			DRM_LOCK();
 			return DRM_ERR(ENOMEM);
 		}
 		map->handle = map->dmah->vaddr;
 		map->offset = map->dmah->busaddr;
+		map->mem = map->dmah->mem;
 		break;
 	default:
 		DRM_ERROR("Bad map type %d\n", map->type);
 		free(map, M_DRM);
+		DRM_LOCK();
 		return DRM_ERR(EINVAL);
 	}
 
@@ -274,8 +298,11 @@
 	request.mtrr   = map->mtrr;
 	request.handle = map->handle;
 
+	/* NOTE: ensure this code harmonizes with drm_core_findmap(),
+	 *	 drm_mmap(), and/or drm_rmmap().
+	 */
 	if (request.type != _DRM_SHM) {
-		request.handle = (void *)request.offset;
+		request.handle = (void *)map->cookie;
 	} else {
 		request.handle = (void *)DRM_NETBSD_ADDR2HANDLE((uintptr_t)map->handle);
 	}
@@ -304,7 +331,7 @@
 #endif
 		break;
 	case _DRM_SHM:
-		free(map->handle, M_DRM);
+		drm_dmamem_free(map->mem);
 		break;
 	case _DRM_AGP:
 	case _DRM_SCATTER_GATHER:
@@ -314,6 +341,8 @@
 		break;
 	}
 
+	extent_free(dev->ex, map->cookie, map->size, EX_WAITOK);
+
 	TAILQ_REMOVE(&dev->maplist, map, link);
 	free(map, M_DRM);
 }
@@ -771,7 +800,6 @@
 {
 	int order, ret;
 
-	DRM_SPINLOCK(&dev->dma_lock);
 
 	if (request->count < 0 || request->count > 4096)
 		return DRM_ERR(EINVAL);
@@ -780,6 +808,8 @@
 	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
 		return DRM_ERR(EINVAL);
 
+	DRM_SPINLOCK(&dev->dma_lock);
+
 	/* No more allocations after first buffer-using ioctl. */
 	if (dev->buf_use != 0) {
 		DRM_SPINUNLOCK(&dev->dma_lock);
@@ -802,7 +832,6 @@
 {
 	int order, ret;
 
-	DRM_SPINLOCK(&dev->dma_lock);
 
 	if (!DRM_SUSER(DRM_CURPROC))
 		return DRM_ERR(EACCES);
@@ -814,6 +843,8 @@
 	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
 		return DRM_ERR(EINVAL);
 
+	DRM_SPINLOCK(&dev->dma_lock);
+
 	/* No more allocations after first buffer-using ioctl. */
 	if (dev->buf_use != 0) {
 		DRM_SPINUNLOCK(&dev->dma_lock);
@@ -836,7 +867,6 @@
 {
 	int order, ret;
 
-	DRM_SPINLOCK(&dev->dma_lock);
 
 	if (!DRM_SUSER(DRM_CURPROC))
 		return DRM_ERR(EACCES);
@@ -848,6 +878,8 @@
 	if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
 		return DRM_ERR(EINVAL);
 
+	DRM_SPINLOCK(&dev->dma_lock);
+
 	/* No more allocations after first buffer-using ioctl. */
 	if (dev->buf_use != 0) {
 		DRM_SPINUNLOCK(&dev->dma_lock);
@@ -1052,8 +1084,9 @@
 			retcode = EINVAL;
 			goto done;
 		}
+		/* XXX using cookie, not actual offset here */
 		size = round_page(map->size);
-		foff = map->offset;
+		foff = map->cookie;
 	} else {
 		size = round_page(dma->byte_count),
 		foff = 0;
Index: drm_drv.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_drv.c,v
retrieving revision 1.16
diff -u -b -r1.16 drm_drv.c
--- drm_drv.c	30 May 2008 11:26:21 -0000	1.16
+++ drm_drv.c	17 Jun 2008 20:48:45 -0000
@@ -451,7 +451,7 @@
 
 	TAILQ_INIT(&dev->maplist);
 
-	drm_mem_init();
+	drm_mem_init(dev);
 	drm_sysctl_init(dev);
 	TAILQ_INIT(&dev->files);
 
@@ -552,7 +552,7 @@
 	if (dev->driver.unload != NULL)
 		dev->driver.unload(dev);
 
-	drm_mem_uninit();
+	drm_mem_uninit(dev);
 	DRM_SPINUNINIT(&dev->dev_lock);
 }
 
Index: drm_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_irq.c,v
retrieving revision 1.12
diff -u -b -r1.12 drm_irq.c
--- drm_irq.c	19 May 2008 00:17:39 -0000	1.12
+++ drm_irq.c	17 Jun 2008 20:48:45 -0000
@@ -68,9 +68,9 @@
 	irqreturn_t ret;
 	drm_device_t *dev = (drm_device_t *)arg;
 
-	DRM_SPINLOCK(&dev->irq_lock);
+	mutex_spin_enter(&dev->irq_lock);
 	ret = dev->driver.irq_handler(arg);
-	DRM_SPINUNLOCK(&dev->irq_lock);
+	mutex_spin_exit(&dev->irq_lock);
 	return ret;
 }
 
@@ -94,7 +94,7 @@
 
 	dev->context_flag = 0;
 
-	DRM_SPININIT(&dev->irq_lock, "DRM IRQ lock");
+	mutex_init(&dev->irq_lock, MUTEX_SPIN, IPL_VM);
 
 				/* Before installing handler */
 
@@ -124,7 +124,7 @@
 err:
 	DRM_LOCK();
 	dev->irq_enabled = 0;
-	DRM_SPINUNINIT(&dev->irq_lock);
+	mutex_destroy(&dev->irq_lock);
 	DRM_UNLOCK();
 	return retcode;
 }
@@ -141,7 +141,7 @@
 	dev->driver.irq_uninstall(dev);
 
 	pci_intr_disestablish(dev->pa.pa_pc, dev->irqh);
-	DRM_SPINUNINIT(&dev->irq_lock);
+	mutex_destroy(&dev->irq_lock);
 
 	return 0;
 }
@@ -209,9 +209,9 @@
 
 		vblwait.reply.sequence = atomic_read(&dev->vbl_received);
 		
-		DRM_SPINLOCK(&dev->irq_lock);
+		mutex_spin_enter(&dev->irq_lock);
 		TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
-		DRM_SPINUNLOCK(&dev->irq_lock);
+		mutex_spin_exit(&dev->irq_lock);
 		ret = 0;
 #endif
 		ret = EINVAL;
Index: drm_memory.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_memory.c,v
retrieving revision 1.12
diff -u -b -r1.12 drm_memory.c
--- drm_memory.c	19 May 2008 21:05:37 -0000	1.12
+++ drm_memory.c	17 Jun 2008 20:48:45 -0000
@@ -58,20 +58,23 @@
 MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures");
 #endif
 
-void drm_mem_init(void)
+void drm_mem_init(struct drm_device *dev)
 {
-/*
-	malloc_type_attach(M_DRM);
-*/
+
+	dev->ex = extent_create("drm", 0x00000000, 0x40000000, 
+		M_DRM, NULL, 0, EX_NOWAIT);
+	if (dev->ex == NULL)
+		DRM_DEBUG("could not create extent map!\n");
 }
 
-void drm_mem_uninit(void)
+void drm_mem_uninit(struct drm_device *dev)
 {
+	extent_destroy(dev->ex);
 }
 
 void *drm_alloc(size_t size, int area)
 {
-	return malloc(size, M_DRM, M_NOWAIT);
+	return malloc(1 * size, M_DRM, M_NOWAIT);
 }
 
 void *drm_calloc(size_t nmemb, size_t size, int area)
Index: drm_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_pci.c,v
retrieving revision 1.10
diff -u -b -r1.10 drm_pci.c
--- drm_pci.c	6 May 2008 01:45:47 -0000	1.10
+++ drm_pci.c	17 Jun 2008 20:48:45 -0000
@@ -35,55 +35,22 @@
 drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr)
 {
 	drm_dma_handle_t *h;
-	int error, nsegs;
-
-
-	/* Need power-of-two alignment, so fail the allocation if it isn't. */
-	if ((align & (align - 1)) != 0) {
-		DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n",
-		    (int)align);
-		return NULL;
-	}
 
 	h = malloc(sizeof(drm_dma_handle_t), M_DRM, M_ZERO | M_NOWAIT);
 
 	if (h == NULL)
 		return NULL;
-	if ((error = bus_dmamem_alloc(dev->pa.pa_dmat, size, align, 0,
-	    h->segs, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) {
-		printf("drm: Unable to allocate DMA, error %d\n", error);
-		goto fail;
-	}
-	if ((error = bus_dmamem_map(dev->pa.pa_dmat, h->segs, nsegs, size, 
-	     &h->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
-		printf("drm: Unable to map DMA, error %d\n", error);
-	     	goto free;
-	}
-	if ((error = bus_dmamap_create(dev->pa.pa_dmat, size, 1, size, 0,
-	     BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &h->map)) != 0) {
-		printf("drm: Unable to create DMA map, error %d\n", error);
-		goto unmap;
-	}
-	if ((error = bus_dmamap_load(dev->pa.pa_dmat, h->map, h->addr, size,
-	     NULL, BUS_DMA_NOWAIT)) != 0) {
-		printf("drm: Unable to load DMA map, error %d\n", error);
-		goto destroy;
-	}
-	h->busaddr = DRM_PCI_DMAADDR(h);
-	h->vaddr = h->addr;
-	h->size = size;
-
-	return h;
 
-destroy:
-	bus_dmamap_destroy(dev->pa.pa_dmat, h->map);
-unmap:
-	bus_dmamem_unmap(dev->pa.pa_dmat, h->addr, size);
-free:
-	bus_dmamem_free(dev->pa.pa_dmat, h->segs, 1);
-fail:
+	h->mem = drm_dmamem_pgalloc(dev, round_page(btop(size)));
+	if (h->mem == NULL) {
 	free(h, M_DRM);
 	return NULL;
+	}
+
+	h->busaddr = DRM_DMAMEM_BUSADDR(h->mem);
+	h->vaddr = DRM_DMAMEM_KERNADDR(h->mem);
+
+	return h;
 	
 }
 
@@ -96,10 +63,7 @@
 {
 	if (h == NULL)
 		return;
-	bus_dmamap_unload(dev->pa.pa_dmat, h->map);
-	bus_dmamap_destroy(dev->pa.pa_dmat, h->map);
-	bus_dmamem_unmap(dev->pa.pa_dmat, h->addr, h->size);
-	bus_dmamem_free(dev->pa.pa_dmat, h->segs, 1);
 
+	drm_dmamem_free(h->mem);
 	free(h, M_DRM);
 }
Index: drm_scatter.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_scatter.c,v
retrieving revision 1.4
diff -u -b -r1.4 drm_scatter.c
--- drm_scatter.c	15 Dec 2007 00:39:26 -0000	1.4
+++ drm_scatter.c	17 Jun 2008 20:48:45 -0000
@@ -41,23 +41,27 @@
 
 #define DEBUG_SCATTER 0
 
-void drm_sg_cleanup(drm_sg_mem_t *entry)
+void
+drm_sg_cleanup(drm_sg_mem_t *entry)
 {
-	free((void *)entry->handle, M_DRM);
+	if (entry) {
+		if (entry->mem)
+			drm_dmamem_free(entry->mem);
+		if (entry->busaddr)
 	free(entry->busaddr, M_DRM);
 	free(entry, M_DRM);
 }
+}
 
-int drm_sg_alloc(DRM_IOCTL_ARGS)
+int
+drm_sg_alloc(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
-	drm_scatter_gather_t request;
 	drm_sg_mem_t *entry;
+	drm_scatter_gather_t request;
 	unsigned long pages;
 	int i;
 
-	DRM_DEBUG( "%s\n", __func__ );
-
 	if ( dev->sg )
 		return EINVAL;
 
@@ -80,17 +84,23 @@
 		return ENOMEM;
 	}
 
-	entry->handle = (long)malloc(pages << PAGE_SHIFT, M_DRM,
-	    M_WAITOK | M_ZERO);
-	if (entry->handle == 0) {
+	if ((entry->mem = drm_dmamem_pgalloc(dev, pages)) == NULL) {
 		drm_sg_cleanup(entry);
 		return ENOMEM;
 	}
 
-	for (i = 0; i < pages; i++) {
-		entry->busaddr[i] = vtophys(entry->handle + i * PAGE_SIZE);
+	entry->handle = (unsigned long)entry->mem->dd_kva;
+
+	if (pages != entry->mem->dd_dmam->dm_nsegs) {
+		DRM_DEBUG("pages (%ld) != nsegs (%i)\n", pages,
+			entry->mem->dd_dmam->dm_nsegs);
+		drm_sg_cleanup(entry);
+		return ENOMEM;
 	}
 
+	for (i = 0; i < pages; i++) 
+		entry->busaddr[i] = entry->mem->dd_dmam->dm_segs[i].ds_addr;
+
 	DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
 
 	entry->virtual = (void *)entry->handle;
@@ -112,20 +122,21 @@
 	return 0;
 }
 
-int drm_sg_free(DRM_IOCTL_ARGS)
+int
+drm_sg_free(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_scatter_gather_t request;
 	drm_sg_mem_t *entry;
 
-	DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
-			     sizeof(request) );
-
 	DRM_LOCK();
 	entry = dev->sg;
 	dev->sg = NULL;
 	DRM_UNLOCK();
 
+	DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
+			     sizeof(request) );
+
 	if ( !entry || entry->handle != request.handle )
 		return EINVAL;
 
Index: drm_vm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_vm.c,v
retrieving revision 1.10
diff -u -b -r1.10 drm_vm.c
--- drm_vm.c	4 May 2008 21:43:01 -0000	1.10
+++ drm_vm.c	17 Jun 2008 20:48:45 -0000
@@ -86,13 +86,20 @@
 	roffset = DRM_NETBSD_HANDLE2ADDR(offset);
 	TAILQ_FOREACH(map, &dev->maplist, link) {
 		if (map->type == _DRM_SHM) {
-			if (roffset >= (uintptr_t)map->handle && roffset < (uintptr_t)map->handle + map->size)
+			if ((roffset >= (uintptr_t)map->handle) && 
+			    (roffset < (uintptr_t)map->handle + map->size)) {
+				DRM_DEBUG("found _DRM_SHM map for offset (%lx)\n", roffset);
 				break;
+			}  
 		} else {
-			if (offset >= map->offset && offset < map->offset + map->size)
+			if ((offset >= map->cookie) && 
+		    	    (offset < map->cookie + map->size)) {
+			DRM_DEBUG("found cookie (%lx) for offset (%lx)", map->cookie, offset);
+			offset -= map->cookie;
 				break;
 		}
 	}
+	}
 
 	if (map == NULL) {
 		DRM_UNLOCK();
@@ -111,16 +118,22 @@
 	case _DRM_FRAME_BUFFER:
 	case _DRM_REGISTERS:
 	case _DRM_AGP:
-		phys = offset;
+		phys = offset + map->offset;
 		break;
+	/* All _DRM_CONSISTENT and _DRM_SHM mappings have a 0 offset */
 	case _DRM_CONSISTENT:
-		phys = vtophys((paddr_t)map->handle + (offset - map->offset));
+		return bus_dmamem_mmap(dev->pa.pa_dmat, map->dmah->mem->dd_segs,
+			map->dmah->mem->dd_nsegs, 0, prot, BUS_DMA_NOWAIT|
+			BUS_DMA_NOCACHE);
+	case _DRM_SHM:
+		return bus_dmamem_mmap(dev->pa.pa_dmat, map->mem->dd_segs,
+			map->mem->dd_nsegs, 0, prot, BUS_DMA_NOWAIT);
 		break;
 	case _DRM_SCATTER_GATHER:
-		phys = vtophys(offset);
-		break;
-	case _DRM_SHM:
-		phys = vtophys(DRM_NETBSD_HANDLE2ADDR(offset));
+		return bus_dmamem_mmap(dev->pa.pa_dmat, 
+			dev->sg->mem->dd_segs, dev->sg->mem->dd_nsegs, 
+			map->offset - dev->sg->handle + offset, prot,
+			BUS_DMA_NOWAIT|BUS_DMA_NOCACHE);
 		break;
 	default:
 		DRM_ERROR("bad map type %d\n", type);
@@ -133,4 +146,3 @@
 	return atop(phys);
 #endif
 }
-
Index: files.drm
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/files.drm,v
retrieving revision 1.2
diff -u -b -r1.2 files.drm
--- files.drm	28 Mar 2007 11:29:37 -0000	1.2
+++ files.drm	17 Jun 2008 20:48:45 -0000
@@ -15,6 +15,7 @@
 file   dev/drm/drm_irq.c           drmbase
 file   dev/drm/drm_lock.c          drmbase
 file   dev/drm/drm_memory.c        drmbase
+file   dev/drm/drm_netbsd.c	   drmbase
 file   dev/drm/drm_pci.c           drmbase
 file   dev/drm/drm_scatter.c       drmbase
 file   dev/drm/drm_sysctl.c        drmbase
