summaryrefslogtreecommitdiff
path: root/bsd-core
diff options
context:
space:
mode:
Diffstat (limited to 'bsd-core')
-rw-r--r--bsd-core/Makefile64
-rw-r--r--bsd-core/ati_pcigart.c8
l---------bsd-core/drm.h1
-rw-r--r--bsd-core/drmP.h198
-rw-r--r--bsd-core/drm_agpsupport.c34
-rw-r--r--bsd-core/drm_auth.c116
-rw-r--r--bsd-core/drm_bufs.c258
-rw-r--r--bsd-core/drm_context.c136
-rw-r--r--bsd-core/drm_dma.c29
-rw-r--r--bsd-core/drm_drawable.c121
-rw-r--r--bsd-core/drm_drv.c249
-rw-r--r--bsd-core/drm_fops.c13
-rw-r--r--bsd-core/drm_ioctl.c170
-rw-r--r--bsd-core/drm_irq.c138
-rw-r--r--bsd-core/drm_lock.c67
-rw-r--r--bsd-core/drm_memory.c11
-rw-r--r--bsd-core/drm_pci.c14
l---------bsd-core/drm_sarea.h1
-rw-r--r--bsd-core/drm_scatter.c49
-rw-r--r--bsd-core/drm_sysctl.c5
-rw-r--r--bsd-core/drm_vm.c8
l---------bsd-core/i915_dma.c1
l---------bsd-core/i915_drm.h1
l---------bsd-core/i915_drv.h1
l---------bsd-core/i915_irq.c1
l---------bsd-core/i915_mem.c1
l---------bsd-core/mach64_dma.c1
l---------bsd-core/mach64_drm.h1
l---------bsd-core/mach64_drv.h1
l---------bsd-core/mach64_irq.c1
l---------bsd-core/mach64_state.c1
l---------bsd-core/mga_dma.c1
l---------bsd-core/mga_drm.h1
l---------bsd-core/mga_drv.h1
l---------bsd-core/mga_irq.c1
l---------bsd-core/mga_state.c1
l---------bsd-core/mga_ucode.h1
l---------bsd-core/mga_warp.c1
l---------bsd-core/r128_cce.c1
l---------bsd-core/r128_drm.h1
l---------bsd-core/r128_drv.h1
l---------bsd-core/r128_irq.c1
l---------bsd-core/r128_state.c1
l---------bsd-core/r300_cmdbuf.c1
l---------bsd-core/r300_reg.h1
l---------bsd-core/radeon_cp.c1
l---------bsd-core/radeon_drm.h1
l---------bsd-core/radeon_drv.h1
l---------bsd-core/radeon_irq.c1
l---------bsd-core/radeon_mem.c1
l---------bsd-core/radeon_state.c1
l---------bsd-core/savage_bci.c1
l---------bsd-core/savage_drm.h1
l---------bsd-core/savage_drv.h1
l---------bsd-core/savage_state.c1
l---------bsd-core/sis_drm.h1
l---------bsd-core/sis_drv.h1
l---------bsd-core/sis_ds.c1
l---------bsd-core/sis_ds.h1
l---------bsd-core/sis_mm.c1
l---------bsd-core/tdfx_drv.h1
l---------bsd-core/via_3d_reg.h1
l---------bsd-core/via_dma.c1
l---------bsd-core/via_drm.h1
l---------bsd-core/via_drv.h1
l---------bsd-core/via_ds.c1
l---------bsd-core/via_ds.h1
l---------bsd-core/via_irq.c1
l---------bsd-core/via_map.c1
l---------bsd-core/via_mm.c1
l---------bsd-core/via_mm.h1
l---------bsd-core/via_verifier.c1
l---------bsd-core/via_verifier.h1
l---------bsd-core/via_video.c1
74 files changed, 937 insertions, 806 deletions
diff --git a/bsd-core/Makefile b/bsd-core/Makefile
index 00889dae..a58ac0a5 100644
--- a/bsd-core/Makefile
+++ b/bsd-core/Makefile
@@ -1,71 +1,11 @@
SHARED= ../shared-core
-SHAREDFILES= drm.h \
- drm_sarea.h \
- i915_dma.c \
- i915_drm.h \
- i915_drv.h \
- i915_irq.c \
- i915_mem.c \
- mach64_dma.c \
- mach64_drm.h \
- mach64_drv.h \
- mach64_irq.c \
- mach64_state.c \
- mga_dma.c \
- mga_drm.h \
- mga_drv.h \
- mga_irq.c \
- mga_state.c \
- mga_ucode.h \
- mga_warp.c \
- r128_cce.c \
- r128_drm.h \
- r128_drv.h \
- r128_irq.c \
- r128_state.c \
- radeon_cp.c \
- radeon_drm.h \
- radeon_drv.h \
- radeon_irq.c \
- radeon_mem.c \
- radeon_state.c \
- r300_cmdbuf.c \
- r300_reg.h \
- savage_bci.c \
- savage_drm.h \
- savage_drv.h \
- savage_state.c \
- sis_drm.h \
- sis_drv.h \
- sis_ds.c \
- sis_ds.h \
- sis_mm.c \
- tdfx_drv.h \
- via_3d_reg.h \
- via_dma.c \
- via_drm.h \
- via_drv.h \
- via_ds.c \
- via_ds.h \
- via_irq.c \
- via_map.c \
- via_mm.c \
- via_mm.h \
- via_verifier.c \
- via_verifier.h \
- via_video.c
SUBDIR = drm mach64 mga r128 radeon savage sis tdfx i915 # via
-CLEANFILES+= ${SHAREDFILES}
-
.include <bsd.obj.mk>
-depend: drm_pciids.h ${SHAREDFILES}
-all: drm_pciids.h ${SHAREDFILES}
+depend: drm_pciids.h
+all: drm_pciids.h
drm_pciids.h: ${SHARED}/drm_pciids.txt
sh ../scripts/create_bsd_pci_lists.sh < ${SHARED}/drm_pciids.txt
-
-${SHAREDFILES}:
- ln -sf ${SHARED}/$@ $@
diff --git a/bsd-core/ati_pcigart.c b/bsd-core/ati_pcigart.c
index 682eace6..db19a75d 100644
--- a/bsd-core/ati_pcigart.c
+++ b/bsd-core/ati_pcigart.c
@@ -1,6 +1,3 @@
-/* ati_pcigart.h -- ATI PCI GART support -*- linux-c -*-
- * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
- */
/*-
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
@@ -29,6 +26,11 @@
*
*/
+/** @file ati_pcigart.c
+ * Implementation of ATI's PCIGART, which provides an aperture in card virtual
+ * address space with addresses remapped to system memory.
+ */
+
#include "drmP.h"
#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
diff --git a/bsd-core/drm.h b/bsd-core/drm.h
new file mode 120000
index 00000000..29636692
--- /dev/null
+++ b/bsd-core/drm.h
@@ -0,0 +1 @@
+../shared-core/drm.h \ No newline at end of file
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h
index 9ba3d502..8a768f0c 100644
--- a/bsd-core/drmP.h
+++ b/bsd-core/drmP.h
@@ -59,6 +59,8 @@ typedef struct drm_file drm_file_t;
#include <sys/bus.h>
#include <sys/signalvar.h>
#include <sys/poll.h>
+#include <sys/tree.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
@@ -152,6 +154,7 @@ typedef struct drm_file drm_file_t;
#define DRM_MEM_CTXBITMAP 17
#define DRM_MEM_STUB 18
#define DRM_MEM_SGLISTS 19
+#define DRM_MEM_DRAWABLE 20
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
@@ -184,10 +187,15 @@ MALLOC_DECLARE(M_DRM);
#define DRM_CURPROC curthread
#define DRM_STRUCTPROC struct thread
#define DRM_SPINTYPE struct mtx
-#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
-#define DRM_SPINUNINIT(l) mtx_destroy(&l)
+#define DRM_SPININIT(l,name) mtx_init(l, name, NULL, MTX_DEF)
+#define DRM_SPINUNINIT(l) mtx_destroy(l)
#define DRM_SPINLOCK(l) mtx_lock(l)
-#define DRM_SPINUNLOCK(u) mtx_unlock(u);
+#define DRM_SPINUNLOCK(u) mtx_unlock(u)
+#define DRM_SPINLOCK_IRQSAVE(l, irqflags) do { \
+ mtx_lock(l); \
+ (void)irqflags; \
+} while (0)
+#define DRM_SPINUNLOCK_IRQRESTORE(u, irqflags) mtx_unlock(u)
#define DRM_SPINLOCK_ASSERT(l) mtx_assert(l, MA_OWNED)
#define DRM_CURRENTPID curthread->td_proc->p_pid
#define DRM_LOCK() mtx_lock(&dev->dev_lock)
@@ -209,10 +217,6 @@ MALLOC_DECLARE(M_DRM);
#define spldrm() spltty()
#endif /* __NetBSD__ || __OpenBSD__ */
-/* Currently our DRMFILE (filp) is a void * which is actually the pid
- * of the current process. It should be a per-open unique pointer, but
- * code for that is not yet written */
-#define DRMFILE void *
#define DRM_IRQ_ARGS void *arg
typedef void irqreturn_t;
#define IRQ_HANDLED /* nothing */
@@ -226,11 +230,15 @@ enum {
#define DRM_AGP_MEM struct agp_memory_info
#if defined(__FreeBSD__)
-#define DRM_DEVICE \
- drm_device_t *dev = kdev->si_drv1
-#define DRM_IOCTL_ARGS struct cdev *kdev, u_long cmd, caddr_t data, \
- int flags, DRM_STRUCTPROC *p, DRMFILE filp
+#define drm_get_device_from_kdev(_kdev) (_kdev->si_drv1)
+#elif defined(__NetBSD__)
+#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, minor(_kdev))
+#elif defined(__OpenBSD__)
+#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, \
+ minor(_kdev)))->dv_cfdata->cf_driver->cd_devs[minor(_kdev)]
+#endif
+#if defined(__FreeBSD__)
#define PAGE_ALIGN(addr) round_page(addr)
/* DRM_SUSER returns true if the user is superuser */
#if __FreeBSD_version >= 700000
@@ -244,17 +252,6 @@ enum {
#else /* __FreeBSD__ */
-#if defined(__NetBSD__)
-#define DRM_DEVICE \
- drm_device_t *dev = device_lookup(&drm_cd, minor(kdev))
-#elif defined(__OpenBSD__)
-#define DRM_DEVICE \
- drm_device_t *dev = (device_lookup(&drm_cd, \
- minor(kdev)))->dv_cfdata->cf_driver->cd_devs[minor(kdev)]
-#endif /* __OpenBSD__ */
-#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, \
- int flags, DRM_STRUCTPROC *p, DRMFILE filp
-
#define CDEV_MAJOR 34
#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
/* DRM_SUSER returns true if the user is superuser */
@@ -342,14 +339,6 @@ typedef vaddr_t vm_offset_t;
(!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ))
#endif /* !__FreeBSD__ */
-#define DRM_COPY_TO_USER_IOCTL(user, kern, size) \
- if ( IOCPARM_LEN(cmd) != size) \
- return EINVAL; \
- *user = kern;
-#define DRM_COPY_FROM_USER_IOCTL(kern, user, size) \
- if ( IOCPARM_LEN(cmd) != size) \
- return EINVAL; \
- kern = *user;
#define DRM_COPY_TO_USER(user, kern, size) \
copyout(kern, user, size)
#define DRM_COPY_FROM_USER(kern, user, size) \
@@ -369,7 +358,6 @@ typedef vaddr_t vm_offset_t;
#define cpu_to_le32(x) htole32(x)
#define le32_to_cpu(x) le32toh(x)
-#define DRM_ERR(v) v
#define DRM_HZ hz
#define DRM_UDELAY(udelay) DELAY(udelay)
#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
@@ -378,23 +366,10 @@ typedef vaddr_t vm_offset_t;
(_map) = (_dev)->context_sareas[_ctx]; \
} while(0)
-#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) \
-do { \
- if (_filp != (DRMFILE)(intptr_t)DRM_CURRENTPID) { \
- DRM_ERROR("filp doesn't match curproc\n"); \
- return EINVAL; \
- } \
- _priv = drm_find_file_by_proc(dev, DRM_CURPROC); \
- if (_priv == NULL) { \
- DRM_ERROR("can't find authenticator\n"); \
- return EINVAL; \
- } \
-} while (0)
-
-#define LOCK_TEST_WITH_RETURN(dev, filp) \
+#define LOCK_TEST_WITH_RETURN(dev, file_priv) \
do { \
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \
- dev->lock.filp != filp) { \
+ dev->lock.file_priv != file_priv) { \
DRM_ERROR("%s called without lock held\n", \
__FUNCTION__); \
return EINVAL; \
@@ -402,22 +377,24 @@ do { \
} while (0)
#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+/* Returns -errno to shared code */
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
for ( ret = 0 ; !ret && !(condition) ; ) { \
DRM_UNLOCK(); \
mtx_lock(&dev->irq_lock); \
if (!(condition)) \
- ret = msleep(&(queue), &dev->irq_lock, \
+ ret = -msleep(&(queue), &dev->irq_lock, \
PZERO | PCATCH, "drmwtq", (timeout)); \
mtx_unlock(&dev->irq_lock); \
DRM_LOCK(); \
}
#else
+/* Returns -errno to shared code */
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
for ( ret = 0 ; !ret && !(condition) ; ) { \
int s = spldrm(); \
if (!(condition)) \
- ret = tsleep( &(queue), PZERO | PCATCH, \
+ ret = -tsleep( &(queue), PZERO | PCATCH, \
"drmwtq", (timeout) ); \
splx(s); \
}
@@ -447,9 +424,16 @@ typedef struct drm_pci_id_list
#define DRM_MASTER 0x2
#define DRM_ROOT_ONLY 0x4
typedef struct drm_ioctl_desc {
- int (*func)(DRM_IOCTL_ARGS);
+ unsigned long cmd;
+ int (*func)(drm_device_t *dev, void *data, struct drm_file *file_priv);
int flags;
} drm_ioctl_desc_t;
+/**
+ * Creates a driver or general drm_ioctl_desc array entry for the given
+ * ioctl, for use by drm_ioctl().
+ */
+#define DRM_IOCTL_DEF(ioctl, func, flags) \
+ [DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags}
typedef struct drm_magic_entry {
drm_magic_t magic;
@@ -472,7 +456,7 @@ typedef struct drm_buf {
unsigned long bus_address; /* Bus address of buffer */
struct drm_buf *next; /* Kernel-only: used for free list */
__volatile__ int pending; /* On hardware DMA queue */
- DRMFILE filp; /* Unique identifier of holding process */
+ struct drm_file *file_priv; /* Unique identifier of holding process */
int context; /* Kernel queue for this buffer */
enum {
DRM_LIST_NONE = 0,
@@ -534,7 +518,7 @@ 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)*/
+ struct drm_file *file_priv; /* Unique identifier of holding process (NULL is kernel)*/
int lock_queue; /* Queue of blocked processes */
unsigned long lock_time; /* Time of last lock in jiffies */
} drm_lock_data_t;
@@ -638,12 +622,13 @@ struct drm_driver_info {
int (*load)(struct drm_device *, unsigned long flags);
int (*firstopen)(struct drm_device *);
int (*open)(struct drm_device *, drm_file_t *);
- void (*preclose)(struct drm_device *, void *filp);
+ void (*preclose)(struct drm_device *, struct drm_file *file_priv);
void (*postclose)(struct drm_device *, drm_file_t *);
void (*lastclose)(struct drm_device *);
int (*unload)(struct drm_device *);
- void (*reclaim_buffers_locked)(struct drm_device *, void *filp);
- int (*dma_ioctl)(DRM_IOCTL_ARGS);
+ void (*reclaim_buffers_locked)(struct drm_device *,
+ struct drm_file *file_priv);
+ int (*dma_ioctl)(drm_device_t *dev, void *data, struct drm_file *file_priv);
void (*dma_ready)(struct drm_device *);
int (*dma_quiescent)(struct drm_device *);
int (*dma_flush_block_and_flush)(struct drm_device *, int context,
@@ -732,6 +717,8 @@ struct drm_device {
struct mtx irq_lock; /* protects irq condition checks */
struct mtx dev_lock; /* protects everything else */
#endif
+ DRM_SPINTYPE drw_lock;
+
/* Usage Counters */
int open_count; /* Outstanding files open */
int buf_use; /* Buffers in use -- cannot alloc */
@@ -780,6 +767,7 @@ struct drm_device {
int last_context; /* Last current context */
int vbl_queue; /* vbl wait channel */
atomic_t vbl_received;
+ atomic_t vbl_received2;
#ifdef __FreeBSD__
struct sigio *buf_sigio; /* Processes waiting for SIGIO */
@@ -796,6 +784,13 @@ struct drm_device {
void *dev_private;
unsigned int agp_buffer_token;
drm_local_map_t *agp_buffer_map;
+
+ struct unrhdr *drw_unrhdr;
+ /* RB tree of drawable infos */
+ RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head;
+
+ struct task locked_task;
+ void (*locked_task_call)(drm_device_t *dev);
};
extern int drm_debug_flag;
@@ -883,7 +878,7 @@ int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
int drm_dma_setup(drm_device_t *dev);
void drm_dma_takedown(drm_device_t *dev);
void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
-void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp);
+void drm_reclaim_buffers(drm_device_t *dev, struct drm_file *file_priv);
#define drm_core_reclaim_buffers drm_reclaim_buffers
/* IRQ support (drm_irq.c) */
@@ -915,6 +910,7 @@ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
/* Scatter Gather Support (drm_scatter.c) */
void drm_sg_cleanup(drm_sg_mem_t *entry);
+int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request);
#ifdef __FreeBSD__
/* sysctl support (drm_sysctl.h) */
@@ -929,68 +925,72 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev,
drm_ati_pcigart_info *gart_info);
/* Locking IOCTL support (drm_drv.c) */
-int drm_lock(DRM_IOCTL_ARGS);
-int drm_unlock(DRM_IOCTL_ARGS);
-int drm_version(DRM_IOCTL_ARGS);
-int drm_setversion(DRM_IOCTL_ARGS);
+int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_version(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_setversion(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* Misc. IOCTL support (drm_ioctl.c) */
-int drm_irq_by_busid(DRM_IOCTL_ARGS);
-int drm_getunique(DRM_IOCTL_ARGS);
-int drm_setunique(DRM_IOCTL_ARGS);
-int drm_getmap(DRM_IOCTL_ARGS);
-int drm_getclient(DRM_IOCTL_ARGS);
-int drm_getstats(DRM_IOCTL_ARGS);
-int drm_noop(DRM_IOCTL_ARGS);
+int drm_irq_by_busid(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_getunique(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_setunique(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_getmap(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_getclient(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_getstats(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_noop(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* Context IOCTL support (drm_context.c) */
-int drm_resctx(DRM_IOCTL_ARGS);
-int drm_addctx(DRM_IOCTL_ARGS);
-int drm_modctx(DRM_IOCTL_ARGS);
-int drm_getctx(DRM_IOCTL_ARGS);
-int drm_switchctx(DRM_IOCTL_ARGS);
-int drm_newctx(DRM_IOCTL_ARGS);
-int drm_rmctx(DRM_IOCTL_ARGS);
-int drm_setsareactx(DRM_IOCTL_ARGS);
-int drm_getsareactx(DRM_IOCTL_ARGS);
+int drm_resctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_addctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_modctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_getctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_switchctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_newctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_rmctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_setsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_getsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* Drawable IOCTL support (drm_drawable.c) */
-int drm_adddraw(DRM_IOCTL_ARGS);
-int drm_rmdraw(DRM_IOCTL_ARGS);
+int drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv);
+struct drm_drawable_info *drm_get_drawable_info(drm_device_t *dev, int handle);
/* Authentication IOCTL support (drm_auth.c) */
-int drm_getmagic(DRM_IOCTL_ARGS);
-int drm_authmagic(DRM_IOCTL_ARGS);
+int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* Buffer management support (drm_bufs.c) */
-int drm_addmap_ioctl(DRM_IOCTL_ARGS);
-int drm_rmmap_ioctl(DRM_IOCTL_ARGS);
-int drm_addbufs_ioctl(DRM_IOCTL_ARGS);
-int drm_infobufs(DRM_IOCTL_ARGS);
-int drm_markbufs(DRM_IOCTL_ARGS);
-int drm_freebufs(DRM_IOCTL_ARGS);
-int drm_mapbufs(DRM_IOCTL_ARGS);
+int drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_rmmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_addbufs_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_infobufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_markbufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_freebufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* DMA support (drm_dma.c) */
-int drm_dma(DRM_IOCTL_ARGS);
+int drm_dma(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* IRQ support (drm_irq.c) */
-int drm_control(DRM_IOCTL_ARGS);
-int drm_wait_vblank(DRM_IOCTL_ARGS);
+int drm_control(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv);
+void drm_locked_tasklet(drm_device_t *dev,
+ void (*tasklet)(drm_device_t *dev));
/* AGP/GART support (drm_agpsupport.c) */
-int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_release_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_enable_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_info_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_free_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS);
-int drm_agp_bind_ioctl(DRM_IOCTL_ARGS);
+int drm_agp_acquire_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_release_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_enable_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_info_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_free_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_unbind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_agp_bind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* Scatter Gather Support (drm_scatter.c) */
-int drm_sg_alloc(DRM_IOCTL_ARGS);
-int drm_sg_free(DRM_IOCTL_ARGS);
+int drm_sg_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int drm_sg_free(drm_device_t *dev, void *data, struct drm_file *file_priv);
/* consistent PCI memory functions (drm_pci.c) */
drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align,
diff --git a/bsd-core/drm_agpsupport.c b/bsd-core/drm_agpsupport.c
index 28239d1b..6f963b9c 100644
--- a/bsd-core/drm_agpsupport.c
+++ b/bsd-core/drm_agpsupport.c
@@ -1,6 +1,3 @@
-/* drm_agpsupport.h -- DRM support for AGP/GART backend -*- linux-c -*-
- * Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,11 @@
*
*/
+/** @file drm_agpsupport.c
+ * Support code for tying the kernel AGP support to DRM drivers and
+ * the DRM's AGP ioctls.
+ */
+
#include "drmP.h"
#ifdef __FreeBSD__
@@ -125,11 +127,10 @@ int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info)
return 0;
}
-int drm_agp_info_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_info_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
int err;
drm_agp_info_t info;
- DRM_DEVICE;
err = drm_agp_info(dev, &info);
if (err != 0)
@@ -139,9 +140,8 @@ int drm_agp_info_ioctl(DRM_IOCTL_ARGS)
return 0;
}
-int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_acquire_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
return drm_agp_acquire(dev);
}
@@ -161,9 +161,8 @@ int drm_agp_acquire(drm_device_t *dev)
return 0;
}
-int drm_agp_release_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_release_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
return drm_agp_release(dev);
}
@@ -185,15 +184,13 @@ int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
dev->agp->mode = mode.mode;
agp_enable(dev->agp->agpdev, mode.mode);
- dev->agp->base = dev->agp->info.ai_aperture_base;
dev->agp->enabled = 1;
return 0;
}
-int drm_agp_enable_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_enable_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
drm_agp_mode_t mode;
- DRM_DEVICE;
mode = *(drm_agp_mode_t *) data;
@@ -243,9 +240,8 @@ int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
return 0;
}
-int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_agp_buffer_t request;
int retcode;
@@ -292,9 +288,8 @@ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
return retcode;
}
-int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_unbind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_agp_binding_t request;
int retcode;
@@ -333,9 +328,8 @@ int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
return retcode;
}
-int drm_agp_bind_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_bind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_agp_binding_t request;
int retcode;
@@ -378,9 +372,8 @@ int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
}
-int drm_agp_free_ioctl(DRM_IOCTL_ARGS)
+int drm_agp_free_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_agp_buffer_t request;
int retcode;
@@ -411,6 +404,7 @@ drm_agp_head_t *drm_agp_init(void)
return NULL;
head->agpdev = agpdev;
agp_get_info(agpdev, &head->info);
+ head->base = head->info.ai_aperture_base;
head->memory = NULL;
DRM_INFO("AGP at 0x%08lx %dMB\n",
(long)head->info.ai_aperture_base,
diff --git a/bsd-core/drm_auth.c b/bsd-core/drm_auth.c
index aa0e29c0..aa8238c4 100644
--- a/bsd-core/drm_auth.c
+++ b/bsd-core/drm_auth.c
@@ -1,6 +1,3 @@
-/* drm_auth.h -- IOCTLs for authentication -*- linux-c -*-
- * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,11 @@
*
*/
+/** @file drm_auth.c
+ * Implementation of the get/authmagic ioctls implementing the authentication
+ * scheme between the master and clients.
+ */
+
#include "drmP.h"
static int drm_hash_magic(drm_magic_t magic)
@@ -38,25 +40,29 @@ static int drm_hash_magic(drm_magic_t magic)
return magic & (DRM_HASH_SIZE-1);
}
+/**
+ * Returns the file private associated with the given magic number.
+ */
static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
{
- drm_file_t *retval = NULL;
drm_magic_entry_t *pt;
- int hash;
+ int hash = drm_hash_magic(magic);
- hash = drm_hash_magic(magic);
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
- DRM_LOCK();
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
if (pt->magic == magic) {
- retval = pt->priv;
- break;
+ return pt->priv;
}
}
- DRM_UNLOCK();
- return retval;
+
+ return NULL;
}
+/**
+ * Inserts the given magic number into the hash table of used magic number
+ * lists.
+ */
static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
{
int hash;
@@ -64,9 +70,11 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
DRM_DEBUG("%d\n", magic);
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
hash = drm_hash_magic(magic);
entry = malloc(sizeof(*entry), M_DRM, M_ZERO | M_NOWAIT);
- if (!entry) return DRM_ERR(ENOMEM);
+ if (!entry) return ENOMEM;
entry->magic = magic;
entry->priv = priv;
entry->next = NULL;
@@ -84,16 +92,21 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
return 0;
}
+/**
+ * Removes the given magic number from the hash table of used magic number
+ * lists.
+ */
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 hash;
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
DRM_DEBUG("%d\n", magic);
hash = drm_hash_magic(magic);
- DRM_LOCK();
for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
if (pt->magic == magic) {
if (dev->magiclist[hash].head == pt) {
@@ -105,68 +118,69 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
if (prev) {
prev->next = pt->next;
}
- DRM_UNLOCK();
return 0;
}
}
- DRM_UNLOCK();
free(pt, M_DRM);
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
-int drm_getmagic(DRM_IOCTL_ARGS)
+/**
+ * Called by the client, this returns a unique magic number to be authorized
+ * by the master.
+ *
+ * The master may use its own knowledge of the client (such as the X
+ * connection that the magic is passed over) to determine if the magic number
+ * should be authenticated.
+ */
+int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
static drm_magic_t sequence = 0;
- drm_auth_t auth;
- drm_file_t *priv;
-
- DRM_LOCK();
- priv = drm_find_file_by_proc(dev, p);
- DRM_UNLOCK();
- if (priv == NULL) {
- DRM_ERROR("can't find authenticator\n");
- return EINVAL;
- }
+ drm_auth_t *auth = data;
/* Find unique magic */
- if (priv->magic) {
- auth.magic = priv->magic;
+ if (file_priv->magic) {
+ auth->magic = file_priv->magic;
} else {
+ DRM_LOCK();
do {
int old = sequence;
-
- auth.magic = old+1;
-
- if (!atomic_cmpset_int(&sequence, old, auth.magic))
+
+ auth->magic = old+1;
+
+ if (!atomic_cmpset_int(&sequence, old, auth->magic))
continue;
- } while (drm_find_file(dev, auth.magic));
- priv->magic = auth.magic;
- drm_add_magic(dev, priv, auth.magic);
+ } while (drm_find_file(dev, auth->magic));
+ file_priv->magic = auth->magic;
+ drm_add_magic(dev, file_priv, auth->magic);
+ DRM_UNLOCK();
}
- DRM_DEBUG("%u\n", auth.magic);
-
- DRM_COPY_TO_USER_IOCTL((drm_auth_t *)data, auth, sizeof(auth));
+ DRM_DEBUG("%u\n", auth->magic);
return 0;
}
-int drm_authmagic(DRM_IOCTL_ARGS)
+/**
+ * Marks the client associated with the given magic number as authenticated.
+ */
+int drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- drm_auth_t auth;
- drm_file_t *file;
- DRM_DEVICE;
-
- DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth));
+ drm_auth_t *auth = data;
+ drm_file_t *priv;
- DRM_DEBUG("%u\n", auth.magic);
+ DRM_DEBUG("%u\n", auth->magic);
- if ((file = drm_find_file(dev, auth.magic))) {
- file->authenticated = 1;
- drm_remove_magic(dev, auth.magic);
+ DRM_LOCK();
+ priv = drm_find_file(dev, auth->magic);
+ if (priv != NULL) {
+ priv->authenticated = 1;
+ drm_remove_magic(dev, auth->magic);
+ DRM_UNLOCK();
return 0;
+ } else {
+ DRM_UNLOCK();
+ return EINVAL;
}
- return DRM_ERR(EINVAL);
}
diff --git a/bsd-core/drm_bufs.c b/bsd-core/drm_bufs.c
index 343ab1e8..9b58c593 100644
--- a/bsd-core/drm_bufs.c
+++ b/bsd-core/drm_bufs.c
@@ -1,6 +1,3 @@
-/* drm_bufs.h -- Generic buffer template -*- linux-c -*-
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
- */
/*-
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,10 @@
*
*/
+/** @file drm_bufs.c
+ * Implementation of the ioctls for setup of DRM mappings and DMA buffers.
+ */
+
#include "dev/pci/pcireg.h"
#include "drmP.h"
@@ -149,7 +150,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
*/
map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT);
if ( !map )
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
map->offset = offset;
map->size = size;
@@ -172,7 +173,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
map->size, drm_order(map->size), map->handle );
if ( !map->handle ) {
free(map, M_DRM);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
map->offset = (unsigned long)map->handle;
if ( map->flags & _DRM_CONTAINS_LOCK ) {
@@ -182,7 +183,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
DRM_UNLOCK();
free(map->handle, M_DRM);
free(map, M_DRM);
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
dev->lock.hw_lock = map->handle; /* Pointer to lock */
DRM_UNLOCK();
@@ -190,7 +191,17 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
break;
case _DRM_AGP:
/*valid = 0;*/
- map->offset += dev->agp->base;
+ /* In some cases (i810 driver), user space may have already
+ * added the AGP base itself, because dev->agp->base previously
+ * only got set during AGP enable. So, only add the base
+ * address if the map's offset isn't already within the
+ * aperture.
+ */
+ if (map->offset < dev->agp->base ||
+ map->offset > dev->agp->base +
+ dev->agp->info.ai_aperture_size - 1) {
+ map->offset += dev->agp->base;
+ }
map->mtrr = dev->agp->mtrr; /* for getmap */
/*for (entry = dev->agp->memory; entry; entry = entry->next) {
if ((map->offset >= entry->bound) &&
@@ -202,13 +213,13 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
}
if (!valid) {
free(map, M_DRM);
- return DRM_ERR(EACCES);
+ return EACCES;
}*/
break;
case _DRM_SCATTER_GATHER:
if (!dev->sg) {
free(map, M_DRM);
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
map->offset = map->offset + dev->sg->handle;
break;
@@ -225,7 +236,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful);
if (map->dmah == NULL) {
free(map, M_DRM);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
map->handle = map->dmah->vaddr;
map->offset = map->dmah->busaddr;
@@ -233,7 +244,7 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
default:
DRM_ERROR("Bad map type %d\n", map->type);
free(map, M_DRM);
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
DRM_LOCK();
@@ -250,39 +261,35 @@ done:
return 0;
}
-int drm_addmap_ioctl(DRM_IOCTL_ARGS)
+int drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- drm_map_t request;
+ drm_map_t *request = data;
drm_local_map_t *map;
int err;
- DRM_DEVICE;
if (!(dev->flags & (FREAD|FWRITE)))
- return DRM_ERR(EACCES); /* Require read/write */
+ return EACCES; /* Require read/write */
- DRM_COPY_FROM_USER_IOCTL(request, (drm_map_t *)data, sizeof(drm_map_t));
-
- if (!DRM_SUSER(p) && request.type != _DRM_AGP)
- return DRM_ERR(EACCES);
+ if (!DRM_SUSER(DRM_CURPROC) && request->type != _DRM_AGP)
+ return EACCES;
DRM_LOCK();
- err = drm_addmap(dev, request.offset, request.size, request.type,
- request.flags, &map);
+ err = drm_addmap(dev, request->offset, request->size, request->type,
+ request->flags, &map);
DRM_UNLOCK();
if (err != 0)
return err;
- request.offset = map->offset;
- request.size = map->size;
- request.type = map->type;
- request.flags = map->flags;
- request.mtrr = map->mtrr;
- request.handle = map->handle;
+ request->offset = map->offset;
+ request->size = map->size;
+ request->type = map->type;
+ request->flags = map->flags;
+ request->mtrr = map->mtrr;
+ request->handle = map->handle;
- if (request.type != _DRM_SHM) {
- request.handle = (void *)request.offset;
+ if (request->type != _DRM_SHM) {
+ request->handle = (void *)request->offset;
}
- DRM_COPY_TO_USER_IOCTL((drm_map_t *)data, request, sizeof(drm_map_t));
return 0;
}
@@ -333,17 +340,14 @@ void drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
* isn't in use.
*/
-int drm_rmmap_ioctl(DRM_IOCTL_ARGS)
+int drm_rmmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_local_map_t *map;
- drm_map_t request;
-
- DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) );
+ drm_map_t *request = data;
DRM_LOCK();
TAILQ_FOREACH(map, &dev->maplist, link) {
- if (map->handle == request.handle &&
+ if (map->handle == request->handle &&
map->flags & _DRM_REMOVABLE)
break;
}
@@ -351,7 +355,7 @@ int drm_rmmap_ioctl(DRM_IOCTL_ARGS)
/* No match found. */
if (map == NULL) {
DRM_UNLOCK();
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
drm_rmmap(dev, map);
@@ -441,7 +445,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
}
if (!valid) {
DRM_DEBUG("zone invalid\n");
- return DRM_ERR(EINVAL);
+ return EINVAL;
}*/
entry = &dma->bufs[order];
@@ -449,7 +453,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
M_NOWAIT | M_ZERO);
if ( !entry->buflist ) {
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
entry->buf_size = size;
@@ -469,7 +473,7 @@ static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
buf->address = (void *)(agp_offset + offset);
buf->next = NULL;
buf->pending = 0;
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver.buf_priv_size;
buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
@@ -478,7 +482,7 @@ static int drm_do_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);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
offset += alignment;
@@ -494,7 +498,7 @@ static int drm_do_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);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
dma->buflist = temp_buflist;
@@ -563,7 +567,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
temp_pagelist == NULL) {
free(entry->buflist, M_DRM);
free(entry->seglist, M_DRM);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
memcpy(temp_pagelist, dma->pagelist, dma->page_count *
@@ -586,7 +590,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
entry->seg_count = count;
drm_cleanup_buf_error(dev, entry);
free(temp_pagelist, M_DRM);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
entry->seglist[entry->seg_count++] = dmah;
@@ -610,7 +614,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
buf->bus_address = dmah->busaddr + offset;
buf->next = NULL;
buf->pending = 0;
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver.buf_priv_size;
buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
@@ -621,7 +625,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
entry->seg_count = count;
drm_cleanup_buf_error(dev, entry);
free(temp_pagelist, M_DRM);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
DRM_DEBUG( "buffer %d @ %p\n",
@@ -637,7 +641,7 @@ static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
/* Free the entry because it isn't valid */
drm_cleanup_buf_error(dev, entry);
free(temp_pagelist, M_DRM);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
dma->buflist = temp_buflist;
@@ -705,7 +709,7 @@ static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
M_NOWAIT | M_ZERO);
if (entry->buflist == NULL)
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
entry->buf_size = size;
entry->page_order = page_order;
@@ -724,7 +728,7 @@ static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
buf->address = (void *)(agp_offset + offset + dev->sg->handle);
buf->next = NULL;
buf->pending = 0;
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver.buf_priv_size;
buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
@@ -733,7 +737,7 @@ static int drm_do_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);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
DRM_DEBUG( "buffer %d @ %p\n",
@@ -752,7 +756,7 @@ static int drm_do_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);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
dma->buflist = temp_buflist;
@@ -781,21 +785,21 @@ int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
DRM_SPINLOCK(&dev->dma_lock);
if (request->count < 0 || request->count > 4096)
- return DRM_ERR(EINVAL);
+ return EINVAL;
order = drm_order(request->size);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
- return DRM_ERR(EINVAL);
+ return EINVAL;
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
/* No more than one allocation per order */
if (dev->dma->bufs[order].buf_count != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
ret = drm_do_addbufs_agp(dev, request);
@@ -812,24 +816,24 @@ int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
DRM_SPINLOCK(&dev->dma_lock);
if (!DRM_SUSER(DRM_CURPROC))
- return DRM_ERR(EACCES);
+ return EACCES;
if (request->count < 0 || request->count > 4096)
- return DRM_ERR(EINVAL);
+ return EINVAL;
order = drm_order(request->size);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
- return DRM_ERR(EINVAL);
+ return EINVAL;
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
/* No more than one allocation per order */
if (dev->dma->bufs[order].buf_count != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
ret = drm_do_addbufs_sg(dev, request);
@@ -846,24 +850,24 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
DRM_SPINLOCK(&dev->dma_lock);
if (!DRM_SUSER(DRM_CURPROC))
- return DRM_ERR(EACCES);
+ return EACCES;
if (request->count < 0 || request->count > 4096)
- return DRM_ERR(EINVAL);
+ return EINVAL;
order = drm_order(request->size);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
- return DRM_ERR(EINVAL);
+ return EINVAL;
/* No more allocations after first buffer-using ioctl. */
if (dev->buf_use != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
/* No more than one allocation per order */
if (dev->dma->bufs[order].buf_count != 0) {
DRM_SPINUNLOCK(&dev->dma_lock);
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
ret = drm_do_addbufs_pci(dev, request);
@@ -873,39 +877,29 @@ int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
return ret;
}
-int drm_addbufs_ioctl(DRM_IOCTL_ARGS)
+int drm_addbufs_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_buf_desc_t request;
+ drm_buf_desc_t *request = data;
int err;
- DRM_COPY_FROM_USER_IOCTL(request, (drm_buf_desc_t *)data,
- sizeof(request));
-
- if (request.flags & _DRM_AGP_BUFFER)
- err = drm_addbufs_agp(dev, &request);
- else if (request.flags & _DRM_SG_BUFFER)
- err = drm_addbufs_sg(dev, &request);
+ if (request->flags & _DRM_AGP_BUFFER)
+ err = drm_addbufs_agp(dev, request);
+ else if (request->flags & _DRM_SG_BUFFER)
+ err = drm_addbufs_sg(dev, request);
else
- err = drm_addbufs_pci(dev, &request);
-
- DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request,
- sizeof(request));
+ err = drm_addbufs_pci(dev, request);
return err;
}
-int drm_infobufs(DRM_IOCTL_ARGS)
+int drm_infobufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
- drm_buf_info_t request;
+ drm_buf_info_t *request = data;
int i;
int count;
int retcode = 0;
- DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) );
-
DRM_SPINLOCK(&dev->dma_lock);
++dev->buf_use; /* Can't allocate more after this call */
DRM_SPINUNLOCK(&dev->dma_lock);
@@ -916,7 +910,7 @@ int drm_infobufs(DRM_IOCTL_ARGS)
DRM_DEBUG( "count = %d\n", count );
- if ( request.count >= count ) {
+ if ( request->count >= count ) {
for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
if ( dma->bufs[i].buf_count ) {
drm_buf_desc_t from;
@@ -926,9 +920,9 @@ int drm_infobufs(DRM_IOCTL_ARGS)
from.low_mark = dma->bufs[i].freelist.low_mark;
from.high_mark = dma->bufs[i].freelist.high_mark;
- if (DRM_COPY_TO_USER(&request.list[count], &from,
+ if (DRM_COPY_TO_USER(&request->list[count], &from,
sizeof(drm_buf_desc_t)) != 0) {
- retcode = DRM_ERR(EFAULT);
+ retcode = EFAULT;
break;
}
@@ -942,76 +936,68 @@ int drm_infobufs(DRM_IOCTL_ARGS)
}
}
}
- request.count = count;
-
- DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) );
+ request->count = count;
return retcode;
}
-int drm_markbufs(DRM_IOCTL_ARGS)
+int drm_markbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
- drm_buf_desc_t request;
+ drm_buf_desc_t *request = data;
int order;
- 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 );
+ request->size, request->low_mark, request->high_mark );
- order = drm_order(request.size);
+ 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);
+ request->low_mark < 0 || request->high_mark < 0) {
+ return EINVAL;
}
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);
+ if (request->low_mark > dma->bufs[order].buf_count ||
+ request->high_mark > dma->bufs[order].buf_count) {
+ return EINVAL;
}
- dma->bufs[order].freelist.low_mark = request.low_mark;
- dma->bufs[order].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 drm_freebufs(DRM_IOCTL_ARGS)
+int drm_freebufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
- drm_buf_free_t request;
+ drm_buf_free_t *request = data;
int i;
int idx;
drm_buf_t *buf;
int retcode = 0;
- DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) );
-
- DRM_DEBUG( "%d\n", request.count );
+ 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))) {
- retcode = DRM_ERR(EFAULT);
+ for ( i = 0 ; i < request->count ; i++ ) {
+ if (DRM_COPY_FROM_USER(&idx, &request->list[i], sizeof(idx))) {
+ retcode = EFAULT;
break;
}
if ( idx < 0 || idx >= dma->buf_count ) {
DRM_ERROR( "Index %d (of %d max)\n",
idx, dma->buf_count - 1 );
- retcode = DRM_ERR(EINVAL);
+ retcode = EINVAL;
break;
}
buf = dma->buflist[idx];
- if ( buf->filp != filp ) {
+ if ( buf->file_priv != file_priv ) {
DRM_ERROR("Process %d freeing buffer not owned\n",
DRM_CURRENTPID);
- retcode = DRM_ERR(EINVAL);
+ retcode = EINVAL;
break;
}
drm_free_buffer(dev, buf);
@@ -1021,9 +1007,8 @@ int drm_freebufs(DRM_IOCTL_ARGS)
return retcode;
}
-int drm_mapbufs(DRM_IOCTL_ARGS)
+int drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
drm_device_dma_t *dma = dev->dma;
int retcode = 0;
const int zero = 0;
@@ -1040,27 +1025,25 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
vaddr_t vaddr;
#endif /* __NetBSD__ || __OpenBSD__ */
- drm_buf_map_t request;
+ drm_buf_map_t *request = data;
int i;
- DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) );
-
#if defined(__NetBSD__) || defined(__OpenBSD__)
if (!vfinddev(kdev, VCHR, &vn))
return 0; /* FIXME: Shouldn't this be EINVAL or something? */
#endif /* __NetBSD__ || __OpenBSD */
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
- vms = p->td_proc->p_vmspace;
+ vms = DRM_CURPROC->td_proc->p_vmspace;
#else
- vms = p->p_vmspace;
+ vms = DRM_CURPROC->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)
+ if (request->count < dma->buf_count)
goto done;
if ((dev->driver.use_agp && (dma->flags & _DRM_DMA_USE_AGP)) ||
@@ -1082,10 +1065,11 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ);
#if __FreeBSD_version >= 600023
retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
- VM_PROT_ALL, MAP_SHARED, OBJT_DEVICE, kdev, foff );
+ VM_PROT_ALL, MAP_SHARED, OBJT_DEVICE, dev->devnode, foff);
#else
retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
- VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), foff );
+ VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&dev->devnode->si_hlist),
+ foff);
#endif
#elif defined(__NetBSD__) || defined(__OpenBSD__)
vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
@@ -1096,26 +1080,26 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
if (retcode)
goto done;
- request.virtual = (void *)vaddr;
+ request->virtual = (void *)vaddr;
for ( i = 0 ; i < dma->buf_count ; i++ ) {
- if (DRM_COPY_TO_USER(&request.list[i].idx,
- &dma->buflist[i]->idx, sizeof(request.list[0].idx))) {
+ if (DRM_COPY_TO_USER(&request->list[i].idx,
+ &dma->buflist[i]->idx, sizeof(request->list[0].idx))) {
retcode = EFAULT;
goto done;
}
- if (DRM_COPY_TO_USER(&request.list[i].total,
- &dma->buflist[i]->total, sizeof(request.list[0].total))) {
+ if (DRM_COPY_TO_USER(&request->list[i].total,
+ &dma->buflist[i]->total, sizeof(request->list[0].total))) {
retcode = EFAULT;
goto done;
}
- if (DRM_COPY_TO_USER(&request.list[i].used, &zero,
+ if (DRM_COPY_TO_USER(&request->list[i].used, &zero,
sizeof(zero))) {
retcode = EFAULT;
goto done;
}
address = vaddr + dma->buflist[i]->offset; /* *** */
- if (DRM_COPY_TO_USER(&request.list[i].address, &address,
+ if (DRM_COPY_TO_USER(&request->list[i].address, &address,
sizeof(address))) {
retcode = EFAULT;
goto done;
@@ -1123,11 +1107,9 @@ int drm_mapbufs(DRM_IOCTL_ARGS)
}
done:
- request.count = dma->buf_count;
-
- DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
+ request->count = dma->buf_count;
- DRM_COPY_TO_USER_IOCTL((drm_buf_map_t *)data, request, sizeof(request));
+ DRM_DEBUG( "%d buffers, retcode = %d\n", request->count, retcode );
- return DRM_ERR(retcode);
+ return retcode;
}
diff --git a/bsd-core/drm_context.c b/bsd-core/drm_context.c
index 8e009540..4155ee92 100644
--- a/bsd-core/drm_context.c
+++ b/bsd-core/drm_context.c
@@ -1,6 +1,3 @@
-/* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
- * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
- */
/*-
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,10 @@
*
*/
+/** @file drm_context.c
+ * Implementation of the context management ioctls.
+ */
+
#include "drmP.h"
/* ================================================================
@@ -109,7 +110,7 @@ int drm_ctxbitmap_init(drm_device_t *dev)
dev->ctx_bitmap = malloc(PAGE_SIZE, M_DRM, M_NOWAIT | M_ZERO);
if ( dev->ctx_bitmap == NULL ) {
DRM_UNLOCK();
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
dev->context_sareas = NULL;
dev->max_context = -1;
@@ -136,48 +137,39 @@ void drm_ctxbitmap_cleanup(drm_device_t *dev)
* Per Context SAREA Support
*/
-int drm_getsareactx( DRM_IOCTL_ARGS )
+int drm_getsareactx( drm_device_t *dev, void *data, struct drm_file *file_priv )
{
- DRM_DEVICE;
- drm_ctx_priv_map_t request;
+ drm_ctx_priv_map_t *request = data;
drm_local_map_t *map;
- DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
- sizeof(request) );
-
DRM_LOCK();
- if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
+ if (dev->max_context < 0 ||
+ request->ctx_id >= (unsigned) dev->max_context) {
DRM_UNLOCK();
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
- map = dev->context_sareas[request.ctx_id];
+ map = dev->context_sareas[request->ctx_id];
DRM_UNLOCK();
- request.handle = map->handle;
-
- DRM_COPY_TO_USER_IOCTL( (drm_ctx_priv_map_t *)data, request, sizeof(request) );
+ request->handle = map->handle;
return 0;
}
-int drm_setsareactx( DRM_IOCTL_ARGS )
+int drm_setsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_ctx_priv_map_t request;
+ drm_ctx_priv_map_t *request = data;
drm_local_map_t *map = NULL;
- DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
- sizeof(request) );
-
DRM_LOCK();
TAILQ_FOREACH(map, &dev->maplist, link) {
- if (map->handle == request.handle) {
+ if (map->handle == request->handle) {
if (dev->max_context < 0)
goto bad;
- if (request.ctx_id >= (unsigned) dev->max_context)
+ if (request->ctx_id >= (unsigned) dev->max_context)
goto bad;
- dev->context_sareas[request.ctx_id] = map;
+ dev->context_sareas[request->ctx_id] = map;
DRM_UNLOCK();
return 0;
}
@@ -185,7 +177,7 @@ int drm_setsareactx( DRM_IOCTL_ARGS )
bad:
DRM_UNLOCK();
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
/* ================================================================
@@ -196,7 +188,7 @@ int drm_context_switch(drm_device_t *dev, int old, int new)
{
if ( test_and_set_bit( 0, &dev->context_flag ) ) {
DRM_ERROR( "Reentering -- FIXME\n" );
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
DRM_DEBUG( "Context switch from %d to %d\n", old, new );
@@ -225,120 +217,98 @@ int drm_context_switch_complete(drm_device_t *dev, int new)
return 0;
}
-int drm_resctx(DRM_IOCTL_ARGS)
+int drm_resctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- drm_ctx_res_t res;
+ drm_ctx_res_t *res = data;
drm_ctx_t ctx;
int i;
- DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) );
-
- if ( res.count >= DRM_RESERVED_CONTEXTS ) {
+ if ( res->count >= DRM_RESERVED_CONTEXTS ) {
bzero(&ctx, sizeof(ctx));
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
ctx.handle = i;
- if ( DRM_COPY_TO_USER( &res.contexts[i],
+ if ( DRM_COPY_TO_USER( &res->contexts[i],
&ctx, sizeof(ctx) ) )
- return DRM_ERR(EFAULT);
+ return EFAULT;
}
}
- res.count = DRM_RESERVED_CONTEXTS;
-
- DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) );
+ res->count = DRM_RESERVED_CONTEXTS;
return 0;
}
-int drm_addctx(DRM_IOCTL_ARGS)
+int drm_addctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_ctx_t ctx;
-
- DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+ drm_ctx_t *ctx = data;
- ctx.handle = drm_ctxbitmap_next(dev);
- if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
+ ctx->handle = drm_ctxbitmap_next(dev);
+ if ( ctx->handle == DRM_KERNEL_CONTEXT ) {
/* Skip kernel's context and get a new one. */
- ctx.handle = drm_ctxbitmap_next(dev);
+ ctx->handle = drm_ctxbitmap_next(dev);
}
- DRM_DEBUG( "%d\n", ctx.handle );
- if ( ctx.handle == -1 ) {
+ DRM_DEBUG( "%d\n", ctx->handle );
+ if ( ctx->handle == -1 ) {
DRM_DEBUG( "Not enough free contexts.\n" );
/* Should this return -EBUSY instead? */
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
- if (dev->driver.context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) {
+ if (dev->driver.context_ctor && ctx->handle != DRM_KERNEL_CONTEXT) {
DRM_LOCK();
- dev->driver.context_ctor(dev, ctx.handle);
+ dev->driver.context_ctor(dev, ctx->handle);
DRM_UNLOCK();
}
- DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) );
-
return 0;
}
-int drm_modctx(DRM_IOCTL_ARGS)
+int drm_modctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
/* This does nothing */
return 0;
}
-int drm_getctx(DRM_IOCTL_ARGS)
+int drm_getctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- drm_ctx_t ctx;
-
- DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+ drm_ctx_t *ctx = data;
/* This is 0, because we don't handle any context flags */
- ctx.flags = 0;
-
- DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) );
+ ctx->flags = 0;
return 0;
}
-int drm_switchctx(DRM_IOCTL_ARGS)
+int drm_switchctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_ctx_t ctx;
+ drm_ctx_t *ctx = data;
- DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
-
- DRM_DEBUG( "%d\n", ctx.handle );
- return drm_context_switch(dev, dev->last_context, ctx.handle);
+ DRM_DEBUG( "%d\n", ctx->handle );
+ return drm_context_switch(dev, dev->last_context, ctx->handle);
}
-int drm_newctx(DRM_IOCTL_ARGS)
+int drm_newctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_ctx_t ctx;
-
- DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+ drm_ctx_t *ctx = data;
- DRM_DEBUG( "%d\n", ctx.handle );
- drm_context_switch_complete(dev, ctx.handle);
+ DRM_DEBUG( "%d\n", ctx->handle );
+ drm_context_switch_complete(dev, ctx->handle);
return 0;
}
-int drm_rmctx(DRM_IOCTL_ARGS)
+int drm_rmctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_ctx_t ctx;
-
- DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+ drm_ctx_t *ctx = data;
- DRM_DEBUG( "%d\n", ctx.handle );
- if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
+ DRM_DEBUG( "%d\n", ctx->handle );
+ if ( ctx->handle != DRM_KERNEL_CONTEXT ) {
if (dev->driver.context_dtor) {
DRM_LOCK();
- dev->driver.context_dtor(dev, ctx.handle);
+ dev->driver.context_dtor(dev, ctx->handle);
DRM_UNLOCK();
}
- drm_ctxbitmap_free(dev, ctx.handle);
+ drm_ctxbitmap_free(dev, ctx->handle);
}
return 0;
diff --git a/bsd-core/drm_dma.c b/bsd-core/drm_dma.c
index 67b3fe2d..71ef845b 100644
--- a/bsd-core/drm_dma.c
+++ b/bsd-core/drm_dma.c
@@ -1,6 +1,3 @@
-/* drm_dma.c -- DMA IOCTL and function support -*- linux-c -*-
- * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
- */
/*-
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,14 @@
*
*/
+/** @file drm_dma.c
+ * Support code for DMA buffer management.
+ *
+ * The implementation used to be significantly more complicated, but the
+ * complexity has been moved into the drivers as different buffer management
+ * schemes evolved.
+ */
+
#include "drmP.h"
int drm_dma_setup(drm_device_t *dev)
@@ -38,9 +43,9 @@ int drm_dma_setup(drm_device_t *dev)
dev->dma = malloc(sizeof(*dev->dma), M_DRM, M_NOWAIT | M_ZERO);
if (dev->dma == NULL)
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
- DRM_SPININIT(dev->dma_lock, "drmdma");
+ DRM_SPININIT(&dev->dma_lock, "drmdma");
return 0;
}
@@ -80,7 +85,7 @@ void drm_dma_takedown(drm_device_t *dev)
free(dma->pagelist, M_DRM);
free(dev->dma, M_DRM);
dev->dma = NULL;
- DRM_SPINUNINIT(dev->dma_lock);
+ DRM_SPINUNINIT(&dev->dma_lock);
}
@@ -89,18 +94,18 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
if (!buf) return;
buf->pending = 0;
- buf->filp = NULL;
+ buf->file_priv= NULL;
buf->used = 0;
}
-void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
+void drm_reclaim_buffers(drm_device_t *dev, struct drm_file *file_priv)
{
drm_device_dma_t *dma = dev->dma;
int i;
if (!dma) return;
for (i = 0; i < dma->buf_count; i++) {
- if (dma->buflist[i]->filp == filp) {
+ if (dma->buflist[i]->file_priv == file_priv) {
switch (dma->buflist[i]->list) {
case DRM_LIST_NONE:
drm_free_buffer(dev, dma->buflist[i]);
@@ -117,12 +122,12 @@ void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
}
/* Call into the driver-specific DMA handler */
-int drm_dma(DRM_IOCTL_ARGS)
+int drm_dma(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
if (dev->driver.dma_ioctl) {
- return dev->driver.dma_ioctl(kdev, cmd, data, flags, p, filp);
+ /* shared code returns -errno */
+ return -dev->driver.dma_ioctl(dev, data, file_priv);
} else {
DRM_DEBUG("DMA ioctl on driver with no dma handler\n");
return EINVAL;
diff --git a/bsd-core/drm_drawable.c b/bsd-core/drm_drawable.c
index 379e0aa7..fb318d47 100644
--- a/bsd-core/drm_drawable.c
+++ b/bsd-core/drm_drawable.c
@@ -1,6 +1,3 @@
-/* drm_drawable.h -- IOCTLs for drawables -*- linux-c -*-
- * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,21 +28,123 @@
*
*/
+/** @file drm_drawable.c
+ * This file implements ioctls to store information along with DRM drawables,
+ * such as the current set of cliprects for vblank-synced buffer swaps.
+ */
+
#include "drmP.h"
-int drm_adddraw(DRM_IOCTL_ARGS)
+struct bsd_drm_drawable_info {
+ struct drm_drawable_info info;
+ int handle;
+ RB_ENTRY(bsd_drm_drawable_info) tree;
+};
+
+static int
+drm_drawable_compare(struct bsd_drm_drawable_info *a,
+ struct bsd_drm_drawable_info *b)
+{
+ if (a->handle > b->handle)
+ return 1;
+ if (a->handle < b->handle)
+ return -1;
+ return 0;
+}
+
+RB_GENERATE_STATIC(drawable_tree, bsd_drm_drawable_info, tree,
+ drm_drawable_compare);
+
+struct drm_drawable_info *
+drm_get_drawable_info(drm_device_t *dev, int handle)
+{
+ struct bsd_drm_drawable_info find, *result;
+
+ find.handle = handle;
+ result = RB_FIND(drawable_tree, &dev->drw_head, &find);
+
+ return &result->info;
+}
+
+int drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- drm_draw_t draw;
+ drm_draw_t *draw = data;
+ struct bsd_drm_drawable_info *info;
- draw.handle = 0; /* NOOP */
- DRM_DEBUG("%d\n", draw.handle);
-
- DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) );
+ info = drm_calloc(1, sizeof(struct bsd_drm_drawable_info),
+ DRM_MEM_DRAWABLE);
+ if (info == NULL)
+ return ENOMEM;
+
+ info->handle = alloc_unr(dev->drw_unrhdr);
+ DRM_SPINLOCK(&dev->drw_lock);
+ RB_INSERT(drawable_tree, &dev->drw_head, info);
+ draw->handle = info->handle;
+ DRM_SPINUNLOCK(&dev->drw_lock);
+
+ DRM_DEBUG("%d\n", draw->handle);
return 0;
}
-int drm_rmdraw(DRM_IOCTL_ARGS)
+int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- return 0; /* NOOP */
+ drm_draw_t *draw = (drm_draw_t *)data;
+ struct drm_drawable_info *info;
+
+ DRM_SPINLOCK(&dev->drw_lock);
+ info = drm_get_drawable_info(dev, draw->handle);
+ if (info != NULL) {
+ RB_REMOVE(drawable_tree, &dev->drw_head,
+ (struct bsd_drm_drawable_info *)info);
+ DRM_SPINUNLOCK(&dev->drw_lock);
+ free_unr(dev->drw_unrhdr, draw->handle);
+ drm_free(info, sizeof(struct bsd_drm_drawable_info),
+ DRM_MEM_DRAWABLE);
+ return 0;
+ } else {
+ DRM_SPINUNLOCK(&dev->drw_lock);
+ return EINVAL;
+ }
+}
+
+int drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_drawable_info *info;
+ struct drm_update_draw *update = (struct drm_update_draw *)data;
+ int ret;
+
+ info = drm_get_drawable_info(dev, update->handle);
+ if (info == NULL)
+ return EINVAL;
+
+ switch (update->type) {
+ case DRM_DRAWABLE_CLIPRECTS:
+ DRM_SPINLOCK(&dev->drw_lock);
+ if (update->num != info->num_rects) {
+ drm_free(info->rects,
+ sizeof(*info->rects) * info->num_rects,
+ DRM_MEM_DRAWABLE);
+ info->rects = NULL;
+ info->num_rects = 0;
+ }
+ if (update->num == 0) {
+ DRM_SPINUNLOCK(&dev->drw_lock);
+ return 0;
+ }
+ if (info->rects == NULL) {
+ info->rects = drm_alloc(sizeof(*info->rects) *
+ update->num, DRM_MEM_DRAWABLE);
+ if (info->rects == NULL)
+ return ENOMEM;
+ info->num_rects = update->num;
+ }
+ /* For some reason the pointer arg is unsigned long long. */
+ ret = copyin((void *)(intptr_t)update->data, info->rects,
+ sizeof(*info->rects) * info->num_rects);
+ DRM_SPINUNLOCK(&dev->drw_lock);
+ return ret;
+ default:
+ return EINVAL;
+ }
}
diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c
index baaeb43c..d6868b9c 100644
--- a/bsd-core/drm_drv.c
+++ b/bsd-core/drm_drv.c
@@ -1,6 +1,3 @@
-/* drm_drv.h -- Generic driver template -*- linux-c -*-
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
- */
/*-
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,13 @@
*
*/
+/** @file drm_drv.c
+ * The catch-all file for DRM device support, including module setup/teardown,
+ * open/close, and ioctl dispatch.
+ */
+
+
+#include <sys/limits.h>
#include "drmP.h"
#include "drm.h"
#include "drm_sarea.h"
@@ -64,63 +68,64 @@ MODULE_DEPEND(drm, mem, 1, 1, 1);
#endif /* __NetBSD__ || __OpenBSD__ */
static drm_ioctl_desc_t drm_ioctls[256] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, DRM_MASTER|DRM_ROOT_ONLY },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, DRM_AUTH },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, DRM_AUTH },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, DRM_AUTH },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, DRM_AUTH },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, DRM_AUTH|DRM_MASTER },
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { drm_dma, DRM_AUTH },
-
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, DRM_AUTH },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
- [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-
- [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0 },
+ DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER),
+ DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
};
#ifdef __FreeBSD__
@@ -198,6 +203,7 @@ int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist)
"dri/card%d", unit);
#if __FreeBSD_version >= 500000
mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF);
+ mtx_init(&dev->drw_lock, "drmdrw", NULL, MTX_DEF);
#endif
id_entry = drm_find_description(pci_get_vendor(dev->device),
@@ -496,7 +502,7 @@ static int drm_lastclose(drm_device_t *dev)
drm_dma_takedown(dev);
if ( dev->lock.hw_lock ) {
dev->lock.hw_lock = NULL; /* SHM removed */
- dev->lock.filp = NULL;
+ dev->lock.file_priv = NULL;
DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
}
@@ -510,8 +516,11 @@ static int drm_load(drm_device_t *dev)
DRM_DEBUG( "\n" );
dev->irq = pci_get_irq(dev->device);
- /* XXX Fix domain number (alpha hoses) */
+#if defined(__FreeBSD__) && __FreeBSD_version >= 700053
+ dev->pci_domain = pci_get_domain(dev->device);
+#else
dev->pci_domain = 0;
+#endif
dev->pci_bus = pci_get_bus(dev->device);
dev->pci_slot = pci_get_slot(dev->device);
dev->pci_func = pci_get_function(dev->device);
@@ -529,7 +538,9 @@ static int drm_load(drm_device_t *dev)
if (dev->driver.load != NULL) {
DRM_LOCK();
- retcode = dev->driver.load(dev, dev->id_entry->driver_private);
+ /* Shared code returns -errno. */
+ retcode = -dev->driver.load(dev,
+ dev->id_entry->driver_private);
DRM_UNLOCK();
if (retcode != 0)
goto error;
@@ -541,7 +552,7 @@ static int drm_load(drm_device_t *dev)
if (dev->driver.require_agp && dev->agp == NULL) {
DRM_ERROR("Card isn't AGP, or couldn't initialize "
"AGP.\n");
- retcode = DRM_ERR(ENOMEM);
+ retcode = ENOMEM;
goto error;
}
if (dev->agp != NULL) {
@@ -556,7 +567,13 @@ static int drm_load(drm_device_t *dev)
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
goto error;
}
-
+
+ dev->drw_unrhdr = new_unrhdr(1, INT_MAX, NULL);
+ if (dev->drw_unrhdr == NULL) {
+ DRM_ERROR("Couldn't allocate drawable number allocator\n");
+ goto error;
+ }
+
DRM_INFO("Initialized %s %d.%d.%d %s\n",
dev->driver.name,
dev->driver.major,
@@ -628,6 +645,8 @@ static void drm_unload(drm_device_t *dev)
if (dev->driver.unload != NULL)
dev->driver.unload(dev);
+ delete_unrhdr(dev->drw_unrhdr);
+
drm_mem_uninit();
#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
mtx_destroy(&dev->dev_lock);
@@ -635,32 +654,27 @@ static void drm_unload(drm_device_t *dev)
}
-int drm_version(DRM_IOCTL_ARGS)
+int drm_version(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_version_t version;
+ drm_version_t *version = data;
int len;
- DRM_COPY_FROM_USER_IOCTL( version, (drm_version_t *)data, sizeof(version) );
-
#define DRM_COPY( name, value ) \
len = strlen( value ); \
if ( len > name##_len ) len = name##_len; \
name##_len = strlen( value ); \
if ( len && name ) { \
if ( DRM_COPY_TO_USER( name, value, len ) ) \
- return DRM_ERR(EFAULT); \
+ return EFAULT; \
}
- version.version_major = dev->driver.major;
- version.version_minor = dev->driver.minor;
- version.version_patchlevel = dev->driver.patchlevel;
-
- DRM_COPY(version.name, dev->driver.name);
- DRM_COPY(version.date, dev->driver.date);
- DRM_COPY(version.desc, dev->driver.desc);
+ version->version_major = dev->driver.major;
+ version->version_minor = dev->driver.minor;
+ version->version_patchlevel = dev->driver.patchlevel;
- DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) );
+ DRM_COPY(version->name, dev->driver.name);
+ DRM_COPY(version->date, dev->driver.date);
+ DRM_COPY(version->desc, dev->driver.desc);
return 0;
}
@@ -692,24 +706,26 @@ int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
{
- drm_file_t *priv;
- DRM_DEVICE;
+ drm_device_t *dev = drm_get_device_from_kdev(kdev);
+ drm_file_t *file_priv;
int retcode = 0;
- DRMFILE filp = (void *)(uintptr_t)(DRM_CURRENTPID);
-
+
DRM_DEBUG( "open_count = %d\n", dev->open_count );
DRM_LOCK();
- priv = drm_find_file_by_proc(dev, p);
- if (!priv) {
+ file_priv = drm_find_file_by_proc(dev, p);
+ if (!file_priv) {
DRM_UNLOCK();
DRM_ERROR("can't find authenticator\n");
return EINVAL;
}
+ if (--file_priv->refs != 0)
+ goto done;
+
if (dev->driver.preclose != NULL)
- dev->driver.preclose(dev, filp);
+ dev->driver.preclose(dev, file_priv);
/* ========================================================
* Begin inline drm_release
@@ -724,12 +740,12 @@ int drm_close(struct cdev *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 == filp) {
+ && dev->lock.file_priv == file_priv) {
DRM_DEBUG("Process %d dead, freeing lock for context %d\n",
DRM_CURRENTPID,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
if (dev->driver.reclaim_buffers_locked != NULL)
- dev->driver.reclaim_buffers_locked(dev, filp);
+ dev->driver.reclaim_buffers_locked(dev, file_priv);
drm_lock_free(dev, &dev->lock.hw_lock->lock,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
@@ -744,12 +760,12 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
for (;;) {
if ( !dev->lock.hw_lock ) {
/* Device has been unregistered */
- retcode = DRM_ERR(EINTR);
+ retcode = EINTR;
break;
}
if (drm_lock_take(&dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
- dev->lock.filp = filp;
+ dev->lock.file_priv = file_priv;
dev->lock.lock_time = jiffies;
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
break; /* Got lock */
@@ -766,14 +782,14 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
break;
}
if (retcode == 0) {
- dev->driver.reclaim_buffers_locked(dev, filp);
+ dev->driver.reclaim_buffers_locked(dev, file_priv);
drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT);
}
}
if (dev->driver.use_dma && !dev->driver.reclaim_buffers_locked)
- drm_reclaim_buffers(dev, filp);
+ drm_reclaim_buffers(dev, file_priv);
#if defined (__FreeBSD__) && (__FreeBSD_version >= 500000)
funsetown(&dev->buf_sigio);
@@ -783,17 +799,16 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
dev->buf_pgid = 0;
#endif /* __NetBSD__ || __OpenBSD__ */
- if (--priv->refs == 0) {
- if (dev->driver.postclose != NULL)
- dev->driver.postclose(dev, priv);
- TAILQ_REMOVE(&dev->files, priv, link);
- free(priv, M_DRM);
- }
+ if (dev->driver.postclose != NULL)
+ dev->driver.postclose(dev, file_priv);
+ TAILQ_REMOVE(&dev->files, file_priv, link);
+ free(file_priv, M_DRM);
/* ========================================================
* End inline drm_release
*/
+done:
atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
#ifdef __FreeBSD__
device_unbusy(dev->device);
@@ -812,32 +827,33 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags,
DRM_STRUCTPROC *p)
{
- DRM_DEVICE;
+ drm_device_t *dev = drm_get_device_from_kdev(kdev);
int retcode = 0;
drm_ioctl_desc_t *ioctl;
- int (*func)(DRM_IOCTL_ARGS);
+ int (*func)(drm_device_t *dev, void *data, struct drm_file *file_priv);
int nr = DRM_IOCTL_NR(cmd);
int is_driver_ioctl = 0;
- drm_file_t *priv;
- DRMFILE filp = (DRMFILE)(uintptr_t)DRM_CURRENTPID;
+ drm_file_t *file_priv;
DRM_LOCK();
- priv = drm_find_file_by_proc(dev, p);
+ file_priv = drm_find_file_by_proc(dev, p);
DRM_UNLOCK();
- if (priv == NULL) {
+ if (file_priv == NULL) {
DRM_ERROR("can't find authenticator\n");
return EINVAL;
}
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
- ++priv->ioctl_count;
+ ++file_priv->ioctl_count;
#ifdef __FreeBSD__
DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
- DRM_CURRENTPID, cmd, nr, (long)dev->device, priv->authenticated );
+ DRM_CURRENTPID, cmd, nr, (long)dev->device,
+ file_priv->authenticated );
#elif defined(__NetBSD__) || defined(__OpenBSD__)
DRM_DEBUG( "pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
- DRM_CURRENTPID, cmd, nr, (long)&dev->device, priv->authenticated );
+ DRM_CURRENTPID, cmd, nr, (long)&dev->device,
+ file_priv->authenticated );
#endif
switch (cmd) {
@@ -892,24 +908,25 @@ int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags,
DRM_DEBUG( "no function\n" );
return EINVAL;
}
- /* ioctl->master check should be against something in the filp set up
- * for the first opener, but it doesn't matter yet.
- */
+
if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) ||
- ((ioctl->flags & DRM_AUTH) && !priv->authenticated) ||
- ((ioctl->flags & DRM_MASTER) && !priv->master))
+ ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
+ ((ioctl->flags & DRM_MASTER) && !file_priv->master))
return EACCES;
- if (is_driver_ioctl)
+ if (is_driver_ioctl) {
DRM_LOCK();
- retcode = func(kdev, cmd, data, flags, p, filp);
- if (is_driver_ioctl)
+ /* shared code returns -errno */
+ retcode = -func(dev, data, file_priv);
DRM_UNLOCK();
+ } else {
+ retcode = func(dev, data, file_priv);
+ }
if (retcode != 0)
DRM_DEBUG(" returning %d\n", retcode);
- return DRM_ERR(retcode);
+ return retcode;
}
drm_local_map_t *drm_getsarea(drm_device_t *dev)
diff --git a/bsd-core/drm_fops.c b/bsd-core/drm_fops.c
index f5c9349b..20bae8d7 100644
--- a/bsd-core/drm_fops.c
+++ b/bsd-core/drm_fops.c
@@ -1,6 +1,3 @@
-/* drm_fops.h -- File operations for DRM -*- linux-c -*-
- * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -32,6 +29,11 @@
*
*/
+/** @file drm_fops.c
+ * Support code for dealing with the file privates associated with each
+ * open of the DRM device.
+ */
+
#include "drmP.h"
drm_file_t *drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p)
@@ -75,7 +77,7 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
priv = malloc(sizeof(*priv), M_DRM, M_NOWAIT | M_ZERO);
if (priv == NULL) {
DRM_UNLOCK();
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
}
#if __FreeBSD_version >= 500000
priv->uid = p->td_ucred->cr_svuid;
@@ -93,7 +95,8 @@ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
priv->authenticated = DRM_SUSER(p);
if (dev->driver.open) {
- retcode = dev->driver.open(dev, priv);
+ /* shared code returns -errno */
+ retcode = -dev->driver.open(dev, priv);
if (retcode != 0) {
free(priv, M_DRM);
DRM_UNLOCK();
diff --git a/bsd-core/drm_ioctl.c b/bsd-core/drm_ioctl.c
index e22faa83..ce78bb8f 100644
--- a/bsd-core/drm_ioctl.c
+++ b/bsd-core/drm_ioctl.c
@@ -1,6 +1,3 @@
-/* drm_ioctl.h -- IOCTL processing for DRM -*- linux-c -*-
- * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,11 @@
*
*/
+/** @file drm_ioctl.c
+ * Varios minor DRM ioctls not applicable to other files, such as versioning
+ * information and reporting DRM information to userland.
+ */
+
#include "drmP.h"
/*
@@ -39,20 +41,15 @@
* before setunique has been called. The format for the bus-specific part of
* the unique is not defined for any other bus.
*/
-int drm_getunique(DRM_IOCTL_ARGS)
+int drm_getunique(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_unique_t u;
-
- DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) );
+ drm_unique_t *u = data;
- if (u.unique_len >= dev->unique_len) {
- if (DRM_COPY_TO_USER(u.unique, dev->unique, dev->unique_len))
- return DRM_ERR(EFAULT);
+ if (u->unique_len >= dev->unique_len) {
+ if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len))
+ return EFAULT;
}
- u.unique_len = dev->unique_len;
-
- DRM_COPY_TO_USER_IOCTL( (drm_unique_t *)data, u, sizeof(u) );
+ u->unique_len = dev->unique_len;
return 0;
}
@@ -60,28 +57,25 @@ int drm_getunique(DRM_IOCTL_ARGS)
/* Deprecated in DRM version 1.1, and will return EBUSY when setversion has
* requested version 1.1 or greater.
*/
-int drm_setunique(DRM_IOCTL_ARGS)
+int drm_setunique(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_unique_t u;
+ drm_unique_t *u = data;
int domain, bus, slot, func, ret;
char *busid;
- DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) );
-
/* Check and copy in the submitted Bus ID */
- if (!u.unique_len || u.unique_len > 1024)
- return DRM_ERR(EINVAL);
+ if (!u->unique_len || u->unique_len > 1024)
+ return EINVAL;
- busid = malloc(u.unique_len + 1, M_DRM, M_WAITOK);
+ busid = malloc(u->unique_len + 1, M_DRM, M_WAITOK);
if (busid == NULL)
- return DRM_ERR(ENOMEM);
+ return ENOMEM;
- if (DRM_COPY_FROM_USER(busid, u.unique, u.unique_len)) {
+ if (DRM_COPY_FROM_USER(busid, u->unique, u->unique_len)) {
free(busid, M_DRM);
- return DRM_ERR(EFAULT);
+ return EFAULT;
}
- busid[u.unique_len] = '\0';
+ busid[u->unique_len] = '\0';
/* Return error if the busid submitted doesn't match the device's actual
* busid.
@@ -89,7 +83,7 @@ int drm_setunique(DRM_IOCTL_ARGS)
ret = sscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func);
if (ret != 3) {
free(busid, M_DRM);
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
domain = bus >> 8;
bus &= 0xff;
@@ -99,17 +93,17 @@ int drm_setunique(DRM_IOCTL_ARGS)
(slot != dev->pci_slot) ||
(func != dev->pci_func)) {
free(busid, M_DRM);
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
/* Actually set the device's busid now. */
DRM_LOCK();
if (dev->unique_len || dev->unique) {
DRM_UNLOCK();
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
- dev->unique_len = u.unique_len;
+ dev->unique_len = u->unique_len;
dev->unique = busid;
DRM_UNLOCK();
@@ -143,32 +137,29 @@ drm_set_busid(drm_device_t *dev)
return 0;
}
-int drm_getmap(DRM_IOCTL_ARGS)
+int drm_getmap(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_map_t map;
+ drm_map_t *map = data;
drm_local_map_t *mapinlist;
int idx;
int i = 0;
- DRM_COPY_FROM_USER_IOCTL( map, (drm_map_t *)data, sizeof(map) );
-
- idx = map.offset;
+ idx = map->offset;
DRM_LOCK();
if (idx < 0) {
DRM_UNLOCK();
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
TAILQ_FOREACH(mapinlist, &dev->maplist, link) {
if (i==idx) {
- map.offset = mapinlist->offset;
- map.size = mapinlist->size;
- map.type = mapinlist->type;
- map.flags = mapinlist->flags;
- map.handle = mapinlist->handle;
- map.mtrr = mapinlist->mtrr;
+ map->offset = mapinlist->offset;
+ map->size = mapinlist->size;
+ map->type = mapinlist->type;
+ map->flags = mapinlist->flags;
+ map->handle = mapinlist->handle;
+ map->mtrr = mapinlist->mtrr;
break;
}
i++;
@@ -179,100 +170,89 @@ int drm_getmap(DRM_IOCTL_ARGS)
if (mapinlist == NULL)
return EINVAL;
- DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, map, sizeof(map) );
-
return 0;
}
-int drm_getclient(DRM_IOCTL_ARGS)
+int drm_getclient(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_client_t client;
+ drm_client_t *client = data;
drm_file_t *pt;
int idx;
int i = 0;
- DRM_COPY_FROM_USER_IOCTL( client, (drm_client_t *)data, sizeof(client) );
-
- idx = client.idx;
+ idx = client->idx;
DRM_LOCK();
TAILQ_FOREACH(pt, &dev->files, link) {
if (i==idx)
{
- client.auth = pt->authenticated;
- client.pid = pt->pid;
- client.uid = pt->uid;
- client.magic = pt->magic;
- client.iocs = pt->ioctl_count;
+ client->auth = pt->authenticated;
+ client->pid = pt->pid;
+ client->uid = pt->uid;
+ client->magic = pt->magic;
+ client->iocs = pt->ioctl_count;
DRM_UNLOCK();
-
- *(drm_client_t *)data = client;
return 0;
}
i++;
}
DRM_UNLOCK();
- DRM_COPY_TO_USER_IOCTL( (drm_client_t *)data, client, sizeof(client) );
-
- return 0;
+ return EINVAL;
}
-int drm_getstats(DRM_IOCTL_ARGS)
+int drm_getstats(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_stats_t stats;
+ drm_stats_t *stats = data;
int i;
- memset(&stats, 0, sizeof(stats));
+ memset(stats, 0, sizeof(drm_stats_t));
DRM_LOCK();
for (i = 0; i < dev->counters; i++) {
if (dev->types[i] == _DRM_STAT_LOCK)
- stats.data[i].value
+ stats->data[i].value
= (dev->lock.hw_lock
? dev->lock.hw_lock->lock : 0);
else
- stats.data[i].value = atomic_read(&dev->counts[i]);
- stats.data[i].type = dev->types[i];
+ stats->data[i].value = atomic_read(&dev->counts[i]);
+ stats->data[i].type = dev->types[i];
}
- stats.count = dev->counters;
+ stats->count = dev->counters;
DRM_UNLOCK();
- DRM_COPY_TO_USER_IOCTL( (drm_stats_t *)data, stats, sizeof(stats) );
-
return 0;
}
#define DRM_IF_MAJOR 1
#define DRM_IF_MINOR 2
-int drm_setversion(DRM_IOCTL_ARGS)
+int drm_setversion(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_set_version_t sv;
- drm_set_version_t retv;
+ drm_set_version_t *sv = data;
+ drm_set_version_t ver;
int if_version;
- DRM_COPY_FROM_USER_IOCTL(sv, (drm_set_version_t *)data, sizeof(sv));
-
- retv.drm_di_major = DRM_IF_MAJOR;
- retv.drm_di_minor = DRM_IF_MINOR;
- retv.drm_dd_major = dev->driver.major;
- retv.drm_dd_minor = dev->driver.minor;
-
- DRM_COPY_TO_USER_IOCTL((drm_set_version_t *)data, retv, sizeof(sv));
-
- if (sv.drm_di_major != -1) {
- if (sv.drm_di_major != DRM_IF_MAJOR ||
- sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
+ /* Save the incoming data, and set the response before continuing
+ * any further.
+ */
+ ver = *sv;
+ sv->drm_di_major = DRM_IF_MAJOR;
+ sv->drm_di_minor = DRM_IF_MINOR;
+ sv->drm_dd_major = dev->driver.major;
+ sv->drm_dd_minor = dev->driver.minor;
+
+ if (ver.drm_di_major != -1) {
+ if (ver.drm_di_major != DRM_IF_MAJOR ||
+ ver.drm_di_minor < 0 || ver.drm_di_minor > DRM_IF_MINOR) {
return EINVAL;
- if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
+ }
+ if_version = DRM_IF_VERSION(ver.drm_di_major,
+ ver.drm_dd_minor);
dev->if_version = DRM_MAX(if_version, dev->if_version);
- if (sv.drm_di_minor >= 1) {
+ if (ver.drm_di_minor >= 1) {
/*
* Version 1.1 includes tying of DRM to specific device
*/
@@ -280,16 +260,20 @@ int drm_setversion(DRM_IOCTL_ARGS)
}
}
- if (sv.drm_dd_major != -1) {
- if (sv.drm_dd_major != dev->driver.major ||
- sv.drm_dd_minor < 0 || sv.drm_dd_minor > dev->driver.minor)
+ if (ver.drm_dd_major != -1) {
+ if (ver.drm_dd_major != dev->driver.major ||
+ ver.drm_dd_minor < 0 ||
+ ver.drm_dd_minor > dev->driver.minor)
+ {
return EINVAL;
+ }
}
+
return 0;
}
-int drm_noop(DRM_IOCTL_ARGS)
+int drm_noop(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
DRM_DEBUG("\n");
return 0;
diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c
index f7da5ed7..0772445a 100644
--- a/bsd-core/drm_irq.c
+++ b/bsd-core/drm_irq.c
@@ -1,6 +1,3 @@
-/* drm_irq.c -- IRQ IOCTL and function support
- * Created: Fri Oct 18 2003 by anholt@FreeBSD.org
- */
/*-
* Copyright 2003 Eric Anholt
* All Rights Reserved.
@@ -28,28 +25,30 @@
*
*/
+/** @file drm_irq.c
+ * Support code for handling setup/teardown of interrupt handlers and
+ * handing interrupt handlers off to the drivers.
+ */
+
#include "drmP.h"
#include "drm.h"
-int drm_irq_by_busid(DRM_IOCTL_ARGS)
-{
- DRM_DEVICE;
- drm_irq_busid_t irq;
+static void drm_locked_task(void *context, int pending __unused);
- DRM_COPY_FROM_USER_IOCTL(irq, (drm_irq_busid_t *)data, sizeof(irq));
+int drm_irq_by_busid(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+ drm_irq_busid_t *irq = data;
- if ((irq.busnum >> 8) != dev->pci_domain ||
- (irq.busnum & 0xff) != dev->pci_bus ||
- irq.devnum != dev->pci_slot ||
- irq.funcnum != dev->pci_func)
+ if ((irq->busnum >> 8) != dev->pci_domain ||
+ (irq->busnum & 0xff) != dev->pci_bus ||
+ irq->devnum != dev->pci_slot ||
+ irq->funcnum != dev->pci_func)
return EINVAL;
- irq.irq = dev->irq;
+ irq->irq = dev->irq;
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
- irq.busnum, irq.devnum, irq.funcnum, irq.irq);
-
- DRM_COPY_TO_USER_IOCTL( (drm_irq_busid_t *)data, irq, sizeof(irq) );
+ irq->busnum, irq->devnum, irq->funcnum, irq->irq);
return 0;
}
@@ -74,20 +73,20 @@ int drm_irq_install(drm_device_t *dev)
#endif
if (dev->irq == 0 || dev->dev_private == NULL)
- return DRM_ERR(EINVAL);
+ return EINVAL;
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
DRM_LOCK();
if (dev->irq_enabled) {
DRM_UNLOCK();
- return DRM_ERR(EBUSY);
+ return EBUSY;
}
dev->irq_enabled = 1;
dev->context_flag = 0;
- DRM_SPININIT(dev->irq_lock, "DRM IRQ lock");
+ DRM_SPININIT(&dev->irq_lock, "DRM IRQ lock");
/* Before installing handler */
dev->driver.irq_preinstall(dev);
@@ -131,6 +130,7 @@ int drm_irq_install(drm_device_t *dev)
dev->driver.irq_postinstall(dev);
DRM_UNLOCK();
+ TASK_INIT(&dev->locked_task, 0, drm_locked_task, dev);
return 0;
err:
DRM_LOCK();
@@ -142,7 +142,7 @@ err:
dev->irqrid = 0;
}
#endif
- DRM_SPINUNINIT(dev->irq_lock);
+ DRM_SPINUNINIT(&dev->irq_lock);
DRM_UNLOCK();
return retcode;
}
@@ -154,7 +154,7 @@ int drm_irq_uninstall(drm_device_t *dev)
#endif
if (!dev->irq_enabled)
- return DRM_ERR(EINVAL);
+ return EINVAL;
dev->irq_enabled = 0;
#ifdef __FreeBSD__
@@ -174,20 +174,17 @@ int drm_irq_uninstall(drm_device_t *dev)
#elif defined(__NetBSD__) || defined(__OpenBSD__)
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
#endif
- DRM_SPINUNINIT(dev->irq_lock);
+ DRM_SPINUNINIT(&dev->irq_lock);
return 0;
}
-int drm_control(DRM_IOCTL_ARGS)
+int drm_control(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_control_t ctl;
+ drm_control_t *ctl = data;
int err;
- DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
-
- switch ( ctl.func ) {
+ switch ( ctl->func ) {
case DRM_INST_HANDLER:
/* Handle drivers whose DRM used to require IRQ setup but the
* no longer does.
@@ -195,8 +192,8 @@ int drm_control(DRM_IOCTL_ARGS)
if (!dev->driver.use_irq)
return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
- ctl.irq != dev->irq)
- return DRM_ERR(EINVAL);
+ ctl->irq != dev->irq)
+ return EINVAL;
return drm_irq_install(dev);
case DRM_UNINST_HANDLER:
if (!dev->driver.use_irq)
@@ -206,29 +203,25 @@ int drm_control(DRM_IOCTL_ARGS)
DRM_UNLOCK();
return err;
default:
- return DRM_ERR(EINVAL);
+ return EINVAL;
}
}
-int drm_wait_vblank(DRM_IOCTL_ARGS)
+int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_wait_vblank_t vblwait;
+ drm_wait_vblank_t *vblwait = data;
struct timeval now;
- int ret;
+ int ret, flags;
if (!dev->irq_enabled)
- return DRM_ERR(EINVAL);
-
- DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
- sizeof(vblwait) );
+ return EINVAL;
- if (vblwait.request.type & _DRM_VBLANK_RELATIVE) {
- vblwait.request.sequence += atomic_read(&dev->vbl_received);
- vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+ if (vblwait->request.type & _DRM_VBLANK_RELATIVE) {
+ vblwait->request.sequence += atomic_read(&dev->vbl_received);
+ vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
}
- flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+ flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
if (flags & _DRM_VBLANK_SIGNAL) {
#if 0 /* disabled */
drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t), M_DRM,
@@ -236,11 +229,11 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
if (vbl_sig == NULL)
return ENOMEM;
- vbl_sig->sequence = vblwait.request.sequence;
- vbl_sig->signo = vblwait.request.signal;
+ vbl_sig->sequence = vblwait->request.sequence;
+ vbl_sig->signo = vblwait->request.signal;
vbl_sig->pid = DRM_CURRENTPID;
- vblwait.reply.sequence = atomic_read(&dev->vbl_received);
+ vblwait->reply.sequence = atomic_read(&dev->vbl_received);
DRM_SPINLOCK(&dev->irq_lock);
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
@@ -250,17 +243,16 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
ret = EINVAL;
} else {
DRM_LOCK();
- ret = dev->driver.vblank_wait(dev, &vblwait.request.sequence);
+ /* shared code returns -errno */
+ ret = -dev->driver.vblank_wait(dev,
+ &vblwait->request.sequence);
DRM_UNLOCK();
microtime(&now);
- vblwait.reply.tval_sec = now.tv_sec;
- vblwait.reply.tval_usec = now.tv_usec;
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
}
- DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
- sizeof(vblwait) );
-
return ret;
}
@@ -291,3 +283,45 @@ void drm_vbl_send_signals( drm_device_t *dev )
}
}
#endif
+
+static void drm_locked_task(void *context, int pending __unused)
+{
+ drm_device_t *dev = context;
+
+ DRM_LOCK();
+ for (;;) {
+ int ret;
+
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT))
+ {
+ dev->lock.file_priv = NULL; /* kernel owned */
+ 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)
+ return;
+ }
+ DRM_UNLOCK();
+
+ dev->locked_task_call(dev);
+
+ drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+}
+
+void
+drm_locked_tasklet(drm_device_t *dev, void (*tasklet)(drm_device_t *dev))
+{
+ dev->locked_task_call = tasklet;
+ taskqueue_enqueue(taskqueue_swi, &dev->locked_task);
+}
diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c
index d0e61d3a..fb86fc68 100644
--- a/bsd-core/drm_lock.c
+++ b/bsd-core/drm_lock.c
@@ -1,6 +1,3 @@
-/* lock.c -- IOCTLs for locking -*- linux-c -*-
- * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
- */
/*-
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,25 @@
*
*/
+/** @file drm_lock.c
+ * Implementation of the ioctls and other support code for dealing with the
+ * hardware lock.
+ *
+ * The DRM hardware lock is a shared structure between the kernel and userland.
+ *
+ * On uncontended access where the new context was the last context, the
+ * client may take the lock without dropping down into the kernel, using atomic
+ * compare-and-set.
+ *
+ * If the client finds during compare-and-set that it was not the last owner
+ * of the lock, it calls the DRM lock ioctl, which may sleep waiting for the
+ * lock, and may have side-effects of kernel-managed context switching.
+ *
+ * When the client releases the lock, if the lock is marked as being contended
+ * by another client, then the DRM unlock ioctl is called so that the
+ * contending client may be woken up.
+ */
+
#include "drmP.h"
int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
@@ -66,7 +82,7 @@ int drm_lock_transfer(drm_device_t *dev,
{
unsigned int old, new;
- dev->lock.filp = NULL;
+ dev->lock.file_priv = NULL;
do {
old = *lock;
new = context | _DRM_LOCK_HELD;
@@ -80,7 +96,7 @@ int drm_lock_free(drm_device_t *dev,
{
unsigned int old, new;
- dev->lock.filp = NULL;
+ dev->lock.file_priv = NULL;
do {
old = *lock;
new = 0;
@@ -95,30 +111,28 @@ int drm_lock_free(drm_device_t *dev,
return 0;
}
-int drm_lock(DRM_IOCTL_ARGS)
+int drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_lock_t lock;
+ drm_lock_t *lock = data;
int ret = 0;
- DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock));
-
- if (lock.context == DRM_KERNEL_CONTEXT) {
+ if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- DRM_CURRENTPID, lock.context);
+ 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);
+ lock->context, DRM_CURRENTPID, dev->lock.hw_lock->lock,
+ lock->flags);
- if (dev->driver.use_dma_queue && lock.context < 0)
+ if (dev->driver.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;
+ if (drm_lock_take(&dev->lock.hw_lock->lock, lock->context)) {
+ dev->lock.file_priv = file_priv;
dev->lock.lock_time = jiffies;
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
break; /* Got lock */
@@ -136,7 +150,7 @@ int drm_lock(DRM_IOCTL_ARGS)
break;
}
DRM_UNLOCK();
- DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+ DRM_DEBUG("%d %s\n", lock->context, ret ? "interrupted" : "has lock");
if (ret != 0)
return ret;
@@ -144,24 +158,27 @@ int drm_lock(DRM_IOCTL_ARGS)
/* XXX: Add signal blocking here */
if (dev->driver.dma_quiescent != NULL &&
- (lock.flags & _DRM_LOCK_QUIESCENT))
+ (lock->flags & _DRM_LOCK_QUIESCENT))
dev->driver.dma_quiescent(dev);
return 0;
}
-int drm_unlock(DRM_IOCTL_ARGS)
+int drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_lock_t lock;
+ drm_lock_t *lock = data;
- DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock));
-
- if (lock.context == DRM_KERNEL_CONTEXT) {
+ if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- DRM_CURRENTPID, lock.context);
+ DRM_CURRENTPID, lock->context);
return EINVAL;
}
+ /* Check that the context unlock being requested actually matches
+ * who currently holds the lock.
+ */
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) != lock->context)
+ return EINVAL;
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
diff --git a/bsd-core/drm_memory.c b/bsd-core/drm_memory.c
index 6d467e98..1f1f7f4b 100644
--- a/bsd-core/drm_memory.c
+++ b/bsd-core/drm_memory.c
@@ -1,6 +1,3 @@
-/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
- * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
- */
/*-
*Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
@@ -31,6 +28,14 @@
*
*/
+/** @file drm_memory.c
+ * Wrappers for kernel memory allocation routines, and MTRR management support.
+ *
+ * This file previously implemented a memory consumption tracking system using
+ * the "area" argument for various different types of allocations, but that
+ * has been stripped out for now.
+ */
+
#include "drmP.h"
MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures");
diff --git a/bsd-core/drm_pci.c b/bsd-core/drm_pci.c
index a33f5f9c..6ec6b983 100644
--- a/bsd-core/drm_pci.c
+++ b/bsd-core/drm_pci.c
@@ -1,10 +1,3 @@
-/**
- * \file drm_pci.h
- * \brief PCI consistent, DMA-accessible memory functions.
- *
- * \author Eric Anholt <anholt@FreeBSD.org>
- */
-
/*-
* Copyright 2003 Eric Anholt.
* All Rights Reserved.
@@ -28,6 +21,13 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/**
+ * \file drm_pci.h
+ * \brief PCI consistent, DMA-accessible memory allocation.
+ *
+ * \author Eric Anholt <anholt@FreeBSD.org>
+ */
+
#include "drmP.h"
/**********************************************************************/
diff --git a/bsd-core/drm_sarea.h b/bsd-core/drm_sarea.h
new file mode 120000
index 00000000..fd428f42
--- /dev/null
+++ b/bsd-core/drm_sarea.h
@@ -0,0 +1 @@
+../shared-core/drm_sarea.h \ No newline at end of file
diff --git a/bsd-core/drm_scatter.c b/bsd-core/drm_scatter.c
index 9dc280a4..92e715e0 100644
--- a/bsd-core/drm_scatter.c
+++ b/bsd-core/drm_scatter.c
@@ -1,5 +1,3 @@
-/* drm_scatter.h -- IOCTLs to manage scatter/gather memory -*- linux-c -*-
- * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com */
/*-
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
@@ -29,6 +27,13 @@
*
*/
+/** @file drm_scatter.c
+ * Allocation of memory for scatter-gather mappings by the graphics chip.
+ *
+ * The memory allocated here is then made into an aperture in the card
+ * by drm_ati_pcigart_init().
+ */
+
#include "drmP.h"
#define DEBUG_SCATTER 0
@@ -40,28 +45,21 @@ void drm_sg_cleanup(drm_sg_mem_t *entry)
free(entry, M_DRM);
}
-int drm_sg_alloc(DRM_IOCTL_ARGS)
+int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request)
{
- DRM_DEVICE;
- drm_scatter_gather_t request;
drm_sg_mem_t *entry;
unsigned long pages;
int i;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
-
if ( dev->sg )
return EINVAL;
- DRM_COPY_FROM_USER_IOCTL(request, (drm_scatter_gather_t *)data,
- sizeof(request) );
-
entry = malloc(sizeof(*entry), M_DRM, M_WAITOK | M_ZERO);
if ( !entry )
return ENOMEM;
- pages = round_page(request.size) / PAGE_SIZE;
- DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+ pages = round_page(request->size) / PAGE_SIZE;
+ DRM_DEBUG( "sg size=%ld pages=%ld\n", request->size, pages );
entry->pages = pages;
@@ -86,11 +84,7 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
entry->virtual = (void *)entry->handle;
- request.handle = entry->handle;
-
- DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data,
- request,
- sizeof(request) );
+ request->handle = entry->handle;
DRM_LOCK();
if (dev->sg) {
@@ -104,21 +98,28 @@ int drm_sg_alloc(DRM_IOCTL_ARGS)
return 0;
}
-int drm_sg_free(DRM_IOCTL_ARGS)
+int drm_sg_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
{
- DRM_DEVICE;
- drm_scatter_gather_t request;
- drm_sg_mem_t *entry;
+ drm_scatter_gather_t *request = data;
+ int ret;
+
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
- DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
- sizeof(request) );
+ ret = drm_sg_alloc(dev, request);
+ return ret;
+}
+
+int drm_sg_free(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+ drm_scatter_gather_t *request = data;
+ drm_sg_mem_t *entry;
DRM_LOCK();
entry = dev->sg;
dev->sg = NULL;
DRM_UNLOCK();
- if ( !entry || entry->handle != request.handle )
+ if ( !entry || entry->handle != request->handle )
return EINVAL;
DRM_DEBUG( "sg free virtual = 0x%lx\n", entry->handle );
diff --git a/bsd-core/drm_sysctl.c b/bsd-core/drm_sysctl.c
index b2d0cc0c..3de5b8ae 100644
--- a/bsd-core/drm_sysctl.c
+++ b/bsd-core/drm_sysctl.c
@@ -21,6 +21,11 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/** @file drm_sysctl.c
+ * Implementation of various sysctls for controlling DRM behavior and reporting
+ * debug information.
+ */
+
#include "drmP.h"
#include "drm.h"
diff --git a/bsd-core/drm_vm.c b/bsd-core/drm_vm.c
index 7f732c9b..fea31f52 100644
--- a/bsd-core/drm_vm.c
+++ b/bsd-core/drm_vm.c
@@ -21,6 +21,10 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/** @file drm_vm.c
+ * Support code for mmaping of DRM maps.
+ */
+
#include "drmP.h"
#include "drm.h"
@@ -33,7 +37,7 @@ int drm_mmap(dev_t kdev, vm_offset_t offset, int prot)
paddr_t drm_mmap(dev_t kdev, off_t offset, int prot)
#endif
{
- DRM_DEVICE;
+ drm_device_t *dev = drm_get_device_from_kdev(kdev);
drm_local_map_t *map;
drm_file_t *priv;
drm_map_type_t type;
@@ -52,7 +56,7 @@ paddr_t drm_mmap(dev_t kdev, off_t offset, int prot)
}
if (!priv->authenticated)
- return DRM_ERR(EACCES);
+ return EACCES;
if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) {
drm_device_dma_t *dma = dev->dma;
diff --git a/bsd-core/i915_dma.c b/bsd-core/i915_dma.c
new file mode 120000
index 00000000..c61d967e
--- /dev/null
+++ b/bsd-core/i915_dma.c
@@ -0,0 +1 @@
+../shared-core/i915_dma.c \ No newline at end of file
diff --git a/bsd-core/i915_drm.h b/bsd-core/i915_drm.h
new file mode 120000
index 00000000..ed53f01d
--- /dev/null
+++ b/bsd-core/i915_drm.h
@@ -0,0 +1 @@
+../shared-core/i915_drm.h \ No newline at end of file
diff --git a/bsd-core/i915_drv.h b/bsd-core/i915_drv.h
new file mode 120000
index 00000000..085558ca
--- /dev/null
+++ b/bsd-core/i915_drv.h
@@ -0,0 +1 @@
+../shared-core/i915_drv.h \ No newline at end of file
diff --git a/bsd-core/i915_irq.c b/bsd-core/i915_irq.c
new file mode 120000
index 00000000..2058a2e4
--- /dev/null
+++ b/bsd-core/i915_irq.c
@@ -0,0 +1 @@
+../shared-core/i915_irq.c \ No newline at end of file
diff --git a/bsd-core/i915_mem.c b/bsd-core/i915_mem.c
new file mode 120000
index 00000000..e8e56553
--- /dev/null
+++ b/bsd-core/i915_mem.c
@@ -0,0 +1 @@
+../shared-core/i915_mem.c \ No newline at end of file
diff --git a/bsd-core/mach64_dma.c b/bsd-core/mach64_dma.c
new file mode 120000
index 00000000..e5c28975
--- /dev/null
+++ b/bsd-core/mach64_dma.c
@@ -0,0 +1 @@
+../shared-core/mach64_dma.c \ No newline at end of file
diff --git a/bsd-core/mach64_drm.h b/bsd-core/mach64_drm.h
new file mode 120000
index 00000000..136ea936
--- /dev/null
+++ b/bsd-core/mach64_drm.h
@@ -0,0 +1 @@
+../shared-core/mach64_drm.h \ No newline at end of file
diff --git a/bsd-core/mach64_drv.h b/bsd-core/mach64_drv.h
new file mode 120000
index 00000000..85222cc2
--- /dev/null
+++ b/bsd-core/mach64_drv.h
@@ -0,0 +1 @@
+../shared-core/mach64_drv.h \ No newline at end of file
diff --git a/bsd-core/mach64_irq.c b/bsd-core/mach64_irq.c
new file mode 120000
index 00000000..a1235d58
--- /dev/null
+++ b/bsd-core/mach64_irq.c
@@ -0,0 +1 @@
+../shared-core/mach64_irq.c \ No newline at end of file
diff --git a/bsd-core/mach64_state.c b/bsd-core/mach64_state.c
new file mode 120000
index 00000000..b11f202c
--- /dev/null
+++ b/bsd-core/mach64_state.c
@@ -0,0 +1 @@
+../shared-core/mach64_state.c \ No newline at end of file
diff --git a/bsd-core/mga_dma.c b/bsd-core/mga_dma.c
new file mode 120000
index 00000000..f290be9b
--- /dev/null
+++ b/bsd-core/mga_dma.c
@@ -0,0 +1 @@
+../shared-core/mga_dma.c \ No newline at end of file
diff --git a/bsd-core/mga_drm.h b/bsd-core/mga_drm.h
new file mode 120000
index 00000000..1c87036f
--- /dev/null
+++ b/bsd-core/mga_drm.h
@@ -0,0 +1 @@
+../shared-core/mga_drm.h \ No newline at end of file
diff --git a/bsd-core/mga_drv.h b/bsd-core/mga_drv.h
new file mode 120000
index 00000000..cb0c9e1d
--- /dev/null
+++ b/bsd-core/mga_drv.h
@@ -0,0 +1 @@
+../shared-core/mga_drv.h \ No newline at end of file
diff --git a/bsd-core/mga_irq.c b/bsd-core/mga_irq.c
new file mode 120000
index 00000000..cf521d29
--- /dev/null
+++ b/bsd-core/mga_irq.c
@@ -0,0 +1 @@
+../shared-core/mga_irq.c \ No newline at end of file
diff --git a/bsd-core/mga_state.c b/bsd-core/mga_state.c
new file mode 120000
index 00000000..8bda8ba9
--- /dev/null
+++ b/bsd-core/mga_state.c
@@ -0,0 +1 @@
+../shared-core/mga_state.c \ No newline at end of file
diff --git a/bsd-core/mga_ucode.h b/bsd-core/mga_ucode.h
new file mode 120000
index 00000000..728b9aca
--- /dev/null
+++ b/bsd-core/mga_ucode.h
@@ -0,0 +1 @@
+../shared-core/mga_ucode.h \ No newline at end of file
diff --git a/bsd-core/mga_warp.c b/bsd-core/mga_warp.c
new file mode 120000
index 00000000..d35b3255
--- /dev/null
+++ b/bsd-core/mga_warp.c
@@ -0,0 +1 @@
+../shared-core/mga_warp.c \ No newline at end of file
diff --git a/bsd-core/r128_cce.c b/bsd-core/r128_cce.c
new file mode 120000
index 00000000..0c1d659e
--- /dev/null
+++ b/bsd-core/r128_cce.c
@@ -0,0 +1 @@
+../shared-core/r128_cce.c \ No newline at end of file
diff --git a/bsd-core/r128_drm.h b/bsd-core/r128_drm.h
new file mode 120000
index 00000000..363852cb
--- /dev/null
+++ b/bsd-core/r128_drm.h
@@ -0,0 +1 @@
+../shared-core/r128_drm.h \ No newline at end of file
diff --git a/bsd-core/r128_drv.h b/bsd-core/r128_drv.h
new file mode 120000
index 00000000..4f7e822d
--- /dev/null
+++ b/bsd-core/r128_drv.h
@@ -0,0 +1 @@
+../shared-core/r128_drv.h \ No newline at end of file
diff --git a/bsd-core/r128_irq.c b/bsd-core/r128_irq.c
new file mode 120000
index 00000000..66d28b05
--- /dev/null
+++ b/bsd-core/r128_irq.c
@@ -0,0 +1 @@
+../shared-core/r128_irq.c \ No newline at end of file
diff --git a/bsd-core/r128_state.c b/bsd-core/r128_state.c
new file mode 120000
index 00000000..e83d84b5
--- /dev/null
+++ b/bsd-core/r128_state.c
@@ -0,0 +1 @@
+../shared-core/r128_state.c \ No newline at end of file
diff --git a/bsd-core/r300_cmdbuf.c b/bsd-core/r300_cmdbuf.c
new file mode 120000
index 00000000..6674d056
--- /dev/null
+++ b/bsd-core/r300_cmdbuf.c
@@ -0,0 +1 @@
+../shared-core/r300_cmdbuf.c \ No newline at end of file
diff --git a/bsd-core/r300_reg.h b/bsd-core/r300_reg.h
new file mode 120000
index 00000000..ef54eba2
--- /dev/null
+++ b/bsd-core/r300_reg.h
@@ -0,0 +1 @@
+../shared-core/r300_reg.h \ No newline at end of file
diff --git a/bsd-core/radeon_cp.c b/bsd-core/radeon_cp.c
new file mode 120000
index 00000000..ee860943
--- /dev/null
+++ b/bsd-core/radeon_cp.c
@@ -0,0 +1 @@
+../shared-core/radeon_cp.c \ No newline at end of file
diff --git a/bsd-core/radeon_drm.h b/bsd-core/radeon_drm.h
new file mode 120000
index 00000000..54f595a3
--- /dev/null
+++ b/bsd-core/radeon_drm.h
@@ -0,0 +1 @@
+../shared-core/radeon_drm.h \ No newline at end of file
diff --git a/bsd-core/radeon_drv.h b/bsd-core/radeon_drv.h
new file mode 120000
index 00000000..5b415ea8
--- /dev/null
+++ b/bsd-core/radeon_drv.h
@@ -0,0 +1 @@
+../shared-core/radeon_drv.h \ No newline at end of file
diff --git a/bsd-core/radeon_irq.c b/bsd-core/radeon_irq.c
new file mode 120000
index 00000000..2f394a5e
--- /dev/null
+++ b/bsd-core/radeon_irq.c
@@ -0,0 +1 @@
+../shared-core/radeon_irq.c \ No newline at end of file
diff --git a/bsd-core/radeon_mem.c b/bsd-core/radeon_mem.c
new file mode 120000
index 00000000..8cc27989
--- /dev/null
+++ b/bsd-core/radeon_mem.c
@@ -0,0 +1 @@
+../shared-core/radeon_mem.c \ No newline at end of file
diff --git a/bsd-core/radeon_state.c b/bsd-core/radeon_state.c
new file mode 120000
index 00000000..ccee8761
--- /dev/null
+++ b/bsd-core/radeon_state.c
@@ -0,0 +1 @@
+../shared-core/radeon_state.c \ No newline at end of file
diff --git a/bsd-core/savage_bci.c b/bsd-core/savage_bci.c
new file mode 120000
index 00000000..b8436713
--- /dev/null
+++ b/bsd-core/savage_bci.c
@@ -0,0 +1 @@
+../shared-core/savage_bci.c \ No newline at end of file
diff --git a/bsd-core/savage_drm.h b/bsd-core/savage_drm.h
new file mode 120000
index 00000000..0dab2e3b
--- /dev/null
+++ b/bsd-core/savage_drm.h
@@ -0,0 +1 @@
+../shared-core/savage_drm.h \ No newline at end of file
diff --git a/bsd-core/savage_drv.h b/bsd-core/savage_drv.h
new file mode 120000
index 00000000..8397009c
--- /dev/null
+++ b/bsd-core/savage_drv.h
@@ -0,0 +1 @@
+../shared-core/savage_drv.h \ No newline at end of file
diff --git a/bsd-core/savage_state.c b/bsd-core/savage_state.c
new file mode 120000
index 00000000..e55dc5d4
--- /dev/null
+++ b/bsd-core/savage_state.c
@@ -0,0 +1 @@
+../shared-core/savage_state.c \ No newline at end of file
diff --git a/bsd-core/sis_drm.h b/bsd-core/sis_drm.h
new file mode 120000
index 00000000..36c77aac
--- /dev/null
+++ b/bsd-core/sis_drm.h
@@ -0,0 +1 @@
+../shared-core/sis_drm.h \ No newline at end of file
diff --git a/bsd-core/sis_drv.h b/bsd-core/sis_drv.h
new file mode 120000
index 00000000..3fddfdae
--- /dev/null
+++ b/bsd-core/sis_drv.h
@@ -0,0 +1 @@
+../shared-core/sis_drv.h \ No newline at end of file
diff --git a/bsd-core/sis_ds.c b/bsd-core/sis_ds.c
new file mode 120000
index 00000000..242310a0
--- /dev/null
+++ b/bsd-core/sis_ds.c
@@ -0,0 +1 @@
+../shared-core/sis_ds.c \ No newline at end of file
diff --git a/bsd-core/sis_ds.h b/bsd-core/sis_ds.h
new file mode 120000
index 00000000..8cbdaf3b
--- /dev/null
+++ b/bsd-core/sis_ds.h
@@ -0,0 +1 @@
+../shared-core/sis_ds.h \ No newline at end of file
diff --git a/bsd-core/sis_mm.c b/bsd-core/sis_mm.c
new file mode 120000
index 00000000..8f802ec3
--- /dev/null
+++ b/bsd-core/sis_mm.c
@@ -0,0 +1 @@
+../shared-core/sis_mm.c \ No newline at end of file
diff --git a/bsd-core/tdfx_drv.h b/bsd-core/tdfx_drv.h
new file mode 120000
index 00000000..8df70329
--- /dev/null
+++ b/bsd-core/tdfx_drv.h
@@ -0,0 +1 @@
+../shared-core/tdfx_drv.h \ No newline at end of file
diff --git a/bsd-core/via_3d_reg.h b/bsd-core/via_3d_reg.h
new file mode 120000
index 00000000..90d238ec
--- /dev/null
+++ b/bsd-core/via_3d_reg.h
@@ -0,0 +1 @@
+../shared-core/via_3d_reg.h \ No newline at end of file
diff --git a/bsd-core/via_dma.c b/bsd-core/via_dma.c
new file mode 120000
index 00000000..1f4d920f
--- /dev/null
+++ b/bsd-core/via_dma.c
@@ -0,0 +1 @@
+../shared-core/via_dma.c \ No newline at end of file
diff --git a/bsd-core/via_drm.h b/bsd-core/via_drm.h
new file mode 120000
index 00000000..7cd175d3
--- /dev/null
+++ b/bsd-core/via_drm.h
@@ -0,0 +1 @@
+../shared-core/via_drm.h \ No newline at end of file
diff --git a/bsd-core/via_drv.h b/bsd-core/via_drv.h
new file mode 120000
index 00000000..8954fe88
--- /dev/null
+++ b/bsd-core/via_drv.h
@@ -0,0 +1 @@
+../shared-core/via_drv.h \ No newline at end of file
diff --git a/bsd-core/via_ds.c b/bsd-core/via_ds.c
new file mode 120000
index 00000000..b0fbb694
--- /dev/null
+++ b/bsd-core/via_ds.c
@@ -0,0 +1 @@
+../shared-core/via_ds.c \ No newline at end of file
diff --git a/bsd-core/via_ds.h b/bsd-core/via_ds.h
new file mode 120000
index 00000000..dc8f2f44
--- /dev/null
+++ b/bsd-core/via_ds.h
@@ -0,0 +1 @@
+../shared-core/via_ds.h \ No newline at end of file
diff --git a/bsd-core/via_irq.c b/bsd-core/via_irq.c
new file mode 120000
index 00000000..f615af87
--- /dev/null
+++ b/bsd-core/via_irq.c
@@ -0,0 +1 @@
+../shared-core/via_irq.c \ No newline at end of file
diff --git a/bsd-core/via_map.c b/bsd-core/via_map.c
new file mode 120000
index 00000000..b5056634
--- /dev/null
+++ b/bsd-core/via_map.c
@@ -0,0 +1 @@
+../shared-core/via_map.c \ No newline at end of file
diff --git a/bsd-core/via_mm.c b/bsd-core/via_mm.c
new file mode 120000
index 00000000..f9ec0f37
--- /dev/null
+++ b/bsd-core/via_mm.c
@@ -0,0 +1 @@
+../shared-core/via_mm.c \ No newline at end of file
diff --git a/bsd-core/via_mm.h b/bsd-core/via_mm.h
new file mode 120000
index 00000000..fe2234f6
--- /dev/null
+++ b/bsd-core/via_mm.h
@@ -0,0 +1 @@
+../shared-core/via_mm.h \ No newline at end of file
diff --git a/bsd-core/via_verifier.c b/bsd-core/via_verifier.c
new file mode 120000
index 00000000..00b411bd
--- /dev/null
+++ b/bsd-core/via_verifier.c
@@ -0,0 +1 @@
+../shared-core/via_verifier.c \ No newline at end of file
diff --git a/bsd-core/via_verifier.h b/bsd-core/via_verifier.h
new file mode 120000
index 00000000..62d3e287
--- /dev/null
+++ b/bsd-core/via_verifier.h
@@ -0,0 +1 @@
+../shared-core/via_verifier.h \ No newline at end of file
diff --git a/bsd-core/via_video.c b/bsd-core/via_video.c
new file mode 120000
index 00000000..a6d27947
--- /dev/null
+++ b/bsd-core/via_video.c
@@ -0,0 +1 @@
+../shared-core/via_video.c \ No newline at end of file