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 #include #include +#include #include #ifdef __FreeBSD__ #include @@ -71,6 +72,7 @@ #endif #include #include +#include #include #include #include @@ -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; unitpci_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 + +#include +#include + +/* 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; inum_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: