diff options
author | Eric Anholt <anholt@freebsd.org> | 2004-11-06 20:27:19 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2004-11-06 20:27:19 +0000 |
commit | ae7a1713139f1eacec9cc1629cacef0394e270cc (patch) | |
tree | ea0f4e8439bc006c04695b396dd860ddfb16cc55 /bsd-core/drm_lock.c | |
parent | cca29ac9becffc7d5fc8204c706621b842c3557d (diff) |
Move the lock/unlock ioctls to a more logical place, in drm_lock.c.
Diffstat (limited to 'bsd-core/drm_lock.c')
-rw-r--r-- | bsd-core/drm_lock.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 843fe567..af6f6a74 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -94,3 +94,82 @@ int drm_lock_free(drm_device_t *dev, return 0; } +int drm_lock(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_lock_t lock; + int ret = 0; + + DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock)); + + if (lock.context == DRM_KERNEL_CONTEXT) { + DRM_ERROR("Process %d using kernel context %d\n", + DRM_CURRENTPID, lock.context); + return EINVAL; + } + + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", + lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags); + + if (dev->use_dma_queue && lock.context < 0) + return EINVAL; + + DRM_LOCK(); + for (;;) { + if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { + dev->lock.filp = (void *)(uintptr_t)DRM_CURRENTPID; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); + break; /* Got lock */ + } + + /* 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 (dev->dma_quiescent != NULL && (lock.flags & _DRM_LOCK_QUIESCENT)) + dev->dma_quiescent(dev); + + return 0; +} + +int drm_unlock(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + drm_lock_t lock; + + DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock)); + + if (lock.context == DRM_KERNEL_CONTEXT) { + DRM_ERROR("Process %d using kernel context %d\n", + DRM_CURRENTPID, lock.context); + return EINVAL; + } + + atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); + + DRM_LOCK(); + drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); + + if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { + DRM_ERROR("\n"); + } + DRM_UNLOCK(); + + return 0; +} |