Index: dev/drm/drmP.h
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drmP.h,v
retrieving revision 1.32
diff -u -b -r1.32 drmP.h
--- dev/drm/drmP.h      7 Jul 2008 00:33:23 -0000       1.32
+++ dev/drm/drmP.h      10 Aug 2008 00:57:11 -0000
@@ -59,6 +59,7 @@
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/malloc.h>
+#include <sys/vmem.h>
#include <sys/kernel.h>
#ifdef __FreeBSD__
#include <sys/module.h>
@@ -71,6 +72,7 @@
#endif
#include <sys/proc.h>
#include <sys/lock.h>
+#include <sys/condvar.h>
#include <sys/fcntl.h>
#include <sys/uio.h>
#include <sys/filio.h>
@@ -136,6 +138,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)
@@ -206,10 +209,31 @@
#define DRM_DEV_UID    0
#define DRM_DEV_GID    0

-#define wait_queue_head_t      atomic_t
-#define DRM_WAKEUP(w)          wakeup((void *)w)
-#define DRM_WAKEUP_INT(w)      wakeup(w)
-#define DRM_INIT_WAITQUEUE(queue) do {(void)(queue);} while (0)
+typedef struct drm_wait_queue {
+       kcondvar_t      cv;
+       kmutex_t        lock;
+} wait_queue_head_t;
+
+#define        DRM_INIT_WAITQUEUE(q)   \
+{ \
+       mutex_init(&(q)->lock, MUTEX_DEFAULT, IPL_VM); \
+       cv_init(&(q)->cv, "drmwtq");    \
+}
+
+#define        DRM_DESTROY_WAITQUEUE(q)        \
+{ \
+       mutex_destroy(&(q)->lock);      \
+       cv_destroy(&(q)->cv);   \
+}
+
+#define        DRM_WAKEUP(q)   \
+{ \
+       mutex_enter(&(q)->lock); \
+       cv_broadcast(&(q)->cv); \
+       mutex_exit(&(q)->lock); \
+}
+
+#define        DRM_WAKEUP_INT DRM_WAKEUP

#if defined(__FreeBSD__) && __FreeBSD_version < 502109
#define bus_alloc_resource_any(dev, type, rid, flags) \
@@ -238,7 +262,7 @@
#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)
@@ -276,7 +300,7 @@
#define IRQ_NONE               /* nothing */
#elif defined(__NetBSD__)
typedef int                    irqreturn_t;
-#define IRQ_HANDLED            0
+#define IRQ_HANDLED            1
#define IRQ_NONE               0
#endif

@@ -314,8 +338,8 @@
       drm_device_t *dev = (minor(kdev) < DRM_MAXUNITS) ?              \
               drm_units[minor(kdev)] : NULL
#ifdef __x86_64__
-#define DRM_NETBSD_ADDR2HANDLE(addr)   (addr   & 0x7fffffffffffffff)
-#define DRM_NETBSD_HANDLE2ADDR(handle) (handle | 0x8000000000000000)
+#define DRM_NETBSD_ADDR2HANDLE(addr)   ((vaddr_t)(addr) - vm_map_min(kernel_map))
+#define DRM_NETBSD_HANDLE2ADDR(handle) ((vaddr_t)(handle) + vm_map_min(kernel_map))
#else
#define DRM_NETBSD_ADDR2HANDLE(addr)   (addr)
#define DRM_NETBSD_HANDLE2ADDR(handle) (handle)
@@ -389,7 +413,6 @@
                                       "lock; addl $0,0(%%rsp)" : : : "memory");
#endif

-#ifdef __FreeBSD__
#define DRM_READ8(map, offset)                                         \
       *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
#define DRM_READ16(map, offset)                                                \
@@ -404,29 +427,10 @@
       *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val

#define DRM_VERIFYAREA_READ( uaddr, size )             \
-       (!useracc(__DECONST(char *, uaddr), size, VM_PROT_READ))
-
-#else /* __FreeBSD__ */
-
-typedef vaddr_t vm_offset_t;
-
-#define DRM_READ8(map, offset)         \
-       bus_space_read_1( (map)->bst, (map)->bsh, (offset))
-#define DRM_READ16(map, offset)                \
-       bus_space_read_2( (map)->bst, (map)->bsh, (offset))
-#define DRM_READ32(map, offset)                \
-       bus_space_read_4( (map)->bst, (map)->bsh, (offset))
-#define DRM_WRITE8(map, offset, val)   \
-       bus_space_write_1((map)->bst, (map)->bsh, (offset), (val))
-#define DRM_WRITE16(map, offset, val)  \
-       bus_space_write_2((map)->bst, (map)->bsh, (offset), (val))
-#define DRM_WRITE32(map, offset, val)  \
-       bus_space_write_4((map)->bst, (map)->bsh, (offset), (val))
-
-#define DRM_VERIFYAREA_READ( uaddr, size )                             \
       (!uvm_map_checkprot(&(curproc->p_vmspace->vm_map),              \
                           (vaddr_t)uaddr, (vaddr_t)uaddr+size, UVM_PROT_READ))
-#endif /* !__FreeBSD__ */
+
+typedef vaddr_t vm_offset_t;

#define DRM_COPY_TO_USER_IOCTL(user, kern, size)       \
       if ( IOCPARM_LEN(cmd) != size)                  \
@@ -456,7 +460,7 @@
#define le32_to_cpu(x) le32toh(x)

#define DRM_ERR(v)             v
-#define DRM_HZ                 hz
+#define DRM_HZ                 hz /* XXX maybe mstohz(something) */
#define DRM_UDELAY(udelay)     DELAY(udelay)
#define DRM_TIME_SLICE         (hz/20)  /* Time slice for GLXContexts    */

