summaryrefslogtreecommitdiffstats
path: root/sys/dev/drm/drm_drv.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/drm/drm_drv.h')
-rw-r--r--sys/dev/drm/drm_drv.h412
1 files changed, 186 insertions, 226 deletions
diff --git a/sys/dev/drm/drm_drv.h b/sys/dev/drm/drm_drv.h
index 6f8f8f4..f00d6de 100644
--- a/sys/dev/drm/drm_drv.h
+++ b/sys/dev/drm/drm_drv.h
@@ -56,8 +56,8 @@
#ifndef __HAVE_CTX_BITMAP
#define __HAVE_CTX_BITMAP 0
#endif
-#ifndef __HAVE_DMA_IRQ
-#define __HAVE_DMA_IRQ 0
+#ifndef __HAVE_IRQ
+#define __HAVE_IRQ 0
#endif
#ifndef __HAVE_DMA_QUEUE
#define __HAVE_DMA_QUEUE 0
@@ -112,7 +112,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) \
@@ -136,6 +136,7 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { DRM(setversion), 0, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(noop), 1, 1 },
@@ -171,9 +172,9 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 },
-
- /* The DRM_IOCTL_DMA ioctl should be defined by the driver.
- */
+ /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
+#endif
+#if __HAVE_IRQ || __HAVE_DMA
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 },
#endif
@@ -220,16 +221,26 @@ static struct cdevsw DRM(cdevsw) = {
#endif
};
+static drm_pci_id_list_t DRM(pciidlist)[] = {
+ DRIVER_PCI_IDS
+};
+
static int DRM(probe)(device_t dev)
{
const char *s = NULL;
+ int pciid, vendor, device;
+
+ /* XXX: Cope with agp bridge device? */
+ if (!strcmp(device_get_name(dev), "drmsub"))
+ pciid = pci_get_devid(device_get_parent(dev));
+ else
+ pciid = pci_get_devid(dev);
- int pciid=pci_get_devid(dev);
- int vendor = (pciid & 0x0000ffff);
- int device = (pciid & 0xffff0000) >> 16;
+ vendor = (pciid & 0x0000ffff);
+ device = (pciid & 0xffff0000) >> 16;
s = DRM(find_description)(vendor, device);
- if (s) {
+ if (s != NULL) {
device_set_desc(dev, s);
return 0;
}
@@ -244,14 +255,14 @@ 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)[] = {
/* Device interface */
- DEVMETHOD(device_probe, DRM( probe)),
- DEVMETHOD(device_attach, DRM( attach)),
- DEVMETHOD(device_detach, DRM( detach)),
+ DEVMETHOD(device_probe, DRM(probe)),
+ DEVMETHOD(device_attach, DRM(attach)),
+ DEVMETHOD(device_detach, DRM(detach)),
{ 0, 0 }
};
@@ -343,7 +354,8 @@ int DRM(probe)(struct pci_attach_args *pa)
{
const char *desc;
- desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
+ desc = DRM(find_description)(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id));
if (desc != NULL) {
return 1;
}
@@ -390,23 +402,18 @@ int DRM(activate)(struct device *self, enum devact act)
#endif /* __NetBSD__ */
const char *DRM(find_description)(int vendor, int device) {
- const char *s = NULL;
- int i=0, done=0;
+ int i = 0;
- while ( !done && (DRM(devicelist)[i].vendor != 0 ) ) {
- if ( (DRM(devicelist)[i].vendor == vendor) &&
- (DRM(devicelist)[i].device == device) ) {
- done=1;
- if ( DRM(devicelist)[i].supported )
- s = DRM(devicelist)[i].name;
- else
- DRM_INFO("%s not supported\n", DRM(devicelist)[i].name);
+ for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {
+ if ((DRM(pciidlist)[i].vendor == vendor) &&
+ (DRM(pciidlist)[i].device == device)) {
+ return DRM(pciidlist)[i].name;
}
- i++;
}
- return s;
+ return NULL;
}
+/* Initialize the DRM on first open. Called with device's lock held */
static int DRM(setup)( drm_device_t *dev )
{
int i;
@@ -417,7 +424,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
@@ -467,22 +474,11 @@ static int DRM(setup)( drm_device_t *dev )
dev->magiclist[i].tail = NULL;
}
- dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
- DRM_MEM_MAPS);
- if(dev->maplist == NULL) return DRM_ERR(ENOMEM);
- memset(dev->maplist, 0, sizeof(*dev->maplist));
- TAILQ_INIT(dev->maplist);
-
dev->lock.hw_lock = NULL;
dev->lock.lock_queue = 0;
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;
@@ -496,7 +492,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;
@@ -507,13 +505,11 @@ static int DRM(takedown)( drm_device_t *dev )
DRM_DEBUG( "\n" );
DRIVER_PRETAKEDOWN();
-#if __HAVE_DMA_IRQ
- if ( dev->irq ) DRM(irq_uninstall)( dev );
+#if __HAVE_IRQ
+ if (dev->irq != 0)
+ 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 );
@@ -536,7 +532,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 );
@@ -551,8 +547,14 @@ static int DRM(takedown)( drm_device_t *dev )
dev->agp->enabled = 0;
}
#endif
+#if __REALLY_HAVE_SG
+ if (dev->sg != NULL) {
+ DRM(sg_cleanup)(dev->sg);
+ dev->sg = NULL;
+ }
+#endif
- if( dev->maplist ) {
+ if (dev->maplist != NULL) {
while ((list=TAILQ_FIRST(dev->maplist))) {
map = list->map;
switch ( map->type ) {
@@ -560,28 +562,11 @@ static int DRM(takedown)( drm_device_t *dev )
case _DRM_FRAME_BUFFER:
#if __REALLY_HAVE_MTRR
if ( map->mtrr >= 0 ) {
- int retcode;
-#ifdef __FreeBSD__
- int act;
- struct mem_range_desc mrdesc;
- mrdesc.mr_base = map->offset;
- mrdesc.mr_len = map->size;
- mrdesc.mr_flags = MDF_WRITECOMBINE;
- act = MEMRANGE_SET_REMOVE;
- bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME));
- retcode = mem_range_attr_set(&mrdesc, &act);
- map->mtrr=1;
-#elif defined __NetBSD__
- struct mtrr mtrrmap;
- int one = 1;
- mtrrmap.base = map->offset;
- mtrrmap.len = map->size;
- mtrrmap.type = MTRR_TYPE_WC;
- mtrrmap.flags = 0;
- retcode = mtrr_set( &mtrrmap, &one,
- DRM_CURPROC, MTRR_GETSET_KERNEL);
-#endif
- DRM_DEBUG( "mtrr_del=%d\n", retcode );
+ int __unused mtrr;
+
+ mtrr = DRM(mtrr_del)(map->offset,
+ map->size, DRM_MTRR_WC);
+ DRM_DEBUG("mtrr_del=%d\n", mtrr);
}
#endif
DRM(ioremapfree)( map );
@@ -593,28 +578,16 @@ static int DRM(takedown)( drm_device_t *dev )
break;
case _DRM_AGP:
+ case _DRM_SCATTER_GATHER:
/* Do nothing here, because this is all
- * handled in the AGP/GART driver.
- */
- break;
- case _DRM_SCATTER_GATHER:
- /* Handle it, but do nothing, if REALLY_HAVE_SG
- * isn't defined.
+ * handled in the AGP/GART/SG functions.
*/
-#if __REALLY_HAVE_SG
- if(dev->sg) {
- DRM(sg_cleanup)(dev->sg);
- dev->sg = NULL;
- }
-#endif
break;
}
TAILQ_REMOVE(dev->maplist, list, link);
DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
}
- DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
- dev->maplist = NULL;
}
#if __HAVE_DMA
@@ -625,7 +598,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;
}
@@ -652,18 +624,32 @@ static int DRM(init)( device_t nbdev )
unit = device_get_unit(nbdev);
dev = device_get_softc(nbdev);
memset( (void *)dev, 0, sizeof(*dev) );
- dev->device = nbdev;
+
+ if (!strcmp(device_get_name(nbdev), "drmsub"))
+ dev->device = device_get_parent(nbdev);
+ else
+ dev->device = nbdev;
+
dev->devnode = make_dev( &DRM(cdevsw),
unit,
DRM_DEV_UID,
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->maplist = DRM(calloc)(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
+ if (dev->maplist == NULL) {
+ retcode = ENOMEM;
+ goto error;
+ }
+ TAILQ_INIT(dev->maplist);
+
dev->name = DRIVER_NAME;
DRM(mem_init)();
DRM(sysctl_init)(dev);
@@ -674,51 +660,30 @@ 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
if (dev->agp) {
-#ifdef __FreeBSD__
- int retcode = 0, act;
- struct mem_range_desc mrdesc;
- mrdesc.mr_base = dev->agp->info.ai_aperture_base;
- mrdesc.mr_len = dev->agp->info.ai_aperture_size;
- mrdesc.mr_flags = MDF_WRITECOMBINE;
- act = MEMRANGE_SET_UPDATE;
- bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME));
- retcode = mem_range_attr_set(&mrdesc, &act);
- dev->agp->agp_mtrr=1;
-#elif defined __NetBSD__
- struct mtrr mtrrmap;
- int one = 1;
- mtrrmap.base = dev->agp->info.ai_aperture_base;
- mtrrmap.len = dev->agp->info.ai_aperture_size;
- mtrrmap.type = MTRR_TYPE_WC;
- mtrrmap.flags = MTRR_VALID;
- dev->agp->agp_mtrr = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
-#endif /* __NetBSD__ */
+ int retcode;
+
+ retcode = DRM(mtrr_add)(dev->agp->info.ai_aperture_base,
+ dev->agp->info.ai_aperture_size, DRM_MTRR_WC);
+ if (retcode == 0)
+ dev->agp->agp_mtrr=1;
}
#endif /* __REALLY_HAVE_MTRR */
#endif /* __REALLY_HAVE_AGP */
#if __HAVE_CTX_BITMAP
retcode = DRM(ctxbitmap_init)( dev );
- if( retcode ) {
+ 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_NAME,
DRIVER_MAJOR,
@@ -730,28 +695,31 @@ 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
+ DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
+ 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);
@@ -762,17 +730,17 @@ static void DRM(cleanup)(device_t nbdev)
#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR
if ( dev->agp && dev->agp->agp_mtrr >= 0) {
-#if defined(__NetBSD__)
- mtrrmap.base = dev->agp->info.ai_aperture_base;
- mtrrmap.len = dev->agp->info.ai_aperture_size;
- mtrrmap.type = 0;
- mtrrmap.flags = 0;
- mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
-#endif
+ int __unused mtrr;
+
+ mtrr = DRM(mtrr_del)(dev->agp->info.ai_aperture_base,
+ dev->agp->info.ai_aperture_size, DRM_MTRR_WC);
+ DRM_DEBUG("mtrr_del=%d\n", mtrr);
}
#endif
+ DRM_LOCK();
DRM(takedown)( dev );
+ DRM_UNLOCK();
#if __REALLY_HAVE_AGP
if ( dev->agp ) {
@@ -783,7 +751,10 @@ 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
+ DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
}
@@ -829,13 +800,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;
@@ -846,12 +817,16 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
drm_file_t *priv;
DRM_DEVICE;
int retcode = 0;
- DRMFILE __unused filp = (void *)(DRM_CURRENTPID);
+ 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_DEBUG("can't find authenticator\n");
+ DRM_UNLOCK();
+ DRM_ERROR("can't find authenticator\n");
return EINVAL;
}
@@ -870,11 +845,11 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
#endif
if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
- && dev->lock.filp == (void *)DRM_CURRENTPID) {
+ && dev->lock.filp == filp) {
DRM_DEBUG("Process %d dead, freeing lock for context %d\n",
DRM_CURRENTPID,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-#if HAVE_DRIVER_RELEASE
+#if __HAVE_RELEASE
DRIVER_RELEASE();
#endif
DRM(lock_free)(dev,
@@ -903,17 +878,17 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
break; /* Got lock */
}
/* Contention */
-#if 0
- atomic_inc( &dev->total_sleeps );
-#endif
+#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;
}
- if( !retcode ) {
+ if (retcode == 0) {
DRIVER_RELEASE();
DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT );
@@ -931,32 +906,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;
}
@@ -971,7 +938,9 @@ 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_GET_PRIV_WITH_RETURN(priv, (DRMFILE)DRM_CURRENTPID);
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
++priv->ioctl_count;
@@ -986,10 +955,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__
@@ -1015,22 +981,21 @@ int DRM(ioctl)(dev_t kdev, u_long cmd, caddr_t data, int flags,
#endif /* __NetBSD__ */
}
- if ( nr >= DRIVER_IOCTL_COUNT ) {
- retcode = EINVAL;
- } else {
- ioctl = &DRM(ioctls)[nr];
- func = ioctl->func;
-
- if ( !func ) {
- DRM_DEBUG( "no function\n" );
- retcode = EINVAL;
- } else if ( ( ioctl->root_only && DRM_SUSER(p) )
- || ( ioctl->auth_needed && !priv->authenticated ) ) {
- retcode = EACCES;
- } else {
- retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID);
- }
+ if (nr >= DRIVER_IOCTL_COUNT || IOCGROUP(cmd) != DRM_IOCTL_BASE)
+ return EINVAL;
+
+ ioctl = &DRM(ioctls)[nr];
+ func = ioctl->func;
+
+ if (func == NULL) {
+ DRM_DEBUG( "no function\n" );
+ return EINVAL;
}
+ if ((ioctl->root_only && DRM_SUSER(p)) || (ioctl->auth_needed &&
+ !priv->authenticated))
+ return EACCES;
+
+ retcode = func(kdev, cmd, data, flags, p, (void *)DRM_CURRENTPID);
return DRM_ERR(retcode);
}
@@ -1058,44 +1023,41 @@ int DRM(lock)( DRM_IOCTL_ARGS )
return DRM_ERR(EINVAL);
#endif
- if ( !ret ) {
- for (;;) {
- if ( !dev->lock.hw_lock ) {
- /* Device has been unregistered */
- ret = EINTR;
- break;
- }
- if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
- lock.context ) ) {
- dev->lock.filp = (void *)DRM_CURRENTPID;
- dev->lock.lock_time = jiffies;
- atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
- break; /* Got lock */
- }
-
- /* Contention */
- ret = tsleep((void *)&dev->lock.lock_queue,
- PZERO|PCATCH,
- "drmlk2",
- 0);
- if (ret)
- break;
- }
- }
+ DRM_LOCK();
+ for (;;) {
+ if (DRM(lock_take)(&dev->lock.hw_lock->lock, lock.context)) {
+ dev->lock.filp = (void *)DRM_CURRENTPID;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+ break; /* Got lock */
+ }
- if ( !ret ) {
- /* FIXME: Add signal blocking here */
+ /* Contention */
+#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)
+ return ret;
+
+ /* XXX: Add signal blocking here */
#if __HAVE_DMA_QUIESCENT
- if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
- DRIVER_DMA_QUIESCENT();
- }
+ if (lock.flags & _DRM_LOCK_QUIESCENT) {
+ DRIVER_DMA_QUIESCENT();
+ }
#endif
- }
-
- DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
- return DRM_ERR(ret);
+ return 0;
}
@@ -1114,20 +1076,18 @@ 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
DRM(dma_schedule)( dev, 1 );
#endif
- /* FIXME: Do we ever really need to check this?
- */
- if ( 1 /* !dev->context_flag */ ) {
- if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT ) ) {
- DRM_ERROR( "\n" );
- }
+ if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT ) ) {
+ DRM_ERROR( "\n" );
}
+ DRM_UNLOCK();
return 0;
}
OpenPOWER on IntegriCloud