}
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;
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
- DRM_SPINTYPE lock;
} drm_freelist_t;
typedef struct drm_buf_entry {
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;
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 */
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;
#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__
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 );
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;
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;
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) {
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);
return DRM_ERR(EINVAL);
}
TAILQ_REMOVE(dev->maplist, list, link);
+ DRM_UNLOCK();
+
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
switch (map->type) {
break;
}
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
- DRM_UNLOCK();
return 0;
}
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) );
/* 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);
}
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;
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;
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);
DRM_MEM_SEGS);
DRM(free)(entry->seglist_bus, count *
sizeof(*entry->seglist_bus), DRM_MEM_SEGS);
- DRM_UNLOCK();
return DRM_ERR(ENOMEM);
}
DRM(free)(temp_pagelist, (dma->page_count +
(count << page_order)) * sizeof(*dma->pagelist),
DRM_MEM_PAGES);
- DRM_UNLOCK();
return DRM_ERR(ENOMEM);
}
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);
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;
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;
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;
/* 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);
}
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;
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;
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 )
#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;
}
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;
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,
DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) );
- return 0;
+ return retcode;
}
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;
}
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 )
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__
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;
}
#endif /* __HAVE_DMA */
-
if (dev->dma == NULL)
return DRM_ERR(ENOMEM);
+ DRM_SPININIT(dev->dma_lock, "drmdma");
+
return 0;
}
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++) {
DRM_MEM_PAGES);
DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
dev->dma = NULL;
+ DRM_SPINUNINIT(dev->dma_lock);
}
#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) \
static int DRM(detach)(device_t dev)
{
- DRM(cleanup)(dev);
+ DRM(cleanup)(device_get_softc(dev));
return 0;
}
static device_method_t DRM(methods)[] = {
return NULL;
}
+/* Initialize the DRM on first open. Called with device's lock held */
static int DRM(setup)( drm_device_t *dev )
{
int i;
#if __HAVE_DMA
i = DRM(dma_setup)( dev );
- if ( i < 0 )
+ if ( i != 0 )
return i;
#endif
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;
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;
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 );
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 );
dev->lock.filp = NULL;
DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
}
- DRM_UNLOCK();
return 0;
}
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);
#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
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",
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);
}
#endif
+ DRM_LOCK();
DRM(takedown)( dev );
+ DRM_UNLOCK();
#if __REALLY_HAVE_AGP
if ( dev->agp ) {
#endif
DRIVER_POSTCLEANUP();
DRM(mem_uninit)();
- DRM_SPINUNINIT(dev->count_lock);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
+ mtx_destroy(&dev->dev_lock);
+#endif
}
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;
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;
}
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;
}
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;
}
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;
switch (cmd) {
case FIONBIO:
- return 0;
-
case FIOASYNC:
- dev->flags |= FASYNC;
return 0;
#ifdef __FreeBSD__
#endif /* __NetBSD__ */
}
- if (nr >= DRIVER_IOCTL_COUNT)
+ if (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE)
return EINVAL;
ioctl = &DRM(ioctls)[nr];
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;
}
/* 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)
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
DRM_KERNEL_CONTEXT ) ) {
DRM_ERROR( "\n" );
}
+ DRM_UNLOCK();
return 0;
}
#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
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)
{
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;
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
* 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;
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
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();
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__)
#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();
#elif defined(__NetBSD__)
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
#endif
+ DRM_SPINUNINIT(dev->irq_lock);
return 0;
}
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;
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);
}
vbl_sig = next;
}
-
- DRM_SPINUNLOCK(&dev->vbl_lock);
}
#endif
#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
* 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
#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) || \
#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(); \
"drmwtq", (timeout) ); \
splx(s); \
}
+#endif
#define DRM_WAKEUP( queue ) wakeup( queue )
#define DRM_WAKEUP_INT( queue ) wakeup( queue )
#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
* 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
#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) || \
#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
#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 */
{
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);
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
{
- drm_device_t *dev = arg1;
+ drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
{
- drm_device_t *dev = arg1;
+ drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
{
- drm_device_t *dev = arg1;
+ drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
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;
}
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;
int low_mark; /* Low water mark */
int high_mark; /* High water mark */
- DRM_SPINTYPE lock;
} drm_freelist_t;
typedef struct drm_buf_entry {
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;
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 */
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;
#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__
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 );
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;
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;
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) {
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);
return DRM_ERR(EINVAL);
}
TAILQ_REMOVE(dev->maplist, list, link);
+ DRM_UNLOCK();
+
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
switch (map->type) {
break;
}
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
- DRM_UNLOCK();
return 0;
}
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) );
/* 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);
}
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;
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;
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);
DRM_MEM_SEGS);
DRM(free)(entry->seglist_bus, count *
sizeof(*entry->seglist_bus), DRM_MEM_SEGS);
- DRM_UNLOCK();
return DRM_ERR(ENOMEM);
}
DRM(free)(temp_pagelist, (dma->page_count +
(count << page_order)) * sizeof(*dma->pagelist),
DRM_MEM_PAGES);
- DRM_UNLOCK();
return DRM_ERR(ENOMEM);
}
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);
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;
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;
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;
/* 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);
}
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;
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;
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 )
#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;
}
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;
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,
DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) );
- return 0;
+ return retcode;
}
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;
}
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 )
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__
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;
}
#endif /* __HAVE_DMA */
-
if (dev->dma == NULL)
return DRM_ERR(ENOMEM);
+ DRM_SPININIT(dev->dma_lock, "drmdma");
+
return 0;
}
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++) {
DRM_MEM_PAGES);
DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
dev->dma = NULL;
+ DRM_SPINUNINIT(dev->dma_lock);
}
#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) \
static int DRM(detach)(device_t dev)
{
- DRM(cleanup)(dev);
+ DRM(cleanup)(device_get_softc(dev));
return 0;
}
static device_method_t DRM(methods)[] = {
return NULL;
}
+/* Initialize the DRM on first open. Called with device's lock held */
static int DRM(setup)( drm_device_t *dev )
{
int i;
#if __HAVE_DMA
i = DRM(dma_setup)( dev );
- if ( i < 0 )
+ if ( i != 0 )
return i;
#endif
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;
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;
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 );
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 );
dev->lock.filp = NULL;
DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
}
- DRM_UNLOCK();
return 0;
}
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);
#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
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",
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);
}
#endif
+ DRM_LOCK();
DRM(takedown)( dev );
+ DRM_UNLOCK();
#if __REALLY_HAVE_AGP
if ( dev->agp ) {
#endif
DRIVER_POSTCLEANUP();
DRM(mem_uninit)();
- DRM_SPINUNINIT(dev->count_lock);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
+ mtx_destroy(&dev->dev_lock);
+#endif
}
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;
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;
}
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;
}
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;
}
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;
switch (cmd) {
case FIONBIO:
- return 0;
-
case FIOASYNC:
- dev->flags |= FASYNC;
return 0;
#ifdef __FreeBSD__
#endif /* __NetBSD__ */
}
- if (nr >= DRIVER_IOCTL_COUNT)
+ if (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE)
return EINVAL;
ioctl = &DRM(ioctls)[nr];
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;
}
/* 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)
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
DRM_KERNEL_CONTEXT ) ) {
DRM_ERROR( "\n" );
}
+ DRM_UNLOCK();
return 0;
}
#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
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)
{
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;
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
* 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;
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
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();
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__)
#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();
#elif defined(__NetBSD__)
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
#endif
+ DRM_SPINUNINIT(dev->irq_lock);
return 0;
}
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;
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);
}
vbl_sig = next;
}
-
- DRM_SPINUNLOCK(&dev->vbl_lock);
}
#endif
#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
* 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
#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) || \
#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(); \
"drmwtq", (timeout) ); \
splx(s); \
}
+#endif
#define DRM_WAKEUP( queue ) wakeup( queue )
#define DRM_WAKEUP_INT( queue ) wakeup( queue )
#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
* 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
#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) || \
#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
#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 */
{
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);
static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
{
- drm_device_t *dev = arg1;
+ drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
{
- drm_device_t *dev = arg1;
+ drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
{
- drm_device_t *dev = arg1;
+ drm_device_t __unused *dev = arg1;
int ret;
DRM_LOCK();
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;