@@ -512,16 +516,29 @@
       DRM_LOCK();                                             \
}
#elif defined(__NetBSD__)
-#define DRM_WAIT_ON( ret, queue, timeout, condition )          \
-for ( ret = 0 ; !ret && !(condition) ; ) {                     \
-       DRM_UNLOCK();                                           \
-       mutex_enter(&dev->irq_lock);                            \
-       if (!(condition))                                       \
-          ret = mtsleep(&(queue), PZERO | PCATCH,              \
-                        "drmwtq", (timeout), &dev->irq_lock);  \
-       mutex_exit(&dev->irq_lock);                             \
-       DRM_LOCK();                                             \
-}
+#define        DRM_WAIT_ON(ret, q, timeout, condition)                 \
+mutex_enter(&(q)->lock);                                       \
+while (!(condition)) {                                         \
+       ret = cv_timedwait_sig(&(q)->cv, &(q)->lock, (timeout)); \
+       if (ret == EWOULDBLOCK) {                               \
+               ret = EBUSY;                                    \
+               break;                                          \
+       } else if (ret) {                                       \
+               ret = EINTR;                                    \
+               break;                                          \
+       } else {                                                \
+               ret = 0;                                        \
+       }                                                       \
+}                                                              \
+mutex_exit(&(q)->lock);
+#define        DRM_LOCAL_WAIT_ON(ret, mutex, cv)                       \
+do {                                                           \
+       mutex_enter(mutex);                                     \
+       ret = cv_wait_sig(cv, mutex);                           \
+       if (ret)                                                \
+               ret = EINTR;                                    \
+       mutex_exit(mutex);                                      \
+} while (0);
#else
#define DRM_WAIT_ON( ret, queue, timeout, condition )          \
for ( ret = 0 ; !ret && !(condition) ; ) {                     \
@@ -614,13 +631,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;
@@ -650,7 +664,8 @@
typedef struct drm_lock_data {
       drm_hw_lock_t     *hw_lock;     /* Hardware lock                   */
       DRMFILE           filp;         /* Unique identifier of holding process (NULL is kernel)*/
-       int               lock_queue;   /* Queue of blocked processes      */
+       kmutex_t          lock_mutex;
+       kcondvar_t        lock_cv;      /* Queue of blocked processes      */
       unsigned long     lock_time;    /* Time of last lock in jiffies    */
} drm_lock_data_t;

@@ -702,7 +717,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 +745,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;
@@ -916,7 +937,8 @@

       atomic_t          context_flag; /* Context swapping flag           */
       int               last_context; /* Last current context            */
-       int               vbl_queue;    /* vbl wait channel */
+       wait_queue_head_t  vbl_queue;   /* vbl wait channel */
+
       atomic_t          vbl_received;

#ifdef __FreeBSD__
@@ -934,6 +956,8 @@
       void              *dev_private;
       unsigned int      agp_buffer_token;
       drm_local_map_t   *agp_buffer_map;
+
+       vmem_t          *vmem;  /* vmem cookie arena */
};

extern int     drm_debug_flag;
@@ -979,8 +1003,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 +1184,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: dev/drm/drm_auth.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_auth.c,v
retrieving revision 1.6
diff -u -b -r1.6 drm_auth.c
--- dev/drm/drm_auth.c  29 Jun 2008 12:49:08 -0000      1.6
+++ dev/drm/drm_auth.c  10 Aug 2008 00:57:11 -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: dev/drm/drm_bufs.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_bufs.c,v
retrieving revision 1.10
diff -u -b -r1.10 drm_bufs.c
--- dev/drm/drm_bufs.c  29 Jun 2008 12:49:08 -0000      1.10
+++ dev/drm/drm_bufs.c  10 Aug 2008 00:57:11 -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.
+        */
+       map->cookie = vmem_alloc(dev->vmem, map->size,
+               VM_INSTANTFIT | VM_NOSLEEP);
+       if (map->cookie == 0) {
+               DRM_DEBUG("vmem_alloc() failed\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 = (unsigned long)map->mem->dd_kva;
               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,11 +298,8 @@
       request.mtrr   = map->mtrr;
       request.handle = map->handle;

-       if (request.type != _DRM_SHM) {
-               request.handle = (void *)request.offset;
-       } else {
-               request.handle = (void *)DRM_NETBSD_ADDR2HANDLE((uintptr_t)map->handle);
-       }
+       request.handle = (void *)map->cookie;
+
       DRM_COPY_TO_USER_IOCTL((drm_map_t *)data, request, sizeof(drm_map_t));

       return 0;
@@ -304,7 +325,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 +335,9 @@
               break;
       }

+       if (map->cookie != 0)
+               vmem_free(dev->vmem, map->cookie, map->size);
+
       TAILQ_REMOVE(&dev->maplist, map, link);
       free(map, M_DRM);
}
@@ -771,7 +795,6 @@
{
       int order, ret;

-       DRM_SPINLOCK(&dev->dma_lock);

       if (request->count < 0 || request->count > 4096)
               return DRM_ERR(EINVAL);
@@ -780,6 +803,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 +827,6 @@
{
       int order, ret;

-       DRM_SPINLOCK(&dev->dma_lock);

       if (!DRM_SUSER(DRM_CURPROC))
               return DRM_ERR(EACCES);
@@ -814,6 +838,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 +862,6 @@
{
       int order, ret;

-       DRM_SPINLOCK(&dev->dma_lock);

       if (!DRM_SUSER(DRM_CURPROC))
               return DRM_ERR(EACCES);
@@ -848,6 +873,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);
@@ -1024,7 +1051,7 @@
       struct vmspace *vms;
       struct vnode *vn;
       voff_t foff;
-       vsize_t size, rsize;
+       vsize_t size;
       vaddr_t vaddr;

       drm_buf_map_t request;
@@ -1047,25 +1074,25 @@
       if ((dev->driver.use_agp && (dma->flags & _DRM_DMA_USE_AGP)) ||
           (dev->driver.use_sg && (dma->flags & _DRM_DMA_USE_SG))) {
               drm_local_map_t *map = dev->agp_buffer_map;
+               u_long token = dev->agp_buffer_token;

               if (map == NULL) {
                       retcode = EINVAL;
                       goto done;
               }
+               /* XXX using cookie, not actual offset here */
               size = round_page(map->size);
-               foff = map->offset;
+               foff = token ? token : map->cookie;
       } else {
               size = round_page(dma->byte_count),
               foff = 0;
       }

-       vaddr = p->l_proc->p_emul->e_vm_default_addr(p->l_proc,
-           (vaddr_t)vms->vm_daddr, size);
-       rsize = round_page(size);
-       DRM_DEBUG("mmap %lx/%ld\n", vaddr, rsize);
-       retcode = uvm_mmap(&vms->vm_map, &vaddr, rsize,
-           UVM_PROT_READ | UVM_PROT_WRITE, UVM_PROT_ALL, MAP_SHARED,
-           &vn->v_uobj, foff, p->l_proc->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
+       vaddr = VM_DEFAULT_ADDRESS(p->l_proc->p_vmspace->vm_daddr, size);
+       DRM_DEBUG("mmap %lx/%ld\n", vaddr, size);
+       retcode = uvm_mmap(&vms->vm_map, &vaddr, size, UVM_PROT_RW,
+       UVM_PROT_ALL, MAP_SHARED, (void *)vn, foff,
+       p->l_proc->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);

       if (retcode)
               goto done;
Index: dev/drm/drm_dma.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_dma.c,v
retrieving revision 1.7
diff -u -b -r1.7 drm_dma.c
--- dev/drm/drm_dma.c   19 May 2008 00:17:39 -0000      1.7
+++ dev/drm/drm_dma.c   10 Aug 2008 00:57:11 -0000
@@ -48,7 +48,7 @@
       if (dev->dma == NULL)
               return DRM_ERR(ENOMEM);

-       DRM_SPININIT(&dev->dma_lock, "drmdma");
+       mutex_init(&dev->dma_lock, MUTEX_DEFAULT, IPL_NONE);

       return 0;
}
@@ -93,7 +93,7 @@
       if (dev->dma)
               free(dev->dma, M_DRM);
       dev->dma = NULL;
-       DRM_SPINUNINIT(&dev->dma_lock);
+       mutex_destroy(&dev->dma_lock);
}


Index: dev/drm/drm_drv.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_drv.c,v
retrieving revision 1.19
diff -u -b -r1.19 drm_drv.c
--- dev/drm/drm_drv.c   3 Jul 2008 17:36:44 -0000       1.19
+++ dev/drm/drm_drv.c   10 Aug 2008 00:57:11 -0000
@@ -204,12 +204,12 @@
        /* dev->maplist : drm_load */
        dev->context_sareas = NULL;
        dev->max_context = 0;
-       mutex_init(&dev->dev_lock, MUTEX_DEFAULT, IPL_NONE);
        dev->dma = NULL;
       /* dev->irq : drm_load */
       dev->irq_enabled = 0;
       dev->pa = *pa;
       dev->irqh = NULL;
+
       for(unit=0; unit<DRM_MAX_PCI_RESOURCE; unit++)
       {
               dev->pci_map_data[unit].mapped = 0;
@@ -238,7 +238,6 @@
       }
       dev->context_flag = 0;
       dev->last_context = 0;
-       dev->vbl_queue = 0;
       dev->vbl_received = 0;
       dev->buf_pgid = 0;
       dev->sysctl = NULL;
@@ -332,7 +331,6 @@
               dev->magiclist[i].tail = NULL;
       }

-       dev->lock.lock_queue = 0;
       dev->irq_enabled = 0;
       dev->context_flag = 0;
       dev->last_context = 0;
@@ -422,7 +420,9 @@
       if ( dev->lock.hw_lock ) {
               dev->lock.hw_lock = NULL; /* SHM removed */
               dev->lock.filp = NULL;
-               DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
+                mutex_enter(&(dev->lock.lock_mutex));
+               cv_broadcast(&(dev->lock.lock_cv));
+               mutex_exit(&(dev->lock.lock_mutex));
       }

       while ((filep = TAILQ_FIRST(&dev->files)) != NULL) {
@@ -438,6 +438,13 @@
static int drm_load(drm_device_t *dev)
{
       int retcode;
+       pcireg_t reg;
+
+       cv_init(&(dev->lock.lock_cv), "drm_cv");
+       mutex_init(&(dev->lock.lock_mutex), MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&(dev->dev_lock), MUTEX_DEFAULT, IPL_NONE);
+       /*mutex_init(&dev->drw_lock, MUTEX_DEFAULT, IPL_NONE);*/
+

       DRM_DEBUG( "\n" );

@@ -450,9 +457,10 @@
       dev->pci_vendor = PCI_VENDOR(dev->pa.pa_id);
       dev->pci_device = PCI_PRODUCT(dev->pa.pa_id);

+
       TAILQ_INIT(&dev->maplist);

-       drm_mem_init();
+       drm_mem_init(dev);
       drm_sysctl_init(dev);
       TAILQ_INIT(&dev->files);

@@ -464,6 +472,12 @@
                       goto error;
       }

+       /* enable bus mastering */
+       reg = pci_conf_read(dev->pa.pa_pc, dev->pa.pa_tag,
+               PCI_COMMAND_STATUS_REG);
+       pci_conf_write(dev->pa.pa_pc, dev->pa.pa_tag, PCI_COMMAND_STATUS_REG,
+           reg | PCI_COMMAND_MASTER_ENABLE);
+
       if (dev->driver.use_agp) {
               if (drm_device_is_agp(dev))
                       dev->agp = drm_agp_init(dev);
@@ -502,7 +516,10 @@
       DRM_LOCK();
       drm_lastclose(dev);
       DRM_UNLOCK();
-       DRM_SPINUNINIT(&dev->dev_lock);
+        cv_destroy(&(dev->lock.lock_cv));
+       mutex_destroy(&(dev->lock.lock_mutex));
+       mutex_destroy(&dev->dev_lock);
+       /*mutex_destroy(&dev->drw_lock);*/
       return retcode;
}

@@ -553,7 +570,7 @@
       if (dev->driver.unload != NULL)
               dev->driver.unload(dev);

-       drm_mem_uninit();
+       drm_mem_uninit(dev);
       DRM_SPINUNINIT(&dev->dev_lock);
}

