From 6ef79263b68402687ccc2b7447dd908c00e35057 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 29 Mar 2003 03:38:47 +0000 Subject: [PATCH] Add DRMFILE definitions and supply filp for BSD in the post-drm-filp-0-1-branch world. The filp is a void * cast from the current pid. This is a temporary solution which maintains the status quo until a proper solution is implemented. What is really needed is a unique pointer per open, hopefully with a device private area. This can be done in FreeBSD for all entry points except mmap, but is difficult (sys/dev/streams/streams.c is an example). I have partially completed code for this but have not had time to debug, so this is a temporary fix. --- bsd-core/drmP.h | 85 ++++++++++++++- bsd-core/drm_bufs.c | 18 ++-- bsd-core/drm_dma.c | 6 +- bsd-core/drm_drv.c | 18 ++-- bsd-core/drm_lock.c | 11 +- bsd-core/drm_os_freebsd.h | 98 ++++------------- bsd-core/drm_os_netbsd.h | 217 +++++++++++++++++--------------------- bsd/drmP.h | 85 ++++++++++++++- bsd/drm_bufs.h | 18 ++-- bsd/drm_dma.h | 6 +- bsd/drm_drv.h | 18 ++-- bsd/drm_lock.h | 11 +- bsd/drm_os_freebsd.h | 98 ++++------------- bsd/drm_os_netbsd.h | 217 +++++++++++++++++--------------------- 14 files changed, 440 insertions(+), 466 deletions(-) diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index d28af721..a673ecda 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -153,7 +153,7 @@ typedef struct drm_pci_list { } drm_pci_list_t; typedef struct drm_ioctl_desc { - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int auth_needed; int root_only; } drm_ioctl_desc_t; @@ -192,7 +192,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + DRMFILE filp; /* Unique identifier of holding process */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -309,7 +309,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -596,7 +596,7 @@ extern int DRM(order)( unsigned long size ); extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ @@ -668,5 +668,82 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, dma_addr_t bus_addr); #endif +/* Locking IOCTL support (drm_drv.h) */ +extern int DRM(lock)(DRM_IOCTL_ARGS); +extern int DRM(unlock)(DRM_IOCTL_ARGS); + +/* Misc. IOCTL support (drm_ioctl.h) */ +extern int DRM(irq_busid)(DRM_IOCTL_ARGS); +extern int DRM(getunique)(DRM_IOCTL_ARGS); +extern int DRM(setunique)(DRM_IOCTL_ARGS); +extern int DRM(getmap)(DRM_IOCTL_ARGS); +extern int DRM(getclient)(DRM_IOCTL_ARGS); +extern int DRM(getstats)(DRM_IOCTL_ARGS); + +/* Context IOCTL support (drm_context.h) */ +extern int DRM(resctx)(DRM_IOCTL_ARGS); +extern int DRM(addctx)(DRM_IOCTL_ARGS); +extern int DRM(modctx)(DRM_IOCTL_ARGS); +extern int DRM(getctx)(DRM_IOCTL_ARGS); +extern int DRM(switchctx)(DRM_IOCTL_ARGS); +extern int DRM(newctx)(DRM_IOCTL_ARGS); +extern int DRM(rmctx)(DRM_IOCTL_ARGS); +extern int DRM(setsareactx)(DRM_IOCTL_ARGS); +extern int DRM(getsareactx)(DRM_IOCTL_ARGS); + +/* Drawable IOCTL support (drm_drawable.h) */ +extern int DRM(adddraw)(DRM_IOCTL_ARGS); +extern int DRM(rmdraw)(DRM_IOCTL_ARGS); + +/* Authentication IOCTL support (drm_auth.h) */ +extern int DRM(getmagic)(DRM_IOCTL_ARGS); +extern int DRM(authmagic)(DRM_IOCTL_ARGS); + +/* Locking IOCTL support (drm_lock.h) */ +extern int DRM(block)(DRM_IOCTL_ARGS); +extern int DRM(unblock)(DRM_IOCTL_ARGS); +extern int DRM(finish)(DRM_IOCTL_ARGS); + +/* Buffer management support (drm_bufs.h) */ +extern int DRM(addmap)(DRM_IOCTL_ARGS); +extern int DRM(rmmap)(DRM_IOCTL_ARGS); +#if __HAVE_DMA +extern int DRM(addbufs_agp)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_pci)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_sg)(DRM_IOCTL_ARGS); +extern int DRM(addbufs)(DRM_IOCTL_ARGS); +extern int DRM(infobufs)(DRM_IOCTL_ARGS); +extern int DRM(markbufs)(DRM_IOCTL_ARGS); +extern int DRM(freebufs)(DRM_IOCTL_ARGS); +extern int DRM(mapbufs)(DRM_IOCTL_ARGS); +#endif + +/* DMA support (drm_dma.h) */ +#if __HAVE_DMA +extern int DRM(control)(DRM_IOCTL_ARGS); +#endif +#if __HAVE_VBL_IRQ +extern int DRM(wait_vblank)(DRM_IOCTL_ARGS); +#endif + +/* AGP/GART support (drm_agpsupport.h) */ +#if __REALLY_HAVE_AGP +extern int DRM(agp_acquire)(DRM_IOCTL_ARGS); +extern int DRM(agp_release)(DRM_IOCTL_ARGS); +extern int DRM(agp_enable)(DRM_IOCTL_ARGS); +extern int DRM(agp_info)(DRM_IOCTL_ARGS); +extern int DRM(agp_alloc)(DRM_IOCTL_ARGS); +extern int DRM(agp_free)(DRM_IOCTL_ARGS); +extern int DRM(agp_unbind)(DRM_IOCTL_ARGS); +extern int DRM(agp_bind)(DRM_IOCTL_ARGS); +#endif + +/* Scatter Gather Support (drm_scatter.h) */ +#if __HAVE_SG +extern int DRM(sg_alloc)(DRM_IOCTL_ARGS); +extern int DRM(sg_free)(DRM_IOCTL_ARGS); +#endif + + #endif /* __KERNEL__ */ #endif /* _DRM_P_H_ */ diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 5df6f342..8e0534f2 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -417,7 +417,7 @@ int DRM(addbufs_agp)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -625,7 +625,7 @@ int DRM(addbufs_pci)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -778,7 +778,7 @@ int DRM(addbufs_sg)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -862,16 +862,16 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) - return DRM(addbufs_agp)( kdev, cmd, data, flags, p ); + return DRM(addbufs_agp)( kdev, cmd, data, flags, p, filp ); else #endif #if __REALLY_HAVE_SG if ( request.flags & _DRM_SG_BUFFER ) - return DRM(addbufs_sg)( kdev, cmd, data, flags, p ); + return DRM(addbufs_sg)( kdev, cmd, data, flags, p, filp ); else #endif #if __HAVE_PCI_DMA - return DRM(addbufs_pci)( kdev, cmd, data, flags, p ); + return DRM(addbufs_pci)( kdev, cmd, data, flags, p, filp ); #else return DRM_ERR(EINVAL); #endif @@ -995,9 +995,9 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR("Process %d freeing buffer not owned\n", + DRM_CURRENTPID); return DRM_ERR(EINVAL); } DRM(free_buffer)( dev, buf ); diff --git a/bsd-core/drm_dma.c b/bsd-core/drm_dma.c index 946e652c..fa0bd20d 100644 --- a/bsd-core/drm_dma.c +++ b/bsd-core/drm_dma.c @@ -182,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = NULL; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -205,14 +205,14 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp) { drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index d477a0f8..74655ee9 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -705,7 +705,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } DRM_UNLOCK; @@ -929,7 +929,8 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) drm_file_t *priv; DRM_DEVICE; int retcode = 0; - + DRMFILE __unused filp = (void *)(DRM_CURRENTPID); + DRM_DEBUG( "open_count = %d\n", dev->open_count ); priv = DRM(find_file_by_proc)(dev, p); if (!priv) { @@ -952,7 +953,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == DRM_CURRENTPID) { + && dev->lock.filp == (void *)DRM_CURRENTPID) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); @@ -1002,7 +1003,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( dev, (void *)priv->pid ); #endif #if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) @@ -1052,12 +1053,13 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) /* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. */ -int DRM(ioctl)( DRM_IOCTL_ARGS ) +int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, + DRM_STRUCTPROC *p) { DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); DRM_PRIV; @@ -1123,7 +1125,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) || ( ioctl->auth_needed && !priv->authenticated ) ) { retcode = EACCES; } else { - retcode = func( kdev, cmd, data, flags, p ); + retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID); } } @@ -1178,7 +1180,7 @@ int DRM(lock)( DRM_IOCTL_ARGS ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = DRM_CURRENTPID; + dev->lock.filp = (void *)DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 6dd4f3c4..3bab78ef 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -78,7 +78,7 @@ int DRM(lock_transfer)(drm_device_t *dev, { unsigned int old, new; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -91,19 +91,16 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - pid_t pid = dev->lock.pid; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = 0; } while (!atomic_cmpset_int(lock, old, new)); if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", - context, - _DRM_LOCKING_CONTEXT(old), - pid); + DRM_ERROR("%d freed heavyweight lock held by %d\n", + context, _DRM_LOCKING_CONTEXT(old)); return 1; } DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); diff --git a/bsd-core/drm_os_freebsd.h b/bsd-core/drm_os_freebsd.h index 227c9963..30a6e362 100644 --- a/bsd-core/drm_os_freebsd.h +++ b/bsd-core/drm_os_freebsd.h @@ -101,7 +101,11 @@ #define DRM_CURRENTPID curproc->p_pid #endif -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, DRM_CURPROC) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, DRM_CURPROC) #define DRM_SUSER(p) suser(p) @@ -133,6 +137,16 @@ return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -368,8 +382,6 @@ find_first_zero_bit(volatile void *p, int max) /* drm_drv.h */ extern d_ioctl_t DRM(ioctl); -extern d_ioctl_t DRM(lock); -extern d_ioctl_t DRM(unlock); extern d_open_t DRM(open); extern d_close_t DRM(close); extern d_read_t DRM(read); @@ -381,81 +393,9 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern d_ioctl_t DRM(irq_busid); -extern d_ioctl_t DRM(getunique); -extern d_ioctl_t DRM(setunique); -extern d_ioctl_t DRM(getmap); -extern d_ioctl_t DRM(getclient); -extern d_ioctl_t DRM(getstats); - -/* Context IOCTL support (drm_context.h) */ -extern d_ioctl_t DRM(resctx); -extern d_ioctl_t DRM(addctx); -extern d_ioctl_t DRM(modctx); -extern d_ioctl_t DRM(getctx); -extern d_ioctl_t DRM(switchctx); -extern d_ioctl_t DRM(newctx); -extern d_ioctl_t DRM(rmctx); -extern d_ioctl_t DRM(setsareactx); -extern d_ioctl_t DRM(getsareactx); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern d_ioctl_t DRM(adddraw); -extern d_ioctl_t DRM(rmdraw); - -/* Authentication IOCTL support (drm_auth.h) */ -extern d_ioctl_t DRM(getmagic); -extern d_ioctl_t DRM(authmagic); - -/* Locking IOCTL support (drm_lock.h) */ -extern d_ioctl_t DRM(block); -extern d_ioctl_t DRM(unblock); -extern d_ioctl_t DRM(finish); - -/* Buffer management support (drm_bufs.h) */ -extern d_ioctl_t DRM(addmap); -extern d_ioctl_t DRM(rmmap); -#if __HAVE_DMA -extern d_ioctl_t DRM(addbufs_agp); -extern d_ioctl_t DRM(addbufs_pci); -extern d_ioctl_t DRM(addbufs_sg); -extern d_ioctl_t DRM(addbufs); -extern d_ioctl_t DRM(infobufs); -extern d_ioctl_t DRM(markbufs); -extern d_ioctl_t DRM(freebufs); -extern d_ioctl_t DRM(mapbufs); -#endif - -/* Memory management support (drm_memory.h) */ -extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern d_ioctl_t DRM(control); -#endif -#if __HAVE_VBL_IRQ -extern d_ioctl_t DRM(wait_vblank); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern d_ioctl_t DRM(agp_acquire); -extern d_ioctl_t DRM(agp_release); -extern d_ioctl_t DRM(agp_enable); -extern d_ioctl_t DRM(agp_info); -extern d_ioctl_t DRM(agp_alloc); -extern d_ioctl_t DRM(agp_free); -extern d_ioctl_t DRM(agp_unbind); -extern d_ioctl_t DRM(agp_bind); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern d_ioctl_t DRM(sg_alloc); -extern d_ioctl_t DRM(sg_free); -#endif - -/* SysCtl Support (drm_sysctl.h) */ +/* sysctl support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); + +/* Memory info sysctl (drm_memory.h) */ +extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; diff --git a/bsd-core/drm_os_netbsd.h b/bsd-core/drm_os_netbsd.h index 605b6a2c..fa158254 100644 --- a/bsd-core/drm_os_netbsd.h +++ b/bsd-core/drm_os_netbsd.h @@ -17,6 +17,7 @@ #include #include #include +#include /* For TIOCSPGRP/TIOCGPGRP */ #include @@ -31,11 +32,9 @@ #include #include -#include "drmvar.h" - #define __REALLY_HAVE_AGP __HAVE_AGP -#define __REALLY_HAVE_MTRR 0 +#define __REALLY_HAVE_MTRR 1 #define __REALLY_HAVE_SG 0 #if __REALLY_HAVE_AGP @@ -43,8 +42,7 @@ #include #endif -#define device_t struct device * -extern struct cfdriver DRM(_cd); +#include #if DRM_DEBUG #undef DRM_DEBUG_CODE @@ -52,12 +50,20 @@ extern struct cfdriver DRM(_cd); #endif #undef DRM_DEBUG +#if DRM_LINUX +#undef DRM_LINUX /* FIXME: Linux compat has not been ported yet */ +#endif + +typedef drm_device_t *device_t; + +extern struct cfdriver DRM(cd); + #define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) #define DRM_DEV_UID 0 #define DRM_DEV_GID 0 -#define CDEV_MAJOR 90 +#define CDEV_MAJOR 34 #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc @@ -68,21 +74,34 @@ extern struct cfdriver DRM(_cd); #define DRM_SPINUNLOCK(u) simple_unlock(u); #define DRM_CURRENTPID curproc->p_pid -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL) #define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) #define DRM_TASKQUEUE_ARGS void *dev, int pending -#define DRM_IRQ_ARGS void *device -#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev)) +#define DRM_IRQ_ARGS void *arg +#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev)) +/* XXX Not sure if this is the 'right' version.. */ +#if __NetBSD_Version__ >= 106140000 +MALLOC_DECLARE(DRM(M_DRM)); +#else +/* XXX Make sure this works */ +extern const int DRM(M_DRM) = M_DEVBUF; +#endif /* __NetBSD_Version__ */ #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) +#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) ) #define DRM_VTOPHYS(addr) vtophys(addr) -#define DRM_READ8(addr) *((volatile char *)(addr)) -#define DRM_READ32(addr) *((volatile long *)(addr)) -#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val) -#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val) -#define DRM_AGP_FIND_DEVICE() + +#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) +#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) ) +#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) ) +#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) ) + +#define DRM_AGP_FIND_DEVICE() agp_find_device(0) #define DRM_PRIV \ drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ @@ -91,6 +110,16 @@ extern struct cfdriver DRM(_cd); return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -105,7 +134,7 @@ do { \ do { \ drm_map_list_entry_t *listentry; \ TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_map_t *map = listentry->map; \ + drm_local_map_t *map = listentry->map; \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -114,7 +143,15 @@ do { \ } \ } while (0) -#define return DRM_ERR(v) return v; +#define DRM_HZ hz + +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +while (!condition) { \ + ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ + if ( ret ) \ + return ret; \ +} + #define DRM_ERR(v) v #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ @@ -125,21 +162,25 @@ do { \ copyout(arg2, arg1, arg3) #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ copyin(arg2, arg1, arg3) +/* Macros for userspace access with checking readability once */ +/* FIXME: can't find equivalent functionality for nocheck yet. + * It'll be slower than linux, but should be correct. + */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ)) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + copyin(arg2, arg1, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + ((val) = fuword(uaddr), 0) -#define DRM_READMEMORYBARRIER \ -{ \ - int xchangeDummy; \ - DRM_DEBUG("%s\n", __FUNCTION__); \ - __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); \ - __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" \ - " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" \ - " pop %%eax" : /* no outputs */ : /* no inputs */ ); \ -} while (0); +#define DRM_WRITEMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0); +#define DRM_READMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ); -#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER - -#define DRM_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP(w) wakeup((void *)w) #define DRM_WAKEUP_INT(w) wakeup(w) +#define DRM_INIT_WAITQUEUE( queue ) do {} while (0) #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) @@ -151,30 +192,46 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; +#define cpu_to_le32(x) (x) /* FIXME */ + typedef u_int32_t dma_addr_t; -typedef volatile u_int32_t atomic_t; +typedef volatile long atomic_t; typedef u_int32_t cycles_t; -typedef u_int32_t spinlock_t; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; typedef dev_type_ioctl(d_ioctl_t); typedef vaddr_t vm_offset_t; +/* FIXME */ #define atomic_set(p, v) (*(p) = (v)) #define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_int(p, 1) -#define atomic_dec(p) atomic_subtract_int(p, 1) -#define atomic_add(n, p) atomic_add_int(p, n) -#define atomic_sub(n, p) atomic_subtract_int(p, n) +#define atomic_inc(p) (*(p) += 1) +#define atomic_dec(p) (*(p) -= 1) +#define atomic_add(n, p) (*(p) += (n)) +#define atomic_sub(n, p) (*(p) -= (n)) -/* FIXME: Is NetBSD's kernel non-reentrant? */ +/* FIXME */ #define atomic_add_int(p, v) *(p) += v #define atomic_subtract_int(p, v) *(p) -= v #define atomic_set_int(p, bits) *(p) |= (bits) #define atomic_clear_int(p, bits) *(p) &= ~(bits) /* Fake this */ + +static __inline int +atomic_cmpset_int(__volatile__ int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} + static __inline atomic_t test_and_set_bit(int b, atomic_t *p) { @@ -224,20 +281,6 @@ find_first_zero_bit(atomic_t *p, int max) #define spldrm() spltty() #define jiffies hardclock_ticks -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void @@ -258,7 +301,7 @@ do { \ #define DRM_DEBUG(fmt, arg...) \ do { \ if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \ + printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -292,8 +335,6 @@ do { \ /* drm_drv.h */ extern dev_type_ioctl(DRM(ioctl)); -extern dev_type_ioctl(DRM(lock)); -extern dev_type_ioctl(DRM(unlock)); extern dev_type_open(DRM(open)); extern dev_type_close(DRM(close)); extern dev_type_read(DRM(read)); @@ -305,75 +346,5 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern dev_type_ioctl(DRM(irq_busid)); -extern dev_type_ioctl(DRM(getunique)); -extern dev_type_ioctl(DRM(setunique)); -extern dev_type_ioctl(DRM(getmap)); -extern dev_type_ioctl(DRM(getclient)); -extern dev_type_ioctl(DRM(getstats)); - -/* Context IOCTL support (drm_context.h) */ -extern dev_type_ioctl(DRM(resctx)); -extern dev_type_ioctl(DRM(addctx)); -extern dev_type_ioctl(DRM(modctx)); -extern dev_type_ioctl(DRM(getctx)); -extern dev_type_ioctl(DRM(switchctx)); -extern dev_type_ioctl(DRM(newctx)); -extern dev_type_ioctl(DRM(rmctx)); -extern dev_type_ioctl(DRM(setsareactx)); -extern dev_type_ioctl(DRM(getsareactx)); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern dev_type_ioctl(DRM(adddraw)); -extern dev_type_ioctl(DRM(rmdraw)); - -/* Authentication IOCTL support (drm_auth.h) */ -extern dev_type_ioctl(DRM(getmagic)); -extern dev_type_ioctl(DRM(authmagic)); - -/* Locking IOCTL support (drm_lock.h) */ -extern dev_type_ioctl(DRM(block)); -extern dev_type_ioctl(DRM(unblock)); -extern dev_type_ioctl(DRM(finish)); - -/* Buffer management support (drm_bufs.h) */ -extern dev_type_ioctl(DRM(addmap)); -extern dev_type_ioctl(DRM(rmmap)); -#if __HAVE_DMA -extern dev_type_ioctl(DRM(addbufs_agp)); -extern dev_type_ioctl(DRM(addbufs_pci)); -extern dev_type_ioctl(DRM(addbufs_sg)); -extern dev_type_ioctl(DRM(addbufs)); -extern dev_type_ioctl(DRM(infobufs)); -extern dev_type_ioctl(DRM(markbufs)); -extern dev_type_ioctl(DRM(freebufs)); -extern dev_type_ioctl(DRM(mapbufs)); -#endif - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern dev_type_ioctl(DRM(control)); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern dev_type_ioctl(DRM(agp_acquire)); -extern dev_type_ioctl(DRM(agp_release)); -extern dev_type_ioctl(DRM(agp_enable)); -extern dev_type_ioctl(DRM(agp_info)); -extern dev_type_ioctl(DRM(agp_alloc)); -extern dev_type_ioctl(DRM(agp_free)); -extern dev_type_ioctl(DRM(agp_unbind)); -extern dev_type_ioctl(DRM(agp_bind)); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern dev_type_ioctl(DRM(sg_alloc)); -extern dev_type_ioctl(DRM(sg_free)); -#endif - -/* SysCtl Support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); diff --git a/bsd/drmP.h b/bsd/drmP.h index d28af721..a673ecda 100644 --- a/bsd/drmP.h +++ b/bsd/drmP.h @@ -153,7 +153,7 @@ typedef struct drm_pci_list { } drm_pci_list_t; typedef struct drm_ioctl_desc { - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int auth_needed; int root_only; } drm_ioctl_desc_t; @@ -192,7 +192,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + DRMFILE filp; /* Unique identifier of holding process */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -309,7 +309,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -596,7 +596,7 @@ extern int DRM(order)( unsigned long size ); extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ @@ -668,5 +668,82 @@ extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev, dma_addr_t bus_addr); #endif +/* Locking IOCTL support (drm_drv.h) */ +extern int DRM(lock)(DRM_IOCTL_ARGS); +extern int DRM(unlock)(DRM_IOCTL_ARGS); + +/* Misc. IOCTL support (drm_ioctl.h) */ +extern int DRM(irq_busid)(DRM_IOCTL_ARGS); +extern int DRM(getunique)(DRM_IOCTL_ARGS); +extern int DRM(setunique)(DRM_IOCTL_ARGS); +extern int DRM(getmap)(DRM_IOCTL_ARGS); +extern int DRM(getclient)(DRM_IOCTL_ARGS); +extern int DRM(getstats)(DRM_IOCTL_ARGS); + +/* Context IOCTL support (drm_context.h) */ +extern int DRM(resctx)(DRM_IOCTL_ARGS); +extern int DRM(addctx)(DRM_IOCTL_ARGS); +extern int DRM(modctx)(DRM_IOCTL_ARGS); +extern int DRM(getctx)(DRM_IOCTL_ARGS); +extern int DRM(switchctx)(DRM_IOCTL_ARGS); +extern int DRM(newctx)(DRM_IOCTL_ARGS); +extern int DRM(rmctx)(DRM_IOCTL_ARGS); +extern int DRM(setsareactx)(DRM_IOCTL_ARGS); +extern int DRM(getsareactx)(DRM_IOCTL_ARGS); + +/* Drawable IOCTL support (drm_drawable.h) */ +extern int DRM(adddraw)(DRM_IOCTL_ARGS); +extern int DRM(rmdraw)(DRM_IOCTL_ARGS); + +/* Authentication IOCTL support (drm_auth.h) */ +extern int DRM(getmagic)(DRM_IOCTL_ARGS); +extern int DRM(authmagic)(DRM_IOCTL_ARGS); + +/* Locking IOCTL support (drm_lock.h) */ +extern int DRM(block)(DRM_IOCTL_ARGS); +extern int DRM(unblock)(DRM_IOCTL_ARGS); +extern int DRM(finish)(DRM_IOCTL_ARGS); + +/* Buffer management support (drm_bufs.h) */ +extern int DRM(addmap)(DRM_IOCTL_ARGS); +extern int DRM(rmmap)(DRM_IOCTL_ARGS); +#if __HAVE_DMA +extern int DRM(addbufs_agp)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_pci)(DRM_IOCTL_ARGS); +extern int DRM(addbufs_sg)(DRM_IOCTL_ARGS); +extern int DRM(addbufs)(DRM_IOCTL_ARGS); +extern int DRM(infobufs)(DRM_IOCTL_ARGS); +extern int DRM(markbufs)(DRM_IOCTL_ARGS); +extern int DRM(freebufs)(DRM_IOCTL_ARGS); +extern int DRM(mapbufs)(DRM_IOCTL_ARGS); +#endif + +/* DMA support (drm_dma.h) */ +#if __HAVE_DMA +extern int DRM(control)(DRM_IOCTL_ARGS); +#endif +#if __HAVE_VBL_IRQ +extern int DRM(wait_vblank)(DRM_IOCTL_ARGS); +#endif + +/* AGP/GART support (drm_agpsupport.h) */ +#if __REALLY_HAVE_AGP +extern int DRM(agp_acquire)(DRM_IOCTL_ARGS); +extern int DRM(agp_release)(DRM_IOCTL_ARGS); +extern int DRM(agp_enable)(DRM_IOCTL_ARGS); +extern int DRM(agp_info)(DRM_IOCTL_ARGS); +extern int DRM(agp_alloc)(DRM_IOCTL_ARGS); +extern int DRM(agp_free)(DRM_IOCTL_ARGS); +extern int DRM(agp_unbind)(DRM_IOCTL_ARGS); +extern int DRM(agp_bind)(DRM_IOCTL_ARGS); +#endif + +/* Scatter Gather Support (drm_scatter.h) */ +#if __HAVE_SG +extern int DRM(sg_alloc)(DRM_IOCTL_ARGS); +extern int DRM(sg_free)(DRM_IOCTL_ARGS); +#endif + + #endif /* __KERNEL__ */ #endif /* _DRM_P_H_ */ diff --git a/bsd/drm_bufs.h b/bsd/drm_bufs.h index 5df6f342..8e0534f2 100644 --- a/bsd/drm_bufs.h +++ b/bsd/drm_bufs.h @@ -417,7 +417,7 @@ int DRM(addbufs_agp)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -625,7 +625,7 @@ int DRM(addbufs_pci)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -778,7 +778,7 @@ int DRM(addbufs_sg)( DRM_IOCTL_ARGS ) buf->waiting = 0; buf->pending = 0; buf->dma_wait = 0; - buf->pid = 0; + buf->filp = NULL; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -862,16 +862,16 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) - return DRM(addbufs_agp)( kdev, cmd, data, flags, p ); + return DRM(addbufs_agp)( kdev, cmd, data, flags, p, filp ); else #endif #if __REALLY_HAVE_SG if ( request.flags & _DRM_SG_BUFFER ) - return DRM(addbufs_sg)( kdev, cmd, data, flags, p ); + return DRM(addbufs_sg)( kdev, cmd, data, flags, p, filp ); else #endif #if __HAVE_PCI_DMA - return DRM(addbufs_pci)( kdev, cmd, data, flags, p ); + return DRM(addbufs_pci)( kdev, cmd, data, flags, p, filp ); #else return DRM_ERR(EINVAL); #endif @@ -995,9 +995,9 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } buf = dma->buflist[idx]; - if ( buf->pid != DRM_CURRENTPID ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - DRM_CURRENTPID, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR("Process %d freeing buffer not owned\n", + DRM_CURRENTPID); return DRM_ERR(EINVAL); } DRM(free_buffer)( dev, buf ); diff --git a/bsd/drm_dma.h b/bsd/drm_dma.h index 946e652c..fa0bd20d 100644 --- a/bsd/drm_dma.h +++ b/bsd/drm_dma.h @@ -182,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = NULL; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -205,14 +205,14 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp) { drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); diff --git a/bsd/drm_drv.h b/bsd/drm_drv.h index d477a0f8..74655ee9 100644 --- a/bsd/drm_drv.h +++ b/bsd/drm_drv.h @@ -705,7 +705,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } DRM_UNLOCK; @@ -929,7 +929,8 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) drm_file_t *priv; DRM_DEVICE; int retcode = 0; - + DRMFILE __unused filp = (void *)(DRM_CURRENTPID); + DRM_DEBUG( "open_count = %d\n", dev->open_count ); priv = DRM(find_file_by_proc)(dev, p); if (!priv) { @@ -952,7 +953,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) #endif if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == DRM_CURRENTPID) { + && dev->lock.filp == (void *)DRM_CURRENTPID) { DRM_DEBUG("Process %d dead, freeing lock for context %d\n", DRM_CURRENTPID, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); @@ -1002,7 +1003,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( dev, (void *)priv->pid ); #endif #if defined (__FreeBSD__) && (__FreeBSD_version >= 500000) @@ -1052,12 +1053,13 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) /* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm. */ -int DRM(ioctl)( DRM_IOCTL_ARGS ) +int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, + DRM_STRUCTPROC *p) { DRM_DEVICE; int retcode = 0; drm_ioctl_desc_t *ioctl; - d_ioctl_t *func; + int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); DRM_PRIV; @@ -1123,7 +1125,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS ) || ( ioctl->auth_needed && !priv->authenticated ) ) { retcode = EACCES; } else { - retcode = func( kdev, cmd, data, flags, p ); + retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID); } } @@ -1178,7 +1180,7 @@ int DRM(lock)( DRM_IOCTL_ARGS ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = DRM_CURRENTPID; + dev->lock.filp = (void *)DRM_CURRENTPID; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ diff --git a/bsd/drm_lock.h b/bsd/drm_lock.h index 6dd4f3c4..3bab78ef 100644 --- a/bsd/drm_lock.h +++ b/bsd/drm_lock.h @@ -78,7 +78,7 @@ int DRM(lock_transfer)(drm_device_t *dev, { unsigned int old, new; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -91,19 +91,16 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - pid_t pid = dev->lock.pid; - dev->lock.pid = 0; + dev->lock.filp = NULL; do { old = *lock; new = 0; } while (!atomic_cmpset_int(lock, old, new)); if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", - context, - _DRM_LOCKING_CONTEXT(old), - pid); + DRM_ERROR("%d freed heavyweight lock held by %d\n", + context, _DRM_LOCKING_CONTEXT(old)); return 1; } DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); diff --git a/bsd/drm_os_freebsd.h b/bsd/drm_os_freebsd.h index 227c9963..30a6e362 100644 --- a/bsd/drm_os_freebsd.h +++ b/bsd/drm_os_freebsd.h @@ -101,7 +101,11 @@ #define DRM_CURRENTPID curproc->p_pid #endif -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, 0, DRM_CURPROC) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, 0, DRM_CURPROC) #define DRM_SUSER(p) suser(p) @@ -133,6 +137,16 @@ return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -368,8 +382,6 @@ find_first_zero_bit(volatile void *p, int max) /* drm_drv.h */ extern d_ioctl_t DRM(ioctl); -extern d_ioctl_t DRM(lock); -extern d_ioctl_t DRM(unlock); extern d_open_t DRM(open); extern d_close_t DRM(close); extern d_read_t DRM(read); @@ -381,81 +393,9 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern d_ioctl_t DRM(irq_busid); -extern d_ioctl_t DRM(getunique); -extern d_ioctl_t DRM(setunique); -extern d_ioctl_t DRM(getmap); -extern d_ioctl_t DRM(getclient); -extern d_ioctl_t DRM(getstats); - -/* Context IOCTL support (drm_context.h) */ -extern d_ioctl_t DRM(resctx); -extern d_ioctl_t DRM(addctx); -extern d_ioctl_t DRM(modctx); -extern d_ioctl_t DRM(getctx); -extern d_ioctl_t DRM(switchctx); -extern d_ioctl_t DRM(newctx); -extern d_ioctl_t DRM(rmctx); -extern d_ioctl_t DRM(setsareactx); -extern d_ioctl_t DRM(getsareactx); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern d_ioctl_t DRM(adddraw); -extern d_ioctl_t DRM(rmdraw); - -/* Authentication IOCTL support (drm_auth.h) */ -extern d_ioctl_t DRM(getmagic); -extern d_ioctl_t DRM(authmagic); - -/* Locking IOCTL support (drm_lock.h) */ -extern d_ioctl_t DRM(block); -extern d_ioctl_t DRM(unblock); -extern d_ioctl_t DRM(finish); - -/* Buffer management support (drm_bufs.h) */ -extern d_ioctl_t DRM(addmap); -extern d_ioctl_t DRM(rmmap); -#if __HAVE_DMA -extern d_ioctl_t DRM(addbufs_agp); -extern d_ioctl_t DRM(addbufs_pci); -extern d_ioctl_t DRM(addbufs_sg); -extern d_ioctl_t DRM(addbufs); -extern d_ioctl_t DRM(infobufs); -extern d_ioctl_t DRM(markbufs); -extern d_ioctl_t DRM(freebufs); -extern d_ioctl_t DRM(mapbufs); -#endif - -/* Memory management support (drm_memory.h) */ -extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern d_ioctl_t DRM(control); -#endif -#if __HAVE_VBL_IRQ -extern d_ioctl_t DRM(wait_vblank); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern d_ioctl_t DRM(agp_acquire); -extern d_ioctl_t DRM(agp_release); -extern d_ioctl_t DRM(agp_enable); -extern d_ioctl_t DRM(agp_info); -extern d_ioctl_t DRM(agp_alloc); -extern d_ioctl_t DRM(agp_free); -extern d_ioctl_t DRM(agp_unbind); -extern d_ioctl_t DRM(agp_bind); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern d_ioctl_t DRM(sg_alloc); -extern d_ioctl_t DRM(sg_free); -#endif - -/* SysCtl Support (drm_sysctl.h) */ +/* sysctl support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev); + +/* Memory info sysctl (drm_memory.h) */ +extern int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS; diff --git a/bsd/drm_os_netbsd.h b/bsd/drm_os_netbsd.h index 605b6a2c..fa158254 100644 --- a/bsd/drm_os_netbsd.h +++ b/bsd/drm_os_netbsd.h @@ -17,6 +17,7 @@ #include #include #include +#include /* For TIOCSPGRP/TIOCGPGRP */ #include @@ -31,11 +32,9 @@ #include #include -#include "drmvar.h" - #define __REALLY_HAVE_AGP __HAVE_AGP -#define __REALLY_HAVE_MTRR 0 +#define __REALLY_HAVE_MTRR 1 #define __REALLY_HAVE_SG 0 #if __REALLY_HAVE_AGP @@ -43,8 +42,7 @@ #include #endif -#define device_t struct device * -extern struct cfdriver DRM(_cd); +#include #if DRM_DEBUG #undef DRM_DEBUG_CODE @@ -52,12 +50,20 @@ extern struct cfdriver DRM(_cd); #endif #undef DRM_DEBUG +#if DRM_LINUX +#undef DRM_LINUX /* FIXME: Linux compat has not been ported yet */ +#endif + +typedef drm_device_t *device_t; + +extern struct cfdriver DRM(cd); + #define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */ #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) #define DRM_DEV_UID 0 #define DRM_DEV_GID 0 -#define CDEV_MAJOR 90 +#define CDEV_MAJOR 34 #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc @@ -68,21 +74,34 @@ extern struct cfdriver DRM(_cd); #define DRM_SPINUNLOCK(u) simple_unlock(u); #define DRM_CURRENTPID curproc->p_pid -#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p +/* Currently our DRMFILE (filp) is a void * which is actually the pid + * of the current process. It should be a per-open unique pointer, but + * code for that is not yet written */ +#define DRMFILE void * +#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p, DRMFILE filp #define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL) #define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL) #define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) #define DRM_TASKQUEUE_ARGS void *dev, int pending -#define DRM_IRQ_ARGS void *device -#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev)) +#define DRM_IRQ_ARGS void *arg +#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev)) +/* XXX Not sure if this is the 'right' version.. */ +#if __NetBSD_Version__ >= 106140000 +MALLOC_DECLARE(DRM(M_DRM)); +#else +/* XXX Make sure this works */ +extern const int DRM(M_DRM) = M_DEVBUF; +#endif /* __NetBSD_Version__ */ #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) -#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) +#define DRM_FREE(pt,size) free( pt, DRM(M_DRM) ) #define DRM_VTOPHYS(addr) vtophys(addr) -#define DRM_READ8(addr) *((volatile char *)(addr)) -#define DRM_READ32(addr) *((volatile long *)(addr)) -#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val) -#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val) -#define DRM_AGP_FIND_DEVICE() + +#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) +#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) ) +#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) ) +#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) ) + +#define DRM_AGP_FIND_DEVICE() agp_find_device(0) #define DRM_PRIV \ drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ @@ -91,6 +110,16 @@ extern struct cfdriver DRM(_cd); return EINVAL; \ } +#define LOCK_TEST_WITH_RETURN(dev, filp) \ +do { \ + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ + dev->lock.filp != filp) { \ + DRM_ERROR("%s called without lock held\n", \ + __FUNCTION__); \ + return EINVAL; \ + } \ +} while (0) + #define DRM_UDELAY( udelay ) \ do { \ struct timeval tv1, tv2; \ @@ -105,7 +134,7 @@ do { \ do { \ drm_map_list_entry_t *listentry; \ TAILQ_FOREACH(listentry, dev->maplist, link) { \ - drm_map_t *map = listentry->map; \ + drm_local_map_t *map = listentry->map; \ if (map->type == _DRM_SHM && \ map->flags & _DRM_CONTAINS_LOCK) { \ dev_priv->sarea = map; \ @@ -114,7 +143,15 @@ do { \ } \ } while (0) -#define return DRM_ERR(v) return v; +#define DRM_HZ hz + +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +while (!condition) { \ + ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ + if ( ret ) \ + return ret; \ +} + #define DRM_ERR(v) v #define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \ @@ -125,21 +162,25 @@ do { \ copyout(arg2, arg1, arg3) #define DRM_COPY_FROM_USER(arg1, arg2, arg3) \ copyin(arg2, arg1, arg3) +/* Macros for userspace access with checking readability once */ +/* FIXME: can't find equivalent functionality for nocheck yet. + * It'll be slower than linux, but should be correct. + */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ)) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + copyin(arg2, arg1, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + ((val) = fuword(uaddr), 0) -#define DRM_READMEMORYBARRIER \ -{ \ - int xchangeDummy; \ - DRM_DEBUG("%s\n", __FUNCTION__); \ - __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); \ - __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" \ - " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" \ - " pop %%eax" : /* no outputs */ : /* no inputs */ ); \ -} while (0); +#define DRM_WRITEMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0); +#define DRM_READMEMORYBARRIER( map ) \ + bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ); -#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER - -#define DRM_WAKEUP(w) wakeup(w) +#define DRM_WAKEUP(w) wakeup((void *)w) #define DRM_WAKEUP_INT(w) wakeup(w) +#define DRM_INIT_WAITQUEUE( queue ) do {} while (0) #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) @@ -151,30 +192,46 @@ typedef struct drm_chipinfo char *name; } drm_chipinfo_t; +#define cpu_to_le32(x) (x) /* FIXME */ + typedef u_int32_t dma_addr_t; -typedef volatile u_int32_t atomic_t; +typedef volatile long atomic_t; typedef u_int32_t cycles_t; -typedef u_int32_t spinlock_t; typedef u_int32_t u32; typedef u_int16_t u16; typedef u_int8_t u8; typedef dev_type_ioctl(d_ioctl_t); typedef vaddr_t vm_offset_t; +/* FIXME */ #define atomic_set(p, v) (*(p) = (v)) #define atomic_read(p) (*(p)) -#define atomic_inc(p) atomic_add_int(p, 1) -#define atomic_dec(p) atomic_subtract_int(p, 1) -#define atomic_add(n, p) atomic_add_int(p, n) -#define atomic_sub(n, p) atomic_subtract_int(p, n) +#define atomic_inc(p) (*(p) += 1) +#define atomic_dec(p) (*(p) -= 1) +#define atomic_add(n, p) (*(p) += (n)) +#define atomic_sub(n, p) (*(p) -= (n)) -/* FIXME: Is NetBSD's kernel non-reentrant? */ +/* FIXME */ #define atomic_add_int(p, v) *(p) += v #define atomic_subtract_int(p, v) *(p) -= v #define atomic_set_int(p, bits) *(p) |= (bits) #define atomic_clear_int(p, bits) *(p) &= ~(bits) /* Fake this */ + +static __inline int +atomic_cmpset_int(__volatile__ int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} + static __inline atomic_t test_and_set_bit(int b, atomic_t *p) { @@ -224,20 +281,6 @@ find_first_zero_bit(atomic_t *p, int max) #define spldrm() spltty() #define jiffies hardclock_ticks -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void @@ -258,7 +301,7 @@ do { \ #define DRM_DEBUG(fmt, arg...) \ do { \ if (DRM(flags) & DRM_FLAG_DEBUG) \ - printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \ + printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -292,8 +335,6 @@ do { \ /* drm_drv.h */ extern dev_type_ioctl(DRM(ioctl)); -extern dev_type_ioctl(DRM(lock)); -extern dev_type_ioctl(DRM(unlock)); extern dev_type_open(DRM(open)); extern dev_type_close(DRM(close)); extern dev_type_read(DRM(read)); @@ -305,75 +346,5 @@ extern int DRM(open_helper)(dev_t kdev, int flags, int fmt, extern drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p); -/* Misc. IOCTL support (drm_ioctl.h) */ -extern dev_type_ioctl(DRM(irq_busid)); -extern dev_type_ioctl(DRM(getunique)); -extern dev_type_ioctl(DRM(setunique)); -extern dev_type_ioctl(DRM(getmap)); -extern dev_type_ioctl(DRM(getclient)); -extern dev_type_ioctl(DRM(getstats)); - -/* Context IOCTL support (drm_context.h) */ -extern dev_type_ioctl(DRM(resctx)); -extern dev_type_ioctl(DRM(addctx)); -extern dev_type_ioctl(DRM(modctx)); -extern dev_type_ioctl(DRM(getctx)); -extern dev_type_ioctl(DRM(switchctx)); -extern dev_type_ioctl(DRM(newctx)); -extern dev_type_ioctl(DRM(rmctx)); -extern dev_type_ioctl(DRM(setsareactx)); -extern dev_type_ioctl(DRM(getsareactx)); - -/* Drawable IOCTL support (drm_drawable.h) */ -extern dev_type_ioctl(DRM(adddraw)); -extern dev_type_ioctl(DRM(rmdraw)); - -/* Authentication IOCTL support (drm_auth.h) */ -extern dev_type_ioctl(DRM(getmagic)); -extern dev_type_ioctl(DRM(authmagic)); - -/* Locking IOCTL support (drm_lock.h) */ -extern dev_type_ioctl(DRM(block)); -extern dev_type_ioctl(DRM(unblock)); -extern dev_type_ioctl(DRM(finish)); - -/* Buffer management support (drm_bufs.h) */ -extern dev_type_ioctl(DRM(addmap)); -extern dev_type_ioctl(DRM(rmmap)); -#if __HAVE_DMA -extern dev_type_ioctl(DRM(addbufs_agp)); -extern dev_type_ioctl(DRM(addbufs_pci)); -extern dev_type_ioctl(DRM(addbufs_sg)); -extern dev_type_ioctl(DRM(addbufs)); -extern dev_type_ioctl(DRM(infobufs)); -extern dev_type_ioctl(DRM(markbufs)); -extern dev_type_ioctl(DRM(freebufs)); -extern dev_type_ioctl(DRM(mapbufs)); -#endif - -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA -extern dev_type_ioctl(DRM(control)); -#endif - -/* AGP/GART support (drm_agpsupport.h) */ -#if __REALLY_HAVE_AGP -extern dev_type_ioctl(DRM(agp_acquire)); -extern dev_type_ioctl(DRM(agp_release)); -extern dev_type_ioctl(DRM(agp_enable)); -extern dev_type_ioctl(DRM(agp_info)); -extern dev_type_ioctl(DRM(agp_alloc)); -extern dev_type_ioctl(DRM(agp_free)); -extern dev_type_ioctl(DRM(agp_unbind)); -extern dev_type_ioctl(DRM(agp_bind)); -#endif - -/* Scatter Gather Support (drm_scatter.h) */ -#if __HAVE_SG -extern dev_type_ioctl(DRM(sg_alloc)); -extern dev_type_ioctl(DRM(sg_free)); -#endif - -/* SysCtl Support (drm_sysctl.h) */ extern int DRM(sysctl_init)(drm_device_t *dev); extern int DRM(sysctl_cleanup)(drm_device_t *dev);