? 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