@@ -657,8 +674,10 @@
                               break;  /* Got lock */
                       }
                               /* Contention */
-                       retcode = mtsleep((void *)&dev->lock.lock_queue,
-                           PZERO | PCATCH, "drmlk2", 0, &dev->dev_lock);
+
+
+                       DRM_LOCAL_WAIT_ON(retcode, &dev->dev_lock,
+                                         &dev->lock.lock_cv);
                       if (retcode)
                               break;
               }
Index: dev/drm/drm_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_irq.c,v
retrieving revision 1.16
diff -u -b -r1.16 drm_irq.c
--- dev/drm/drm_irq.c   7 Jul 2008 00:33:23 -0000       1.16
+++ dev/drm/drm_irq.c   10 Aug 2008 00:57:11 -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_DEFAULT, IPL_VM);

                               /* Before installing handler */

@@ -107,7 +107,7 @@
               goto err;
       }
       istr = pci_intr_string(dev->pa.pa_pc, ih);
-       dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_TTY,
+       dev->irqh = pci_intr_establish(dev->pa.pa_pc, ih, IPL_VM,
           drm_irq_handler_wrap, dev);
       if (!dev->irqh) {
               retcode = ENOENT;
@@ -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: dev/drm/drm_lock.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_lock.c,v
retrieving revision 1.7
diff -u -b -r1.7 drm_lock.c
--- dev/drm/drm_lock.c  19 May 2008 00:17:39 -0000      1.7
+++ dev/drm/drm_lock.c  10 Aug 2008 00:57:11 -0000
@@ -88,6 +88,7 @@
{
       unsigned int old, new;

+       mutex_enter(&dev->lock.lock_mutex);
       dev->lock.filp = NULL;
       do {
               old  = *lock;
@@ -97,9 +98,11 @@
       if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
               DRM_ERROR("%d freed heavyweight lock held by %d\n",
                         context, _DRM_LOCKING_CONTEXT(old));
+               mutex_exit(&dev->lock.lock_mutex);
               return 1;
       }
-       DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
+        cv_broadcast(&(dev->lock.lock_cv));
+       mutex_exit(&(dev->lock.lock_mutex));
       return 0;
}

@@ -123,7 +126,7 @@
        if (dev->driver.use_dma_queue && lock.context < 0)
                return EINVAL;

-       DRM_LOCK();
+       mutex_enter(&(dev->lock.lock_mutex));
       for (;;) {
               if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
                       dev->lock.filp = (void *)(uintptr_t)DRM_CURRENTPID;
@@ -133,12 +136,13 @@
               }

               /* Contention */
-               ret = mtsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH,
-                   "drmlk2", 0, &dev->dev_lock);
-               if (ret != 0)
+                ret = cv_wait_sig(&(dev->lock.lock_cv), &(dev->lock.lock_mutex));
+               if (ret != 0) {
+                       mutex_exit(&(dev->lock.lock_mutex));
                       break;
       }
-       DRM_UNLOCK();
+       }
+       mutex_exit(&(dev->lock.lock_mutex));
       DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");

       if (ret != 0)
Index: dev/drm/drm_memory.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_memory.c,v
retrieving revision 1.14
diff -u -b -r1.14 drm_memory.c
--- dev/drm/drm_memory.c        29 Jun 2008 12:49:08 -0000      1.14
+++ dev/drm/drm_memory.c        10 Aug 2008 00:57:11 -0000
@@ -58,15 +58,18 @@
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->vmem = vmem_create("drm_vmem", 0x40000000, LONG_MAX, PAGE_SIZE,
+               NULL, NULL, NULL, PAGE_SIZE, VM_NOSLEEP, IPL_VM);
+
+       if (dev->vmem == NULL)
+               DRM_DEBUG("could not create vmem arena\n");
}

-void drm_mem_uninit(void)
+void drm_mem_uninit(struct drm_device *dev)
{
+       vmem_destroy(dev->vmem);
}

void *drm_alloc(size_t size, int area)
@@ -95,7 +98,10 @@

void drm_free(void *pt, size_t size, int area)
{
+       if (pt != NULL) {
       free(pt, M_DRM);
+               pt = NULL;
+       }
}

void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map)
Index: dev/drm/drm_netbsd.c
===================================================================
RCS file: dev/drm/drm_netbsd.c
diff -N dev/drm/drm_netbsd.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/drm/drm_netbsd.c        10 Aug 2008 00:57:11 -0000
@@ -0,0 +1,142 @@
+/* $NetBSD: drm_netbsd.c,v 1.1 2008/05/28 04:52:48 bjs Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Blair Sadewitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <dev/drm/drmP.h>
+#include <sys/hash.h>
+
+/* XXX Most everything the DRM wants is expressed in pages.  There are possible
+   scenarios where e.g. the page size does not equal the page size of the GART,
+   but our DRM does not work on those platforms yet. */
+
+struct drm_dmamem *
+drm_dmamem_pgalloc(drm_device_t *dev, size_t pages)
+{
+       struct drm_dmamem       *mem = NULL;
+       size_t                  size = pages << PAGE_SHIFT;
+       int                      ret = 0;
+
+       mem = malloc(sizeof(*mem), M_DRM, M_NOWAIT | M_ZERO);
+       if (mem == NULL)
+               return NULL;
+
+       mem->phase = DRM_DMAMEM_INIT;
+
+       mem->dd_segs = malloc(sizeof(*mem->dd_segs) * pages, M_DRM,
+           M_NOWAIT | M_ZERO);
+       if (mem->dd_segs == NULL)
+               goto error;
+
+       mem->dd_dmat = dev->pa.pa_dmat;
+       mem->dd_size = size;
+
+       if (bus_dmamap_create(dev->pa.pa_dmat, size, pages, PAGE_SIZE, 0,
+           BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mem->dd_dmam) != 0)
+               goto error;
+       mem->phase = DRM_DMAMAP_CREATE;
+
+       if ((ret = bus_dmamem_alloc(dev->pa.pa_dmat, size, PAGE_SIZE, 0,
+           mem->dd_segs, pages, &mem->dd_nsegs, BUS_DMA_NOWAIT)) != 0) {
+               goto error;
+       }
+       mem->phase = DRM_DMAMEM_ALLOC;
+
+       if (bus_dmamem_map(dev->pa.pa_dmat, mem->dd_segs, mem->dd_nsegs, size,
+           &mem->dd_kva, BUS_DMA_COHERENT|BUS_DMA_NOWAIT) != 0)
+               goto error;
+       mem->phase = DRM_DMAMEM_MAP;
+
+       if (bus_dmamap_load(dev->pa.pa_dmat, mem->dd_dmam, mem->dd_kva, size,
+           NULL, BUS_DMA_NOWAIT) != 0)
+               goto error;
+       mem->phase = DRM_DMAMAP_LOAD;
+
+       memset(mem->dd_kva, 0, size);
+
+       return mem;
+error:
+       mem->phase &= DRM_DMAMEM_FAIL;
+       drm_dmamem_free(mem);
+       return NULL;
+}
+
+void
+drm_dmamem_free(struct drm_dmamem *mem)
+{
+       if (mem == NULL)
+               return;
+
+       if (mem->phase & DRM_DMAMEM_FAIL) {
+               DRM_DEBUG("attempted allocation failed; teardown sequence follows:\n");
+               mem->phase &= ~DRM_DMAMEM_FAIL;
+       } else if (mem->phase & ~DRM_DMAMAP_LOAD) {
+               DRM_DEBUG("invoked by another function on unloaded map; teardown sequence follows:\n");
+       } else {
+               DRM_DEBUG("freeing DMA memory; teardown sequence follows:\n");
+       }
+
+
+       switch (mem->phase) {
+       case DRM_DMAMAP_LOAD:
+               DRM_DEBUG("bus_dmamap_unload: tag (%p), map (%p)\n",
+                       (void *)mem->dd_dmat, (void *)mem->dd_dmam);
+               bus_dmamap_unload(mem->dd_dmat, mem->dd_dmam);
+               /* FALLTHRU */
+       case DRM_DMAMEM_MAP:
+               DRM_DEBUG("bus_dmamem_unmap: tag (%p), kva (%p), size (%zd)\n",
+                       mem->dd_dmat, mem->dd_kva, mem->dd_size);
+               bus_dmamem_unmap(mem->dd_dmat, mem->dd_kva, mem->dd_size);
+               /* FALLTHRU */
+       case DRM_DMAMEM_ALLOC:
+               DRM_DEBUG("bus_dmamem_free: tag (%p), segs (%p), nsegs (%i)\n",
+                       mem->dd_dmat, mem->dd_segs, mem->dd_nsegs);
+               bus_dmamem_free(mem->dd_dmat, mem->dd_segs,
+                       mem->dd_nsegs);
+               /* FALLTHRU */
+       case DRM_DMAMAP_CREATE:
+               DRM_DEBUG("bus_dmamap_destroy: tag (%p), map (%p)\n",
+                       (void *)mem->dd_dmat, (void *)mem->dd_dmam);
+               bus_dmamap_destroy(mem->dd_dmat, mem->dd_dmam);
+               /* FALLTHRU */
+       case DRM_DMAMEM_INIT:
+               if (mem->dd_segs != NULL) {
+                       free(mem->dd_segs, M_DRM);
+                       mem->dd_segs = NULL;
+               }
+       break;
+       }
+
+       free(mem, M_DRM);
+       mem = NULL;
+
+       return;
+}
Index: dev/drm/drm_netbsd.h
===================================================================
RCS file: dev/drm/drm_netbsd.h
diff -N dev/drm/drm_netbsd.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/drm/drm_netbsd.h        10 Aug 2008 00:57:11 -0000
@@ -0,0 +1,57 @@
+/* $NetBSD: drm_netbsd.h,v 1.1 2008/05/28 04:52:48 bjs Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Blair Sadewitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "drmP.h"
+
+#define        DRM_DMAMEM_INIT         0x000
+#define DRM_DMAMAP_CREATE      0x001
+#define DRM_DMAMEM_ALLOC       0x002
+#define DRM_DMAMEM_MAP         0x004
+#define DRM_DMAMAP_LOAD                0x008
+#define        DRM_DMAMEM_FAIL         0x800
+
+#define DRM_DMA_BUSADDR(__m)           ((__m)->dd_dmam->dm_segs[0].ds_addr)
+#define DRM_DMA_SEGADDR(__m, __s)      ((__m)->dd_dmam->dm_segs[__s].ds_addr)
+#define DRM_DMA_SEGSIZE(__m, __s)      ((__m)->dd_dmam->dm_segs[__s].ds_len)
+#define DRM_DMA_KERNADDR(__m)          ((__m)->dd_kva)
+
+struct drm_dmamem {
+       bus_dma_tag_t           dd_dmat;
+       bus_dmamap_t            dd_dmam;
+       bus_dma_segment_t       *dd_segs;
+       int                     dd_nsegs;
+       size_t                  dd_size;
+       void                    *dd_kva;
+       u_int                   phase;
+};
+
+struct drm_dmamem *drm_dmamem_pgalloc(struct drm_device *, size_t);
+void   drm_dmamem_free(struct drm_dmamem *);
Index: dev/drm/drm_pci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_pci.c,v
retrieving revision 1.13
diff -u -b -r1.13 drm_pci.c
--- dev/drm/drm_pci.c   29 Jun 2008 12:49:08 -0000      1.13
+++ dev/drm/drm_pci.c   10 Aug 2008 00:57:11 -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_DMA_BUSADDR(h->mem);
+       h->vaddr = DRM_DMA_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: dev/drm/drm_scatter.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_scatter.c,v
retrieving revision 1.7
diff -u -b -r1.7 drm_scatter.c
--- dev/drm/drm_scatter.c       7 Jul 2008 00:33:23 -0000       1.7
+++ dev/drm/drm_scatter.c       10 Aug 2008 00:57:11 -0000
@@ -43,7 +43,11 @@

void drm_sg_cleanup(drm_sg_mem_t *entry)
{
-       free((void *)entry->handle, M_DRM);
+       if (entry == NULL)
+               return;
+       if (entry->mem != NULL)
+               drm_dmamem_free(entry->mem);
+       if (entry->busaddr != NULL)
       free(entry->busaddr, M_DRM);
       free(entry, M_DRM);
}
@@ -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: dev/drm/drm_vm.c
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/drm_vm.c,v
retrieving revision 1.15
diff -u -b -r1.15 drm_vm.c
--- dev/drm/drm_vm.c    29 Jun 2008 12:49:08 -0000      1.15
+++ dev/drm/drm_vm.c    10 Aug 2008 00:57:11 -0000
@@ -41,7 +41,6 @@
       drm_file_t *priv;
       drm_map_type_t type;
       paddr_t phys;
-       uintptr_t roffset;

       DRM_LOCK();
       priv = drm_find_file_by_proc(dev, DRM_CURPROC);
@@ -83,13 +82,10 @@
                                  for performance, even if the list was a
                                  bit longer. */
       DRM_LOCK();
