diff options
author | Eric Anholt <anholt@freebsd.org> | 2003-10-19 23:35:58 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2003-10-19 23:35:58 +0000 |
commit | 0cf1887139eb1ce18d09f7be0567aa93d802040d (patch) | |
tree | 05704a5a90bc9b0fbabed4029f200f9eff955953 | |
parent | 59fbe01fea8f77fc3810643c14a1738d197d4291 (diff) |
- SMPng lock the DRM. This is only partial -- there are a few code paths
used by root (the X Server) which are not locked. However, it should
deal with lost-IRQ issues on -current which I think people have been
experiencing but I am unable to reproduce (though I understand why they
would occur, because of a bug of mine). Note that most of the locking
(DRM_LOCK()/UNLOCK()) is all covered by Giant still, so it doesn't
matter yet.
- Remove locking on FreeBSD-stable and NetBSD. These are covered by the
fact that there is no reentrancy of the kernel except by interrupts,
which are locked using spldrm()/splx() instead.
-rw-r--r-- | bsd-core/ati_pcigart.c | 2 | ||||
-rw-r--r-- | bsd-core/drmP.h | 37 | ||||
-rw-r--r-- | bsd-core/drm_auth.c | 17 | ||||
-rw-r--r-- | bsd-core/drm_bufs.c | 161 | ||||
-rw-r--r-- | bsd-core/drm_dma.c | 6 | ||||
-rw-r--r-- | bsd-core/drm_drv.c | 138 | ||||
-rw-r--r-- | bsd-core/drm_fops.c | 13 | ||||
-rw-r--r-- | bsd-core/drm_irq.c | 30 | ||||
-rw-r--r-- | bsd-core/drm_os_freebsd.h | 36 | ||||
-rw-r--r-- | bsd-core/drm_os_netbsd.h | 21 | ||||
-rw-r--r-- | bsd-core/drm_pci.c | 2 | ||||
-rw-r--r-- | bsd-core/drm_sysctl.c | 6 | ||||
-rw-r--r-- | bsd-core/drm_vm.c | 2 | ||||
-rw-r--r-- | bsd/ati_pcigart.h | 2 | ||||
-rw-r--r-- | bsd/drmP.h | 37 | ||||
-rw-r--r-- | bsd/drm_auth.h | 17 | ||||
-rw-r--r-- | bsd/drm_bufs.h | 161 | ||||
-rw-r--r-- | bsd/drm_dma.h | 6 | ||||
-rw-r--r-- | bsd/drm_drv.h | 138 | ||||
-rw-r--r-- | bsd/drm_fops.h | 13 | ||||
-rw-r--r-- | bsd/drm_irq.h | 30 | ||||
-rw-r--r-- | bsd/drm_os_freebsd.h | 36 | ||||
-rw-r--r-- | bsd/drm_os_netbsd.h | 21 | ||||
-rw-r--r-- | bsd/drm_pci.h | 2 | ||||
-rw-r--r-- | bsd/drm_sysctl.h | 6 | ||||
-rw-r--r-- | bsd/drm_vm.h | 2 |
26 files changed, 470 insertions, 472 deletions
diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c index 0a05dda6..9aa2192f 100644 --- a/bsd-core/ati_pcigart.c +++ b/bsd-core/ati_pcigart.c @@ -59,7 +59,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, } address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, - DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0); + DRM(M_DRM), M_NOWAIT, 0ul, 0xfffffffful, PAGE_SIZE, 0); if ( !address ) { DRM_ERROR( "cannot allocate PCI GART page!\n" ); goto done; diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index c39df162..67915374 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -180,7 +180,6 @@ typedef struct drm_freelist { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ - DRM_SPINTYPE lock; } drm_freelist_t; typedef struct drm_buf_entry { @@ -216,10 +215,17 @@ struct drm_file { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ - wait_queue_head_t lock_queue; /* Queue of blocked processes */ + int lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; +/* This structure, in the drm_device_t, is always initialized while the device + * is open. dev->dma_lock protects the incrementing of dev->buf_use, which + * when set marks that no further bufs may be allocated until device teardown + * occurs (when the last open of the device has closed). The high/low + * watermarks of bufs are only touched by the X Server, and thus not + * concurrently accessed, so no locking is needed. + */ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; @@ -311,8 +317,15 @@ struct drm_device { int flags; /* Flags to open(2) */ /* Locks */ - DRM_SPINTYPE count_lock; /* For open_count, buf_use, buf_alloc */ - struct lock dev_lock; /* For others */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#if __HAVE_DMA + struct mtx dma_lock; /* protects dev->dma */ +#endif +#if __HAVE_IRQ + struct mtx irq_lock; /* protects irq condition checks */ +#endif + struct mtx dev_lock; /* protects everything else */ +#endif /* Usage Counters */ int open_count; /* Outstanding files open */ int buf_use; /* Buffers in use -- cannot alloc */ @@ -327,8 +340,8 @@ struct drm_device { drm_file_list_t files; drm_magic_head_t magiclist[DRM_HASH_SIZE]; - /* Memory management */ - drm_map_list_t *maplist; /* Linked list of regions */ + /* Linked list of mappable regions. Protected by dev_lock */ + drm_map_list_t *maplist; drm_local_map_t **context_sareas; int max_context; @@ -349,18 +362,13 @@ struct drm_device { #endif void *irqh; /* Handle from bus_setup_intr */ atomic_t context_flag; /* Context swapping flag */ - struct callout timer; /* Timer for delaying ctx switch */ int last_context; /* Last current context */ #if __FreeBSD_version >= 400005 struct task task; #endif #if __HAVE_VBL_IRQ - wait_queue_head_t vbl_queue; /* vbl wait channel */ + int vbl_queue; /* vbl wait channel */ atomic_t vbl_received; -#if 0 /* vbl signals are untested */ - struct drm_vbl_sig_list vbl_sig_list; - DRM_SPINTYPE vbl_lock; -#endif #endif #ifdef __FreeBSD__ @@ -382,11 +390,6 @@ struct drm_device { extern int DRM(flags); - /* Authentication (drm_auth.h) */ -extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, - drm_magic_t magic); -extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); - /* Driver support (drm_drv.h) */ extern int DRM(version)( DRM_IOCTL_ARGS ); diff --git a/bsd-core/drm_auth.c b/bsd-core/drm_auth.c index 6f819ad8..9e34b35c 100644 --- a/bsd-core/drm_auth.c +++ b/bsd-core/drm_auth.c @@ -54,7 +54,7 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) return retval; } -int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) +static int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) { int hash; drm_magic_entry_t *entry; @@ -82,7 +82,7 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) return 0; } -int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) +static int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) { drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; @@ -116,9 +116,17 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; - drm_auth_t auth; + drm_auth_t auth; + drm_file_t *priv; DRM_DEVICE; - DRM_PRIV; + + DRM_LOCK(); + priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); + DRM_UNLOCK(); + if (priv == NULL) { + DRM_DEBUG("can't find authenticator\n"); + return EINVAL; + } /* Find unique magic */ if (priv->magic) { @@ -152,6 +160,7 @@ int DRM(authmagic)(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth)); DRM_DEBUG("%u\n", auth.magic); + if ((file = DRM(find_file)(dev, auth.magic))) { file->authenticated = 1; DRM(remove_magic)(dev, auth.magic); diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c index 4c33763c..cdd2359d 100644 --- a/bsd-core/drm_bufs.c +++ b/bsd-core/drm_bufs.c @@ -226,6 +226,8 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } TAILQ_REMOVE(dev->maplist, list, link); + DRM_UNLOCK(); + DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); switch (map->type) { @@ -268,7 +270,6 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) break; } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); - DRM_UNLOCK(); return 0; } @@ -350,20 +351,11 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - - DRM_LOCK(); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK(); - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -394,7 +386,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -413,7 +404,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -428,8 +418,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); - DRM_UNLOCK(); - request->count = entry->buf_count; request->size = size; @@ -467,20 +455,12 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "count=%d, size=%d (%d), order=%d\n", request->count, request->size, size, order ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - alignment = (request->flags & _DRM_PAGE_ALIGN) ? round_page(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; - DRM_LOCK(); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK(); - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } entry->buflist = DRM(alloc)(count * sizeof(*entry->buflist), DRM_MEM_BUFS); @@ -503,7 +483,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM_MEM_SEGS); DRM(free)(entry->seglist_bus, count * sizeof(*entry->seglist_bus), DRM_MEM_SEGS); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -532,7 +511,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -571,7 +549,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES ); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } bzero(buf->dev_private, buf->dev_priv_size); @@ -593,7 +570,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -614,8 +590,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) dma->page_count += entry->seg_count << page_order; dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - DRM_UNLOCK(); - request->count = entry->buf_count; request->size = size; @@ -662,23 +636,12 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - - DRM_LOCK(); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK(); - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } - entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - if ( !entry->buflist ) { - DRM_UNLOCK(); + entry->buflist = DRM(calloc)(1, count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (entry->buflist == NULL) return DRM_ERR(ENOMEM); - } - memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); entry->buf_size = size; entry->page_order = page_order; @@ -706,7 +669,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -728,7 +690,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -743,8 +704,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); - DRM_UNLOCK(); - request->count = entry->buf_count; request->size = size; @@ -759,25 +718,28 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_buf_desc_t request; int err; + int order; DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); - if (dev->dma == NULL) + if (request.count < 0 || request.count > 4096) return DRM_ERR(EINVAL); - if (request.count < 0 || request.count > 4096) + order = DRM(order)(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return DRM_ERR(EINVAL); - DRM_SPINLOCK(&dev->count_lock); - if (dev->buf_use) { - DRM_SPINUNLOCK(&dev->count_lock); + DRM_SPINLOCK(&dev->dma_lock); + /* No more allocations after first buffer-using ioctl. */ + if (dev->buf_use != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); return DRM_ERR(EBUSY); } - /* dev->buf_alloc acts as a lock to prevent infobufs/mapbufs from - * trying to read from the dma->bufs while buffers are being allocated */ - dev->buf_alloc++; - DRM_SPINUNLOCK(&dev->count_lock); - + /* No more than one allocation per order */ + if (dev->dma->bufs[order].buf_count != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(ENOMEM); + } #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) @@ -794,13 +756,10 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #else err = DRM_ERR(EINVAL); #endif + DRM_SPINUNLOCK(&dev->dma_lock); DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request, sizeof(request)); - DRM_SPINLOCK(&dev->count_lock); - dev->buf_alloc--; - DRM_SPINUNLOCK(&dev->count_lock); - return err; } @@ -811,18 +770,13 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) drm_buf_info_t request; int i; int count; + int retcode = 0; - if ( !dma ) return DRM_ERR(EINVAL); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); - DRM_SPINLOCK( &dev->count_lock ); - if (dev->buf_alloc != 0) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM_ERR(EBUSY); - } + DRM_SPINLOCK(&dev->dma_lock); ++dev->buf_use; /* Can't allocate more after this call */ - DRM_SPINUNLOCK( &dev->count_lock ); - - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); + DRM_SPINUNLOCK(&dev->dma_lock); for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { if ( dma->bufs[i].buf_count ) ++count; @@ -841,8 +795,10 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) from.high_mark = dma->bufs[i].freelist.high_mark; if (DRM_COPY_TO_USER(&request.list[count], &from, - sizeof(drm_buf_desc_t)) != 0) - return DRM_ERR(EFAULT); + sizeof(drm_buf_desc_t)) != 0) { + retcode = DRM_ERR(EFAULT); + break; + } DRM_DEBUG( "%d %d %d %d %d\n", i, @@ -858,7 +814,7 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) ); - return 0; + return retcode; } int DRM(markbufs)( DRM_IOCTL_ARGS ) @@ -867,26 +823,28 @@ int DRM(markbufs)( DRM_IOCTL_ARGS ) drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int order; - drm_buf_entry_t *entry; - - if ( !dma ) return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); DRM_DEBUG( "%d, %d, %d\n", request.size, request.low_mark, request.high_mark ); - order = DRM(order)( request.size ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - entry = &dma->bufs[order]; + - if ( request.low_mark < 0 || request.low_mark > entry->buf_count ) + order = DRM(order)(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER || + request.low_mark < 0 || request.high_mark < 0) { return DRM_ERR(EINVAL); - if ( request.high_mark < 0 || request.high_mark > entry->buf_count ) + } + + DRM_SPINLOCK(&dev->dma_lock); + if (request.low_mark > dma->bufs[order].buf_count || + request.high_mark > dma->bufs[order].buf_count) { return DRM_ERR(EINVAL); + } - entry->freelist.low_mark = request.low_mark; - entry->freelist.high_mark = request.high_mark; + dma->bufs[order].freelist.low_mark = request.low_mark; + dma->bufs[order].freelist.high_mark = request.high_mark; + DRM_SPINUNLOCK(&dev->dma_lock); return 0; } @@ -899,32 +857,36 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) int i; int idx; drm_buf_t *buf; - - if ( !dma ) return DRM_ERR(EINVAL); + int retcode = 0; DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) ); DRM_DEBUG( "%d\n", request.count ); + + DRM_SPINLOCK(&dev->dma_lock); for ( i = 0 ; i < request.count ; i++ ) { - if ( DRM_COPY_FROM_USER( &idx, - &request.list[i], - sizeof(idx) ) ) - return DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(&idx, &request.list[i], sizeof(idx))) { + retcode = DRM_ERR(EFAULT); + break; + } if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "Index %d (of %d max)\n", idx, dma->buf_count - 1 ); - return DRM_ERR(EINVAL); + retcode = DRM_ERR(EINVAL); + break; } buf = dma->buflist[idx]; if ( buf->filp != filp ) { DRM_ERROR("Process %d freeing buffer not owned\n", DRM_CURRENTPID); - return DRM_ERR(EINVAL); + retcode = DRM_ERR(EINVAL); + break; } DRM(free_buffer)( dev, buf ); } + DRM_SPINUNLOCK(&dev->dma_lock); - return 0; + return retcode; } int DRM(mapbufs)( DRM_IOCTL_ARGS ) @@ -949,16 +911,6 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) drm_buf_map_t request; int i; - if ( !dma ) return DRM_ERR(EINVAL); - - DRM_SPINLOCK( &dev->count_lock ); - if (dev->buf_alloc != 0) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM_ERR(EBUSY); - } - dev->buf_use++; /* Can't allocate more after this call */ - DRM_SPINUNLOCK( &dev->count_lock ); - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) ); #ifdef __NetBSD__ @@ -972,6 +924,10 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) vms = p->p_vmspace; #endif + DRM_SPINLOCK(&dev->dma_lock); + dev->buf_use++; /* Can't allocate more after this call */ + DRM_SPINUNLOCK(&dev->dma_lock); + if (request.count < dma->buf_count) goto done; @@ -1040,4 +996,3 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) } #endif /* __HAVE_DMA */ - diff --git a/bsd-core/drm_dma.c b/bsd-core/drm_dma.c index d5852403..8d87c38a 100644 --- a/bsd-core/drm_dma.c +++ b/bsd-core/drm_dma.c @@ -51,6 +51,8 @@ int DRM(dma_setup)( drm_device_t *dev ) if (dev->dma == NULL) return DRM_ERR(ENOMEM); + DRM_SPININIT(dev->dma_lock, "drmdma"); + return 0; } @@ -59,7 +61,8 @@ void DRM(dma_takedown)(drm_device_t *dev) drm_device_dma_t *dma = dev->dma; int i, j; - if (!dma) return; + if (dma == NULL) + return; /* Clear dma buffers */ for (i = 0; i <= DRM_MAX_ORDER; i++) { @@ -106,6 +109,7 @@ void DRM(dma_takedown)(drm_device_t *dev) DRM_MEM_PAGES); DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); dev->dma = NULL; + DRM_SPINUNINIT(dev->dma_lock); } diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index 8a9e3036..731f31da 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -111,7 +111,7 @@ int DRM(flags) = 0; #endif static int DRM(init)(device_t nbdev); -static void DRM(cleanup)(device_t nbdev); +static void DRM(cleanup)(drm_device_t *dev); #ifdef __FreeBSD__ #define DRIVER_SOFTC(unit) \ @@ -253,7 +253,7 @@ static int DRM(attach)(device_t dev) static int DRM(detach)(device_t dev) { - DRM(cleanup)(dev); + DRM(cleanup)(device_get_softc(dev)); return 0; } static device_method_t DRM(methods)[] = { @@ -411,6 +411,7 @@ const char *DRM(find_description)(int vendor, int device) { return NULL; } +/* Initialize the DRM on first open. Called with device's lock held */ static int DRM(setup)( drm_device_t *dev ) { int i; @@ -421,7 +422,7 @@ static int DRM(setup)( drm_device_t *dev ) #if __HAVE_DMA i = DRM(dma_setup)( dev ); - if ( i < 0 ) + if ( i != 0 ) return i; #endif @@ -481,11 +482,6 @@ static int DRM(setup)( drm_device_t *dev ) dev->irq = 0; dev->context_flag = 0; dev->last_context = 0; -#if __FreeBSD_version >= 500000 - callout_init( &dev->timer, 1 ); -#else - callout_init( &dev->timer ); -#endif #ifdef __FreeBSD__ dev->buf_sigio = NULL; @@ -499,7 +495,9 @@ static int DRM(setup)( drm_device_t *dev ) return 0; } - +/* Free resources associated with the DRM on the last close. + * Called with the device's lock held. + */ static int DRM(takedown)( drm_device_t *dev ) { drm_magic_entry_t *pt, *next; @@ -515,9 +513,6 @@ static int DRM(takedown)( drm_device_t *dev ) DRM(irq_uninstall)( dev ); #endif - DRM_LOCK(); - callout_stop( &dev->timer ); - if ( dev->unique ) { DRM(free)( dev->unique, strlen( dev->unique ) + 1, DRM_MEM_DRIVER ); @@ -540,7 +535,7 @@ static int DRM(takedown)( drm_device_t *dev ) drm_agp_mem_t *nexte; /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ + intact until DRM(cleanup) is called. */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; if ( entry->bound ) DRM(unbind_agp)( entry->handle ); @@ -625,7 +620,6 @@ static int DRM(takedown)( drm_device_t *dev ) dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } - DRM_UNLOCK(); return 0; } @@ -664,11 +658,12 @@ static int DRM(init)( device_t nbdev ) DRM_DEV_GID, DRM_DEV_MODE, "dri/card%d", unit ); +#if __FreeBSD_version >= 500000 + mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF); +#endif #elif defined(__NetBSD__) unit = minor(dev->device.dv_unit); #endif - DRM_SPININIT(dev->count_lock, "drm device"); - lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); dev->name = DRIVER_NAME; DRM(mem_init)(); DRM(sysctl_init)(dev); @@ -679,12 +674,8 @@ static int DRM(init)( device_t nbdev ) #if __MUST_HAVE_AGP if ( dev->agp == NULL ) { DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(sysctl_cleanup)( dev ); -#ifdef __FreeBSD__ - destroy_dev(dev->devnode); -#endif - DRM(takedown)( dev ); - return DRM_ERR(ENOMEM); + retcode = DRM_ERR(ENOMEM); + goto error; } #endif /* __MUST_HAVE_AGP */ #if __REALLY_HAVE_MTRR @@ -716,12 +707,7 @@ static int DRM(init)( device_t nbdev ) retcode = DRM(ctxbitmap_init)( dev ); if (retcode != 0) { DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(sysctl_cleanup)( dev ); -#ifdef __FreeBSD__ - destroy_dev(dev->devnode); -#endif - DRM(takedown)( dev ); - return retcode; + goto error; } #endif DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", @@ -735,28 +721,36 @@ static int DRM(init)( device_t nbdev ) DRIVER_POSTINIT(); return 0; + +error: + DRM(sysctl_cleanup)(dev); + DRM_LOCK(); + DRM(takedown)(dev); + DRM_UNLOCK(); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); +#if __FreeBSD_version >= 500000 + mtx_destroy(&dev->dev_lock); +#endif +#endif + return retcode; } /* linux: drm_cleanup is called via cleanup_module at module unload time. * bsd: drm_cleanup is called per device at module unload time. * FIXME: NetBSD */ -static void DRM(cleanup)(device_t nbdev) +static void DRM(cleanup)(drm_device_t *dev) { - drm_device_t *dev; #ifdef __NetBSD__ #if __REALLY_HAVE_MTRR struct mtrr mtrrmap; int one = 1; #endif /* __REALLY_HAVE_MTRR */ - dev = nbdev; #endif /* __NetBSD__ */ DRM_DEBUG( "\n" ); -#ifdef __FreeBSD__ - dev = device_get_softc(nbdev); -#endif DRM(sysctl_cleanup)( dev ); #ifdef __FreeBSD__ destroy_dev(dev->devnode); @@ -777,7 +771,9 @@ static void DRM(cleanup)(device_t nbdev) } #endif + DRM_LOCK(); DRM(takedown)( dev ); + DRM_UNLOCK(); #if __REALLY_HAVE_AGP if ( dev->agp ) { @@ -788,7 +784,9 @@ static void DRM(cleanup)(device_t nbdev) #endif DRIVER_POSTCLEANUP(); DRM(mem_uninit)(); - DRM_SPINUNINIT(dev->count_lock); +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 + mtx_destroy(&dev->dev_lock); +#endif } @@ -834,13 +832,13 @@ int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); - DRM_SPINLOCK( &dev->count_lock ); + DRM_LOCK(); #ifdef __FreeBSD__ device_busy(dev->device); #endif if ( !dev->open_count++ ) retcode = DRM(setup)( dev ); - DRM_SPINUNLOCK( &dev->count_lock ); + DRM_UNLOCK(); } return retcode; @@ -854,8 +852,12 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) DRMFILE filp = (void *)(DRM_CURRENTPID); DRM_DEBUG( "open_count = %d\n", dev->open_count ); + + DRM_LOCK(); + priv = DRM(find_file_by_proc)(dev, p); if (!priv) { + DRM_UNLOCK(); DRM_DEBUG("can't find authenticator\n"); return EINVAL; } @@ -908,10 +910,13 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) break; /* Got lock */ } /* Contention */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + retcode = msleep((void *)&dev->lock.lock_queue, + dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); +#else retcode = tsleep((void *)&dev->lock.lock_queue, - PZERO|PCATCH, - "drmlk2", - 0); + PZERO | PCATCH, "drmlk2", 0); +#endif if (retcode) break; } @@ -933,32 +938,24 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) dev->buf_pgid = 0; #endif /* __NetBSD__ */ - DRM_LOCK(); - priv = DRM(find_file_by_proc)(dev, p); - if (priv) { - priv->refs--; - if (!priv->refs) { - TAILQ_REMOVE(&dev->files, priv, link); - DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); - } + if (--priv->refs == 0) { + TAILQ_REMOVE(&dev->files, priv, link); + DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); } - DRM_UNLOCK(); - /* ======================================================== * End inline drm_release */ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); - DRM_SPINLOCK( &dev->count_lock ); #ifdef __FreeBSD__ device_unbusy(dev->device); #endif - if ( !--dev->open_count ) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM(takedown)( dev ); + if (--dev->open_count == 0) { + retcode = DRM(takedown)(dev); } - DRM_SPINUNLOCK( &dev->count_lock ); + + DRM_UNLOCK(); return retcode; } @@ -973,7 +970,15 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, drm_ioctl_desc_t *ioctl; int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); - DRM_PRIV; + drm_file_t *priv; + + DRM_LOCK(); + priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); + DRM_UNLOCK(); + if (priv == NULL) { + DRM_DEBUG("can't find authenticator\n"); + return EINVAL; + } atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; @@ -988,10 +993,7 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, switch (cmd) { case FIONBIO: - return 0; - case FIOASYNC: - dev->flags |= FASYNC; return 0; #ifdef __FreeBSD__ @@ -1017,7 +1019,7 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, #endif /* __NetBSD__ */ } - if (nr >= DRIVER_IOCTL_COUNT) + if (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE) return EINVAL; ioctl = &DRM(ioctls)[nr]; @@ -1059,12 +1061,8 @@ int DRM(lock)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); #endif + DRM_LOCK(); for (;;) { - if (dev->lock.hw_lock == NULL) { - /* Device has been unregistered */ - ret = DRM_ERR(EINTR); - break; - } if (DRM(lock_take)(&dev->lock.hw_lock->lock, lock.context)) { dev->lock.filp = (void *)DRM_CURRENTPID; dev->lock.lock_time = jiffies; @@ -1073,11 +1071,17 @@ int DRM(lock)( DRM_IOCTL_ARGS ) } /* Contention */ - ret = tsleep((void *)&dev->lock.lock_queue, PZERO|PCATCH, +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock, + PZERO | PCATCH, "drmlk2", 0); +#else + ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH, "drmlk2", 0); +#endif if (ret != 0) break; } + DRM_UNLOCK(); DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); if (ret != 0) @@ -1110,6 +1114,7 @@ int DRM(unlock)( DRM_IOCTL_ARGS ) atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); + DRM_LOCK(); DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); #if __HAVE_DMA_SCHEDULE @@ -1120,6 +1125,7 @@ int DRM(unlock)( DRM_IOCTL_ARGS ) DRM_KERNEL_CONTEXT ) ) { DRM_ERROR( "\n" ); } + DRM_UNLOCK(); return 0; } diff --git a/bsd-core/drm_fops.c b/bsd-core/drm_fops.c index b44254b8..3c4553de 100644 --- a/bsd-core/drm_fops.c +++ b/bsd-core/drm_fops.c @@ -33,6 +33,7 @@ #include "drmP.h" +/* Requires device lock held */ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) { #if __FreeBSD_version >= 500021 @@ -50,8 +51,7 @@ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) return NULL; } -/* DRM(open) is called whenever a process opens /dev/drm. */ - +/* DRM(open_helper) is called whenever a process opens /dev/drm. */ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, drm_device_t *dev) { @@ -64,12 +64,16 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); - /* FIXME: linux mallocs and bzeros here */ + DRM_LOCK(); priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); if (priv) { priv->refs++; } else { priv = (drm_file_t *) DRM(alloc)(sizeof(*priv), DRM_MEM_FILES); + if (priv == NULL) { + DRM_UNLOCK(); + return DRM_ERR(ENOMEM); + } bzero(priv, sizeof(*priv)); #if __FreeBSD_version >= 500000 priv->uid = p->td_ucred->cr_svuid; @@ -84,10 +88,9 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, priv->devXX = dev; priv->ioctl_count = 0; priv->authenticated = !DRM_SUSER(p); - DRM_LOCK(); TAILQ_INSERT_TAIL(&dev->files, priv, link); - DRM_UNLOCK(); } + DRM_UNLOCK(); #ifdef __FreeBSD__ kdev->si_drv1 = dev; #endif diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c index 3366ff1c..f984118e 100644 --- a/bsd-core/drm_irq.c +++ b/bsd-core/drm_irq.c @@ -27,7 +27,19 @@ * Eric Anholt <anholt@FreeBSD.org> * */ - + +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 +static irqreturn_t +DRM(irq_handler_wrap)(DRM_IRQ_ARGS) +{ + drm_device_t *dev = (drm_device_t *)arg; + + DRM_SPINLOCK(&dev->irq_lock); + DRM(irq_handler)(arg); + DRM_SPINUNLOCK(&dev->irq_lock); +} +#endif + int DRM(irq_install)( drm_device_t *dev, int irq ) { int retcode; @@ -54,8 +66,9 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); #endif + DRM_SPININIT(dev->irq_lock, "DRM IRQ lock"); + #if __HAVE_VBL_IRQ && 0 /* disabled */ - DRM_SPININIT( dev->vbl_lock, "vblsig" ); TAILQ_INIT( &dev->vbl_sig_list ); #endif @@ -72,6 +85,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) if (pci_intr_map(&dev->pa, &dev->ih) != 0) { #endif DRM_LOCK(); + DRM_SPINUNINIT(dev->irq_lock); dev->irq = 0; dev->irqrid = 0; DRM_UNLOCK(); @@ -84,7 +98,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) DRM(irq_handler), dev, &dev->irqh); #else retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, - DRM(irq_handler), dev, &dev->irqh); + DRM(irq_handler_wrap), dev, &dev->irqh); #endif if ( retcode ) { #elif defined(__NetBSD__) @@ -96,6 +110,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) #ifdef __FreeBSD__ bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); #endif + DRM_SPINUNINIT(dev->irq_lock); dev->irq = 0; dev->irqrid = 0; DRM_UNLOCK(); @@ -133,6 +148,7 @@ int DRM(irq_uninstall)( drm_device_t *dev ) #elif defined(__NetBSD__) pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); #endif + DRM_SPINUNINIT(dev->irq_lock); return 0; } @@ -187,9 +203,9 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) vblwait.reply.sequence = atomic_read(&dev->vbl_received); - DRM_SPINLOCK(&dev->vbl_lock); + DRM_SPINLOCK(&dev->irq_lock); TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); - DRM_SPINUNLOCK(&dev->vbl_lock); + DRM_SPINUNLOCK(&dev->irq_lock); ret = 0; #endif ret = EINVAL; @@ -218,8 +234,6 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) unsigned int vbl_seq = atomic_read( &dev->vbl_received ); struct proc *p; - DRM_SPINLOCK(&dev->vbl_lock); - vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list); while (vbl_sig != NULL) { drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link); @@ -234,8 +248,6 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) } vbl_sig = next; } - - DRM_SPINUNLOCK(&dev->vbl_lock); } #endif diff --git a/bsd-core/drm_os_freebsd.h b/bsd-core/drm_os_freebsd.h index 3894f54d..320db342 100644 --- a/bsd-core/drm_os_freebsd.h +++ b/bsd-core/drm_os_freebsd.h @@ -123,15 +123,23 @@ #define DRM_SPINLOCK(l) mtx_lock(l) #define DRM_SPINUNLOCK(u) mtx_unlock(u); #define DRM_CURRENTPID curthread->td_proc->p_pid +#define DRM_LOCK() mtx_lock(&dev->dev_lock) +#define DRM_UNLOCK() mtx_unlock(&dev->dev_lock) #else +/* There is no need for locking on FreeBSD 4.x. Synchronization is handled by + * the fact that there is no reentrancy of the kernel except for interrupt + * handlers, and the interrupt handler synchronization is managed by spls. + */ #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc -#define DRM_SPINTYPE struct simplelock -#define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPINTYPE +#define DRM_SPININIT(l,name) #define DRM_SPINUNINIT(l) -#define DRM_SPINLOCK(l) simple_lock(l) -#define DRM_SPINUNLOCK(u) simple_unlock(u); +#define DRM_SPINLOCK(l) +#define DRM_SPINUNLOCK(u) #define DRM_CURRENTPID curproc->p_pid +#define DRM_LOCK() +#define DRM_UNLOCK() #endif /* Currently our DRMFILE (filp) is a void * which is actually the pid @@ -139,8 +147,6 @@ * 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) #define DRM_TASKQUEUE_ARGS void *arg, int pending #define DRM_IRQ_ARGS void *arg @@ -165,13 +171,6 @@ typedef void irqreturn_t; #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_ERR(v) v -#define DRM_PRIV \ - drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ - if (!priv) { \ - DRM_DEBUG("can't find authenticator\n"); \ - return EINVAL; \ - } - #define LOCK_TEST_WITH_RETURN(dev, filp) \ do { \ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ @@ -207,6 +206,16 @@ do { \ #define DRM_HZ hz +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +for ( ret = 0 ; !ret && !(condition) ; ) { \ + mtx_lock(&dev->irq_lock); \ + if (!(condition)) \ + ret = msleep(&(queue), &dev->irq_lock, \ + PZERO | PCATCH, "drmwtq", (timeout)); \ + mtx_unlock(&dev->irq_lock); \ +} +#else #define DRM_WAIT_ON( ret, queue, timeout, condition ) \ for ( ret = 0 ; !ret && !(condition) ; ) { \ int s = spldrm(); \ @@ -215,6 +224,7 @@ for ( ret = 0 ; !ret && !(condition) ; ) { \ "drmwtq", (timeout) ); \ splx(s); \ } +#endif #define DRM_WAKEUP( queue ) wakeup( queue ) #define DRM_WAKEUP_INT( queue ) wakeup( queue ) diff --git a/bsd-core/drm_os_netbsd.h b/bsd-core/drm_os_netbsd.h index 47e710c7..7653b05e 100644 --- a/bsd-core/drm_os_netbsd.h +++ b/bsd-core/drm_os_netbsd.h @@ -101,10 +101,10 @@ extern struct cfdriver DRM(cd); #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc #define DRM_SPINTYPE struct simplelock -#define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPININIT(l,name) #define DRM_SPINUNINIT(l) -#define DRM_SPINLOCK(l) simple_lock(l) -#define DRM_SPINUNLOCK(u) simple_unlock(u); +#define DRM_SPINLOCK(l) +#define DRM_SPINUNLOCK(u) #define DRM_CURRENTPID curproc->p_pid /* Currently our DRMFILE (filp) is a void * which is actually the pid @@ -112,8 +112,8 @@ extern struct cfdriver DRM(cd); * 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_LOCK() +#define DRM_UNLOCK() #define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) #define DRM_TASKQUEUE_ARGS void *dev, int pending #define DRM_IRQ_ARGS void *arg @@ -138,13 +138,6 @@ extern const int DRM(M_DRM) = M_DEVBUF; #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); \ - if (!priv) { \ - DRM_DEBUG("can't find authenticator\n"); \ - return EINVAL; \ - } - #define LOCK_TEST_WITH_RETURN(dev, filp) \ do { \ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ @@ -182,9 +175,11 @@ do { \ #define DRM_WAIT_ON( ret, queue, timeout, condition ) \ while (!condition) { \ + int s = spldrm(); \ ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ if ( ret ) \ return ret; \ + splx(s); \ } #define DRM_ERR(v) v @@ -320,7 +315,7 @@ find_first_zero_bit(atomic_t *p, int max) #define jiffies hardclock_ticks /* Redefinitions to make templating easy */ -#define wait_queue_head_t atomic_t +#define wait_queue_head_t int #define agp_memory void /* Macros to make printf easier */ diff --git a/bsd-core/drm_pci.c b/bsd-core/drm_pci.c index aa065b64..1d8b593d 100644 --- a/bsd-core/drm_pci.c +++ b/bsd-core/drm_pci.c @@ -44,7 +44,7 @@ DRM(pci_alloc)(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr, { void *vaddr; - vaddr = contigmalloc(size, DRM(M_DRM), M_WAITOK, 0ul, maxaddr, align, + vaddr = contigmalloc(size, DRM(M_DRM), M_NOWAIT, 0ul, maxaddr, align, 0); *busaddr = vtophys(vaddr); diff --git a/bsd-core/drm_sysctl.c b/bsd-core/drm_sysctl.c index 270b3947..fe586d4c 100644 --- a/bsd-core/drm_sysctl.c +++ b/bsd-core/drm_sysctl.c @@ -173,7 +173,7 @@ static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS { - drm_device_t *dev = arg1; + drm_device_t __unused *dev = arg1; int ret; DRM_LOCK(); @@ -225,7 +225,7 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS { - drm_device_t *dev = arg1; + drm_device_t __unused *dev = arg1; int ret; DRM_LOCK(); @@ -259,7 +259,7 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS { - drm_device_t *dev = arg1; + drm_device_t __unused *dev = arg1; int ret; DRM_LOCK(); diff --git a/bsd-core/drm_vm.c b/bsd-core/drm_vm.c index da815329..9e9f1e14 100644 --- a/bsd-core/drm_vm.c +++ b/bsd-core/drm_vm.c @@ -65,7 +65,9 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) drm_map_list_entry_t *listentry = NULL; drm_file_t *priv; + DRM_LOCK(); priv = DRM(find_file_by_proc)(dev, DRM_CURPROC); + DRM_UNLOCK(); if (!priv) { DRM_DEBUG("can't find authenticator\n"); return EINVAL; diff --git a/bsd/ati_pcigart.h b/bsd/ati_pcigart.h index 0a05dda6..9aa2192f 100644 --- a/bsd/ati_pcigart.h +++ b/bsd/ati_pcigart.h @@ -59,7 +59,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev, } address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, - DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0); + DRM(M_DRM), M_NOWAIT, 0ul, 0xfffffffful, PAGE_SIZE, 0); if ( !address ) { DRM_ERROR( "cannot allocate PCI GART page!\n" ); goto done; @@ -180,7 +180,6 @@ typedef struct drm_freelist { int low_mark; /* Low water mark */ int high_mark; /* High water mark */ - DRM_SPINTYPE lock; } drm_freelist_t; typedef struct drm_buf_entry { @@ -216,10 +215,17 @@ struct drm_file { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ DRMFILE filp; /* Unique identifier of holding process (NULL is kernel)*/ - wait_queue_head_t lock_queue; /* Queue of blocked processes */ + int lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; +/* This structure, in the drm_device_t, is always initialized while the device + * is open. dev->dma_lock protects the incrementing of dev->buf_use, which + * when set marks that no further bufs may be allocated until device teardown + * occurs (when the last open of the device has closed). The high/low + * watermarks of bufs are only touched by the X Server, and thus not + * concurrently accessed, so no locking is needed. + */ typedef struct drm_device_dma { drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; int buf_count; @@ -311,8 +317,15 @@ struct drm_device { int flags; /* Flags to open(2) */ /* Locks */ - DRM_SPINTYPE count_lock; /* For open_count, buf_use, buf_alloc */ - struct lock dev_lock; /* For others */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#if __HAVE_DMA + struct mtx dma_lock; /* protects dev->dma */ +#endif +#if __HAVE_IRQ + struct mtx irq_lock; /* protects irq condition checks */ +#endif + struct mtx dev_lock; /* protects everything else */ +#endif /* Usage Counters */ int open_count; /* Outstanding files open */ int buf_use; /* Buffers in use -- cannot alloc */ @@ -327,8 +340,8 @@ struct drm_device { drm_file_list_t files; drm_magic_head_t magiclist[DRM_HASH_SIZE]; - /* Memory management */ - drm_map_list_t *maplist; /* Linked list of regions */ + /* Linked list of mappable regions. Protected by dev_lock */ + drm_map_list_t *maplist; drm_local_map_t **context_sareas; int max_context; @@ -349,18 +362,13 @@ struct drm_device { #endif void *irqh; /* Handle from bus_setup_intr */ atomic_t context_flag; /* Context swapping flag */ - struct callout timer; /* Timer for delaying ctx switch */ int last_context; /* Last current context */ #if __FreeBSD_version >= 400005 struct task task; #endif #if __HAVE_VBL_IRQ - wait_queue_head_t vbl_queue; /* vbl wait channel */ + int vbl_queue; /* vbl wait channel */ atomic_t vbl_received; -#if 0 /* vbl signals are untested */ - struct drm_vbl_sig_list vbl_sig_list; - DRM_SPINTYPE vbl_lock; -#endif #endif #ifdef __FreeBSD__ @@ -382,11 +390,6 @@ struct drm_device { extern int DRM(flags); - /* Authentication (drm_auth.h) */ -extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, - drm_magic_t magic); -extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); - /* Driver support (drm_drv.h) */ extern int DRM(version)( DRM_IOCTL_ARGS ); diff --git a/bsd/drm_auth.h b/bsd/drm_auth.h index 6f819ad8..9e34b35c 100644 --- a/bsd/drm_auth.h +++ b/bsd/drm_auth.h @@ -54,7 +54,7 @@ static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic) return retval; } -int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) +static int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) { int hash; drm_magic_entry_t *entry; @@ -82,7 +82,7 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic) return 0; } -int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) +static int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) { drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; @@ -116,9 +116,17 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic) int DRM(getmagic)(DRM_IOCTL_ARGS) { static drm_magic_t sequence = 0; - drm_auth_t auth; + drm_auth_t auth; + drm_file_t *priv; DRM_DEVICE; - DRM_PRIV; + + DRM_LOCK(); + priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); + DRM_UNLOCK(); + if (priv == NULL) { + DRM_DEBUG("can't find authenticator\n"); + return EINVAL; + } /* Find unique magic */ if (priv->magic) { @@ -152,6 +160,7 @@ int DRM(authmagic)(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth)); DRM_DEBUG("%u\n", auth.magic); + if ((file = DRM(find_file)(dev, auth.magic))) { file->authenticated = 1; DRM(remove_magic)(dev, auth.magic); diff --git a/bsd/drm_bufs.h b/bsd/drm_bufs.h index 4c33763c..cdd2359d 100644 --- a/bsd/drm_bufs.h +++ b/bsd/drm_bufs.h @@ -226,6 +226,8 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } TAILQ_REMOVE(dev->maplist, list, link); + DRM_UNLOCK(); + DRM(free)(list, sizeof(*list), DRM_MEM_MAPS); switch (map->type) { @@ -268,7 +270,6 @@ int DRM(rmmap)( DRM_IOCTL_ARGS ) break; } DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); - DRM_UNLOCK(); return 0; } @@ -350,20 +351,11 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - - DRM_LOCK(); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK(); - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), DRM_MEM_BUFS ); if ( !entry->buflist ) { - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); @@ -394,7 +386,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -413,7 +404,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -428,8 +418,6 @@ static int DRM(addbufs_agp)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); - DRM_UNLOCK(); - request->count = entry->buf_count; request->size = size; @@ -467,20 +455,12 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "count=%d, size=%d (%d), order=%d\n", request->count, request->size, size, order ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - alignment = (request->flags & _DRM_PAGE_ALIGN) ? round_page(size) : size; page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; - DRM_LOCK(); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK(); - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } entry->buflist = DRM(alloc)(count * sizeof(*entry->buflist), DRM_MEM_BUFS); @@ -503,7 +483,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM_MEM_SEGS); DRM(free)(entry->seglist_bus, count * sizeof(*entry->seglist_bus), DRM_MEM_SEGS); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -532,7 +511,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -571,7 +549,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES ); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } bzero(buf->dev_private, buf->dev_priv_size); @@ -593,7 +570,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) DRM(free)(temp_pagelist, (dma->page_count + (count << page_order)) * sizeof(*dma->pagelist), DRM_MEM_PAGES); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -614,8 +590,6 @@ static int DRM(addbufs_pci)(drm_device_t *dev, drm_buf_desc_t *request) dma->page_count += entry->seg_count << page_order; dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - DRM_UNLOCK(); - request->count = entry->buf_count; request->size = size; @@ -662,23 +636,12 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "page_order: %d\n", page_order ); DRM_DEBUG( "total: %d\n", total ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - - DRM_LOCK(); entry = &dma->bufs[order]; - if ( entry->buf_count ) { - DRM_UNLOCK(); - return DRM_ERR(ENOMEM); /* May only call once for each order */ - } - entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist), - DRM_MEM_BUFS ); - if ( !entry->buflist ) { - DRM_UNLOCK(); + entry->buflist = DRM(calloc)(1, count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (entry->buflist == NULL) return DRM_ERR(ENOMEM); - } - memset( entry->buflist, 0, count * sizeof(*entry->buflist) ); entry->buf_size = size; entry->page_order = page_order; @@ -706,7 +669,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) /* Set count correctly so we free the proper amount. */ entry->buf_count = count; DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } @@ -728,7 +690,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) if (temp_buflist == NULL) { /* Free the entry because it isn't valid */ DRM(cleanup_buf_error)(dev, entry); - DRM_UNLOCK(); return DRM_ERR(ENOMEM); } dma->buflist = temp_buflist; @@ -743,8 +704,6 @@ static int DRM(addbufs_sg)(drm_device_t *dev, drm_buf_desc_t *request) DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); - DRM_UNLOCK(); - request->count = entry->buf_count; request->size = size; @@ -759,25 +718,28 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) DRM_DEVICE; drm_buf_desc_t request; int err; + int order; DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); - if (dev->dma == NULL) + if (request.count < 0 || request.count > 4096) return DRM_ERR(EINVAL); - if (request.count < 0 || request.count > 4096) + order = DRM(order)(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return DRM_ERR(EINVAL); - DRM_SPINLOCK(&dev->count_lock); - if (dev->buf_use) { - DRM_SPINUNLOCK(&dev->count_lock); + DRM_SPINLOCK(&dev->dma_lock); + /* No more allocations after first buffer-using ioctl. */ + if (dev->buf_use != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); return DRM_ERR(EBUSY); } - /* dev->buf_alloc acts as a lock to prevent infobufs/mapbufs from - * trying to read from the dma->bufs while buffers are being allocated */ - dev->buf_alloc++; - DRM_SPINUNLOCK(&dev->count_lock); - + /* No more than one allocation per order */ + if (dev->dma->bufs[order].buf_count != 0) { + DRM_SPINUNLOCK(&dev->dma_lock); + return DRM_ERR(ENOMEM); + } #if __REALLY_HAVE_AGP if ( request.flags & _DRM_AGP_BUFFER ) @@ -794,13 +756,10 @@ int DRM(addbufs)( DRM_IOCTL_ARGS ) #else err = DRM_ERR(EINVAL); #endif + DRM_SPINUNLOCK(&dev->dma_lock); DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request, sizeof(request)); - DRM_SPINLOCK(&dev->count_lock); - dev->buf_alloc--; - DRM_SPINUNLOCK(&dev->count_lock); - return err; } @@ -811,18 +770,13 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) drm_buf_info_t request; int i; int count; + int retcode = 0; - if ( !dma ) return DRM_ERR(EINVAL); + DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); - DRM_SPINLOCK( &dev->count_lock ); - if (dev->buf_alloc != 0) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM_ERR(EBUSY); - } + DRM_SPINLOCK(&dev->dma_lock); ++dev->buf_use; /* Can't allocate more after this call */ - DRM_SPINUNLOCK( &dev->count_lock ); - - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) ); + DRM_SPINUNLOCK(&dev->dma_lock); for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) { if ( dma->bufs[i].buf_count ) ++count; @@ -841,8 +795,10 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) from.high_mark = dma->bufs[i].freelist.high_mark; if (DRM_COPY_TO_USER(&request.list[count], &from, - sizeof(drm_buf_desc_t)) != 0) - return DRM_ERR(EFAULT); + sizeof(drm_buf_desc_t)) != 0) { + retcode = DRM_ERR(EFAULT); + break; + } DRM_DEBUG( "%d %d %d %d %d\n", i, @@ -858,7 +814,7 @@ int DRM(infobufs)( DRM_IOCTL_ARGS ) DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) ); - return 0; + return retcode; } int DRM(markbufs)( DRM_IOCTL_ARGS ) @@ -867,26 +823,28 @@ int DRM(markbufs)( DRM_IOCTL_ARGS ) drm_device_dma_t *dma = dev->dma; drm_buf_desc_t request; int order; - drm_buf_entry_t *entry; - - if ( !dma ) return DRM_ERR(EINVAL); DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_desc_t *)data, sizeof(request) ); DRM_DEBUG( "%d, %d, %d\n", request.size, request.low_mark, request.high_mark ); - order = DRM(order)( request.size ); - if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) - return DRM_ERR(EINVAL); - entry = &dma->bufs[order]; + - if ( request.low_mark < 0 || request.low_mark > entry->buf_count ) + order = DRM(order)(request.size); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER || + request.low_mark < 0 || request.high_mark < 0) { return DRM_ERR(EINVAL); - if ( request.high_mark < 0 || request.high_mark > entry->buf_count ) + } + + DRM_SPINLOCK(&dev->dma_lock); + if (request.low_mark > dma->bufs[order].buf_count || + request.high_mark > dma->bufs[order].buf_count) { return DRM_ERR(EINVAL); + } - entry->freelist.low_mark = request.low_mark; - entry->freelist.high_mark = request.high_mark; + dma->bufs[order].freelist.low_mark = request.low_mark; + dma->bufs[order].freelist.high_mark = request.high_mark; + DRM_SPINUNLOCK(&dev->dma_lock); return 0; } @@ -899,32 +857,36 @@ int DRM(freebufs)( DRM_IOCTL_ARGS ) int i; int idx; drm_buf_t *buf; - - if ( !dma ) return DRM_ERR(EINVAL); + int retcode = 0; DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) ); DRM_DEBUG( "%d\n", request.count ); + + DRM_SPINLOCK(&dev->dma_lock); for ( i = 0 ; i < request.count ; i++ ) { - if ( DRM_COPY_FROM_USER( &idx, - &request.list[i], - sizeof(idx) ) ) - return DRM_ERR(EFAULT); + if (DRM_COPY_FROM_USER(&idx, &request.list[i], sizeof(idx))) { + retcode = DRM_ERR(EFAULT); + break; + } if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "Index %d (of %d max)\n", idx, dma->buf_count - 1 ); - return DRM_ERR(EINVAL); + retcode = DRM_ERR(EINVAL); + break; } buf = dma->buflist[idx]; if ( buf->filp != filp ) { DRM_ERROR("Process %d freeing buffer not owned\n", DRM_CURRENTPID); - return DRM_ERR(EINVAL); + retcode = DRM_ERR(EINVAL); + break; } DRM(free_buffer)( dev, buf ); } + DRM_SPINUNLOCK(&dev->dma_lock); - return 0; + return retcode; } int DRM(mapbufs)( DRM_IOCTL_ARGS ) @@ -949,16 +911,6 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) drm_buf_map_t request; int i; - if ( !dma ) return DRM_ERR(EINVAL); - - DRM_SPINLOCK( &dev->count_lock ); - if (dev->buf_alloc != 0) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM_ERR(EBUSY); - } - dev->buf_use++; /* Can't allocate more after this call */ - DRM_SPINUNLOCK( &dev->count_lock ); - DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) ); #ifdef __NetBSD__ @@ -972,6 +924,10 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) vms = p->p_vmspace; #endif + DRM_SPINLOCK(&dev->dma_lock); + dev->buf_use++; /* Can't allocate more after this call */ + DRM_SPINUNLOCK(&dev->dma_lock); + if (request.count < dma->buf_count) goto done; @@ -1040,4 +996,3 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS ) } #endif /* __HAVE_DMA */ - diff --git a/bsd/drm_dma.h b/bsd/drm_dma.h index d5852403..8d87c38a 100644 --- a/bsd/drm_dma.h +++ b/bsd/drm_dma.h @@ -51,6 +51,8 @@ int DRM(dma_setup)( drm_device_t *dev ) if (dev->dma == NULL) return DRM_ERR(ENOMEM); + DRM_SPININIT(dev->dma_lock, "drmdma"); + return 0; } @@ -59,7 +61,8 @@ void DRM(dma_takedown)(drm_device_t *dev) drm_device_dma_t *dma = dev->dma; int i, j; - if (!dma) return; + if (dma == NULL) + return; /* Clear dma buffers */ for (i = 0; i <= DRM_MAX_ORDER; i++) { @@ -106,6 +109,7 @@ void DRM(dma_takedown)(drm_device_t *dev) DRM_MEM_PAGES); DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); dev->dma = NULL; + DRM_SPINUNINIT(dev->dma_lock); } diff --git a/bsd/drm_drv.h b/bsd/drm_drv.h index 8a9e3036..731f31da 100644 --- a/bsd/drm_drv.h +++ b/bsd/drm_drv.h @@ -111,7 +111,7 @@ int DRM(flags) = 0; #endif static int DRM(init)(device_t nbdev); -static void DRM(cleanup)(device_t nbdev); +static void DRM(cleanup)(drm_device_t *dev); #ifdef __FreeBSD__ #define DRIVER_SOFTC(unit) \ @@ -253,7 +253,7 @@ static int DRM(attach)(device_t dev) static int DRM(detach)(device_t dev) { - DRM(cleanup)(dev); + DRM(cleanup)(device_get_softc(dev)); return 0; } static device_method_t DRM(methods)[] = { @@ -411,6 +411,7 @@ const char *DRM(find_description)(int vendor, int device) { return NULL; } +/* Initialize the DRM on first open. Called with device's lock held */ static int DRM(setup)( drm_device_t *dev ) { int i; @@ -421,7 +422,7 @@ static int DRM(setup)( drm_device_t *dev ) #if __HAVE_DMA i = DRM(dma_setup)( dev ); - if ( i < 0 ) + if ( i != 0 ) return i; #endif @@ -481,11 +482,6 @@ static int DRM(setup)( drm_device_t *dev ) dev->irq = 0; dev->context_flag = 0; dev->last_context = 0; -#if __FreeBSD_version >= 500000 - callout_init( &dev->timer, 1 ); -#else - callout_init( &dev->timer ); -#endif #ifdef __FreeBSD__ dev->buf_sigio = NULL; @@ -499,7 +495,9 @@ static int DRM(setup)( drm_device_t *dev ) return 0; } - +/* Free resources associated with the DRM on the last close. + * Called with the device's lock held. + */ static int DRM(takedown)( drm_device_t *dev ) { drm_magic_entry_t *pt, *next; @@ -515,9 +513,6 @@ static int DRM(takedown)( drm_device_t *dev ) DRM(irq_uninstall)( dev ); #endif - DRM_LOCK(); - callout_stop( &dev->timer ); - if ( dev->unique ) { DRM(free)( dev->unique, strlen( dev->unique ) + 1, DRM_MEM_DRIVER ); @@ -540,7 +535,7 @@ static int DRM(takedown)( drm_device_t *dev ) drm_agp_mem_t *nexte; /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ + intact until DRM(cleanup) is called. */ for ( entry = dev->agp->memory ; entry ; entry = nexte ) { nexte = entry->next; if ( entry->bound ) DRM(unbind_agp)( entry->handle ); @@ -625,7 +620,6 @@ static int DRM(takedown)( drm_device_t *dev ) dev->lock.filp = NULL; DRM_WAKEUP_INT((void *)&dev->lock.lock_queue); } - DRM_UNLOCK(); return 0; } @@ -664,11 +658,12 @@ static int DRM(init)( device_t nbdev ) DRM_DEV_GID, DRM_DEV_MODE, "dri/card%d", unit ); +#if __FreeBSD_version >= 500000 + mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF); +#endif #elif defined(__NetBSD__) unit = minor(dev->device.dv_unit); #endif - DRM_SPININIT(dev->count_lock, "drm device"); - lockinit(&dev->dev_lock, PZERO, "drmlk", 0, 0); dev->name = DRIVER_NAME; DRM(mem_init)(); DRM(sysctl_init)(dev); @@ -679,12 +674,8 @@ static int DRM(init)( device_t nbdev ) #if __MUST_HAVE_AGP if ( dev->agp == NULL ) { DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(sysctl_cleanup)( dev ); -#ifdef __FreeBSD__ - destroy_dev(dev->devnode); -#endif - DRM(takedown)( dev ); - return DRM_ERR(ENOMEM); + retcode = DRM_ERR(ENOMEM); + goto error; } #endif /* __MUST_HAVE_AGP */ #if __REALLY_HAVE_MTRR @@ -716,12 +707,7 @@ static int DRM(init)( device_t nbdev ) retcode = DRM(ctxbitmap_init)( dev ); if (retcode != 0) { DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(sysctl_cleanup)( dev ); -#ifdef __FreeBSD__ - destroy_dev(dev->devnode); -#endif - DRM(takedown)( dev ); - return retcode; + goto error; } #endif DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", @@ -735,28 +721,36 @@ static int DRM(init)( device_t nbdev ) DRIVER_POSTINIT(); return 0; + +error: + DRM(sysctl_cleanup)(dev); + DRM_LOCK(); + DRM(takedown)(dev); + DRM_UNLOCK(); +#ifdef __FreeBSD__ + destroy_dev(dev->devnode); +#if __FreeBSD_version >= 500000 + mtx_destroy(&dev->dev_lock); +#endif +#endif + return retcode; } /* linux: drm_cleanup is called via cleanup_module at module unload time. * bsd: drm_cleanup is called per device at module unload time. * FIXME: NetBSD */ -static void DRM(cleanup)(device_t nbdev) +static void DRM(cleanup)(drm_device_t *dev) { - drm_device_t *dev; #ifdef __NetBSD__ #if __REALLY_HAVE_MTRR struct mtrr mtrrmap; int one = 1; #endif /* __REALLY_HAVE_MTRR */ - dev = nbdev; #endif /* __NetBSD__ */ DRM_DEBUG( "\n" ); -#ifdef __FreeBSD__ - dev = device_get_softc(nbdev); -#endif DRM(sysctl_cleanup)( dev ); #ifdef __FreeBSD__ destroy_dev(dev->devnode); @@ -777,7 +771,9 @@ static void DRM(cleanup)(device_t nbdev) } #endif + DRM_LOCK(); DRM(takedown)( dev ); + DRM_UNLOCK(); #if __REALLY_HAVE_AGP if ( dev->agp ) { @@ -788,7 +784,9 @@ static void DRM(cleanup)(device_t nbdev) #endif DRIVER_POSTCLEANUP(); DRM(mem_uninit)(); - DRM_SPINUNINIT(dev->count_lock); +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 + mtx_destroy(&dev->dev_lock); +#endif } @@ -834,13 +832,13 @@ int DRM(open)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); - DRM_SPINLOCK( &dev->count_lock ); + DRM_LOCK(); #ifdef __FreeBSD__ device_busy(dev->device); #endif if ( !dev->open_count++ ) retcode = DRM(setup)( dev ); - DRM_SPINUNLOCK( &dev->count_lock ); + DRM_UNLOCK(); } return retcode; @@ -854,8 +852,12 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) DRMFILE filp = (void *)(DRM_CURRENTPID); DRM_DEBUG( "open_count = %d\n", dev->open_count ); + + DRM_LOCK(); + priv = DRM(find_file_by_proc)(dev, p); if (!priv) { + DRM_UNLOCK(); DRM_DEBUG("can't find authenticator\n"); return EINVAL; } @@ -908,10 +910,13 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) break; /* Got lock */ } /* Contention */ +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + retcode = msleep((void *)&dev->lock.lock_queue, + dev->dev_lock, PZERO | PCATCH, "drmlk2", 0); +#else retcode = tsleep((void *)&dev->lock.lock_queue, - PZERO|PCATCH, - "drmlk2", - 0); + PZERO | PCATCH, "drmlk2", 0); +#endif if (retcode) break; } @@ -933,32 +938,24 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p) dev->buf_pgid = 0; #endif /* __NetBSD__ */ - DRM_LOCK(); - priv = DRM(find_file_by_proc)(dev, p); - if (priv) { - priv->refs--; - if (!priv->refs) { - TAILQ_REMOVE(&dev->files, priv, link); - DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); - } + if (--priv->refs == 0) { + TAILQ_REMOVE(&dev->files, priv, link); + DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); } - DRM_UNLOCK(); - /* ======================================================== * End inline drm_release */ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); - DRM_SPINLOCK( &dev->count_lock ); #ifdef __FreeBSD__ device_unbusy(dev->device); #endif - if ( !--dev->open_count ) { - DRM_SPINUNLOCK( &dev->count_lock ); - return DRM(takedown)( dev ); + if (--dev->open_count == 0) { + retcode = DRM(takedown)(dev); } - DRM_SPINUNLOCK( &dev->count_lock ); + + DRM_UNLOCK(); return retcode; } @@ -973,7 +970,15 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, drm_ioctl_desc_t *ioctl; int (*func)(DRM_IOCTL_ARGS); int nr = DRM_IOCTL_NR(cmd); - DRM_PRIV; + drm_file_t *priv; + + DRM_LOCK(); + priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); + DRM_UNLOCK(); + if (priv == NULL) { + DRM_DEBUG("can't find authenticator\n"); + return EINVAL; + } atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); ++priv->ioctl_count; @@ -988,10 +993,7 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, switch (cmd) { case FIONBIO: - return 0; - case FIOASYNC: - dev->flags |= FASYNC; return 0; #ifdef __FreeBSD__ @@ -1017,7 +1019,7 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags, #endif /* __NetBSD__ */ } - if (nr >= DRIVER_IOCTL_COUNT) + if (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE) return EINVAL; ioctl = &DRM(ioctls)[nr]; @@ -1059,12 +1061,8 @@ int DRM(lock)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); #endif + DRM_LOCK(); for (;;) { - if (dev->lock.hw_lock == NULL) { - /* Device has been unregistered */ - ret = DRM_ERR(EINTR); - break; - } if (DRM(lock_take)(&dev->lock.hw_lock->lock, lock.context)) { dev->lock.filp = (void *)DRM_CURRENTPID; dev->lock.lock_time = jiffies; @@ -1073,11 +1071,17 @@ int DRM(lock)( DRM_IOCTL_ARGS ) } /* Contention */ - ret = tsleep((void *)&dev->lock.lock_queue, PZERO|PCATCH, +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 + ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock, + PZERO | PCATCH, "drmlk2", 0); +#else + ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH, "drmlk2", 0); +#endif if (ret != 0) break; } + DRM_UNLOCK(); DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); if (ret != 0) @@ -1110,6 +1114,7 @@ int DRM(unlock)( DRM_IOCTL_ARGS ) atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] ); + DRM_LOCK(); DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ); #if __HAVE_DMA_SCHEDULE @@ -1120,6 +1125,7 @@ int DRM(unlock)( DRM_IOCTL_ARGS ) DRM_KERNEL_CONTEXT ) ) { DRM_ERROR( "\n" ); } + DRM_UNLOCK(); return 0; } diff --git a/bsd/drm_fops.h b/bsd/drm_fops.h index b44254b8..3c4553de 100644 --- a/bsd/drm_fops.h +++ b/bsd/drm_fops.h @@ -33,6 +33,7 @@ #include "drmP.h" +/* Requires device lock held */ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) { #if __FreeBSD_version >= 500021 @@ -50,8 +51,7 @@ drm_file_t *DRM(find_file_by_proc)(drm_device_t *dev, DRM_STRUCTPROC *p) return NULL; } -/* DRM(open) is called whenever a process opens /dev/drm. */ - +/* DRM(open_helper) is called whenever a process opens /dev/drm. */ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, drm_device_t *dev) { @@ -64,12 +64,16 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); - /* FIXME: linux mallocs and bzeros here */ + DRM_LOCK(); priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); if (priv) { priv->refs++; } else { priv = (drm_file_t *) DRM(alloc)(sizeof(*priv), DRM_MEM_FILES); + if (priv == NULL) { + DRM_UNLOCK(); + return DRM_ERR(ENOMEM); + } bzero(priv, sizeof(*priv)); #if __FreeBSD_version >= 500000 priv->uid = p->td_ucred->cr_svuid; @@ -84,10 +88,9 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p, priv->devXX = dev; priv->ioctl_count = 0; priv->authenticated = !DRM_SUSER(p); - DRM_LOCK(); TAILQ_INSERT_TAIL(&dev->files, priv, link); - DRM_UNLOCK(); } + DRM_UNLOCK(); #ifdef __FreeBSD__ kdev->si_drv1 = dev; #endif diff --git a/bsd/drm_irq.h b/bsd/drm_irq.h index 3366ff1c..f984118e 100644 --- a/bsd/drm_irq.h +++ b/bsd/drm_irq.h @@ -27,7 +27,19 @@ * Eric Anholt <anholt@FreeBSD.org> * */ - + +#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 +static irqreturn_t +DRM(irq_handler_wrap)(DRM_IRQ_ARGS) +{ + drm_device_t *dev = (drm_device_t *)arg; + + DRM_SPINLOCK(&dev->irq_lock); + DRM(irq_handler)(arg); + DRM_SPINUNLOCK(&dev->irq_lock); +} +#endif + int DRM(irq_install)( drm_device_t *dev, int irq ) { int retcode; @@ -54,8 +66,9 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); #endif + DRM_SPININIT(dev->irq_lock, "DRM IRQ lock"); + #if __HAVE_VBL_IRQ && 0 /* disabled */ - DRM_SPININIT( dev->vbl_lock, "vblsig" ); TAILQ_INIT( &dev->vbl_sig_list ); #endif @@ -72,6 +85,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) if (pci_intr_map(&dev->pa, &dev->ih) != 0) { #endif DRM_LOCK(); + DRM_SPINUNINIT(dev->irq_lock); dev->irq = 0; dev->irqrid = 0; DRM_UNLOCK(); @@ -84,7 +98,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) DRM(irq_handler), dev, &dev->irqh); #else retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, - DRM(irq_handler), dev, &dev->irqh); + DRM(irq_handler_wrap), dev, &dev->irqh); #endif if ( retcode ) { #elif defined(__NetBSD__) @@ -96,6 +110,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq ) #ifdef __FreeBSD__ bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); #endif + DRM_SPINUNINIT(dev->irq_lock); dev->irq = 0; dev->irqrid = 0; DRM_UNLOCK(); @@ -133,6 +148,7 @@ int DRM(irq_uninstall)( drm_device_t *dev ) #elif defined(__NetBSD__) pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); #endif + DRM_SPINUNINIT(dev->irq_lock); return 0; } @@ -187,9 +203,9 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS ) vblwait.reply.sequence = atomic_read(&dev->vbl_received); - DRM_SPINLOCK(&dev->vbl_lock); + DRM_SPINLOCK(&dev->irq_lock); TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); - DRM_SPINUNLOCK(&dev->vbl_lock); + DRM_SPINUNLOCK(&dev->irq_lock); ret = 0; #endif ret = EINVAL; @@ -218,8 +234,6 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) unsigned int vbl_seq = atomic_read( &dev->vbl_received ); struct proc *p; - DRM_SPINLOCK(&dev->vbl_lock); - vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list); while (vbl_sig != NULL) { drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link); @@ -234,8 +248,6 @@ void DRM(vbl_send_signals)( drm_device_t *dev ) } vbl_sig = next; } - - DRM_SPINUNLOCK(&dev->vbl_lock); } #endif diff --git a/bsd/drm_os_freebsd.h b/bsd/drm_os_freebsd.h index 3894f54d..320db342 100644 --- a/bsd/drm_os_freebsd.h +++ b/bsd/drm_os_freebsd.h @@ -123,15 +123,23 @@ #define DRM_SPINLOCK(l) mtx_lock(l) #define DRM_SPINUNLOCK(u) mtx_unlock(u); #define DRM_CURRENTPID curthread->td_proc->p_pid +#define DRM_LOCK() mtx_lock(&dev->dev_lock) +#define DRM_UNLOCK() mtx_unlock(&dev->dev_lock) #else +/* There is no need for locking on FreeBSD 4.x. Synchronization is handled by + * the fact that there is no reentrancy of the kernel except for interrupt + * handlers, and the interrupt handler synchronization is managed by spls. + */ #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc -#define DRM_SPINTYPE struct simplelock -#define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPINTYPE +#define DRM_SPININIT(l,name) #define DRM_SPINUNINIT(l) -#define DRM_SPINLOCK(l) simple_lock(l) -#define DRM_SPINUNLOCK(u) simple_unlock(u); +#define DRM_SPINLOCK(l) +#define DRM_SPINUNLOCK(u) #define DRM_CURRENTPID curproc->p_pid +#define DRM_LOCK() +#define DRM_UNLOCK() #endif /* Currently our DRMFILE (filp) is a void * which is actually the pid @@ -139,8 +147,6 @@ * 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) #define DRM_TASKQUEUE_ARGS void *arg, int pending #define DRM_IRQ_ARGS void *arg @@ -165,13 +171,6 @@ typedef void irqreturn_t; #define DRM_AGP_FIND_DEVICE() agp_find_device() #define DRM_ERR(v) v -#define DRM_PRIV \ - drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \ - if (!priv) { \ - DRM_DEBUG("can't find authenticator\n"); \ - return EINVAL; \ - } - #define LOCK_TEST_WITH_RETURN(dev, filp) \ do { \ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ @@ -207,6 +206,16 @@ do { \ #define DRM_HZ hz +#if defined(__FreeBSD__) && __FreeBSD_version > 500000 +#define DRM_WAIT_ON( ret, queue, timeout, condition ) \ +for ( ret = 0 ; !ret && !(condition) ; ) { \ + mtx_lock(&dev->irq_lock); \ + if (!(condition)) \ + ret = msleep(&(queue), &dev->irq_lock, \ + PZERO | PCATCH, "drmwtq", (timeout)); \ + mtx_unlock(&dev->irq_lock); \ +} +#else #define DRM_WAIT_ON( ret, queue, timeout, condition ) \ for ( ret = 0 ; !ret && !(condition) ; ) { \ int s = spldrm(); \ @@ -215,6 +224,7 @@ for ( ret = 0 ; !ret && !(condition) ; ) { \ "drmwtq", (timeout) ); \ splx(s); \ } +#endif #define DRM_WAKEUP( queue ) wakeup( queue ) #define DRM_WAKEUP_INT( queue ) wakeup( queue ) diff --git a/bsd/drm_os_netbsd.h b/bsd/drm_os_netbsd.h index 47e710c7..7653b05e 100644 --- a/bsd/drm_os_netbsd.h +++ b/bsd/drm_os_netbsd.h @@ -101,10 +101,10 @@ extern struct cfdriver DRM(cd); #define DRM_CURPROC curproc #define DRM_STRUCTPROC struct proc #define DRM_SPINTYPE struct simplelock -#define DRM_SPININIT(l,name) simple_lock_init(&l) +#define DRM_SPININIT(l,name) #define DRM_SPINUNINIT(l) -#define DRM_SPINLOCK(l) simple_lock(l) -#define DRM_SPINUNLOCK(u) simple_unlock(u); +#define DRM_SPINLOCK(l) +#define DRM_SPINUNLOCK(u) #define DRM_CURRENTPID curproc->p_pid /* Currently our DRMFILE (filp) is a void * which is actually the pid @@ -112,8 +112,8 @@ extern struct cfdriver DRM(cd); * 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_LOCK() +#define DRM_UNLOCK() #define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag) #define DRM_TASKQUEUE_ARGS void *dev, int pending #define DRM_IRQ_ARGS void *arg @@ -138,13 +138,6 @@ extern const int DRM(M_DRM) = M_DEVBUF; #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); \ - if (!priv) { \ - DRM_DEBUG("can't find authenticator\n"); \ - return EINVAL; \ - } - #define LOCK_TEST_WITH_RETURN(dev, filp) \ do { \ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \ @@ -182,9 +175,11 @@ do { \ #define DRM_WAIT_ON( ret, queue, timeout, condition ) \ while (!condition) { \ + int s = spldrm(); \ ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \ if ( ret ) \ return ret; \ + splx(s); \ } #define DRM_ERR(v) v @@ -320,7 +315,7 @@ find_first_zero_bit(atomic_t *p, int max) #define jiffies hardclock_ticks /* Redefinitions to make templating easy */ -#define wait_queue_head_t atomic_t +#define wait_queue_head_t int #define agp_memory void /* Macros to make printf easier */ diff --git a/bsd/drm_pci.h b/bsd/drm_pci.h index aa065b64..1d8b593d 100644 --- a/bsd/drm_pci.h +++ b/bsd/drm_pci.h @@ -44,7 +44,7 @@ DRM(pci_alloc)(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr, { void *vaddr; - vaddr = contigmalloc(size, DRM(M_DRM), M_WAITOK, 0ul, maxaddr, align, + vaddr = contigmalloc(size, DRM(M_DRM), M_NOWAIT, 0ul, maxaddr, align, 0); *busaddr = vtophys(vaddr); diff --git a/bsd/drm_sysctl.h b/bsd/drm_sysctl.h index 270b3947..fe586d4c 100644 --- a/bsd/drm_sysctl.h +++ b/bsd/drm_sysctl.h @@ -173,7 +173,7 @@ static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS { - drm_device_t *dev = arg1; + drm_device_t __unused *dev = arg1; int ret; DRM_LOCK(); @@ -225,7 +225,7 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS { - drm_device_t *dev = arg1; + drm_device_t __unused *dev = arg1; int ret; DRM_LOCK(); @@ -259,7 +259,7 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS { - drm_device_t *dev = arg1; + drm_device_t __unused *dev = arg1; int ret; DRM_LOCK(); diff --git a/bsd/drm_vm.h b/bsd/drm_vm.h index da815329..9e9f1e14 100644 --- a/bsd/drm_vm.h +++ b/bsd/drm_vm.h @@ -65,7 +65,9 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) drm_map_list_entry_t *listentry = NULL; drm_file_t *priv; + DRM_LOCK(); priv = DRM(find_file_by_proc)(dev, DRM_CURPROC); + DRM_UNLOCK(); if (!priv) { DRM_DEBUG("can't find authenticator\n"); return EINVAL; |