-       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)
-                               break;
-               } else {
-                       if (offset >= map->offset && offset < map->offset + map->size)
+                       if ((offset >= map->cookie) &&
+                           (offset < map->cookie + map->size)) {
+                               offset -= map->cookie;
                               break;
               }
       }
@@ -111,16 +107,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 +135,3 @@
       return atop(phys);
#endif
}
-
Index: dev/drm/files.drm
===================================================================
RCS file: /cvsroot/src/sys/dev/drm/files.drm,v
retrieving revision 1.6
diff -u -b -r1.6 files.drm
--- dev/drm/files.drm   19 Jul 2008 07:26:54 -0000      1.6
+++ dev/drm/files.drm   10 Aug 2008 00:57:11 -0000
@@ -15,6 +15,7 @@
file   dev/drm/drm_irq.c           drmbase & !drm_external
file   dev/drm/drm_lock.c          drmbase & !drm_external
file   dev/drm/drm_memory.c        drmbase & !drm_external
+file   dev/drm/drm_netbsd.c       drmbase & !drm_external
file   dev/drm/drm_pci.c           drmbase & !drm_external
file   dev/drm/drm_scatter.c       drmbase & !drm_external
file   dev/drm/drm_sysctl.c        drmbase & !drm_external
@@ -32,6 +33,7 @@
file   external/bsd/drm/dist/bsd-core/drm_irq.c           drmbase & drm_external
file   external/bsd/drm/dist/bsd-core/drm_lock.c          drmbase & drm_external
file   external/bsd/drm/dist/bsd-core/drm_memory.c        drmbase & drm_external
+file   external/bsd/drm/dist/bsd-core/drm_netbsd.c        drmbase & drm_external
file   external/bsd/drm/dist/bsd-core/drm_pci.c           drmbase & drm_external
file   external/bsd/drm/dist/bsd-core/drm_scatter.c       drmbase & drm_external
file   external/bsd/drm/dist/bsd-core/drm_sysctl.c        drmbase & drm_external
Index: dev/pci/drm/i915_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/i915_irq.c,v
retrieving revision 1.7
diff -u -b -r1.7 i915_irq.c
--- dev/pci/drm/i915_irq.c      8 Jul 2008 06:50:22 -0000       1.7
+++ dev/pci/drm/i915_irq.c      10 Aug 2008 00:57:11 -0000
@@ -67,11 +67,11 @@
       dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);

       if (temp & USER_INT_FLAG)
-               DRM_WAKEUP(&dev_priv->irq_queue);
+               DRM_WAKEUP(&(dev_priv->irq_queue));

       if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
               atomic_inc(&dev->vbl_received);
-               DRM_WAKEUP(&dev->vbl_queue);
+               DRM_WAKEUP(&(dev->vbl_queue));
               drm_vbl_send_signals(dev);
       }

@@ -121,7 +121,7 @@

       dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;

-       DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev_priv->irq_queue), 3 * DRM_HZ,
                   READ_BREADCRUMB(dev_priv) >= irq_nr);

       if (ret == DRM_ERR(EBUSY)) {
@@ -145,7 +145,7 @@
               return DRM_ERR(EINVAL);
       }

-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
                   (((cur_vblank = atomic_read(&dev->vbl_received))
                       - *sequence) <= (1<<23)));

@@ -280,7 +280,7 @@
       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;

       i915_enable_interrupt(dev);
-       DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
+       DRM_INIT_WAITQUEUE(&(dev_priv->irq_queue));
}

void i915_driver_irq_uninstall(drm_device_t * dev)
@@ -296,4 +296,5 @@

       temp = I915_READ16(I915REG_INT_IDENTITY_R);
       I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+       DRM_DESTROY_WAITQUEUE(&(dev_priv->irq_queue));
}
Index: dev/pci/drm/mach64_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/mach64_irq.c,v
retrieving revision 1.6
diff -u -b -r1.6 mach64_irq.c
--- dev/pci/drm/mach64_irq.c    8 Jul 2008 06:50:23 -0000       1.6
+++ dev/pci/drm/mach64_irq.c    10 Aug 2008 00:57:11 -0000
@@ -71,7 +71,7 @@
                            | MACH64_CRTC_VBLANK_INT);

               atomic_inc(&dev->vbl_received);
-               DRM_WAKEUP(&dev->vbl_queue);
+               DRM_WAKEUP(&(dev->vbl_queue));
               drm_vbl_send_signals(dev);
               return IRQ_HANDLED;
       }
@@ -87,7 +87,7 @@
        * by about a day rather than she wants to wait for years
        * using vertical blanks...
        */
-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
                   (((cur_vblank = atomic_read(&dev->vbl_received))
                     - *sequence) <= (1 << 23)));

Index: dev/pci/drm/mga_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/mga_irq.c,v
retrieving revision 1.6
diff -u -b -r1.6 mga_irq.c
--- dev/pci/drm/mga_irq.c       8 Jul 2008 06:50:23 -0000       1.6
+++ dev/pci/drm/mga_irq.c       10 Aug 2008 00:57:11 -0000
@@ -57,7 +57,7 @@
       if (status & MGA_VLINEPEN) {
               MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
               atomic_inc(&dev->vbl_received);
-               DRM_WAKEUP(&dev->vbl_queue);
+               DRM_WAKEUP(&(dev->vbl_queue));
               drm_vbl_send_signals(dev);
               handled = 1;
       }
@@ -78,7 +78,7 @@
               }

               atomic_inc(&dev_priv->last_fence_retired);
-               DRM_WAKEUP(&dev_priv->fence_queue);
+               DRM_WAKEUP(&(dev_priv->fence_queue));
               handled = 1;
       }

@@ -97,7 +97,7 @@
        * by about a day rather than she wants to wait for years
        * using vertical blanks...
        */
-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
                   (((cur_vblank = atomic_read(&dev->vbl_received))
                     - *sequence) <= (1 << 23)));

@@ -116,7 +116,7 @@
        * by about a day rather than she wants to wait for years
        * using fences.
        */
-       DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev_priv->fence_queue), 3 * DRM_HZ,
                   (((cur_fence = atomic_read(&dev_priv->last_fence_retired))
                     - *sequence) <= (1 << 23)));

@@ -139,7 +139,7 @@
{
       drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;

-       DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
+       DRM_INIT_WAITQUEUE( &(dev_priv->fence_queue) );

       /* Turn on vertical blank interrupt and soft trap interrupt. */
       MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
@@ -153,6 +153,7 @@

       /* Disable *all* interrupts */
       MGA_WRITE(MGA_IEN, 0);
+       DRM_DESTROY_WAITQUEUE(&(dev_priv->fence_queue));

       dev->irq_enabled = 0;
}
Index: dev/pci/drm/r128_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/r128_irq.c,v
retrieving revision 1.6
diff -u -b -r1.6 r128_irq.c
--- dev/pci/drm/r128_irq.c      8 Jul 2008 06:50:23 -0000       1.6
+++ dev/pci/drm/r128_irq.c      10 Aug 2008 00:57:11 -0000
@@ -72,7 +72,7 @@
        * by about a day rather than she wants to wait for years
        * using vertical blanks...
        */
-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
                   (((cur_vblank = atomic_read(&dev->vbl_received))
                     - *sequence) <= (1 << 23)));

Index: dev/pci/drm/radeon_cp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/radeon_cp.c,v
retrieving revision 1.10
diff -u -b -r1.10 radeon_cp.c
--- dev/pci/drm/radeon_cp.c     8 Jul 2008 06:50:23 -0000       1.10
+++ dev/pci/drm/radeon_cp.c     10 Aug 2008 00:57:12 -0000
@@ -1944,8 +1944,8 @@
                               msleep(&ret, &dev->dev_lock, PZERO, "rdnrel",
                                      1);
#else
-                               mtsleep(&ret, PZERO, "rdnrel", 1,
-                                       &dev->dev_lock);
+                               ret = cv_timedwait(&(dev->lock.lock_cv),
+                                       &(dev->lock.lock_mutex), 1);
#endif
#endif
                       }
Index: dev/pci/drm/radeon_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/radeon_irq.c,v
retrieving revision 1.8
diff -u -b -r1.8 radeon_irq.c
--- dev/pci/drm/radeon_irq.c    8 Jul 2008 06:50:23 -0000       1.8
+++ dev/pci/drm/radeon_irq.c    10 Aug 2008 00:57:12 -0000
@@ -87,13 +87,13 @@

       /* SW interrupt */
       if (stat & RADEON_SW_INT_TEST) {
-               DRM_WAKEUP(&dev_priv->swi_queue);
+               DRM_WAKEUP(&(dev_priv->swi_queue));
       }

       /* VBLANK interrupt */
       if (stat & RADEON_CRTC_VBLANK_STAT) {
               atomic_inc(&dev->vbl_received);
-               DRM_WAKEUP(&dev->vbl_queue);
+               DRM_WAKEUP(&(dev->vbl_queue));
               drm_vbl_send_signals(dev);
       }

@@ -129,7 +129,7 @@

       dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;

-       DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev_priv->swi_queue), 3 * DRM_HZ,
                   RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);

       return ret;
@@ -155,7 +155,7 @@
        * by about a day rather than she wants to wait for years
        * using vertical blanks...
        */
-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
                   (((cur_vblank = atomic_read(&dev->vbl_received))
                     - *sequence) <= (1 << 23)));

@@ -233,7 +233,7 @@
           (drm_radeon_private_t *) dev->dev_private;

       atomic_set(&dev_priv->swi_emitted, 0);
-       DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
+       DRM_INIT_WAITQUEUE(&(dev_priv->swi_queue));

       /* Turn on SW and VBL ints */
       RADEON_WRITE(RADEON_GEN_INT_CNTL,
@@ -249,4 +249,5 @@

       /* Disable *all* interrupts */
       RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+       DRM_DESTROY_WAITQUEUE(&(dev_priv->swi_queue));
}
Index: dev/pci/drm/via_irq.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/via_irq.c,v
retrieving revision 1.7
diff -u -b -r1.7 via_irq.c
--- dev/pci/drm/via_irq.c       8 Jul 2008 06:50:23 -0000       1.7
+++ dev/pci/drm/via_irq.c       10 Aug 2008 00:57:12 -0000
@@ -142,7 +142,7 @@
       for (i=0; i<dev_priv->num_irqs; ++i) {
               if (status & cur_irq->pending_mask) {
                       atomic_inc( &cur_irq->irq_received );
-                       DRM_WAKEUP( &cur_irq->irq_queue );
+                       DRM_WAKEUP( &(cur_irq->irq_queue) );
                       handled = 1;
#ifdef VIA_HAVE_DMABLIT
                       if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
@@ -196,7 +196,7 @@
        * using vertical blanks...
        */

-       DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+       DRM_WAIT_ON(ret, &(dev->vbl_queue), 3 * DRM_HZ,
                   (((cur_vblank = atomic_read(&dev->vbl_received)) -
                     *sequence) <= (1 << 23)));

@@ -240,12 +240,12 @@
       cur_irq = dev_priv->via_irqs + real_irq;

       if (masks[real_irq][2] && !force_sequence) {
-               DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+               DRM_WAIT_ON(ret, &(cur_irq->irq_queue), 3 * DRM_HZ,
                           ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
                            masks[irq][4]));
               cur_irq_sequence = atomic_read(&cur_irq->irq_received);
       } else {
-               DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+               DRM_WAIT_ON(ret, &(cur_irq->irq_queue), 3 * DRM_HZ,
                           (((cur_irq_sequence =
                              atomic_read(&cur_irq->irq_received)) -
                             *sequence) <= (1 << 23)));
@@ -288,7 +288,7 @@
                       atomic_set(&cur_irq->irq_received, 0);
                       cur_irq->enable_mask = dev_priv->irq_masks[i][0];
                       cur_irq->pending_mask = dev_priv->irq_masks[i][1];
-                       DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
+                       DRM_INIT_WAITQUEUE( &(cur_irq->irq_queue) );
                       dev_priv->irq_enable_mask |= cur_irq->enable_mask;
                       dev_priv->irq_pending_mask |= cur_irq->pending_mask;
                       cur_irq++;
@@ -330,7 +330,9 @@
void via_driver_irq_uninstall(drm_device_t * dev)
{
       drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+       drm_via_irq_t *cur_irq;
       u32 status;
+       int i;

       DRM_DEBUG("driver_irq_uninstall)\n");
       if (dev_priv) {
@@ -343,6 +345,12 @@
               status = VIA_READ(VIA_REG_INTERRUPT);
               VIA_WRITE(VIA_REG_INTERRUPT, status &
                         ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
+               cur_irq = dev_priv->via_irqs;
+               for(i = 0; i < dev_priv->num_irqs; ++i) {
+                       DRM_DESTROY_WAITQUEUE(&(cur_irq->irq_queue));
+                       cur_irq++;
+               }
+
       }
}

Index: dev/pci/drm/via_video.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/drm/via_video.c,v
retrieving revision 1.7
diff -u -b -r1.7 via_video.c
--- dev/pci/drm/via_video.c     8 Jul 2008 06:50:23 -0000       1.7
+++ dev/pci/drm/via_video.c     10 Aug 2008 00:57:12 -0000
@@ -67,6 +67,7 @@
                       }
                       *lock = 0;
               }
+               DRM_DESTROY_WAITQUEUE(&(dev_priv->decoder_queue[i]));
       }
}

@@ -91,7 +92,7 @@

       switch (fx.func) {
       case VIA_FUTEX_WAIT:
-               DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock],
+               DRM_WAIT_ON(ret, &(dev_priv->decoder_queue[fx.lock]),
                           (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val);
               return ret;
       case VIA_FUTEX_WAKE: