aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/drm/bsd-core
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
commitf4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch)
tree2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/extras/drm/bsd-core
parenta840692edc9c6d19cd7c057f68e39c7d95eb767d (diff)
downloadnx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository
Diffstat (limited to 'nx-X11/extras/drm/bsd-core')
-rw-r--r--nx-X11/extras/drm/bsd-core/.cvsignore1
-rw-r--r--nx-X11/extras/drm/bsd-core/Makefile72
-rw-r--r--nx-X11/extras/drm/bsd-core/ati_pcigart.c100
-rw-r--r--nx-X11/extras/drm/bsd-core/drm/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/drm/Makefile41
-rw-r--r--nx-X11/extras/drm/bsd-core/drmP.h1023
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_agpsupport.c459
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_atomic.h141
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_auth.c172
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_bufs.c1125
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_context.c345
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_dma.c130
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_drawable.c51
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_drv.c932
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_fops.c128
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_ioctl.c296
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_irq.c291
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_linux_list.h71
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_lock.c177
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_memory.c154
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_pci.c141
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_scatter.c128
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_sysctl.c304
-rw-r--r--nx-X11/extras/drm/bsd-core/drm_vm.c126
-rw-r--r--nx-X11/extras/drm/bsd-core/i915/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/i915/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/i915_drv.c111
-rw-r--r--nx-X11/extras/drm/bsd-core/mach64/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/mach64/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/mach64_drv.c117
-rw-r--r--nx-X11/extras/drm/bsd-core/mga/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/mga/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/mga_drv.c148
-rw-r--r--nx-X11/extras/drm/bsd-core/r128/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/r128/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/r128_drv.c122
-rw-r--r--nx-X11/extras/drm/bsd-core/radeon/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/radeon/Makefile24
-rw-r--r--nx-X11/extras/drm/bsd-core/radeon_drv.c127
-rw-r--r--nx-X11/extras/drm/bsd-core/savage/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/savage/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/savage_drv.c107
-rw-r--r--nx-X11/extras/drm/bsd-core/sis/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/sis/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/sis_drv.c105
-rw-r--r--nx-X11/extras/drm/bsd-core/tdfx/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/tdfx/Makefile23
-rw-r--r--nx-X11/extras/drm/bsd-core/tdfx_drv.c106
-rw-r--r--nx-X11/extras/drm/bsd-core/via/.cvsignore8
-rw-r--r--nx-X11/extras/drm/bsd-core/via/Makefile24
-rw-r--r--nx-X11/extras/drm/bsd-core/via_drv.c118
51 files changed, 7758 insertions, 0 deletions
diff --git a/nx-X11/extras/drm/bsd-core/.cvsignore b/nx-X11/extras/drm/bsd-core/.cvsignore
new file mode 100644
index 000000000..c196cbc7a
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/.cvsignore
@@ -0,0 +1 @@
+drm_pciids.h
diff --git a/nx-X11/extras/drm/bsd-core/Makefile b/nx-X11/extras/drm/bsd-core/Makefile
new file mode 100644
index 000000000..a5ac952bc
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/Makefile
@@ -0,0 +1,72 @@
+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 sis tdfx # via i915
+
+CLEANFILES+= ${SHAREDFILES}
+
+.include <bsd.obj.mk>
+
+depend: drm_pciids.h ${SHAREDFILES}
+all: drm_pciids.h ${SHAREDFILES}
+
+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/nx-X11/extras/drm/bsd-core/ati_pcigart.c b/nx-X11/extras/drm/bsd-core/ati_pcigart.c
new file mode 100644
index 000000000..d48d0a80c
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/ati_pcigart.c
@@ -0,0 +1,100 @@
+/* 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.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
+#define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
+#define ATI_PCIGART_TABLE_SIZE 32768
+
+int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
+{
+ unsigned long pages;
+ u32 *pci_gart = NULL, page_base;
+ int i, j;
+
+ if (dev->sg == NULL) {
+ DRM_ERROR( "no scatter/gather memory!\n" );
+ return 0;
+ }
+
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+ /* GART table in system memory */
+ dev->sg->dmah = drm_pci_alloc(dev, ATI_PCIGART_TABLE_SIZE, 0,
+ 0xfffffffful);
+ if (dev->sg->dmah == NULL) {
+ DRM_ERROR("cannot allocate PCI GART table!\n");
+ return 0;
+ }
+
+ gart_info->addr = (void *)dev->sg->dmah->vaddr;
+ gart_info->bus_addr = dev->sg->dmah->busaddr;
+ pci_gart = (u32 *)dev->sg->dmah->vaddr;
+ } else {
+ /* GART table in framebuffer memory */
+ pci_gart = gart_info->addr;
+ }
+
+ pages = DRM_MIN(dev->sg->pages, ATI_MAX_PCIGART_PAGES);
+
+ bzero(pci_gart, ATI_PCIGART_TABLE_SIZE);
+
+ KASSERT(PAGE_SIZE >= ATI_PCIGART_PAGE_SIZE, ("page size too small"));
+
+ for ( i = 0 ; i < pages ; i++ ) {
+ page_base = (u32) dev->sg->busaddr[i];
+
+ for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+ if (gart_info->is_pcie)
+ *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc;
+ else
+ *pci_gart = cpu_to_le32(page_base);
+ pci_gart++;
+ page_base += ATI_PCIGART_PAGE_SIZE;
+ }
+ }
+
+ DRM_MEMORYBARRIER();
+
+ return 1;
+}
+
+int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
+{
+ if (dev->sg == NULL) {
+ DRM_ERROR( "no scatter/gather memory!\n" );
+ return 0;
+ }
+
+ drm_pci_free(dev, dev->sg->dmah);
+
+ return 1;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm/.cvsignore b/nx-X11/extras/drm/bsd-core/drm/.cvsignore
new file mode 100644
index 000000000..806f346cd
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+drm.kld
+drm.ko
diff --git a/nx-X11/extras/drm/bsd-core/drm/Makefile b/nx-X11/extras/drm/bsd-core/drm/Makefile
new file mode 100644
index 000000000..7a7ccd90e
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm/Makefile
@@ -0,0 +1,41 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = drm
+NO_MAN = YES
+SRCS = \
+ ati_pcigart.c \
+ drm_agpsupport.c \
+ drm_auth.c \
+ drm_bufs.c \
+ drm_context.c \
+ drm_dma.c \
+ drm_drawable.c \
+ drm_drv.c \
+ drm_fops.c \
+ drm_ioctl.c \
+ drm_irq.c \
+ drm_lock.c \
+ drm_memory.c \
+ drm_pci.c \
+ drm_scatter.c \
+ drm_sysctl.c \
+ drm_vm.c
+
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/drmP.h b/nx-X11/extras/drm/bsd-core/drmP.h
new file mode 100644
index 000000000..0adfef934
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drmP.h
@@ -0,0 +1,1023 @@
+/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
+ */
+/*-
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#ifndef _DRM_P_H_
+#define _DRM_P_H_
+
+#if defined(_KERNEL) || defined(__KERNEL__)
+
+typedef struct drm_device drm_device_t;
+typedef struct drm_file drm_file_t;
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/fcntl.h>
+#include <sys/uio.h>
+#include <sys/filio.h>
+#include <sys/sysctl.h>
+#include <sys/bus.h>
+#include <sys/signalvar.h>
+#include <sys/poll.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_param.h>
+#include <machine/param.h>
+#include <machine/pmap.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/sysarch.h>
+#include <sys/endian.h>
+#include <sys/mman.h>
+#if defined(__FreeBSD__)
+#include <sys/rman.h>
+#include <sys/memrange.h>
+#include <pci/agpvar.h>
+#include <sys/agpio.h>
+#if __FreeBSD_version >= 500000
+#include <sys/mutex.h>
+#include <dev/pci/pcivar.h>
+#include <sys/selinfo.h>
+#else /* __FreeBSD_version >= 500000 */
+#include <pci/pcivar.h>
+#include <sys/select.h>
+#endif /* __FreeBSD_version < 500000 */
+#elif defined(__NetBSD__)
+#include <machine/mtrr.h>
+#include <sys/vnode.h>
+#include <sys/select.h>
+#include <sys/device.h>
+#include <sys/resourcevar.h>
+#include <sys/lkm.h>
+#include <sys/agpio.h>
+#include <sys/ttycom.h>
+#include <uvm/uvm.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/agpvar.h>
+#elif defined(__OpenBSD__)
+#include <sys/lkm.h>
+#include <uvm/uvm.h>
+#endif
+#include <sys/bus.h>
+
+#include "drm.h"
+#include "drm_linux_list.h"
+#include "drm_atomic.h"
+
+#ifdef __FreeBSD__
+#include <opt_drm.h>
+#ifdef DRM_DEBUG
+#undef DRM_DEBUG
+#define DRM_DEBUG_DEFAULT_ON 1
+#endif /* DRM_DEBUG */
+#endif
+
+#if defined(DRM_LINUX) && DRM_LINUX && !defined(__amd64__)
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <machine/../linux/linux.h>
+#include <machine/../linux/linux_proto.h>
+#else
+/* Either it was defined when it shouldn't be (FreeBSD amd64) or it isn't
+ * supported on this OS yet.
+ */
+#undef DRM_LINUX
+#define DRM_LINUX 0
+#endif
+
+#define DRM_HASH_SIZE 16 /* Size of key hash table */
+#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */
+#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */
+
+#define DRM_MEM_DMA 0
+#define DRM_MEM_SAREA 1
+#define DRM_MEM_DRIVER 2
+#define DRM_MEM_MAGIC 3
+#define DRM_MEM_IOCTLS 4
+#define DRM_MEM_MAPS 5
+#define DRM_MEM_BUFS 6
+#define DRM_MEM_SEGS 7
+#define DRM_MEM_PAGES 8
+#define DRM_MEM_FILES 9
+#define DRM_MEM_QUEUES 10
+#define DRM_MEM_CMDS 11
+#define DRM_MEM_MAPPINGS 12
+#define DRM_MEM_BUFLISTS 13
+#define DRM_MEM_AGPLISTS 14
+#define DRM_MEM_TOTALAGP 15
+#define DRM_MEM_BOUNDAGP 16
+#define DRM_MEM_CTXBITMAP 17
+#define DRM_MEM_STUB 18
+#define DRM_MEM_SGLISTS 19
+
+#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
+
+ /* Internal types and structures */
+#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
+#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
+
+#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
+
+MALLOC_DECLARE(M_DRM);
+
+#define __OS_HAS_AGP 1
+
+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+#define DRM_DEV_UID 0
+#define DRM_DEV_GID 0
+
+#define wait_queue_head_t atomic_t
+#define DRM_WAKEUP(w) wakeup((void *)w)
+#define DRM_WAKEUP_INT(w) wakeup(w)
+#define DRM_INIT_WAITQUEUE(queue) do {} while (0)
+
+#if defined(__FreeBSD__) && __FreeBSD_version < 502109
+#define bus_alloc_resource_any(dev, type, rid, flags) \
+ bus_alloc_resource(dev, type, rid, 0ul, ~0ul, 1, flags)
+#endif
+
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
+#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_SPINLOCK(l) mtx_lock(l)
+#define DRM_SPINUNLOCK(u) 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)
+#define DRM_UNLOCK() mtx_unlock(&dev->dev_lock)
+#define DRM_SYSCTL_HANDLER_ARGS (SYSCTL_HANDLER_ARGS)
+#else /* __FreeBSD__ && __FreeBSD_version >= 500000 */
+#define DRM_CURPROC curproc
+#define DRM_STRUCTPROC struct proc
+#define DRM_SPINTYPE struct simplelock
+#define DRM_SPININIT(l,name)
+#define DRM_SPINUNINIT(l)
+#define DRM_SPINLOCK(l)
+#define DRM_SPINUNLOCK(u)
+#define DRM_SPINLOCK_ASSERT(l)
+#define DRM_CURRENTPID curproc->p_pid
+#define DRM_LOCK()
+#define DRM_UNLOCK()
+#define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS
+#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 */
+#define IRQ_NONE /* nothing */
+
+enum {
+ DRM_IS_NOT_AGP,
+ DRM_MIGHT_BE_AGP,
+ DRM_IS_AGP
+};
+#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 PAGE_ALIGN(addr) round_page(addr)
+/* DRM_SUSER returns true if the user is superuser */
+#define DRM_SUSER(p) (suser(p) == 0)
+#define DRM_AGP_FIND_DEVICE() agp_find_device()
+#define DRM_MTRR_WC MDF_WRITECOMBINE
+#define jiffies ticks
+
+#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 */
+#define DRM_SUSER(p) (suser(p->p_ucred, &p->p_acflag) == 0)
+#define DRM_AGP_FIND_DEVICE() agp_find_device(0)
+#define DRM_MTRR_WC MTRR_TYPE_WC
+#define jiffies hardclock_ticks
+
+typedef drm_device_t *device_t;
+extern struct cfdriver drm_cd;
+#endif /* !__FreeBSD__ */
+
+/* Capabilities taken from src/sys/dev/pci/pcireg.h. */
+#ifndef PCIY_AGP
+#define PCIY_AGP 0x02
+#endif
+
+#ifndef PCIY_EXPRESS
+#define PCIY_EXPRESS 0x10
+#endif
+
+typedef unsigned long dma_addr_t;
+typedef u_int32_t u32;
+typedef u_int16_t u16;
+typedef u_int8_t u8;
+
+/* DRM_READMEMORYBARRIER() prevents reordering of reads.
+ * DRM_WRITEMEMORYBARRIER() prevents reordering of writes.
+ * DRM_MEMORYBARRIER() prevents reordering of reads and writes.
+ */
+#if defined(__i386__)
+#define DRM_READMEMORYBARRIER() __asm __volatile( \
+ "lock; addl $0,0(%%esp)" : : : "memory");
+#define DRM_WRITEMEMORYBARRIER() __asm __volatile("" : : : "memory");
+#define DRM_MEMORYBARRIER() __asm __volatile( \
+ "lock; addl $0,0(%%esp)" : : : "memory");
+#elif defined(__alpha__)
+#define DRM_READMEMORYBARRIER() alpha_mb();
+#define DRM_WRITEMEMORYBARRIER() alpha_wmb();
+#define DRM_MEMORYBARRIER() alpha_mb();
+#elif defined(__amd64__)
+#define DRM_READMEMORYBARRIER() __asm __volatile( \
+ "lock; addl $0,0(%%rsp)" : : : "memory");
+#define DRM_WRITEMEMORYBARRIER() __asm __volatile("" : : : "memory");
+#define DRM_MEMORYBARRIER() __asm __volatile( \
+ "lock; addl $0,0(%%rsp)" : : : "memory");
+#endif
+
+#ifdef __FreeBSD__
+#define DRM_READ8(map, offset) \
+ *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
+#define DRM_READ16(map, offset) \
+ *(volatile u_int16_t *) (((unsigned long)(map)->handle) + (offset))
+#define DRM_READ32(map, offset) \
+ *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset))
+#define DRM_WRITE8(map, offset, val) \
+ *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) = val
+#define DRM_WRITE16(map, offset, val) \
+ *(volatile u_int16_t *) (((unsigned long)(map)->handle) + (offset)) = val
+#define DRM_WRITE32(map, offset, val) \
+ *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val
+
+#define DRM_VERIFYAREA_READ( uaddr, size ) \
+ (!useracc(__DECONST(caddr_t, uaddr), size, VM_PROT_READ))
+
+#else /* __FreeBSD__ */
+
+typedef vaddr_t vm_offset_t;
+
+#define DRM_READ8(map, offset) \
+ bus_space_read_1( (map)->bst, (map)->bsh, (offset))
+#define DRM_READ16(map, offset) \
+ bus_space_read_2( (map)->bst, (map)->bsh, (offset))
+#define DRM_READ32(map, offset) \
+ bus_space_read_4( (map)->bst, (map)->bsh, (offset))
+#define DRM_WRITE8(map, offset, val) \
+ bus_space_write_1((map)->bst, (map)->bsh, (offset), (val))
+#define DRM_WRITE16(map, offset, val) \
+ bus_space_write_2((map)->bst, (map)->bsh, (offset), (val))
+#define DRM_WRITE32(map, offset, val) \
+ bus_space_write_4((map)->bst, (map)->bsh, (offset), (val))
+
+#define DRM_VERIFYAREA_READ( uaddr, size ) \
+ (!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) \
+ copyin(user, kern, size)
+#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
+ copyin(arg2, arg1, arg3)
+#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \
+ copyout(arg2, arg1, arg3)
+#if __FreeBSD_version > 500000
+#define DRM_GET_USER_UNCHECKED(val, uaddr) \
+ ((val) = fuword32(uaddr), 0)
+#else
+#define DRM_GET_USER_UNCHECKED(val, uaddr) \
+ ((val) = fuword(uaddr), 0)
+#endif
+
+#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 */
+
+#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
+ (_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) \
+do { \
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || \
+ dev->lock.filp != filp) { \
+ DRM_ERROR("%s called without lock held\n", \
+ __FUNCTION__); \
+ return EINVAL; \
+ } \
+} while (0)
+
+#define DRM_GETSAREA() \
+do { \
+ drm_local_map_t *map; \
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock); \
+ TAILQ_FOREACH(map, &dev->maplist, link) { \
+ if (map->type == _DRM_SHM && \
+ map->flags & _DRM_CONTAINS_LOCK) { \
+ dev_priv->sarea = map; \
+ break; \
+ } \
+ } \
+} while (0)
+
+#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+#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, \
+ PZERO | PCATCH, "drmwtq", (timeout)); \
+ mtx_unlock(&dev->irq_lock); \
+ DRM_LOCK(); \
+}
+#else
+#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
+for ( ret = 0 ; !ret && !(condition) ; ) { \
+ int s = spldrm(); \
+ if (!(condition)) \
+ ret = tsleep( &(queue), PZERO | PCATCH, \
+ "drmwtq", (timeout) ); \
+ splx(s); \
+}
+#endif
+
+#define DRM_ERROR(fmt, arg...) \
+ printf("error: [" DRM_NAME ":pid%d:%s] *ERROR* " fmt, \
+ DRM_CURRENTPID, __func__ , ## arg)
+
+#define DRM_INFO(fmt, arg...) printf("info: [" DRM_NAME "] " fmt , ## arg)
+
+#define DRM_DEBUG(fmt, arg...) do { \
+ if (drm_debug_flag) \
+ printf("[" DRM_NAME ":pid%d:%s] " fmt, DRM_CURRENTPID, \
+ __func__ , ## arg); \
+} while (0)
+
+typedef struct drm_pci_id_list
+{
+ int vendor;
+ int device;
+ long driver_private;
+ char *name;
+} drm_pci_id_list_t;
+
+#define DRM_AUTH 0x1
+#define DRM_MASTER 0x2
+#define DRM_ROOT_ONLY 0x4
+typedef struct drm_ioctl_desc {
+ int (*func)(DRM_IOCTL_ARGS);
+ int flags;
+} drm_ioctl_desc_t;
+
+typedef struct drm_magic_entry {
+ drm_magic_t magic;
+ struct drm_file *priv;
+ struct drm_magic_entry *next;
+} drm_magic_entry_t;
+
+typedef struct drm_magic_head {
+ struct drm_magic_entry *head;
+ struct drm_magic_entry *tail;
+} drm_magic_head_t;
+
+typedef struct drm_buf {
+ int idx; /* Index into master buflist */
+ int total; /* Buffer size */
+ int order; /* log-base-2(total) */
+ int used; /* Amount of buffer in use (for DMA) */
+ unsigned long offset; /* Byte offset (used internally) */
+ void *address; /* Address of buffer */
+ 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 */
+ int context; /* Kernel queue for this buffer */
+ enum {
+ DRM_LIST_NONE = 0,
+ DRM_LIST_FREE = 1,
+ DRM_LIST_WAIT = 2,
+ DRM_LIST_PEND = 3,
+ DRM_LIST_PRIO = 4,
+ DRM_LIST_RECLAIM = 5
+ } list; /* Which list we're on */
+
+ int dev_priv_size; /* Size of buffer private stoarge */
+ void *dev_private; /* Per-buffer private storage */
+} drm_buf_t;
+
+typedef struct drm_freelist {
+ int initialized; /* Freelist in use */
+ atomic_t count; /* Number of free buffers */
+ drm_buf_t *next; /* End pointer */
+
+ int low_mark; /* Low water mark */
+ int high_mark; /* High water mark */
+} drm_freelist_t;
+
+typedef struct drm_dma_handle {
+ void *vaddr;
+ bus_addr_t busaddr;
+#if defined(__FreeBSD__)
+ bus_dma_tag_t tag;
+ bus_dmamap_t map;
+#elif defined(__NetBSD__)
+ bus_dma_segment_t seg;
+#endif
+} drm_dma_handle_t;
+
+typedef struct drm_buf_entry {
+ int buf_size;
+ int buf_count;
+ drm_buf_t *buflist;
+ int seg_count;
+ drm_dma_handle_t **seglist;
+ int page_order;
+
+ drm_freelist_t freelist;
+} drm_buf_entry_t;
+
+typedef TAILQ_HEAD(drm_file_list, drm_file) drm_file_list_t;
+struct drm_file {
+ TAILQ_ENTRY(drm_file) link;
+ int authenticated;
+ int master;
+ int minor;
+ pid_t pid;
+ uid_t uid;
+ int refs;
+ drm_magic_t magic;
+ unsigned long ioctl_count;
+ void *driver_priv;
+};
+
+typedef struct drm_lock_data {
+ drm_hw_lock_t *hw_lock; /* Hardware lock */
+ DRMFILE filp; /* 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;
+
+/* This structure, in the drm_device_t, is always initialized while the device
+ * is open. dev->dma_lock protects the incrementing of dev->buf_use, which
+ * when set marks that no further bufs may be allocated until device teardown
+ * occurs (when the last open of the device has closed). The high/low
+ * watermarks of bufs are only touched by the X Server, and thus not
+ * concurrently accessed, so no locking is needed.
+ */
+typedef struct drm_device_dma {
+ drm_buf_entry_t bufs[DRM_MAX_ORDER+1];
+ int buf_count;
+ drm_buf_t **buflist; /* Vector of pointers info bufs */
+ int seg_count;
+ int page_count;
+ unsigned long *pagelist;
+ unsigned long byte_count;
+ enum {
+ _DRM_DMA_USE_AGP = 0x01,
+ _DRM_DMA_USE_SG = 0x02
+ } flags;
+} drm_device_dma_t;
+
+typedef struct drm_agp_mem {
+ void *handle;
+ unsigned long bound; /* address */
+ int pages;
+ struct drm_agp_mem *prev;
+ struct drm_agp_mem *next;
+} drm_agp_mem_t;
+
+typedef struct drm_agp_head {
+ device_t agpdev;
+ struct agp_info info;
+ const char *chipset;
+ drm_agp_mem_t *memory;
+ unsigned long mode;
+ int enabled;
+ int acquired;
+ unsigned long base;
+ int mtrr;
+ int cant_use_aperture;
+ unsigned long page_mask;
+} drm_agp_head_t;
+
+typedef struct drm_sg_mem {
+ unsigned long handle;
+ void *virtual;
+ int pages;
+ dma_addr_t *busaddr;
+ drm_dma_handle_t *dmah; /* Handle to PCI memory for ATI PCIGART table */
+} drm_sg_mem_t;
+
+typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t;
+
+typedef struct drm_local_map {
+ unsigned long offset; /* Physical address (0 for SAREA)*/
+ unsigned long size; /* Physical size (bytes) */
+ drm_map_type_t type; /* Type of memory mapped */
+ drm_map_flags_t flags; /* Flags */
+ void *handle; /* User-space: "Handle" to pass to mmap */
+ /* Kernel-space: kernel-virtual address */
+ int mtrr; /* Boolean: MTRR used */
+ /* Private data */
+ int rid; /* PCI resource ID for bus_space */
+ struct resource *bsr;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ drm_dma_handle_t *dmah;
+ TAILQ_ENTRY(drm_local_map) link;
+} drm_local_map_t;
+
+TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
+typedef struct drm_vbl_sig {
+ TAILQ_ENTRY(drm_vbl_sig) link;
+ unsigned int sequence;
+ int signo;
+ int pid;
+} drm_vbl_sig_t;
+
+/* location of GART table */
+#define DRM_ATI_GART_MAIN 1
+#define DRM_ATI_GART_FB 2
+
+typedef struct ati_pcigart_info {
+ int gart_table_location;
+ int is_pcie;
+ void *addr;
+ dma_addr_t bus_addr;
+ drm_local_map_t mapping;
+} drm_ati_pcigart_info;
+
+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 (*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 (*dma_ready)(struct drm_device *);
+ int (*dma_quiescent)(struct drm_device *);
+ int (*dma_flush_block_and_flush)(struct drm_device *, int context,
+ drm_lock_flags_t flags);
+ int (*dma_flush_unblock)(struct drm_device *, int context,
+ drm_lock_flags_t flags);
+ int (*context_ctor)(struct drm_device *dev, int context);
+ int (*context_dtor)(struct drm_device *dev, int context);
+ int (*kernel_context_switch)(struct drm_device *dev, int old,
+ int new);
+ int (*kernel_context_switch_unlock)(struct drm_device *dev);
+ void (*irq_preinstall)(drm_device_t *dev);
+ void (*irq_postinstall)(drm_device_t *dev);
+ void (*irq_uninstall)(drm_device_t *dev);
+ void (*irq_handler)(DRM_IRQ_ARGS);
+ int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence);
+
+ drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
+
+ /**
+ * Called by \c drm_device_is_agp. Typically used to determine if a
+ * card is really attached to AGP or not.
+ *
+ * \param dev DRM device handle
+ *
+ * \returns
+ * One of three values is returned depending on whether or not the
+ * card is absolutely \b not AGP (return of 0), absolutely \b is AGP
+ * (return of 1), or may or may not be AGP (return of 2).
+ */
+ int (*device_is_agp) (struct drm_device * dev);
+
+ drm_ioctl_desc_t *ioctls;
+ int max_ioctl;
+
+ int buf_priv_size;
+
+ int major;
+ int minor;
+ int patchlevel;
+ const char *name; /* Simple driver name */
+ const char *desc; /* Longer driver name */
+ const char *date; /* Date of last major changes. */
+
+ unsigned use_agp :1;
+ unsigned require_agp :1;
+ unsigned use_sg :1;
+ unsigned use_dma :1;
+ unsigned use_pci_dma :1;
+ unsigned use_dma_queue :1;
+ unsigned use_irq :1;
+ unsigned use_vbl_irq :1;
+ unsigned use_mtrr :1;
+};
+
+/* Length for the array of resource pointers for drm_get_resource_*. */
+#define DRM_MAX_PCI_RESOURCE 3
+
+/**
+ * DRM device functions structure
+ */
+struct drm_device {
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ struct device device; /* softc is an extension of struct device */
+#endif
+
+ struct drm_driver_info driver;
+ drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
+
+ char *unique; /* Unique identifier: e.g., busid */
+ int unique_len; /* Length of unique field */
+#ifdef __FreeBSD__
+ device_t device; /* Device instance from newbus */
+#endif
+ struct cdev *devnode; /* Device number for mknod */
+ int if_version; /* Highest interface version set */
+
+ int flags; /* Flags to open(2) */
+
+ /* Locks */
+#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+ struct mtx dma_lock; /* protects dev->dma */
+ struct mtx irq_lock; /* protects irq condition checks */
+ struct mtx dev_lock; /* protects everything else */
+#endif
+ /* Usage Counters */
+ int open_count; /* Outstanding files open */
+ int buf_use; /* Buffers in use -- cannot alloc */
+
+ /* Performance counters */
+ unsigned long counters;
+ drm_stat_type_t types[15];
+ atomic_t counts[15];
+
+ /* Authentication */
+ drm_file_list_t files;
+ drm_magic_head_t magiclist[DRM_HASH_SIZE];
+
+ /* Linked list of mappable regions. Protected by dev_lock */
+ drm_map_list_t maplist;
+
+ drm_local_map_t **context_sareas;
+ int max_context;
+
+ drm_lock_data_t lock; /* Information on hardware lock */
+
+ /* DMA queues (contexts) */
+ drm_device_dma_t *dma; /* Optional pointer for DMA support */
+
+ /* Context support */
+ int irq; /* Interrupt used by board */
+ int irq_enabled; /* True if the irq handler is enabled */
+#ifdef __FreeBSD__
+ int irqrid; /* Interrupt used by board */
+ struct resource *irqr; /* Resource for interrupt used by board */
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ struct pci_attach_args pa;
+#endif
+ void *irqh; /* Handle from bus_setup_intr */
+
+ /* Storage of resource pointers for drm_get_resource_* */
+ struct resource *pcir[DRM_MAX_PCI_RESOURCE];
+ int pcirid[DRM_MAX_PCI_RESOURCE];
+
+ int pci_domain;
+ int pci_bus;
+ int pci_slot;
+ int pci_func;
+
+ atomic_t context_flag; /* Context swapping flag */
+ int last_context; /* Last current context */
+ int vbl_queue; /* vbl wait channel */
+ atomic_t vbl_received;
+
+#ifdef __FreeBSD__
+ struct sigio *buf_sigio; /* Processes waiting for SIGIO */
+#elif defined(__NetBSD__)
+ pid_t buf_pgid;
+#endif
+
+ /* Sysctl support */
+ struct drm_sysctl_info *sysctl;
+
+ drm_agp_head_t *agp;
+ drm_sg_mem_t *sg; /* Scatter gather memory */
+ atomic_t *ctx_bitmap;
+ void *dev_private;
+ unsigned int agp_buffer_token;
+ drm_local_map_t *agp_buffer_map;
+};
+
+extern int drm_debug_flag;
+
+/* Device setup support (drm_drv.c) */
+#ifdef __FreeBSD__
+int drm_probe(device_t nbdev, drm_pci_id_list_t *idlist);
+int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist);
+int drm_detach(device_t nbdev);
+d_ioctl_t drm_ioctl;
+d_open_t drm_open;
+d_close_t drm_close;
+d_read_t drm_read;
+d_poll_t drm_poll;
+d_mmap_t drm_mmap;
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+int drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t *idlist);
+int drm_attach(struct pci_attach_args *pa, dev_t kdev, drm_pci_id_list_t *idlist);
+dev_type_ioctl(drm_ioctl);
+dev_type_open(drm_open);
+dev_type_close(drm_close);
+dev_type_read(drm_read);
+dev_type_poll(drm_poll);
+dev_type_mmap(drm_mmap);
+#endif
+
+/* File operations helpers (drm_fops.c) */
+#ifdef __FreeBSD__
+extern int drm_open_helper(struct cdev *kdev, int flags, int fmt,
+ DRM_STRUCTPROC *p, drm_device_t *dev);
+extern drm_file_t *drm_find_file_by_proc(drm_device_t *dev,
+ DRM_STRUCTPROC *p);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+extern int drm_open_helper(dev_t kdev, int flags, int fmt,
+ DRM_STRUCTPROC *p, drm_device_t *dev);
+extern drm_file_t *drm_find_file_by_proc(drm_device_t *dev,
+ DRM_STRUCTPROC *p);
+#endif /* __NetBSD__ || __OpenBSD__ */
+
+/* Memory management support (drm_memory.c) */
+void drm_mem_init(void);
+void drm_mem_uninit(void);
+void *drm_alloc(size_t size, int area);
+void *drm_calloc(size_t nmemb, size_t size, int area);
+void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
+ int area);
+void drm_free(void *pt, size_t size, int area);
+void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map);
+void drm_ioremapfree(drm_local_map_t *map);
+int drm_mtrr_add(unsigned long offset, size_t size, int flags);
+int drm_mtrr_del(unsigned long offset, size_t size, int flags);
+
+int drm_context_switch(drm_device_t *dev, int old, int new);
+int drm_context_switch_complete(drm_device_t *dev, int new);
+
+int drm_ctxbitmap_init(drm_device_t *dev);
+void drm_ctxbitmap_cleanup(drm_device_t *dev);
+void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
+int drm_ctxbitmap_next(drm_device_t *dev);
+
+/* Locking IOCTL support (drm_lock.c) */
+int drm_lock_take(__volatile__ unsigned int *lock,
+ unsigned int context);
+int drm_lock_transfer(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context);
+int drm_lock_free(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context);
+
+/* Buffer management support (drm_bufs.c) */
+unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource);
+unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource);
+void drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
+int drm_order(unsigned long size);
+int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
+ drm_map_type_t type, drm_map_flags_t flags,
+ drm_local_map_t **map_ptr);
+int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request);
+int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request);
+int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request);
+
+/* DMA support (drm_dma.c) */
+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);
+
+/* IRQ support (drm_irq.c) */
+int drm_irq_install(drm_device_t *dev);
+int drm_irq_uninstall(drm_device_t *dev);
+irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
+void drm_driver_irq_preinstall(drm_device_t *dev);
+void drm_driver_irq_postinstall(drm_device_t *dev);
+void drm_driver_irq_uninstall(drm_device_t *dev);
+int drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
+void drm_vbl_send_signals(drm_device_t *dev);
+
+/* AGP/PCI Express/GART support (drm_agpsupport.c) */
+int drm_device_is_agp(drm_device_t *dev);
+int drm_device_is_pcie(drm_device_t *dev);
+drm_agp_head_t *drm_agp_init(void);
+int drm_agp_acquire(drm_device_t *dev);
+int drm_agp_release(drm_device_t *dev);
+int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
+int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
+void *drm_agp_allocate_memory(size_t pages, u32 type);
+int drm_agp_free_memory(void *handle);
+int drm_agp_bind_memory(void *handle, off_t start);
+int drm_agp_unbind_memory(void *handle);
+int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
+int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
+int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
+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);
+
+#ifdef __FreeBSD__
+/* sysctl support (drm_sysctl.h) */
+extern int drm_sysctl_init(drm_device_t *dev);
+extern int drm_sysctl_cleanup(drm_device_t *dev);
+#endif /* __FreeBSD__ */
+
+/* ATI PCIGART support (ati_pcigart.c) */
+int drm_ati_pcigart_init(drm_device_t *dev,
+ drm_ati_pcigart_info *gart_info);
+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);
+
+/* 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);
+
+/* 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);
+
+/* Drawable IOCTL support (drm_drawable.c) */
+int drm_adddraw(DRM_IOCTL_ARGS);
+int drm_rmdraw(DRM_IOCTL_ARGS);
+
+/* Authentication IOCTL support (drm_auth.c) */
+int drm_getmagic(DRM_IOCTL_ARGS);
+int drm_authmagic(DRM_IOCTL_ARGS);
+
+/* 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);
+
+/* DMA support (drm_dma.c) */
+int drm_dma(DRM_IOCTL_ARGS);
+
+/* IRQ support (drm_irq.c) */
+int drm_control(DRM_IOCTL_ARGS);
+int drm_wait_vblank(DRM_IOCTL_ARGS);
+
+/* 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);
+
+/* Scatter Gather Support (drm_scatter.c) */
+int drm_sg_alloc(DRM_IOCTL_ARGS);
+int drm_sg_free(DRM_IOCTL_ARGS);
+
+/* consistent PCI memory functions (drm_pci.c) */
+drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align,
+ dma_addr_t maxaddr);
+void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
+
+/* Inline replacements for DRM_IOREMAP macros */
+static __inline__ void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev)
+{
+ map->handle = drm_ioremap(dev, map);
+}
+static __inline__ void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
+{
+ if ( map->handle && map->size )
+ drm_ioremapfree(map);
+}
+
+static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev, unsigned long offset)
+{
+ drm_local_map_t *map;
+
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+ TAILQ_FOREACH(map, &dev->maplist, link) {
+ if (map->offset == offset)
+ return map;
+ }
+ return NULL;
+}
+
+static __inline__ void drm_core_dropmap(struct drm_map *map)
+{
+}
+
+#endif /* __KERNEL__ */
+#endif /* _DRM_P_H_ */
diff --git a/nx-X11/extras/drm/bsd-core/drm_agpsupport.c b/nx-X11/extras/drm/bsd-core/drm_agpsupport.c
new file mode 100644
index 000000000..582935661
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_agpsupport.c
@@ -0,0 +1,459 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+#ifdef __FreeBSD__
+#include <pci/agpreg.h>
+#include <dev/pci/pcireg.h>
+#endif
+
+/* Returns 1 if AGP or 0 if not. */
+static int
+drm_device_find_capability(drm_device_t *dev, int cap)
+{
+ int ret;
+
+ if (dev->driver.device_is_agp != NULL) {
+ ret = (*dev->driver.device_is_agp)(dev);
+
+ if (ret != DRM_MIGHT_BE_AGP) {
+ return ret == 2;
+ }
+ }
+
+#ifdef __FreeBSD__
+ /* Code taken from agp.c. IWBNI that was a public interface. */
+ u_int32_t status;
+ u_int8_t ptr, next;
+
+ /*
+ * Check the CAP_LIST bit of the PCI status register first.
+ */
+ status = pci_read_config(dev->device, PCIR_STATUS, 2);
+ if (!(status & 0x10))
+ return 0;
+
+ /*
+ * Traverse the capabilities list.
+ */
+ for (ptr = pci_read_config(dev->device, AGP_CAPPTR, 1);
+ ptr != 0;
+ ptr = next) {
+ u_int32_t capid = pci_read_config(dev->device, ptr, 4);
+ next = AGP_CAPID_GET_NEXT_PTR(capid);
+
+ /*
+ * If this capability entry ID is cap, then we are done.
+ */
+ if (AGP_CAPID_GET_CAP_ID(capid) == cap)
+ return 1;
+ }
+
+ return 0;
+#else
+ /* XXX: fill me in for non-FreeBSD */
+ return 1;
+#endif
+}
+
+int drm_device_is_agp(drm_device_t *dev)
+{
+ return (drm_device_find_capability(dev, PCIY_AGP));
+}
+
+int drm_device_is_pcie(drm_device_t *dev)
+{
+ return (drm_device_find_capability(dev, PCIY_EXPRESS));
+}
+
+int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info)
+{
+ struct agp_info *kern;
+
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+
+ kern = &dev->agp->info;
+ agp_get_info(dev->agp->agpdev, kern);
+ info->agp_version_major = 1;
+ info->agp_version_minor = 0;
+ info->mode = kern->ai_mode;
+ info->aperture_base = kern->ai_aperture_base;
+ info->aperture_size = kern->ai_aperture_size;
+ info->memory_allowed = kern->ai_memory_allowed;
+ info->memory_used = kern->ai_memory_used;
+ info->id_vendor = kern->ai_devid & 0xffff;
+ info->id_device = kern->ai_devid >> 16;
+
+ return 0;
+}
+
+int drm_agp_info_ioctl(DRM_IOCTL_ARGS)
+{
+ int err;
+ drm_agp_info_t info;
+ DRM_DEVICE;
+
+ err = drm_agp_info(dev, &info);
+ if (err != 0)
+ return err;
+
+ *(drm_agp_info_t *) data = info;
+ return 0;
+}
+
+int drm_agp_acquire_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+
+ return drm_agp_acquire(dev);
+}
+
+int drm_agp_acquire(drm_device_t *dev)
+{
+ int retcode;
+
+ if (!dev->agp || dev->agp->acquired)
+ return EINVAL;
+
+ retcode = agp_acquire(dev->agp->agpdev);
+ if (retcode)
+ return retcode;
+
+ dev->agp->acquired = 1;
+ return 0;
+}
+
+int drm_agp_release_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+
+ return drm_agp_release(dev);
+}
+
+int drm_agp_release(drm_device_t * dev)
+{
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+ agp_release(dev->agp->agpdev);
+ dev->agp->acquired = 0;
+ return 0;
+}
+
+int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
+{
+
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+
+ 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)
+{
+ drm_agp_mode_t mode;
+ DRM_DEVICE;
+
+ mode = *(drm_agp_mode_t *) data;
+
+ return drm_agp_enable(dev, mode);
+}
+
+int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request)
+{
+ drm_agp_mem_t *entry;
+ void *handle;
+ unsigned long pages;
+ u_int32_t type;
+ struct agp_memory_info info;
+
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+
+ entry = malloc(sizeof(*entry), M_DRM, M_NOWAIT | M_ZERO);
+ if (entry == NULL)
+ return ENOMEM;
+
+ pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
+ type = (u_int32_t) request->type;
+
+ DRM_UNLOCK();
+ handle = drm_agp_allocate_memory(pages, type);
+ DRM_LOCK();
+ if (handle == NULL) {
+ free(entry, M_DRM);
+ return ENOMEM;
+ }
+
+ entry->handle = handle;
+ entry->bound = 0;
+ entry->pages = pages;
+ entry->prev = NULL;
+ entry->next = dev->agp->memory;
+ if (dev->agp->memory)
+ dev->agp->memory->prev = entry;
+ dev->agp->memory = entry;
+
+ agp_memory_info(dev->agp->agpdev, entry->handle, &info);
+
+ request->handle = (unsigned long) entry->handle;
+ request->physical = info.ami_physical;
+
+ return 0;
+}
+
+int drm_agp_alloc_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_agp_buffer_t request;
+ int retcode;
+
+ request = *(drm_agp_buffer_t *) data;
+
+ DRM_LOCK();
+ retcode = drm_agp_alloc(dev, &request);
+ DRM_UNLOCK();
+
+ *(drm_agp_buffer_t *) data = request;
+
+ return retcode;
+}
+
+static drm_agp_mem_t * drm_agp_lookup_entry(drm_device_t *dev, void *handle)
+{
+ drm_agp_mem_t *entry;
+
+ for (entry = dev->agp->memory; entry; entry = entry->next) {
+ if (entry->handle == handle) return entry;
+ }
+ return NULL;
+}
+
+int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request)
+{
+ drm_agp_mem_t *entry;
+ int retcode;
+
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+
+ entry = drm_agp_lookup_entry(dev, (void *)request->handle);
+ if (entry == NULL || !entry->bound)
+ return EINVAL;
+
+ DRM_UNLOCK();
+ retcode = drm_agp_unbind_memory(entry->handle);
+ DRM_LOCK();
+
+ if (retcode == 0)
+ entry->bound = 0;
+
+ return retcode;
+}
+
+int drm_agp_unbind_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_agp_binding_t request;
+ int retcode;
+
+ request = *(drm_agp_binding_t *) data;
+
+ DRM_LOCK();
+ retcode = drm_agp_unbind(dev, &request);
+ DRM_UNLOCK();
+
+ return retcode;
+}
+
+int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request)
+{
+ drm_agp_mem_t *entry;
+ int retcode;
+ int page;
+
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+
+ DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE);
+
+ entry = drm_agp_lookup_entry(dev, (void *)request->handle);
+ if (entry == NULL || entry->bound)
+ return EINVAL;
+
+ page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ DRM_UNLOCK();
+ retcode = drm_agp_bind_memory(entry->handle, page);
+ DRM_LOCK();
+ if (retcode == 0)
+ entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+
+ return retcode;
+}
+
+int drm_agp_bind_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_agp_binding_t request;
+ int retcode;
+
+ request = *(drm_agp_binding_t *) data;
+
+ DRM_LOCK();
+ retcode = drm_agp_bind(dev, &request);
+ DRM_UNLOCK();
+
+ return retcode;
+}
+
+int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request)
+{
+ drm_agp_mem_t *entry;
+
+ if (!dev->agp || !dev->agp->acquired)
+ return EINVAL;
+
+ entry = drm_agp_lookup_entry(dev, (void*)request->handle);
+ if (entry == NULL)
+ return EINVAL;
+
+ if (entry->prev)
+ entry->prev->next = entry->next;
+ else
+ dev->agp->memory = entry->next;
+ if (entry->next)
+ entry->next->prev = entry->prev;
+
+ DRM_UNLOCK();
+ if (entry->bound)
+ drm_agp_unbind_memory(entry->handle);
+ drm_agp_free_memory(entry->handle);
+ DRM_LOCK();
+
+ free(entry, M_DRM);
+
+ return 0;
+
+}
+
+int drm_agp_free_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_agp_buffer_t request;
+ int retcode;
+
+ request = *(drm_agp_buffer_t *) data;
+
+ DRM_LOCK();
+ retcode = drm_agp_free(dev, &request);
+ DRM_UNLOCK();
+
+ return retcode;
+}
+
+drm_agp_head_t *drm_agp_init(void)
+{
+ device_t agpdev;
+ drm_agp_head_t *head = NULL;
+ int agp_available = 1;
+
+ agpdev = DRM_AGP_FIND_DEVICE();
+ if (!agpdev)
+ agp_available = 0;
+
+ DRM_DEBUG("agp_available = %d\n", agp_available);
+
+ if (agp_available) {
+ head = malloc(sizeof(*head), M_DRM, M_NOWAIT | M_ZERO);
+ if (head == NULL)
+ return NULL;
+ head->agpdev = agpdev;
+ agp_get_info(agpdev, &head->info);
+ head->memory = NULL;
+ DRM_INFO("AGP at 0x%08lx %dMB\n",
+ (long)head->info.ai_aperture_base,
+ (int)(head->info.ai_aperture_size >> 20));
+ }
+ return head;
+}
+
+void *drm_agp_allocate_memory(size_t pages, u32 type)
+{
+ device_t agpdev;
+
+ agpdev = DRM_AGP_FIND_DEVICE();
+ if (!agpdev)
+ return NULL;
+
+ return agp_alloc_memory(agpdev, type, pages << AGP_PAGE_SHIFT);
+}
+
+int drm_agp_free_memory(void *handle)
+{
+ device_t agpdev;
+
+ agpdev = DRM_AGP_FIND_DEVICE();
+ if (!agpdev || !handle)
+ return 0;
+
+ agp_free_memory(agpdev, handle);
+ return 1;
+}
+
+int drm_agp_bind_memory(void *handle, off_t start)
+{
+ device_t agpdev;
+
+ agpdev = DRM_AGP_FIND_DEVICE();
+ if (!agpdev || !handle)
+ return EINVAL;
+
+ return agp_bind_memory(agpdev, handle, start * PAGE_SIZE);
+}
+
+int drm_agp_unbind_memory(void *handle)
+{
+ device_t agpdev;
+
+ agpdev = DRM_AGP_FIND_DEVICE();
+ if (!agpdev || !handle)
+ return EINVAL;
+
+ return agp_unbind_memory(agpdev, handle);
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_atomic.h b/nx-X11/extras/drm/bsd-core/drm_atomic.h
new file mode 100644
index 000000000..b499fc967
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_atomic.h
@@ -0,0 +1,141 @@
+/**
+ * \file drm_atomic.h
+ * Atomic operations used in the DRM which may or may not be provided by the OS.
+ *
+ * \author Eric Anholt <anholt@FreeBSD.org>
+ */
+
+/*-
+ * Copyright 2004 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Many of these implementations are rather fake, but good enough. */
+
+typedef u_int32_t atomic_t;
+
+#ifdef __FreeBSD__
+#define atomic_set(p, v) (*(p) = (v))
+#define atomic_read(p) (*(p))
+#define atomic_inc(p) atomic_add_int(p, 1)
+#define atomic_dec(p) atomic_subtract_int(p, 1)
+#define atomic_add(n, p) atomic_add_int(p, n)
+#define atomic_sub(n, p) atomic_subtract_int(p, n)
+#else /* __FreeBSD__ */
+/* FIXME */
+#define atomic_set(p, v) (*(p) = (v))
+#define atomic_read(p) (*(p))
+#define atomic_inc(p) (*(p) += 1)
+#define atomic_dec(p) (*(p) -= 1)
+#define atomic_add(n, p) (*(p) += (n))
+#define atomic_sub(n, p) (*(p) -= (n))
+/* FIXME */
+#define atomic_add_int(p, v) *(p) += v
+#define atomic_subtract_int(p, v) *(p) -= v
+#define atomic_set_int(p, bits) *(p) |= (bits)
+#define atomic_clear_int(p, bits) *(p) &= ~(bits)
+#endif /* !__FreeBSD__ */
+
+#if !defined(__FreeBSD_version) || (__FreeBSD_version < 500000)
+#if defined(__i386__)
+/* The extra atomic functions from 5.0 haven't been merged to 4.x */
+static __inline int
+atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
+{
+ int res = exp;
+
+ __asm __volatile (
+ " lock ; "
+ " cmpxchgl %1,%2 ; "
+ " setz %%al ; "
+ " movzbl %%al,%0 ; "
+ "1: "
+ "# atomic_cmpset_int"
+ : "+a" (res) /* 0 (result) */
+ : "r" (src), /* 1 */
+ "m" (*(dst)) /* 2 */
+ : "memory");
+
+ return (res);
+}
+#else /* __i386__ */
+static __inline int
+atomic_cmpset_int(__volatile__ int *dst, int old, int new)
+{
+ int s = splhigh();
+ if (*dst==old) {
+ *dst = new;
+ splx(s);
+ return 1;
+ }
+ splx(s);
+ return 0;
+}
+#endif /* !__i386__ */
+#endif /* !__FreeBSD_version || __FreeBSD_version < 500000 */
+
+static __inline atomic_t
+test_and_set_bit(int b, volatile void *p)
+{
+ int s = splhigh();
+ unsigned int m = 1<<b;
+ unsigned int r = *(volatile int *)p & m;
+ *(volatile int *)p |= m;
+ splx(s);
+ return r;
+}
+
+static __inline void
+clear_bit(int b, volatile void *p)
+{
+ atomic_clear_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
+}
+
+static __inline void
+set_bit(int b, volatile void *p)
+{
+ atomic_set_int(((volatile int *)p) + (b >> 5), 1 << (b & 0x1f));
+}
+
+static __inline int
+test_bit(int b, volatile void *p)
+{
+ return ((volatile int *)p)[b >> 5] & (1 << (b & 0x1f));
+}
+
+static __inline int
+find_first_zero_bit(volatile void *p, int max)
+{
+ int b;
+ volatile int *ptr = (volatile int *)p;
+
+ for (b = 0; b < max; b += 32) {
+ if (ptr[b >> 5] != ~0) {
+ for (;;) {
+ if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0)
+ return b;
+ b++;
+ }
+ }
+ }
+ return max;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_auth.c b/nx-X11/extras/drm/bsd-core/drm_auth.c
new file mode 100644
index 000000000..aa0e29c0c
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_auth.c
@@ -0,0 +1,172 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+static int drm_hash_magic(drm_magic_t magic)
+{
+ return magic & (DRM_HASH_SIZE-1);
+}
+
+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;
+
+ hash = drm_hash_magic(magic);
+
+ DRM_LOCK();
+ for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+ if (pt->magic == magic) {
+ retval = pt->priv;
+ break;
+ }
+ }
+ DRM_UNLOCK();
+ return retval;
+}
+
+static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+{
+ int hash;
+ drm_magic_entry_t *entry;
+
+ DRM_DEBUG("%d\n", magic);
+
+ hash = drm_hash_magic(magic);
+ entry = malloc(sizeof(*entry), M_DRM, M_ZERO | M_NOWAIT);
+ if (!entry) return DRM_ERR(ENOMEM);
+ entry->magic = magic;
+ entry->priv = priv;
+ entry->next = NULL;
+
+ DRM_LOCK();
+ if (dev->magiclist[hash].tail) {
+ dev->magiclist[hash].tail->next = entry;
+ dev->magiclist[hash].tail = entry;
+ } else {
+ dev->magiclist[hash].head = entry;
+ dev->magiclist[hash].tail = entry;
+ }
+ DRM_UNLOCK();
+
+ return 0;
+}
+
+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_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) {
+ dev->magiclist[hash].head = pt->next;
+ }
+ if (dev->magiclist[hash].tail == pt) {
+ dev->magiclist[hash].tail = prev;
+ }
+ if (prev) {
+ prev->next = pt->next;
+ }
+ DRM_UNLOCK();
+ return 0;
+ }
+ }
+ DRM_UNLOCK();
+
+ free(pt, M_DRM);
+ return DRM_ERR(EINVAL);
+}
+
+int drm_getmagic(DRM_IOCTL_ARGS)
+{
+ 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;
+ }
+
+ /* Find unique magic */
+ if (priv->magic) {
+ auth.magic = priv->magic;
+ } else {
+ do {
+ int old = sequence;
+
+ 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);
+ }
+
+ DRM_DEBUG("%u\n", auth.magic);
+
+ DRM_COPY_TO_USER_IOCTL((drm_auth_t *)data, auth, sizeof(auth));
+
+ return 0;
+}
+
+int drm_authmagic(DRM_IOCTL_ARGS)
+{
+ drm_auth_t auth;
+ drm_file_t *file;
+ DRM_DEVICE;
+
+ DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth));
+
+ DRM_DEBUG("%u\n", auth.magic);
+
+ if ((file = drm_find_file(dev, auth.magic))) {
+ file->authenticated = 1;
+ drm_remove_magic(dev, auth.magic);
+ return 0;
+ }
+ return DRM_ERR(EINVAL);
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_bufs.c b/nx-X11/extras/drm/bsd-core/drm_bufs.c
new file mode 100644
index 000000000..93bcc8121
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_bufs.c
@@ -0,0 +1,1125 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "dev/pci/pcireg.h"
+
+#include "drmP.h"
+
+/*
+ * Compute order. Can be made faster.
+ */
+int drm_order(unsigned long size)
+{
+ int order;
+ unsigned long tmp;
+
+ for ( order = 0, tmp = size ; tmp >>= 1 ; ++order );
+
+ if ( size & ~(1 << order) )
+ ++order;
+
+ return order;
+}
+
+/* Allocation of PCI memory resources (framebuffer, registers, etc.) for
+ * drm_get_resource_*. Note that they are not RF_ACTIVE, so there's no virtual
+ * address for accessing them. Cleaned up at unload.
+ */
+static int drm_alloc_resource(drm_device_t *dev, int resource)
+{
+ if (resource >= DRM_MAX_PCI_RESOURCE) {
+ DRM_ERROR("Resource %d too large\n", resource);
+ return 1;
+ }
+ if (dev->pcir[resource] != NULL)
+ return 0;
+
+ dev->pcirid[resource] = PCIR_BAR(resource);
+ dev->pcir[resource] = bus_alloc_resource_any(dev->device,
+ SYS_RES_MEMORY, &dev->pcirid[resource], RF_SHAREABLE);
+
+ if (dev->pcir[resource] == NULL) {
+ DRM_ERROR("Couldn't find resource 0x%x\n", resource);
+ return 1;
+ }
+
+ return 0;
+}
+
+unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
+{
+ if (drm_alloc_resource(dev, resource) != 0)
+ return 0;
+
+ return rman_get_start(dev->pcir[resource]);
+}
+
+unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
+{
+ if (drm_alloc_resource(dev, resource) != 0)
+ return 0;
+
+ return rman_get_size(dev->pcir[resource]);
+}
+
+int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
+ drm_map_type_t type, drm_map_flags_t flags, drm_local_map_t **map_ptr)
+{
+ drm_local_map_t *map;
+ int align;
+ /*drm_agp_mem_t *entry;
+ int valid;*/
+
+ /* Only allow shared memory to be removable since we only keep enough
+ * book keeping information about shared memory to allow for removal
+ * when processes fork.
+ */
+ if ((flags & _DRM_REMOVABLE) && type != _DRM_SHM) {
+ DRM_ERROR("Requested removable map for non-DRM_SHM\n");
+ return EINVAL;
+ }
+ if ((offset & PAGE_MASK) || (size & PAGE_MASK)) {
+ DRM_ERROR("offset/size not page aligned: 0x%lx/0x%lx\n",
+ offset, size);
+ return EINVAL;
+ }
+ if (offset + size < offset) {
+ DRM_ERROR("offset and size wrap around: 0x%lx/0x%lx\n",
+ offset, size);
+ return EINVAL;
+ }
+
+ DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", offset,
+ size, type);
+
+ /* Check if this is just another version of a kernel-allocated map, and
+ * just hand that back if so.
+ */
+ if (type == _DRM_REGISTERS || type == _DRM_FRAME_BUFFER ||
+ type == _DRM_SHM) {
+ TAILQ_FOREACH(map, &dev->maplist, link) {
+ if (map->type == type && (map->offset == offset ||
+ (map->type == _DRM_SHM &&
+ map->flags == _DRM_CONTAINS_LOCK))) {
+ map->size = size;
+ DRM_DEBUG("Found kernel map %d\n", type);
+ goto done;
+ }
+ }
+ }
+ DRM_UNLOCK();
+
+ /* Allocate a new map structure, fill it in, and do any type-specific
+ * initialization necessary.
+ */
+ map = malloc(sizeof(*map), M_DRM, M_ZERO | M_NOWAIT);
+ if ( !map )
+ return DRM_ERR(ENOMEM);
+
+ map->offset = offset;
+ map->size = size;
+ map->type = type;
+ map->flags = flags;
+
+ switch ( map->type ) {
+ case _DRM_REGISTERS:
+ map->handle = drm_ioremap(dev, map);
+ if (!(map->flags & _DRM_WRITE_COMBINING))
+ break;
+ /* FALLTHROUGH */
+ case _DRM_FRAME_BUFFER:
+ if (drm_mtrr_add(map->offset, map->size, DRM_MTRR_WC) == 0)
+ map->mtrr = 1;
+ break;
+ case _DRM_SHM:
+ map->handle = malloc(map->size, M_DRM, M_NOWAIT);
+ DRM_DEBUG( "%lu %d %p\n",
+ map->size, drm_order(map->size), map->handle );
+ if ( !map->handle ) {
+ free(map, M_DRM);
+ return DRM_ERR(ENOMEM);
+ }
+ map->offset = (unsigned long)map->handle;
+ if ( map->flags & _DRM_CONTAINS_LOCK ) {
+ /* Prevent a 2nd X Server from creating a 2nd lock */
+ DRM_LOCK();
+ if (dev->lock.hw_lock != NULL) {
+ DRM_UNLOCK();
+ free(map->handle, M_DRM);
+ free(map, M_DRM);
+ return DRM_ERR(EBUSY);
+ }
+ dev->lock.hw_lock = map->handle; /* Pointer to lock */
+ DRM_UNLOCK();
+ }
+ break;
+ case _DRM_AGP:
+ /*valid = 0;*/
+ 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) &&
+ (map->offset + map->size <=
+ entry->bound + entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid) {
+ free(map, M_DRM);
+ return DRM_ERR(EACCES);
+ }*/
+ break;
+ case _DRM_SCATTER_GATHER:
+ if (!dev->sg) {
+ free(map, M_DRM);
+ return DRM_ERR(EINVAL);
+ }
+ map->offset = map->offset + dev->sg->handle;
+ break;
+ case _DRM_CONSISTENT:
+ /* Unfortunately, we don't get any alignment specification from
+ * the caller, so we have to guess. drm_pci_alloc requires
+ * a power-of-two alignment, so try to align the bus address of
+ * the map to it size if possible, otherwise just assume
+ * PAGE_SIZE alignment.
+ */
+ align = map->size;
+ if ((align & (align - 1)) != 0)
+ align = PAGE_SIZE;
+ map->dmah = drm_pci_alloc(dev, map->size, align, 0xfffffffful);
+ if (map->dmah == NULL) {
+ free(map, M_DRM);
+ return DRM_ERR(ENOMEM);
+ }
+ map->handle = map->dmah->vaddr;
+ map->offset = map->dmah->busaddr;
+ break;
+ default:
+ DRM_ERROR("Bad map type %d\n", map->type);
+ free(map, M_DRM);
+ return DRM_ERR(EINVAL);
+ }
+
+ DRM_LOCK();
+ TAILQ_INSERT_TAIL(&dev->maplist, map, link);
+
+done:
+ /* Jumped to, with lock held, when a kernel map is found. */
+
+ DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", map->type, map->offset,
+ map->size);
+
+ *map_ptr = map;
+
+ return 0;
+}
+
+int drm_addmap_ioctl(DRM_IOCTL_ARGS)
+{
+ drm_map_t request;
+ drm_local_map_t *map;
+ int err;
+ DRM_DEVICE;
+
+ if (!(dev->flags & (FREAD|FWRITE)))
+ return DRM_ERR(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);
+
+ DRM_LOCK();
+ 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;
+
+ 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;
+}
+
+void drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
+{
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
+ TAILQ_REMOVE(&dev->maplist, map, link);
+
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ if (map->bsr == NULL)
+ drm_ioremapfree(map);
+ /* FALLTHROUGH */
+ case _DRM_FRAME_BUFFER:
+ if (map->mtrr) {
+ int __unused retcode;
+
+ retcode = drm_mtrr_del(map->offset, map->size,
+ DRM_MTRR_WC);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+ break;
+ case _DRM_SHM:
+ free(map->handle, M_DRM);
+ break;
+ case _DRM_AGP:
+ case _DRM_SCATTER_GATHER:
+ break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->dmah);
+ break;
+ }
+
+ if (map->bsr != NULL) {
+ bus_release_resource(dev->device, SYS_RES_MEMORY, map->rid,
+ map->bsr);
+ }
+
+ free(map, M_DRM);
+}
+
+/* Remove a map private from list and deallocate resources if the mapping
+ * isn't in use.
+ */
+
+int drm_rmmap_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_local_map_t *map;
+ drm_map_t request;
+
+ DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) );
+
+ DRM_LOCK();
+ TAILQ_FOREACH(map, &dev->maplist, link) {
+ if (map->handle == request.handle &&
+ map->flags & _DRM_REMOVABLE)
+ break;
+ }
+
+ /* No match found. */
+ if (map == NULL) {
+ DRM_UNLOCK();
+ return DRM_ERR(EINVAL);
+ }
+
+ drm_rmmap(dev, map);
+
+ DRM_UNLOCK();
+
+ return 0;
+}
+
+
+static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
+{
+ int i;
+
+ if (entry->seg_count) {
+ for (i = 0; i < entry->seg_count; i++) {
+ drm_pci_free(dev, entry->seglist[i]);
+ }
+ free(entry->seglist, M_DRM);
+
+ entry->seg_count = 0;
+ }
+
+ if (entry->buf_count) {
+ for (i = 0; i < entry->buf_count; i++) {
+ free(entry->buflist[i].dev_private, M_DRM);
+ }
+ free(entry->buflist, M_DRM);
+
+ entry->buf_count = 0;
+ }
+}
+
+static int drm_do_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_entry_t *entry;
+ /*drm_agp_mem_t *agp_entry;
+ int valid*/
+ drm_buf_t *buf;
+ unsigned long offset;
+ unsigned long agp_offset;
+ int count;
+ int order;
+ int size;
+ int alignment;
+ int page_order;
+ int total;
+ int byte_count;
+ int i;
+ drm_buf_t **temp_buflist;
+
+ count = request->count;
+ order = drm_order(request->size);
+ size = 1 << order;
+
+ alignment = (request->flags & _DRM_PAGE_ALIGN)
+ ? round_page(size) : size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ byte_count = 0;
+ agp_offset = dev->agp->base + request->agp_start;
+
+ DRM_DEBUG( "count: %d\n", count );
+ DRM_DEBUG( "order: %d\n", order );
+ DRM_DEBUG( "size: %d\n", size );
+ DRM_DEBUG( "agp_offset: 0x%lx\n", agp_offset );
+ DRM_DEBUG( "alignment: %d\n", alignment );
+ DRM_DEBUG( "page_order: %d\n", page_order );
+ DRM_DEBUG( "total: %d\n", total );
+
+ /* Make sure buffers are located in AGP memory that we own */
+ /* Breaks MGA due to drm_alloc_agp not setting up entries for the
+ * memory. Safe to ignore for now because these ioctls are still
+ * root-only.
+ */
+ /*valid = 0;
+ for (agp_entry = dev->agp->memory; agp_entry;
+ agp_entry = agp_entry->next) {
+ if ((agp_offset >= agp_entry->bound) &&
+ (agp_offset + total * count <=
+ agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid) {
+ DRM_DEBUG("zone invalid\n");
+ return DRM_ERR(EINVAL);
+ }*/
+
+ entry = &dma->bufs[order];
+
+ entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
+ M_NOWAIT | M_ZERO);
+ if ( !entry->buflist ) {
+ return DRM_ERR(ENOMEM);
+ }
+
+ entry->buf_size = size;
+ entry->page_order = page_order;
+
+ offset = 0;
+
+ while ( entry->buf_count < count ) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+
+ buf->offset = (dma->byte_count + offset);
+ buf->bus_address = agp_offset + offset;
+ buf->address = (void *)(agp_offset + offset);
+ buf->next = NULL;
+ buf->pending = 0;
+ buf->filp = NULL;
+
+ buf->dev_priv_size = dev->driver.buf_priv_size;
+ buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
+ M_NOWAIT | M_ZERO);
+ if (buf->dev_private == NULL) {
+ /* Set count correctly so we free the proper amount. */
+ entry->buf_count = count;
+ drm_cleanup_buf_error(dev, entry);
+ return DRM_ERR(ENOMEM);
+ }
+
+ offset += alignment;
+ entry->buf_count++;
+ byte_count += PAGE_SIZE << page_order;
+ }
+
+ DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+ temp_buflist = realloc(dma->buflist,
+ (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), M_DRM,
+ M_NOWAIT);
+ if (temp_buflist == NULL) {
+ /* Free the entry because it isn't valid */
+ drm_cleanup_buf_error(dev, entry);
+ return DRM_ERR(ENOMEM);
+ }
+ dma->buflist = temp_buflist;
+
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ }
+
+ dma->buf_count += entry->buf_count;
+ dma->byte_count += byte_count;
+
+ DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+ DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+ request->count = entry->buf_count;
+ request->size = size;
+
+ dma->flags = _DRM_DMA_USE_AGP;
+
+ return 0;
+}
+
+static int drm_do_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int count;
+ int order;
+ int size;
+ int total;
+ int page_order;
+ drm_buf_entry_t *entry;
+ drm_buf_t *buf;
+ int alignment;
+ unsigned long offset;
+ int i;
+ int byte_count;
+ int page_count;
+ unsigned long *temp_pagelist;
+ drm_buf_t **temp_buflist;
+
+ count = request->count;
+ order = drm_order(request->size);
+ size = 1 << order;
+
+ DRM_DEBUG( "count=%d, size=%d (%d), order=%d\n",
+ request->count, request->size, size, order );
+
+ alignment = (request->flags & _DRM_PAGE_ALIGN)
+ ? round_page(size) : size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ entry = &dma->bufs[order];
+
+ entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
+ M_NOWAIT | M_ZERO);
+ entry->seglist = malloc(count * sizeof(*entry->seglist), M_DRM,
+ M_NOWAIT | M_ZERO);
+
+ /* Keep the original pagelist until we know all the allocations
+ * have succeeded
+ */
+ temp_pagelist = malloc((dma->page_count + (count << page_order)) *
+ sizeof(*dma->pagelist), M_DRM, M_NOWAIT);
+
+ if (entry->buflist == NULL || entry->seglist == NULL ||
+ temp_pagelist == NULL) {
+ free(entry->buflist, M_DRM);
+ free(entry->seglist, M_DRM);
+ return DRM_ERR(ENOMEM);
+ }
+
+ memcpy(temp_pagelist, dma->pagelist, dma->page_count *
+ sizeof(*dma->pagelist));
+
+ DRM_DEBUG( "pagelist: %d entries\n",
+ dma->page_count + (count << page_order) );
+
+ entry->buf_size = size;
+ entry->page_order = page_order;
+ byte_count = 0;
+ page_count = 0;
+
+ while ( entry->buf_count < count ) {
+ drm_dma_handle_t *dmah = drm_pci_alloc(dev, size, alignment,
+ 0xfffffffful);
+ if (dmah == NULL) {
+ /* Set count correctly so we free the proper amount. */
+ entry->buf_count = count;
+ entry->seg_count = count;
+ drm_cleanup_buf_error(dev, entry);
+ free(temp_pagelist, M_DRM);
+ return DRM_ERR(ENOMEM);
+ }
+
+ entry->seglist[entry->seg_count++] = dmah;
+ for ( i = 0 ; i < (1 << page_order) ; i++ ) {
+ DRM_DEBUG( "page %d @ %p\n",
+ dma->page_count + page_count,
+ (char *)dmah->vaddr + PAGE_SIZE * i );
+ temp_pagelist[dma->page_count + page_count++] =
+ (long)dmah->vaddr + PAGE_SIZE * i;
+ }
+ for ( offset = 0 ;
+ offset + size <= total && entry->buf_count < count ;
+ offset += alignment, ++entry->buf_count ) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+ buf->offset = (dma->byte_count + byte_count + offset);
+ buf->address = ((char *)dmah->vaddr + offset);
+ buf->bus_address = dmah->busaddr + offset;
+ buf->next = NULL;
+ buf->pending = 0;
+ buf->filp = NULL;
+
+ buf->dev_priv_size = dev->driver.buf_priv_size;
+ buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
+ M_NOWAIT | M_ZERO);
+ if (buf->dev_private == NULL) {
+ /* Set count correctly so we free the proper amount. */
+ entry->buf_count = count;
+ entry->seg_count = count;
+ drm_cleanup_buf_error(dev, entry);
+ free(temp_pagelist, M_DRM);
+ return DRM_ERR(ENOMEM);
+ }
+
+ DRM_DEBUG( "buffer %d @ %p\n",
+ entry->buf_count, buf->address );
+ }
+ byte_count += PAGE_SIZE << page_order;
+ }
+
+ temp_buflist = realloc(dma->buflist,
+ (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), M_DRM,
+ M_NOWAIT);
+ if (temp_buflist == NULL) {
+ /* Free the entry because it isn't valid */
+ drm_cleanup_buf_error(dev, entry);
+ free(temp_pagelist, M_DRM);
+ return DRM_ERR(ENOMEM);
+ }
+ dma->buflist = temp_buflist;
+
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ }
+
+ /* No allocations failed, so now we can replace the orginal pagelist
+ * with the new one.
+ */
+ free(dma->pagelist, M_DRM);
+ dma->pagelist = temp_pagelist;
+
+ dma->buf_count += entry->buf_count;
+ dma->seg_count += entry->seg_count;
+ dma->page_count += entry->seg_count << page_order;
+ dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+
+ request->count = entry->buf_count;
+ request->size = size;
+
+ return 0;
+
+}
+
+static int drm_do_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
+{
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_entry_t *entry;
+ drm_buf_t *buf;
+ unsigned long offset;
+ unsigned long agp_offset;
+ int count;
+ int order;
+ int size;
+ int alignment;
+ int page_order;
+ int total;
+ int byte_count;
+ int i;
+ drm_buf_t **temp_buflist;
+
+ count = request->count;
+ order = drm_order(request->size);
+ size = 1 << order;
+
+ alignment = (request->flags & _DRM_PAGE_ALIGN)
+ ? round_page(size) : size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ byte_count = 0;
+ agp_offset = request->agp_start;
+
+ DRM_DEBUG( "count: %d\n", count );
+ DRM_DEBUG( "order: %d\n", order );
+ DRM_DEBUG( "size: %d\n", size );
+ DRM_DEBUG( "agp_offset: %ld\n", agp_offset );
+ DRM_DEBUG( "alignment: %d\n", alignment );
+ DRM_DEBUG( "page_order: %d\n", page_order );
+ DRM_DEBUG( "total: %d\n", total );
+
+ entry = &dma->bufs[order];
+
+ entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
+ M_NOWAIT | M_ZERO);
+ if (entry->buflist == NULL)
+ return DRM_ERR(ENOMEM);
+
+ entry->buf_size = size;
+ entry->page_order = page_order;
+
+ offset = 0;
+
+ while ( entry->buf_count < count ) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dma->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+
+ buf->offset = (dma->byte_count + offset);
+ buf->bus_address = agp_offset + offset;
+ buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+ buf->next = NULL;
+ buf->pending = 0;
+ buf->filp = NULL;
+
+ buf->dev_priv_size = dev->driver.buf_priv_size;
+ buf->dev_private = malloc(buf->dev_priv_size, M_DRM,
+ M_NOWAIT | M_ZERO);
+ if (buf->dev_private == NULL) {
+ /* Set count correctly so we free the proper amount. */
+ entry->buf_count = count;
+ drm_cleanup_buf_error(dev, entry);
+ return DRM_ERR(ENOMEM);
+ }
+
+ DRM_DEBUG( "buffer %d @ %p\n",
+ entry->buf_count, buf->address );
+
+ offset += alignment;
+ entry->buf_count++;
+ byte_count += PAGE_SIZE << page_order;
+ }
+
+ DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+ temp_buflist = realloc(dma->buflist,
+ (dma->buf_count + entry->buf_count) * sizeof(*dma->buflist), M_DRM,
+ M_NOWAIT);
+ if (temp_buflist == NULL) {
+ /* Free the entry because it isn't valid */
+ drm_cleanup_buf_error(dev, entry);
+ return DRM_ERR(ENOMEM);
+ }
+ dma->buflist = temp_buflist;
+
+ for ( i = 0 ; i < entry->buf_count ; i++ ) {
+ dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+ }
+
+ dma->buf_count += entry->buf_count;
+ dma->byte_count += byte_count;
+
+ DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+ DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+ request->count = entry->buf_count;
+ request->size = size;
+
+ dma->flags = _DRM_DMA_USE_SG;
+
+ return 0;
+}
+
+int drm_addbufs_agp(drm_device_t *dev, drm_buf_desc_t *request)
+{
+ int order, ret;
+
+ DRM_SPINLOCK(&dev->dma_lock);
+
+ if (request->count < 0 || request->count > 4096)
+ return DRM_ERR(EINVAL);
+
+ order = drm_order(request->size);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return DRM_ERR(EINVAL);
+
+ /* No more allocations after first buffer-using ioctl. */
+ if (dev->buf_use != 0) {
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ return DRM_ERR(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);
+ }
+
+ ret = drm_do_addbufs_agp(dev, request);
+
+ DRM_SPINUNLOCK(&dev->dma_lock);
+
+ return ret;
+}
+
+int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
+{
+ int order, ret;
+
+ DRM_SPINLOCK(&dev->dma_lock);
+
+ if (!DRM_SUSER(DRM_CURPROC))
+ return DRM_ERR(EACCES);
+
+ if (request->count < 0 || request->count > 4096)
+ return DRM_ERR(EINVAL);
+
+ order = drm_order(request->size);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return DRM_ERR(EINVAL);
+
+ /* No more allocations after first buffer-using ioctl. */
+ if (dev->buf_use != 0) {
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ return DRM_ERR(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);
+ }
+
+ ret = drm_do_addbufs_sg(dev, request);
+
+ DRM_SPINUNLOCK(&dev->dma_lock);
+
+ return ret;
+}
+
+int drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
+{
+ int order, ret;
+
+ DRM_SPINLOCK(&dev->dma_lock);
+
+ if (!DRM_SUSER(DRM_CURPROC))
+ return DRM_ERR(EACCES);
+
+ if (request->count < 0 || request->count > 4096)
+ return DRM_ERR(EINVAL);
+
+ order = drm_order(request->size);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+ return DRM_ERR(EINVAL);
+
+ /* No more allocations after first buffer-using ioctl. */
+ if (dev->buf_use != 0) {
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ return DRM_ERR(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);
+ }
+
+ ret = drm_do_addbufs_pci(dev, request);
+
+ DRM_SPINUNLOCK(&dev->dma_lock);
+
+ return ret;
+}
+
+int drm_addbufs_ioctl(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_buf_desc_t request;
+ 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);
+ else
+ err = drm_addbufs_pci(dev, &request);
+
+ DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request,
+ sizeof(request));
+
+ return err;
+}
+
+int drm_infobufs(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_info_t request;
+ 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);
+
+ for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+ if ( dma->bufs[i].buf_count ) ++count;
+ }
+
+ DRM_DEBUG( "count = %d\n", 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;
+
+ from.count = dma->bufs[i].buf_count;
+ from.size = dma->bufs[i].buf_size;
+ 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,
+ sizeof(drm_buf_desc_t)) != 0) {
+ retcode = DRM_ERR(EFAULT);
+ break;
+ }
+
+ DRM_DEBUG( "%d %d %d %d %d\n",
+ i,
+ dma->bufs[i].buf_count,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].freelist.low_mark,
+ dma->bufs[i].freelist.high_mark );
+ ++count;
+ }
+ }
+ }
+ request.count = count;
+
+ DRM_COPY_TO_USER_IOCTL( (drm_buf_info_t *)data, request, sizeof(request) );
+
+ return retcode;
+}
+
+int drm_markbufs(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_desc_t request;
+ 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 );
+
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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)
+{
+ DRM_DEVICE;
+ drm_device_dma_t *dma = dev->dma;
+ drm_buf_free_t request;
+ 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_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);
+ 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);
+ break;
+ }
+ buf = dma->buflist[idx];
+ if ( buf->filp != filp ) {
+ DRM_ERROR("Process %d freeing buffer not owned\n",
+ DRM_CURRENTPID);
+ retcode = DRM_ERR(EINVAL);
+ break;
+ }
+ drm_free_buffer(dev, buf);
+ }
+ DRM_SPINUNLOCK(&dev->dma_lock);
+
+ return retcode;
+}
+
+int drm_mapbufs(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_device_dma_t *dma = dev->dma;
+ int retcode = 0;
+ const int zero = 0;
+ vm_offset_t address;
+ struct vmspace *vms;
+#ifdef __FreeBSD__
+ vm_ooffset_t foff;
+ vm_size_t size;
+ vm_offset_t vaddr;
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ struct vnode *vn;
+ voff_t foff;
+ vsize_t size;
+ vaddr_t vaddr;
+#endif /* __NetBSD__ || __OpenBSD__ */
+
+ drm_buf_map_t request;
+ 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;
+#else
+ vms = p->p_vmspace;
+#endif
+
+ DRM_SPINLOCK(&dev->dma_lock);
+ dev->buf_use++; /* Can't allocate more after this call */
+ DRM_SPINUNLOCK(&dev->dma_lock);
+
+ if (request.count < dma->buf_count)
+ goto done;
+
+ if ((dev->driver.use_agp && (dma->flags & _DRM_DMA_USE_AGP)) ||
+ (dev->driver.use_sg && (dma->flags & _DRM_DMA_USE_SG))) {
+ drm_local_map_t *map = dev->agp_buffer_map;
+
+ if (map == NULL) {
+ retcode = EINVAL;
+ goto done;
+ }
+ size = round_page(map->size);
+ foff = map->offset;
+ } else {
+ size = round_page(dma->byte_count),
+ foff = 0;
+ }
+
+#ifdef __FreeBSD__
+ 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 );
+#else
+ retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
+ VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&kdev->si_hlist), foff );
+#endif
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
+ retcode = uvm_mmap(&vms->vm_map, &vaddr, size,
+ UVM_PROT_READ | UVM_PROT_WRITE, UVM_PROT_ALL, MAP_SHARED,
+ &vn->v_uobj, foff, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
+#endif /* __NetBSD__ || __OpenBSD */
+ if (retcode)
+ goto done;
+
+ 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))) {
+ retcode = EFAULT;
+ goto done;
+ }
+ 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,
+ sizeof(zero))) {
+ retcode = EFAULT;
+ goto done;
+ }
+ address = vaddr + dma->buflist[i]->offset; /* *** */
+ if (DRM_COPY_TO_USER(&request.list[i].address, &address,
+ sizeof(address))) {
+ retcode = EFAULT;
+ goto done;
+ }
+ }
+
+ done:
+ request.count = dma->buf_count;
+
+ DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
+
+ DRM_COPY_TO_USER_IOCTL((drm_buf_map_t *)data, request, sizeof(request));
+
+ return DRM_ERR(retcode);
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_context.c b/nx-X11/extras/drm/bsd-core/drm_context.c
new file mode 100644
index 000000000..8e0095403
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_context.c
@@ -0,0 +1,345 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+/* ================================================================
+ * Context bitmap support
+ */
+
+void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle)
+{
+ if (ctx_handle < 0 || ctx_handle >= DRM_MAX_CTXBITMAP ||
+ dev->ctx_bitmap == NULL) {
+ DRM_ERROR("Attempt to free invalid context handle: %d\n",
+ ctx_handle);
+ return;
+ }
+
+ DRM_LOCK();
+ clear_bit(ctx_handle, dev->ctx_bitmap);
+ dev->context_sareas[ctx_handle] = NULL;
+ DRM_UNLOCK();
+ return;
+}
+
+int drm_ctxbitmap_next(drm_device_t *dev)
+{
+ int bit;
+
+ if (dev->ctx_bitmap == NULL)
+ return -1;
+
+ DRM_LOCK();
+ bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
+ if (bit >= DRM_MAX_CTXBITMAP) {
+ DRM_UNLOCK();
+ return -1;
+ }
+
+ set_bit(bit, dev->ctx_bitmap);
+ DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
+ if ((bit+1) > dev->max_context) {
+ dev->max_context = (bit+1);
+ if (dev->context_sareas != NULL) {
+ drm_local_map_t **ctx_sareas;
+
+ ctx_sareas = realloc(dev->context_sareas,
+ dev->max_context * sizeof(*dev->context_sareas),
+ M_DRM, M_NOWAIT);
+ if (ctx_sareas == NULL) {
+ clear_bit(bit, dev->ctx_bitmap);
+ DRM_UNLOCK();
+ return -1;
+ }
+ dev->context_sareas = ctx_sareas;
+ dev->context_sareas[bit] = NULL;
+ } else {
+ /* max_context == 1 at this point */
+ dev->context_sareas = malloc(dev->max_context *
+ sizeof(*dev->context_sareas), M_DRM, M_NOWAIT);
+ if (dev->context_sareas == NULL) {
+ clear_bit(bit, dev->ctx_bitmap);
+ DRM_UNLOCK();
+ return -1;
+ }
+ dev->context_sareas[bit] = NULL;
+ }
+ }
+ DRM_UNLOCK();
+ return bit;
+}
+
+int drm_ctxbitmap_init(drm_device_t *dev)
+{
+ int i;
+ int temp;
+
+ DRM_LOCK();
+ dev->ctx_bitmap = malloc(PAGE_SIZE, M_DRM, M_NOWAIT | M_ZERO);
+ if ( dev->ctx_bitmap == NULL ) {
+ DRM_UNLOCK();
+ return DRM_ERR(ENOMEM);
+ }
+ dev->context_sareas = NULL;
+ dev->max_context = -1;
+ DRM_UNLOCK();
+
+ for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+ temp = drm_ctxbitmap_next(dev);
+ DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
+ }
+
+ return 0;
+}
+
+void drm_ctxbitmap_cleanup(drm_device_t *dev)
+{
+ DRM_LOCK();
+ if (dev->context_sareas != NULL)
+ free(dev->context_sareas, M_DRM);
+ free(dev->ctx_bitmap, M_DRM);
+ DRM_UNLOCK();
+}
+
+/* ================================================================
+ * Per Context SAREA Support
+ */
+
+int drm_getsareactx( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_ctx_priv_map_t request;
+ 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) {
+ DRM_UNLOCK();
+ return DRM_ERR(EINVAL);
+ }
+
+ 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) );
+
+ return 0;
+}
+
+int drm_setsareactx( DRM_IOCTL_ARGS )
+{
+ DRM_DEVICE;
+ drm_ctx_priv_map_t request;
+ 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 (dev->max_context < 0)
+ goto bad;
+ if (request.ctx_id >= (unsigned) dev->max_context)
+ goto bad;
+ dev->context_sareas[request.ctx_id] = map;
+ DRM_UNLOCK();
+ return 0;
+ }
+ }
+
+bad:
+ DRM_UNLOCK();
+ return DRM_ERR(EINVAL);
+}
+
+/* ================================================================
+ * The actual DRM context handling routines
+ */
+
+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);
+ }
+
+ DRM_DEBUG( "Context switch from %d to %d\n", old, new );
+
+ if ( new == dev->last_context ) {
+ clear_bit( 0, &dev->context_flag );
+ return 0;
+ }
+
+ return 0;
+}
+
+int drm_context_switch_complete(drm_device_t *dev, int new)
+{
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+
+ if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
+ DRM_ERROR( "Lock isn't held after context switch\n" );
+ }
+
+ /* If a context switch is ever initiated
+ when the kernel holds the lock, release
+ that lock here. */
+ clear_bit( 0, &dev->context_flag );
+
+ return 0;
+}
+
+int drm_resctx(DRM_IOCTL_ARGS)
+{
+ drm_ctx_res_t res;
+ 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 ) {
+ bzero(&ctx, sizeof(ctx));
+ for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+ ctx.handle = i;
+ if ( DRM_COPY_TO_USER( &res.contexts[i],
+ &ctx, sizeof(ctx) ) )
+ return DRM_ERR(EFAULT);
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+
+ DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) );
+
+ return 0;
+}
+
+int drm_addctx(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_ctx_t ctx;
+
+ DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+
+ 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);
+ }
+ 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);
+ }
+
+ if (dev->driver.context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) {
+ DRM_LOCK();
+ 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)
+{
+ /* This does nothing */
+ return 0;
+}
+
+int drm_getctx(DRM_IOCTL_ARGS)
+{
+ drm_ctx_t ctx;
+
+ DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+
+ /* 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) );
+
+ return 0;
+}
+
+int drm_switchctx(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_ctx_t ctx;
+
+ 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);
+}
+
+int drm_newctx(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_ctx_t ctx;
+
+ DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+
+ DRM_DEBUG( "%d\n", ctx.handle );
+ drm_context_switch_complete(dev, ctx.handle);
+
+ return 0;
+}
+
+int drm_rmctx(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_ctx_t ctx;
+
+ DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
+
+ 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);
+ DRM_UNLOCK();
+ }
+
+ drm_ctxbitmap_free(dev, ctx.handle);
+ }
+
+ return 0;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_dma.c b/nx-X11/extras/drm/bsd-core/drm_dma.c
new file mode 100644
index 000000000..67b3fe2d4
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_dma.c
@@ -0,0 +1,130 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+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);
+
+ DRM_SPININIT(dev->dma_lock, "drmdma");
+
+ return 0;
+}
+
+void drm_dma_takedown(drm_device_t *dev)
+{
+ drm_device_dma_t *dma = dev->dma;
+ int i, j;
+
+ if (dma == NULL)
+ return;
+
+ /* Clear dma buffers */
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dma->bufs[i].seg_count) {
+ DRM_DEBUG("order %d: buf_count = %d,"
+ " seg_count = %d\n",
+ i,
+ dma->bufs[i].buf_count,
+ dma->bufs[i].seg_count);
+ for (j = 0; j < dma->bufs[i].seg_count; j++) {
+ drm_pci_free(dev, dma->bufs[i].seglist[j]);
+ }
+ free(dma->bufs[i].seglist, M_DRM);
+ }
+
+ if (dma->bufs[i].buf_count) {
+ for (j = 0; j < dma->bufs[i].buf_count; j++) {
+ free(dma->bufs[i].buflist[j].dev_private,
+ M_DRM);
+ }
+ free(dma->bufs[i].buflist, M_DRM);
+ }
+ }
+
+ free(dma->buflist, M_DRM);
+ free(dma->pagelist, M_DRM);
+ free(dev->dma, M_DRM);
+ dev->dma = NULL;
+ DRM_SPINUNINIT(dev->dma_lock);
+}
+
+
+void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+{
+ if (!buf) return;
+
+ buf->pending = 0;
+ buf->filp = NULL;
+ buf->used = 0;
+}
+
+void drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp)
+{
+ 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) {
+ switch (dma->buflist[i]->list) {
+ case DRM_LIST_NONE:
+ drm_free_buffer(dev, dma->buflist[i]);
+ break;
+ case DRM_LIST_WAIT:
+ dma->buflist[i]->list = DRM_LIST_RECLAIM;
+ break;
+ default:
+ /* Buffer already on hardware. */
+ break;
+ }
+ }
+ }
+}
+
+/* Call into the driver-specific DMA handler */
+int drm_dma(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+
+ if (dev->driver.dma_ioctl) {
+ return dev->driver.dma_ioctl(kdev, cmd, data, flags, p, filp);
+ } else {
+ DRM_DEBUG("DMA ioctl on driver with no dma handler\n");
+ return EINVAL;
+ }
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_drawable.c b/nx-X11/extras/drm/bsd-core/drm_drawable.c
new file mode 100644
index 000000000..379e0aa77
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_drawable.c
@@ -0,0 +1,51 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+int drm_adddraw(DRM_IOCTL_ARGS)
+{
+ drm_draw_t draw;
+
+ draw.handle = 0; /* NOOP */
+ DRM_DEBUG("%d\n", draw.handle);
+
+ DRM_COPY_TO_USER_IOCTL( (drm_draw_t *)data, draw, sizeof(draw) );
+
+ return 0;
+}
+
+int drm_rmdraw(DRM_IOCTL_ARGS)
+{
+ return 0; /* NOOP */
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_drv.c b/nx-X11/extras/drm/bsd-core/drm_drv.c
new file mode 100644
index 000000000..6766195ba
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_drv.c
@@ -0,0 +1,932 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+
+int drm_debug_flag = 0;
+
+static int drm_load(drm_device_t *dev);
+static void drm_unload(drm_device_t *dev);
+static drm_pci_id_list_t *drm_find_description(int vendor, int device,
+ drm_pci_id_list_t *idlist);
+
+#ifdef __FreeBSD__
+#define DRIVER_SOFTC(unit) \
+ ((drm_device_t *)devclass_get_softc(drm_devclass, unit))
+
+MODULE_VERSION(drm, 1);
+MODULE_DEPEND(drm, agp, 1, 1, 1);
+MODULE_DEPEND(drm, pci, 1, 1, 1);
+#if __FreeBSD_version > 502127
+MODULE_DEPEND(drm, mem, 1, 1, 1);
+#endif
+#endif /* __FreeBSD__ */
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+#define DRIVER_SOFTC(unit) \
+ ((drm_device_t *)device_lookup(&drm_cd, unit))
+#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 },
+};
+
+#ifdef __FreeBSD__
+static struct cdevsw drm_cdevsw = {
+#if __FreeBSD_version >= 502103
+ .d_version = D_VERSION,
+#endif
+ .d_open = drm_open,
+ .d_close = drm_close,
+ .d_read = drm_read,
+ .d_ioctl = drm_ioctl,
+ .d_poll = drm_poll,
+ .d_mmap = drm_mmap,
+ .d_name = "drm",
+#if __FreeBSD_version >= 502103
+ .d_flags = D_TRACKCLOSE | D_NEEDGIANT,
+#else
+ .d_maj = 145,
+ .d_flags = D_TRACKCLOSE,
+#endif
+#if __FreeBSD_version < 500000
+ .d_bmaj = -1
+#endif
+};
+
+int drm_probe(device_t dev, drm_pci_id_list_t *idlist)
+{
+ drm_pci_id_list_t *id_entry;
+ int vendor, device;
+
+ vendor = pci_get_vendor(dev);
+ device = pci_get_device(dev);
+
+ id_entry = drm_find_description(vendor, device, idlist);
+ if (id_entry != NULL) {
+ device_set_desc(dev, id_entry->name);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist)
+{
+ drm_device_t *dev;
+ drm_pci_id_list_t *id_entry;
+ int unit;
+
+ unit = device_get_unit(nbdev);
+ dev = device_get_softc(nbdev);
+
+ if (!strcmp(device_get_name(nbdev), "drmsub"))
+ dev->device = device_get_parent(nbdev);
+ else
+ dev->device = nbdev;
+
+ dev->devnode = make_dev(&drm_cdevsw,
+ unit,
+ DRM_DEV_UID,
+ DRM_DEV_GID,
+ DRM_DEV_MODE,
+ "dri/card%d", unit);
+#if __FreeBSD_version >= 500000
+ mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF);
+#endif
+
+ id_entry = drm_find_description(pci_get_vendor(nbdev),
+ pci_get_device(nbdev), idlist);
+ dev->id_entry = id_entry;
+
+ return drm_load(dev);
+}
+
+int drm_detach(device_t dev)
+{
+ drm_unload(device_get_softc(dev));
+ return 0;
+}
+
+#ifndef DRM_DEV_NAME
+#define DRM_DEV_NAME "drm"
+#endif
+
+devclass_t drm_devclass;
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+
+static struct cdevsw drm_cdevsw = {
+ drm_open,
+ drm_close,
+ drm_read,
+ nowrite,
+ drm_ioctl,
+ nostop,
+ notty,
+ drm_poll,
+ drm_mmap,
+ nokqfilter,
+ D_TTY
+};
+
+int drm_refcnt = 0;
+
+#if defined(__NetBSD__) && __NetBSD_Version__ >= 106080000
+MOD_DEV("drm", DRIVER_NAME, NULL, -1, &drm_cdevsw, CDEV_MAJOR);
+#else
+MOD_DEV("drm", LM_DT_CHAR, CDEV_MAJOR, &drm_cdevsw);
+#endif
+
+int drm_lkmentry(struct lkm_table *lkmtp, int cmd, int ver);
+static int drm_lkmhandle(struct lkm_table *lkmtp, int cmd);
+
+int drm_modprobe(void);
+int drm_probe(struct pci_attach_args *pa);
+void drm_attach(struct pci_attach_args *pa, dev_t kdev);
+
+int drm_lkmentry(struct lkm_table *lkmtp, int cmd, int ver) {
+ DISPATCH(lkmtp, cmd, ver, drm_lkmhandle, drm_lkmhandle, drm_lkmhandle);
+}
+
+static int drm_lkmhandle(struct lkm_table *lkmtp, int cmd)
+{
+ int error = 0;
+
+ switch(cmd) {
+ case LKM_E_LOAD:
+ if (lkmexists(lkmtp))
+ return EEXIST;
+
+ if(drm_modprobe())
+ return 0;
+
+ return 1;
+
+ case LKM_E_UNLOAD:
+ if (drm_refcnt > 0)
+ return (EBUSY);
+ break;
+ case LKM_E_STAT:
+ break;
+
+ default:
+ error = EIO;
+ break;
+ }
+
+ return error;
+}
+
+int drm_modprobe(void)
+{
+ struct pci_attach_args pa;
+ int error;
+
+ error = pci_find_device(&pa, drm_probe, idlist);
+ if (error != 0)
+ drm_attach(&pa, 0);
+
+ return error;
+}
+
+int drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t idlist)
+{
+ const char *desc;
+ drm_pci_id_list_t *id_entry;
+
+ id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id), idlist);
+ if (id_entry != NULL) {
+ return 1;
+ }
+
+ return 0;
+}
+
+void drm_attach(struct pci_attach_args *pa, dev_t kdev,
+ drm_pci_id_list_t *idlist)
+{
+ int i;
+ drm_device_t *dev;
+ drm_pci_id_list_t *id_entry;
+
+ config_makeroom(kdev, &drm_cd);
+ drm_cd.cd_devs[(kdev)] = malloc(sizeof(drm_device_t), M_DRM, M_WAITOK);
+ dev = DRIVER_SOFTC(kdev);
+
+ memset(dev, 0, sizeof(drm_device_t));
+ memcpy(&dev->pa, pa, sizeof(dev->pa));
+
+ dev->irq = pa->pa_intrline;
+ dev->pci_domain = 0;
+ dev->pci_bus = pa->pa_bus;
+ dev->pci_slot = pa->pa_device;
+ dev->pci_func = pa->pa_function;
+ dev->dma_tag = pa->pa_dmat;
+
+ id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
+ PCI_PRODUCT(pa->pa_id), idlist);
+ dev->driver.pci_id_entry = id_entry;
+
+ DRM_INFO("%s", id_entry->name);
+ drm_load(dev);
+}
+
+int drm_detach(struct device *self, int flags)
+{
+ drm_unload((drm_device_t *)self);
+ return 0;
+}
+
+int drm_activate(struct device *self, enum devact act)
+{
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ break;
+
+ case DVACT_DEACTIVATE:
+ /* FIXME */
+ break;
+ }
+ return (0);
+}
+#endif /* __NetBSD__ || __OpenBSD__ */
+
+drm_pci_id_list_t *drm_find_description(int vendor, int device,
+ drm_pci_id_list_t *idlist)
+{
+ int i = 0;
+
+ for (i = 0; idlist[i].vendor != 0; i++) {
+ if ((idlist[i].vendor == vendor) &&
+ (idlist[i].device == device)) {
+ return &idlist[i];
+ }
+ }
+ return NULL;
+}
+
+static int drm_firstopen(drm_device_t *dev)
+{
+ drm_local_map_t *map;
+ int i;
+
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
+ /* prebuild the SAREA */
+ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
+ _DRM_CONTAINS_LOCK, &map);
+ if (i != 0)
+ return i;
+
+ if (dev->driver.firstopen)
+ dev->driver.firstopen(dev);
+
+ dev->buf_use = 0;
+
+ if (dev->driver.use_dma) {
+ i = drm_dma_setup(dev);
+ if (i != 0)
+ return i;
+ }
+
+ dev->counters = 6;
+ dev->types[0] = _DRM_STAT_LOCK;
+ dev->types[1] = _DRM_STAT_OPENS;
+ dev->types[2] = _DRM_STAT_CLOSES;
+ dev->types[3] = _DRM_STAT_IOCTLS;
+ dev->types[4] = _DRM_STAT_LOCKS;
+ dev->types[5] = _DRM_STAT_UNLOCKS;
+
+ for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
+ atomic_set( &dev->counts[i], 0 );
+
+ for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+ dev->magiclist[i].head = NULL;
+ dev->magiclist[i].tail = NULL;
+ }
+
+ dev->lock.lock_queue = 0;
+ dev->irq_enabled = 0;
+ dev->context_flag = 0;
+ dev->last_context = 0;
+ dev->if_version = 0;
+
+#ifdef __FreeBSD__
+ dev->buf_sigio = NULL;
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ dev->buf_pgid = 0;
+#endif
+
+ DRM_DEBUG( "\n" );
+
+ return 0;
+}
+
+static int drm_lastclose(drm_device_t *dev)
+{
+ drm_magic_entry_t *pt, *next;
+ drm_local_map_t *map, *mapsave;
+ int i;
+
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
+ DRM_DEBUG( "\n" );
+
+ if (dev->driver.lastclose != NULL)
+ dev->driver.lastclose(dev);
+
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
+
+ if ( dev->unique ) {
+ free(dev->unique, M_DRM);
+ dev->unique = NULL;
+ dev->unique_len = 0;
+ }
+ /* Clear pid list */
+ for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+ for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
+ next = pt->next;
+ free(pt, M_DRM);
+ }
+ dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ }
+
+ /* Clear AGP information */
+ if ( dev->agp ) {
+ drm_agp_mem_t *entry;
+ drm_agp_mem_t *nexte;
+
+ /* Remove AGP resources, but leave dev->agp intact until
+ * drm_unload is called.
+ */
+ for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
+ nexte = entry->next;
+ if ( entry->bound )
+ drm_agp_unbind_memory(entry->handle);
+ drm_agp_free_memory(entry->handle);
+ free(entry, M_DRM);
+ }
+ dev->agp->memory = NULL;
+
+ if (dev->agp->acquired)
+ drm_agp_release(dev);
+
+ dev->agp->acquired = 0;
+ dev->agp->enabled = 0;
+ }
+ if (dev->sg != NULL) {
+ drm_sg_cleanup(dev->sg);
+ dev->sg = NULL;
+ }
+
+ TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) {
+ drm_rmmap(dev, map);
+ }
+
+
+ drm_dma_takedown(dev);
+ if ( dev->lock.hw_lock ) {
+ dev->lock.hw_lock = NULL; /* SHM removed */
+ dev->lock.filp = NULL;
+ DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
+ }
+
+ return 0;
+}
+
+static int drm_load(drm_device_t *dev)
+{
+ int retcode;
+
+ DRM_DEBUG( "\n" );
+
+ dev->irq = pci_get_irq(dev->device);
+ /* XXX Fix domain number (alpha hoses) */
+ dev->pci_domain = 0;
+ dev->pci_bus = pci_get_bus(dev->device);
+ dev->pci_slot = pci_get_slot(dev->device);
+ dev->pci_func = pci_get_function(dev->device);
+
+ TAILQ_INIT(&dev->maplist);
+
+ drm_mem_init();
+#ifdef __FreeBSD__
+ drm_sysctl_init(dev);
+#endif
+ TAILQ_INIT(&dev->files);
+
+ if (dev->driver.load != NULL) {
+ retcode = dev->driver.load(dev, dev->id_entry->driver_private);
+ if (retcode != 0)
+ goto error;
+ }
+
+ if (dev->driver.use_agp) {
+ if (drm_device_is_agp(dev))
+ dev->agp = drm_agp_init();
+ if (dev->driver.require_agp && dev->agp == NULL) {
+ DRM_ERROR("Card isn't AGP, or couldn't initialize "
+ "AGP.\n");
+ retcode = DRM_ERR(ENOMEM);
+ goto error;
+ }
+ if (dev->agp != NULL) {
+ if (drm_mtrr_add(dev->agp->info.ai_aperture_base,
+ dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0)
+ dev->agp->mtrr = 1;
+ }
+ }
+
+ retcode = drm_ctxbitmap_init(dev);
+ if (retcode != 0) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ goto error;
+ }
+
+ DRM_INFO("Initialized %s %d.%d.%d %s\n",
+ dev->driver.name,
+ dev->driver.major,
+ dev->driver.minor,
+ dev->driver.patchlevel,
+ dev->driver.date);
+
+ return 0;
+
+error:
+#ifdef __FreeBSD__
+ drm_sysctl_cleanup(dev);
+#endif
+ DRM_LOCK();
+ drm_lastclose(dev);
+ DRM_UNLOCK();
+#ifdef __FreeBSD__
+ destroy_dev(dev->devnode);
+#if __FreeBSD_version >= 500000
+ mtx_destroy(&dev->dev_lock);
+#endif
+#endif
+ return retcode;
+}
+
+static void drm_unload(drm_device_t *dev)
+{
+ int i;
+
+ DRM_DEBUG( "\n" );
+
+#ifdef __FreeBSD__
+ drm_sysctl_cleanup(dev);
+ destroy_dev(dev->devnode);
+#endif
+
+ drm_ctxbitmap_cleanup(dev);
+
+ if (dev->agp && dev->agp->mtrr) {
+ int __unused retcode;
+
+ retcode = drm_mtrr_del(dev->agp->info.ai_aperture_base,
+ dev->agp->info.ai_aperture_size, DRM_MTRR_WC);
+ DRM_DEBUG("mtrr_del = %d", retcode);
+ }
+
+ DRM_LOCK();
+ drm_lastclose(dev);
+ DRM_UNLOCK();
+
+ /* Clean up PCI resources allocated by drm_bufs.c. We're not really
+ * worried about resource consumption while the DRM is inactive (between
+ * lastclose and firstopen or unload) because these aren't actually
+ * taking up KVA, just keeping the PCI resource allocated.
+ */
+ for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) {
+ if (dev->pcir[i] == NULL)
+ continue;
+ bus_release_resource(dev->device, SYS_RES_MEMORY,
+ dev->pcirid[i], dev->pcir[i]);
+ dev->pcir[i] = NULL;
+ }
+
+ if ( dev->agp ) {
+ free(dev->agp, M_DRM);
+ dev->agp = NULL;
+ }
+
+ if (dev->driver.unload != NULL)
+ dev->driver.unload(dev);
+
+ drm_mem_uninit();
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
+ mtx_destroy(&dev->dev_lock);
+#endif
+}
+
+
+int drm_version(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_version_t version;
+ 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); \
+ }
+
+ 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);
+
+ DRM_COPY_TO_USER_IOCTL( (drm_version_t *)data, version, sizeof(version) );
+
+ return 0;
+}
+
+int drm_open(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
+{
+ drm_device_t *dev = NULL;
+ int retcode = 0;
+
+ dev = DRIVER_SOFTC(minor(kdev));
+
+ DRM_DEBUG( "open_count = %d\n", dev->open_count );
+
+ retcode = drm_open_helper(kdev, flags, fmt, p, dev);
+
+ if ( !retcode ) {
+ atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
+ DRM_LOCK();
+#ifdef __FreeBSD__
+ device_busy(dev->device);
+#endif
+ if ( !dev->open_count++ )
+ retcode = drm_firstopen(dev);
+ DRM_UNLOCK();
+ }
+
+ return retcode;
+}
+
+int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p)
+{
+ drm_file_t *priv;
+ DRM_DEVICE;
+ 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) {
+ DRM_UNLOCK();
+ DRM_ERROR("can't find authenticator\n");
+ return EINVAL;
+ }
+
+ if (dev->driver.preclose != NULL)
+ dev->driver.preclose(dev, filp);
+
+ /* ========================================================
+ * Begin inline drm_release
+ */
+
+#ifdef __FreeBSD__
+ DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+ DRM_CURRENTPID, (long)dev->device, dev->open_count );
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+ DRM_CURRENTPID, (long)&dev->device, dev->open_count);
+#endif
+
+ if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
+ && dev->lock.filp == filp) {
+ DRM_DEBUG("Process %d dead, freeing lock for context %d\n",
+ DRM_CURRENTPID,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ if (dev->driver.reclaim_buffers_locked != NULL)
+ dev->driver.reclaim_buffers_locked(dev, filp);
+
+ drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+
+ /* FIXME: may require heavy-handed reset of
+ hardware at this point, possibly
+ processed via a callback to the X
+ server. */
+ } else if (dev->driver.reclaim_buffers_locked != NULL &&
+ dev->lock.hw_lock != NULL) {
+ /* The lock is required to reclaim buffers */
+ for (;;) {
+ if ( !dev->lock.hw_lock ) {
+ /* Device has been unregistered */
+ retcode = DRM_ERR(EINTR);
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ dev->lock.filp = filp;
+ dev->lock.lock_time = jiffies;
+ atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+ break; /* Got lock */
+ }
+ /* Contention */
+#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+ retcode = msleep((void *)&dev->lock.lock_queue,
+ &dev->dev_lock, PZERO | PCATCH, "drmlk2", 0);
+#else
+ retcode = tsleep((void *)&dev->lock.lock_queue,
+ PZERO | PCATCH, "drmlk2", 0);
+#endif
+ if (retcode)
+ break;
+ }
+ if (retcode == 0) {
+ dev->driver.reclaim_buffers_locked(dev, filp);
+ 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);
+
+#if defined (__FreeBSD__) && (__FreeBSD_version >= 500000)
+ funsetown(&dev->buf_sigio);
+#elif defined(__FreeBSD__)
+ funsetown(dev->buf_sigio);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ 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);
+ }
+
+ /* ========================================================
+ * End inline drm_release
+ */
+
+ atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
+#ifdef __FreeBSD__
+ device_unbusy(dev->device);
+#endif
+ if (--dev->open_count == 0) {
+ retcode = drm_lastclose(dev);
+ }
+
+ DRM_UNLOCK();
+
+ return retcode;
+}
+
+/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm.
+ */
+int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags,
+ DRM_STRUCTPROC *p)
+{
+ DRM_DEVICE;
+ int retcode = 0;
+ drm_ioctl_desc_t *ioctl;
+ int (*func)(DRM_IOCTL_ARGS);
+ int nr = DRM_IOCTL_NR(cmd);
+ int is_driver_ioctl = 0;
+ drm_file_t *priv;
+ DRMFILE filp = (DRMFILE)(uintptr_t)DRM_CURRENTPID;
+
+ DRM_LOCK();
+ priv = drm_find_file_by_proc(dev, p);
+ DRM_UNLOCK();
+ if (priv == NULL) {
+ DRM_ERROR("can't find authenticator\n");
+ return EINVAL;
+ }
+
+ atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
+ ++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 );
+#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 );
+#endif
+
+ switch (cmd) {
+ case FIONBIO:
+ case FIOASYNC:
+ return 0;
+
+#ifdef __FreeBSD__
+ case FIOSETOWN:
+ return fsetown(*(int *)data, &dev->buf_sigio);
+
+ case FIOGETOWN:
+#if (__FreeBSD_version >= 500000)
+ *(int *) data = fgetown(&dev->buf_sigio);
+#else
+ *(int *) data = fgetown(dev->buf_sigio);
+#endif
+ return 0;
+#endif /* __FreeBSD__ */
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ case TIOCSPGRP:
+ dev->buf_pgid = *(int *)data;
+ return 0;
+
+ case TIOCGPGRP:
+ *(int *)data = dev->buf_pgid;
+ return 0;
+#endif /* __NetBSD__ */
+ }
+
+ if (IOCGROUP(cmd) != DRM_IOCTL_BASE) {
+ DRM_DEBUG("Bad ioctl group 0x%x\n", (int)IOCGROUP(cmd));
+ return EINVAL;
+ }
+
+ ioctl = &drm_ioctls[nr];
+ /* It's not a core DRM ioctl, try driver-specific. */
+ if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) {
+ /* The array entries begin at DRM_COMMAND_BASE ioctl nr */
+ nr -= DRM_COMMAND_BASE;
+ if (nr > dev->driver.max_ioctl) {
+ DRM_DEBUG("Bad driver ioctl number, 0x%x (of 0x%x)\n",
+ nr, dev->driver.max_ioctl);
+ return EINVAL;
+ }
+ ioctl = &dev->driver.ioctls[nr];
+ is_driver_ioctl = 1;
+ }
+ func = ioctl->func;
+
+ if (func == NULL) {
+ 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))
+ return EACCES;
+
+ if (is_driver_ioctl)
+ DRM_LOCK();
+ retcode = func(kdev, cmd, data, flags, p, filp);
+ if (is_driver_ioctl)
+ DRM_UNLOCK();
+
+ if (retcode != 0)
+ DRM_DEBUG(" returning %d\n", retcode);
+
+ return DRM_ERR(retcode);
+}
+
+
+#if DRM_LINUX
+
+#include <sys/sysproto.h>
+
+MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1);
+
+#define LINUX_IOCTL_DRM_MIN 0x6400
+#define LINUX_IOCTL_DRM_MAX 0x64ff
+
+static linux_ioctl_function_t drm_linux_ioctl;
+static struct linux_ioctl_handler drm_handler = {drm_linux_ioctl,
+ LINUX_IOCTL_DRM_MIN, LINUX_IOCTL_DRM_MAX};
+
+SYSINIT(drm_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ linux_ioctl_register_handler, &drm_handler);
+SYSUNINIT(drm_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ linux_ioctl_unregister_handler, &drm_handler);
+
+/* The bits for in/out are switched on Linux */
+#define LINUX_IOC_IN IOC_OUT
+#define LINUX_IOC_OUT IOC_IN
+
+static int
+drm_linux_ioctl(DRM_STRUCTPROC *p, struct linux_ioctl_args* args)
+{
+ int error;
+ int cmd = args->cmd;
+
+ args->cmd &= ~(LINUX_IOC_IN | LINUX_IOC_OUT);
+ if (cmd & LINUX_IOC_IN)
+ args->cmd |= IOC_IN;
+ if (cmd & LINUX_IOC_OUT)
+ args->cmd |= IOC_OUT;
+
+ error = ioctl(p, (struct ioctl_args *)args);
+
+ return error;
+}
+#endif /* DRM_LINUX */
diff --git a/nx-X11/extras/drm/bsd-core/drm_fops.c b/nx-X11/extras/drm/bsd-core/drm_fops.c
new file mode 100644
index 000000000..f5c9349bf
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_fops.c
@@ -0,0 +1,128 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Daryll Strauss <daryll@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+drm_file_t *drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p)
+{
+#if __FreeBSD_version >= 500021
+ uid_t uid = p->td_ucred->cr_svuid;
+ pid_t pid = p->td_proc->p_pid;
+#else
+ uid_t uid = p->p_cred->p_svuid;
+ pid_t pid = p->p_pid;
+#endif
+ drm_file_t *priv;
+
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
+ TAILQ_FOREACH(priv, &dev->files, link)
+ if (priv->pid == pid && priv->uid == uid)
+ return priv;
+ return NULL;
+}
+
+/* drm_open_helper is called whenever a process opens /dev/drm. */
+int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p,
+ drm_device_t *dev)
+{
+ int m = minor(kdev);
+ drm_file_t *priv;
+ int retcode;
+
+ if (flags & O_EXCL)
+ return EBUSY; /* No exclusive opens */
+ dev->flags = flags;
+
+ DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m);
+
+ DRM_LOCK();
+ priv = drm_find_file_by_proc(dev, p);
+ if (priv) {
+ priv->refs++;
+ } else {
+ priv = malloc(sizeof(*priv), M_DRM, M_NOWAIT | M_ZERO);
+ if (priv == NULL) {
+ DRM_UNLOCK();
+ return DRM_ERR(ENOMEM);
+ }
+#if __FreeBSD_version >= 500000
+ priv->uid = p->td_ucred->cr_svuid;
+ priv->pid = p->td_proc->p_pid;
+#else
+ priv->uid = p->p_cred->p_svuid;
+ priv->pid = p->p_pid;
+#endif
+
+ priv->refs = 1;
+ priv->minor = m;
+ priv->ioctl_count = 0;
+
+ /* for compatibility root is always authenticated */
+ priv->authenticated = DRM_SUSER(p);
+
+ if (dev->driver.open) {
+ retcode = dev->driver.open(dev, priv);
+ if (retcode != 0) {
+ free(priv, M_DRM);
+ DRM_UNLOCK();
+ return retcode;
+ }
+ }
+
+ /* first opener automatically becomes master */
+ priv->master = TAILQ_EMPTY(&dev->files);
+
+ TAILQ_INSERT_TAIL(&dev->files, priv, link);
+ }
+ DRM_UNLOCK();
+#ifdef __FreeBSD__
+ kdev->si_drv1 = dev;
+#endif
+ return 0;
+}
+
+
+/* The drm_read and drm_poll are stubs to prevent spurious errors
+ * on older X Servers (4.3.0 and earlier) */
+
+int drm_read(struct cdev *kdev, struct uio *uio, int ioflag)
+{
+ return 0;
+}
+
+int drm_poll(struct cdev *kdev, int events, DRM_STRUCTPROC *p)
+{
+ return 0;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_ioctl.c b/nx-X11/extras/drm/bsd-core/drm_ioctl.c
new file mode 100644
index 000000000..e22faa830
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_ioctl.c
@@ -0,0 +1,296 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+/*
+ * Beginning in revision 1.1 of the DRM interface, getunique will return
+ * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function)
+ * 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)
+{
+ DRM_DEVICE;
+ drm_unique_t u;
+
+ DRM_COPY_FROM_USER_IOCTL( u, (drm_unique_t *)data, sizeof(u) );
+
+ if (u.unique_len >= dev->unique_len) {
+ if (DRM_COPY_TO_USER(u.unique, dev->unique, dev->unique_len))
+ return DRM_ERR(EFAULT);
+ }
+ u.unique_len = dev->unique_len;
+
+ DRM_COPY_TO_USER_IOCTL( (drm_unique_t *)data, u, sizeof(u) );
+
+ return 0;
+}
+
+/* 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)
+{
+ DRM_DEVICE;
+ drm_unique_t u;
+ 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);
+
+ busid = malloc(u.unique_len + 1, M_DRM, M_WAITOK);
+ if (busid == NULL)
+ return DRM_ERR(ENOMEM);
+
+ if (DRM_COPY_FROM_USER(busid, u.unique, u.unique_len)) {
+ free(busid, M_DRM);
+ return DRM_ERR(EFAULT);
+ }
+ busid[u.unique_len] = '\0';
+
+ /* Return error if the busid submitted doesn't match the device's actual
+ * busid.
+ */
+ ret = sscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func);
+ if (ret != 3) {
+ free(busid, M_DRM);
+ return DRM_ERR(EINVAL);
+ }
+ domain = bus >> 8;
+ bus &= 0xff;
+
+ if ((domain != dev->pci_domain) ||
+ (bus != dev->pci_bus) ||
+ (slot != dev->pci_slot) ||
+ (func != dev->pci_func)) {
+ free(busid, M_DRM);
+ return DRM_ERR(EINVAL);
+ }
+
+ /* Actually set the device's busid now. */
+ DRM_LOCK();
+ if (dev->unique_len || dev->unique) {
+ DRM_UNLOCK();
+ return DRM_ERR(EBUSY);
+ }
+
+ dev->unique_len = u.unique_len;
+ dev->unique = busid;
+ DRM_UNLOCK();
+
+ return 0;
+}
+
+
+static int
+drm_set_busid(drm_device_t *dev)
+{
+
+ DRM_LOCK();
+
+ if (dev->unique != NULL) {
+ DRM_UNLOCK();
+ return EBUSY;
+ }
+
+ dev->unique_len = 20;
+ dev->unique = malloc(dev->unique_len + 1, M_DRM, M_NOWAIT);
+ if (dev->unique == NULL) {
+ DRM_UNLOCK();
+ return ENOMEM;
+ }
+
+ snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x",
+ dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+
+ DRM_UNLOCK();
+
+ return 0;
+}
+
+int drm_getmap(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_map_t map;
+ 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;
+
+ DRM_LOCK();
+ if (idx < 0) {
+ DRM_UNLOCK();
+ return DRM_ERR(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;
+ break;
+ }
+ i++;
+ }
+
+ DRM_UNLOCK();
+
+ 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)
+{
+ DRM_DEVICE;
+ drm_client_t client;
+ drm_file_t *pt;
+ int idx;
+ int i = 0;
+
+ DRM_COPY_FROM_USER_IOCTL( client, (drm_client_t *)data, sizeof(client) );
+
+ 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;
+ 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;
+}
+
+int drm_getstats(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_stats_t stats;
+ int i;
+
+ memset(&stats, 0, sizeof(stats));
+
+ DRM_LOCK();
+
+ for (i = 0; i < dev->counters; i++) {
+ if (dev->types[i] == _DRM_STAT_LOCK)
+ 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.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)
+{
+ DRM_DEVICE;
+ drm_set_version_t sv;
+ drm_set_version_t retv;
+ 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)
+ return EINVAL;
+ if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
+ dev->if_version = DRM_MAX(if_version, dev->if_version);
+ if (sv.drm_di_minor >= 1) {
+ /*
+ * Version 1.1 includes tying of DRM to specific device
+ */
+ drm_set_busid(dev);
+ }
+ }
+
+ 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)
+ return EINVAL;
+ }
+ return 0;
+}
+
+
+int drm_noop(DRM_IOCTL_ARGS)
+{
+ DRM_DEBUG("\n");
+ return 0;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_irq.c b/nx-X11/extras/drm/bsd-core/drm_irq.c
new file mode 100644
index 000000000..5f44f9183
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_irq.c
@@ -0,0 +1,291 @@
+/* drm_irq.c -- IRQ IOCTL and function support
+ * Created: Fri Oct 18 2003 by anholt@FreeBSD.org
+ */
+/*-
+ * Copyright 2003 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+
+int drm_irq_by_busid(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_irq_busid_t irq;
+
+ DRM_COPY_FROM_USER_IOCTL(irq, (drm_irq_busid_t *)data, sizeof(irq));
+
+ 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;
+
+ 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) );
+
+ return 0;
+}
+
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
+static irqreturn_t
+drm_irq_handler_wrap(DRM_IRQ_ARGS)
+{
+ drm_device_t *dev = (drm_device_t *)arg;
+
+ DRM_SPINLOCK(&dev->irq_lock);
+ dev->driver.irq_handler(arg);
+ DRM_SPINUNLOCK(&dev->irq_lock);
+}
+#endif
+
+int drm_irq_install(drm_device_t *dev)
+{
+ int retcode;
+#ifdef __NetBSD__
+ pci_intr_handle_t ih;
+#endif
+
+ if (dev->irq == 0 || dev->dev_private == NULL)
+ return DRM_ERR(EINVAL);
+
+ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+
+ DRM_LOCK();
+ if (dev->irq_enabled) {
+ DRM_UNLOCK();
+ return DRM_ERR(EBUSY);
+ }
+ dev->irq_enabled = 1;
+
+ dev->context_flag = 0;
+
+ DRM_SPININIT(dev->irq_lock, "DRM IRQ lock");
+
+ /* Before installing handler */
+ dev->driver.irq_preinstall(dev);
+ DRM_UNLOCK();
+
+ /* Install handler */
+#ifdef __FreeBSD__
+ dev->irqrid = 0;
+ dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ,
+ &dev->irqrid, RF_SHAREABLE);
+ if (!dev->irqr) {
+ retcode = ENOENT;
+ goto err;
+ }
+#if __FreeBSD_version < 500000
+ retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY,
+ dev->irq_handler, dev, &dev->irqh);
+#else
+ retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE,
+ drm_irq_handler_wrap, dev, &dev->irqh);
+#endif
+ if (retcode != 0)
+ goto err;
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ if (pci_intr_map(&dev->pa, &ih) != 0) {
+ retcode = ENOENT;
+ goto err;
+ }
+ dev->irqh = pci_intr_establish(&dev->pa.pa_pc, ih, IPL_TTY,
+ (irqreturn_t (*)(void *))dev->irq_handler, dev);
+ if (!dev->irqh) {
+ retcode = ENOENT;
+ goto err;
+ }
+#endif
+
+ /* After installing handler */
+ DRM_LOCK();
+ dev->driver.irq_postinstall(dev);
+ DRM_UNLOCK();
+
+ return 0;
+err:
+ DRM_LOCK();
+ dev->irq_enabled = 0;
+#ifdef ___FreeBSD__
+ if (dev->irqrid != 0) {
+ bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid,
+ dev->irqr);
+ dev->irqrid = 0;
+ }
+#endif
+ DRM_SPINUNINIT(dev->irq_lock);
+ DRM_UNLOCK();
+ return retcode;
+}
+
+int drm_irq_uninstall(drm_device_t *dev)
+{
+#ifdef __FreeBSD__
+ int irqrid;
+#endif
+
+ if (!dev->irq_enabled)
+ return DRM_ERR(EINVAL);
+
+ dev->irq_enabled = 0;
+#ifdef __FreeBSD__
+ irqrid = dev->irqrid;
+ dev->irqrid = 0;
+#endif
+
+ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+
+ dev->driver.irq_uninstall(dev);
+
+#ifdef __FreeBSD__
+ DRM_UNLOCK();
+ bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
+ bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
+ DRM_LOCK();
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
+#endif
+ DRM_SPINUNINIT(dev->irq_lock);
+
+ return 0;
+}
+
+int drm_control(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_control_t ctl;
+ int err;
+
+ DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
+
+ switch ( ctl.func ) {
+ case DRM_INST_HANDLER:
+ /* Handle drivers whose DRM used to require IRQ setup but the
+ * no longer does.
+ */
+ if (!dev->driver.use_irq)
+ return 0;
+ if (dev->if_version < DRM_IF_VERSION(1, 2) &&
+ ctl.irq != dev->irq)
+ return DRM_ERR(EINVAL);
+ return drm_irq_install(dev);
+ case DRM_UNINST_HANDLER:
+ if (!dev->driver.use_irq)
+ return 0;
+ DRM_LOCK();
+ err = drm_irq_uninstall(dev);
+ DRM_UNLOCK();
+ return err;
+ default:
+ return DRM_ERR(EINVAL);
+ }
+}
+
+int drm_wait_vblank(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_wait_vblank_t vblwait;
+ struct timeval now;
+ int ret;
+
+ if (!dev->irq_enabled)
+ return DRM_ERR(EINVAL);
+
+ DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
+ sizeof(vblwait) );
+
+ 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;
+ if (flags & _DRM_VBLANK_SIGNAL) {
+#if 0 /* disabled */
+ drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t), M_DRM,
+ M_NOWAIT | M_ZERO);
+ if (vbl_sig == NULL)
+ return ENOMEM;
+
+ 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);
+
+ DRM_SPINLOCK(&dev->irq_lock);
+ TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
+ DRM_SPINUNLOCK(&dev->irq_lock);
+ ret = 0;
+#endif
+ ret = EINVAL;
+ } else {
+ DRM_LOCK();
+ 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;
+ }
+
+ DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
+ sizeof(vblwait) );
+
+ return ret;
+}
+
+void drm_vbl_send_signals(drm_device_t *dev)
+{
+}
+
+#if 0 /* disabled */
+void drm_vbl_send_signals( drm_device_t *dev )
+{
+ drm_vbl_sig_t *vbl_sig;
+ unsigned int vbl_seq = atomic_read( &dev->vbl_received );
+ struct proc *p;
+
+ vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list);
+ while (vbl_sig != NULL) {
+ drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link);
+
+ if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
+ p = pfind(vbl_sig->pid);
+ if (p != NULL)
+ psignal(p, vbl_sig->signo);
+
+ TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
+ DRM_FREE(vbl_sig,sizeof(*vbl_sig));
+ }
+ vbl_sig = next;
+ }
+}
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/drm_linux_list.h b/nx-X11/extras/drm/bsd-core/drm_linux_list.h
new file mode 100644
index 000000000..c9f1b3e18
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_linux_list.h
@@ -0,0 +1,71 @@
+/* drm_linux_list.h -- linux list functions for the BSDs.
+ * Created: Mon Apr 7 14:30:16 1999 by anholt@FreeBSD.org
+ */
+/*-
+ * Copyright 2003 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+/* Cheat, assume the list_head is at the start of the struct */
+#define list_entry(entry, type, member) (type *)(entry)
+
+static __inline__ void
+INIT_LIST_HEAD(struct list_head *head) {
+ (head)->next = head;
+ (head)->prev = head;
+}
+
+static __inline__ int
+list_empty(struct list_head *head) {
+ return (head)->next == head;
+}
+
+static __inline__ void
+list_add_tail(struct list_head *entry, struct list_head *head) {
+ (entry)->prev = (head)->prev;
+ (entry)->next = head;
+ (head)->prev->next = entry;
+ (head)->prev = entry;
+}
+
+static __inline__ void
+list_del(struct list_head *entry) {
+ (entry)->next->prev = (entry)->prev;
+ (entry)->prev->next = (entry)->next;
+}
+
+#define list_for_each(entry, head) \
+ for (entry = (head)->next; entry != head; entry = (entry)->next)
+
+#define list_for_each_safe(entry, temp, head) \
+ for (entry = (head)->next, temp = (entry)->next; \
+ temp != head; \
+ entry = temp, temp = temp->next)
+
diff --git a/nx-X11/extras/drm/bsd-core/drm_lock.c b/nx-X11/extras/drm/bsd-core/drm_lock.c
new file mode 100644
index 000000000..d0e61d3ab
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_lock.c
@@ -0,0 +1,177 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old, new;
+
+ do {
+ old = *lock;
+ if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+ else new = context | _DRM_LOCK_HELD;
+ } while (!atomic_cmpset_int(lock, old, new));
+
+ if (_DRM_LOCKING_CONTEXT(old) == context) {
+ if (old & _DRM_LOCK_HELD) {
+ if (context != DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("%d holds heavyweight lock\n",
+ context);
+ }
+ return 0;
+ }
+ }
+ if (new == (context | _DRM_LOCK_HELD)) {
+ /* Have lock */
+ return 1;
+ }
+ return 0;
+}
+
+/* This takes a lock forcibly and hands it to context. Should ONLY be used
+ inside *_unlock to give lock to kernel before calling *_dma_schedule. */
+int drm_lock_transfer(drm_device_t *dev,
+ __volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old, new;
+
+ dev->lock.filp = NULL;
+ do {
+ old = *lock;
+ new = context | _DRM_LOCK_HELD;
+ } while (!atomic_cmpset_int(lock, old, new));
+
+ return 1;
+}
+
+int drm_lock_free(drm_device_t *dev,
+ __volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old, new;
+
+ dev->lock.filp = NULL;
+ do {
+ old = *lock;
+ new = 0;
+ } while (!atomic_cmpset_int(lock, old, new));
+
+ if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+ DRM_ERROR("%d freed heavyweight lock held by %d\n",
+ context, _DRM_LOCKING_CONTEXT(old));
+ return 1;
+ }
+ DRM_WAKEUP_INT((void *)&dev->lock.lock_queue);
+ return 0;
+}
+
+int drm_lock(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_lock_t lock;
+ int ret = 0;
+
+ DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock));
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ DRM_CURRENTPID, lock.context);
+ return EINVAL;
+ }
+
+ DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+ lock.context, DRM_CURRENTPID, dev->lock.hw_lock->lock, lock.flags);
+
+ if (dev->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;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+ break; /* Got lock */
+ }
+
+ /* Contention */
+#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+ ret = msleep((void *)&dev->lock.lock_queue, &dev->dev_lock,
+ PZERO | PCATCH, "drmlk2", 0);
+#else
+ ret = tsleep((void *)&dev->lock.lock_queue, PZERO | PCATCH,
+ "drmlk2", 0);
+#endif
+ if (ret != 0)
+ break;
+ }
+ DRM_UNLOCK();
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+ if (ret != 0)
+ return ret;
+
+ /* XXX: Add signal blocking here */
+
+ if (dev->driver.dma_quiescent != NULL &&
+ (lock.flags & _DRM_LOCK_QUIESCENT))
+ dev->driver.dma_quiescent(dev);
+
+ return 0;
+}
+
+int drm_unlock(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_lock_t lock;
+
+ DRM_COPY_FROM_USER_IOCTL(lock, (drm_lock_t *)data, sizeof(lock));
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ DRM_CURRENTPID, lock.context);
+ return EINVAL;
+ }
+
+ atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
+
+ DRM_LOCK();
+ drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ DRM_UNLOCK();
+
+ return 0;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_memory.c b/nx-X11/extras/drm/bsd-core/drm_memory.c
new file mode 100644
index 000000000..ea084c52b
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_memory.c
@@ -0,0 +1,154 @@
+/* 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.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+
+MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures");
+
+void drm_mem_init(void)
+{
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ malloc_type_attach(M_DRM);
+#endif
+}
+
+void drm_mem_uninit(void)
+{
+}
+
+void *drm_alloc(size_t size, int area)
+{
+ return malloc(size, M_DRM, M_NOWAIT);
+}
+
+void *drm_calloc(size_t nmemb, size_t size, int area)
+{
+ return malloc(size * nmemb, M_DRM, M_NOWAIT | M_ZERO);
+}
+
+void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
+{
+ void *pt;
+
+ pt = malloc(size, M_DRM, M_NOWAIT);
+ if (pt == NULL)
+ return NULL;
+ if (oldpt && oldsize) {
+ memcpy(pt, oldpt, oldsize);
+ free(oldpt, M_DRM);
+ }
+ return pt;
+}
+
+void drm_free(void *pt, size_t size, int area)
+{
+ free(pt, M_DRM);
+}
+
+void *drm_ioremap(drm_device_t *dev, drm_local_map_t *map)
+{
+#ifdef __FreeBSD__
+ return pmap_mapdev(map->offset, map->size);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ map->bst = dev->pa.pa_memt;
+ if (bus_space_map(map->bst, map->offset, map->size,
+ BUS_SPACE_MAP_LINEAR, &map->bsh))
+ return NULL;
+ return bus_space_vaddr(map->bst, map->bsh);
+#endif
+}
+
+void drm_ioremapfree(drm_local_map_t *map)
+{
+#ifdef __FreeBSD__
+ pmap_unmapdev((vm_offset_t) map->handle, map->size);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ bus_space_unmap(map->bst, map->bsh, map->size);
+#endif
+}
+
+#ifdef __FreeBSD__
+int
+drm_mtrr_add(unsigned long offset, size_t size, int flags)
+{
+ int act;
+ struct mem_range_desc mrdesc;
+
+ mrdesc.mr_base = offset;
+ mrdesc.mr_len = size;
+ mrdesc.mr_flags = flags;
+ act = MEMRANGE_SET_UPDATE;
+ strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner));
+ return mem_range_attr_set(&mrdesc, &act);
+}
+
+int
+drm_mtrr_del(unsigned long offset, size_t size, int flags)
+{
+ int act;
+ struct mem_range_desc mrdesc;
+
+ mrdesc.mr_base = offset;
+ mrdesc.mr_len = size;
+ mrdesc.mr_flags = flags;
+ act = MEMRANGE_SET_REMOVE;
+ strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner));
+ return mem_range_attr_set(&mrdesc, &act);
+}
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+int
+drm_mtrr_add(unsigned long offset, size_t size, int flags)
+{
+ struct mtrr mtrrmap;
+ int one = 1;
+
+ mtrrmap.base = offset;
+ mtrrmap.len = size;
+ mtrrmap.type = flags;
+ mtrrmap.flags = MTRR_VALID;
+ return mtrr_set(&mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
+}
+
+int
+drm_mtrr_del(unsigned long offset, size_t size, int flags)
+{
+ struct mtrr mtrrmap;
+ int one = 1;
+
+ mtrrmap.base = offset;
+ mtrrmap.len = size;
+ mtrrmap.type = flags;
+ mtrrmap.flags = 0;
+ return mtrr_set(&mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
+}
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/drm_pci.c b/nx-X11/extras/drm/bsd-core/drm_pci.c
new file mode 100644
index 000000000..a33f5f9cf
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_pci.c
@@ -0,0 +1,141 @@
+/**
+ * \file drm_pci.h
+ * \brief PCI consistent, DMA-accessible memory functions.
+ *
+ * \author Eric Anholt <anholt@FreeBSD.org>
+ */
+
+/*-
+ * Copyright 2003 Eric Anholt.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+/**********************************************************************/
+/** \name PCI memory */
+/*@{*/
+
+#if defined(__FreeBSD__)
+static void
+drm_pci_busdma_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ drm_dma_handle_t *dmah = arg;
+
+ if (error != 0)
+ return;
+
+ KASSERT(nsegs == 1, ("drm_pci_busdma_callback: bad dma segment count"));
+ dmah->busaddr = segs[0].ds_addr;
+}
+#endif
+
+/**
+ * \brief Allocate a physically contiguous DMA-accessible consistent
+ * memory block.
+ */
+drm_dma_handle_t *
+drm_pci_alloc(drm_device_t *dev, size_t size, size_t align, dma_addr_t maxaddr)
+{
+ drm_dma_handle_t *dmah;
+ int ret;
+
+ /* Need power-of-two alignment, so fail the allocation if it isn't. */
+ if ((align & (align - 1)) != 0) {
+ DRM_ERROR("drm_pci_alloc with non-power-of-two alignment %d\n",
+ (int)align);
+ return NULL;
+ }
+
+ dmah = malloc(sizeof(drm_dma_handle_t), M_DRM, M_ZERO | M_NOWAIT);
+ if (dmah == NULL)
+ return NULL;
+
+#ifdef __FreeBSD__
+ ret = bus_dma_tag_create(NULL, align, 0, /* tag, align, boundary */
+ maxaddr, BUS_SPACE_MAXADDR, /* lowaddr, highaddr */
+ NULL, NULL, /* filtfunc, filtfuncargs */
+ size, 1, size, /* maxsize, nsegs, maxsegsize */
+ BUS_DMA_ALLOCNOW, NULL, NULL, /* flags, lockfunc, lockfuncargs */
+ &dmah->tag);
+ if (ret != 0) {
+ free(dmah, M_DRM);
+ return NULL;
+ }
+
+ ret = bus_dmamem_alloc(dmah->tag, &dmah->vaddr, BUS_DMA_NOWAIT,
+ &dmah->map);
+ if (ret != 0) {
+ bus_dma_tag_destroy(dmah->tag);
+ free(dmah, M_DRM);
+ return NULL;
+ }
+
+ ret = bus_dmamap_load(dmah->tag, dmah->map, dmah->vaddr, size,
+ drm_pci_busdma_callback, dmah, 0);
+ if (ret != 0) {
+ bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
+ bus_dma_tag_destroy(dmah->tag);
+ free(dmah, M_DRM);
+ return NULL;
+ }
+#elif defined(__NetBSD__)
+ ret = bus_dmamem_alloc(dev->dma_tag, size, align, PAGE_SIZE,
+ &dmah->seg, 1, &nsegs, BUS_DMA_NOWAIT);
+ if ((ret != 0) || (nsegs != 1)) {
+ free(dmah, M_DRM);
+ return NULL;
+ }
+
+ ret = bus_dmamem_map(dev->dma_tag, &dmah->seg, 1, size, &dmah->addr,
+ BUS_DMA_NOWAIT);
+ if (ret != 0) {
+ bus_dmamem_free(dev->dma_tag, &dmah->seg, 1);
+ free(dmah, M_DRM);
+ return NULL;
+ }
+
+ dmah->dmaaddr = h->seg.ds_addr;
+#endif
+
+ return dmah;
+}
+
+/**
+ * \brief Free a DMA-accessible consistent memory block.
+ */
+void
+drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
+{
+ if (dmah == NULL)
+ return;
+
+#if defined(__FreeBSD__)
+ bus_dmamem_free(dmah->tag, dmah->vaddr, dmah->map);
+ bus_dma_tag_destroy(dmah->tag);
+#elif defined(__NetBSD__)
+ bus_dmamem_free(dev->dma_tag, &dmah->seg, 1);
+#endif
+
+ free(dmah, M_DRM);
+}
+
+/*@}*/
diff --git a/nx-X11/extras/drm/bsd-core/drm_scatter.c b/nx-X11/extras/drm/bsd-core/drm_scatter.c
new file mode 100644
index 000000000..c26a38027
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_scatter.c
@@ -0,0 +1,128 @@
+/* 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.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "drmP.h"
+
+#define DEBUG_SCATTER 0
+
+void drm_sg_cleanup(drm_sg_mem_t *entry)
+{
+ free((void *)entry->handle, M_DRM);
+ free(entry->busaddr, M_DRM);
+ free(entry, M_DRM);
+}
+
+int drm_sg_alloc(DRM_IOCTL_ARGS)
+{
+ 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 );
+
+ entry->pages = pages;
+
+ entry->busaddr = malloc(pages * sizeof(*entry->busaddr), M_DRM,
+ M_WAITOK | M_ZERO);
+ if ( !entry->busaddr ) {
+ drm_sg_cleanup(entry);
+ return ENOMEM;
+ }
+
+ entry->handle = (long)malloc(pages << PAGE_SHIFT, M_DRM,
+ M_WAITOK | M_ZERO);
+ if (entry->handle == 0) {
+ drm_sg_cleanup(entry);
+ return ENOMEM;
+ }
+
+ for (i = 0; i < pages; i++) {
+ entry->busaddr[i] = vtophys(entry->handle + i * PAGE_SIZE);
+ }
+
+ DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
+
+ request.handle = entry->handle;
+
+ DRM_COPY_TO_USER_IOCTL( (drm_scatter_gather_t *)data,
+ request,
+ sizeof(request) );
+
+ DRM_LOCK();
+ if (dev->sg) {
+ DRM_UNLOCK();
+ drm_sg_cleanup(entry);
+ return EINVAL;
+ }
+ dev->sg = entry;
+ DRM_UNLOCK();
+
+ return 0;
+}
+
+int drm_sg_free(DRM_IOCTL_ARGS)
+{
+ DRM_DEVICE;
+ drm_scatter_gather_t request;
+ drm_sg_mem_t *entry;
+
+ DRM_COPY_FROM_USER_IOCTL( request, (drm_scatter_gather_t *)data,
+ sizeof(request) );
+
+ DRM_LOCK();
+ entry = dev->sg;
+ dev->sg = NULL;
+ DRM_UNLOCK();
+
+ if ( !entry || entry->handle != request.handle )
+ return EINVAL;
+
+ DRM_DEBUG( "sg free virtual = 0x%lx\n", entry->handle );
+
+ drm_sg_cleanup(entry);
+
+ return 0;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_sysctl.c b/nx-X11/extras/drm/bsd-core/drm_sysctl.c
new file mode 100644
index 000000000..b2d0cc0c8
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_sysctl.c
@@ -0,0 +1,304 @@
+/*-
+ * Copyright 2003 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+
+#include <sys/sysctl.h>
+
+static int drm_name_info DRM_SYSCTL_HANDLER_ARGS;
+static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS;
+static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS;
+static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS;
+
+struct drm_sysctl_list {
+ const char *name;
+ int (*f) DRM_SYSCTL_HANDLER_ARGS;
+} drm_sysctl_list[] = {
+ {"name", drm_name_info},
+ {"vm", drm_vm_info},
+ {"clients", drm_clients_info},
+ {"bufs", drm_bufs_info},
+};
+#define DRM_SYSCTL_ENTRIES (sizeof(drm_sysctl_list)/sizeof(drm_sysctl_list[0]))
+
+struct drm_sysctl_info {
+ struct sysctl_ctx_list ctx;
+ char name[2];
+};
+
+int drm_sysctl_init(drm_device_t *dev)
+{
+ struct drm_sysctl_info *info;
+ struct sysctl_oid *oid;
+ struct sysctl_oid *top, *drioid;
+ int i;
+
+ info = malloc(sizeof *info, M_DRM, M_WAITOK | M_ZERO);
+ if ( !info )
+ return 1;
+ dev->sysctl = info;
+
+ /* Add the sysctl node for DRI if it doesn't already exist */
+ drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
+ if (!drioid)
+ return 1;
+
+ /* Find the next free slot under hw.dri */
+ i = 0;
+ SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
+ if (i <= oid->oid_arg2)
+ i = oid->oid_arg2 + 1;
+ }
+ if (i>9)
+ return 1;
+
+ /* Add the hw.dri.x for our device */
+ info->name[0] = '0' + i;
+ info->name[1] = 0;
+ top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
+ if (!top)
+ return 1;
+
+ for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
+ oid = SYSCTL_ADD_OID(&info->ctx,
+ SYSCTL_CHILDREN(top),
+ OID_AUTO,
+ drm_sysctl_list[i].name,
+ CTLTYPE_INT | CTLFLAG_RD,
+ dev,
+ 0,
+ drm_sysctl_list[i].f,
+ "A",
+ NULL);
+ if (!oid)
+ return 1;
+ }
+ SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(top), OID_AUTO, "debug",
+ CTLFLAG_RW, &drm_debug_flag, sizeof(drm_debug_flag),
+ "Enable debugging output");
+
+ return 0;
+}
+
+int drm_sysctl_cleanup(drm_device_t *dev)
+{
+ int error;
+ error = sysctl_ctx_free( &dev->sysctl->ctx );
+
+ free(dev->sysctl, M_DRM);
+ dev->sysctl = NULL;
+
+ return error;
+}
+
+#define DRM_SYSCTL_PRINT(fmt, arg...) \
+do { \
+ snprintf(buf, sizeof(buf), fmt, ##arg); \
+ retcode = SYSCTL_OUT(req, buf, strlen(buf)); \
+ if (retcode) \
+ goto done; \
+} while (0)
+
+static int drm_name_info DRM_SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ char buf[128];
+ int retcode;
+ int hasunique = 0;
+
+ DRM_SYSCTL_PRINT("%s 0x%x", dev->driver.name, dev2udev(dev->devnode));
+
+ DRM_LOCK();
+ if (dev->unique) {
+ snprintf(buf, sizeof(buf), " %s", dev->unique);
+ hasunique = 1;
+ }
+ DRM_UNLOCK();
+
+ if (hasunique)
+ SYSCTL_OUT(req, buf, strlen(buf));
+
+ SYSCTL_OUT(req, "", 1);
+
+done:
+ return retcode;
+}
+
+static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_local_map_t *map, *tempmaps;
+ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+ const char *type, *yesno;
+ int i, mapcount;
+ char buf[128];
+ int retcode;
+
+ /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
+ * temporary copy of all the map entries and then SYSCTL_OUT that.
+ */
+ DRM_LOCK();
+
+ mapcount = 0;
+ TAILQ_FOREACH(map, &dev->maplist, link)
+ mapcount++;
+
+ tempmaps = malloc(sizeof(drm_local_map_t) * mapcount, M_DRM, M_NOWAIT);
+ if (tempmaps == NULL) {
+ DRM_UNLOCK();
+ return ENOMEM;
+ }
+
+ i = 0;
+ TAILQ_FOREACH(map, &dev->maplist, link)
+ tempmaps[i++] = *map;
+
+ DRM_UNLOCK();
+
+ DRM_SYSCTL_PRINT("\nslot offset size type flags "
+ "address mtrr\n");
+
+ for (i = 0; i < mapcount; i++) {
+ map = &tempmaps[i];
+
+ if (map->type < 0 || map->type > 4)
+ type = "??";
+ else
+ type = types[map->type];
+
+ if (!map->mtrr)
+ yesno = "no";
+ else
+ yesno = "yes";
+
+ DRM_SYSCTL_PRINT(
+ "%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx %s\n", i,
+ map->offset, map->size, type, map->flags,
+ (unsigned long)map->handle, yesno);
+ }
+ SYSCTL_OUT(req, "", 1);
+
+done:
+ free(tempmaps, M_DRM);
+ return retcode;
+}
+
+static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_device_dma_t *dma = dev->dma;
+ drm_device_dma_t tempdma;
+ int *templists;
+ int i;
+ char buf[128];
+ int retcode;
+
+ /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
+ * copy of the whole structure and the relevant data from buflist.
+ */
+ DRM_LOCK();
+ if (dma == NULL) {
+ DRM_UNLOCK();
+ return 0;
+ }
+ DRM_SPINLOCK(&dev->dma_lock);
+ tempdma = *dma;
+ templists = malloc(sizeof(int) * dma->buf_count, M_DRM, M_NOWAIT);
+ for (i = 0; i < dma->buf_count; i++)
+ templists[i] = dma->buflist[i]->list;
+ dma = &tempdma;
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ DRM_UNLOCK();
+
+ DRM_SYSCTL_PRINT("\n o size count free segs pages kB\n");
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dma->bufs[i].buf_count)
+ DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
+ i,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].buf_count,
+ atomic_read(&dma->bufs[i]
+ .freelist.count),
+ dma->bufs[i].seg_count,
+ dma->bufs[i].seg_count
+ *(1 << dma->bufs[i].page_order),
+ (dma->bufs[i].seg_count
+ * (1 << dma->bufs[i].page_order))
+ * PAGE_SIZE / 1024);
+ }
+ DRM_SYSCTL_PRINT("\n");
+ for (i = 0; i < dma->buf_count; i++) {
+ if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
+ DRM_SYSCTL_PRINT(" %d", templists[i]);
+ }
+ DRM_SYSCTL_PRINT("\n");
+
+ SYSCTL_OUT(req, "", 1);
+done:
+ free(templists, M_DRM);
+ return retcode;
+}
+
+static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS
+{
+ drm_device_t *dev = arg1;
+ drm_file_t *priv, *tempprivs;
+ char buf[128];
+ int retcode;
+ int privcount, i;
+
+ DRM_LOCK();
+
+ privcount = 0;
+ TAILQ_FOREACH(priv, &dev->files, link)
+ privcount++;
+
+ tempprivs = malloc(sizeof(drm_file_t) * privcount, M_DRM, M_NOWAIT);
+ if (tempprivs == NULL) {
+ DRM_UNLOCK();
+ return ENOMEM;
+ }
+ i = 0;
+ TAILQ_FOREACH(priv, &dev->files, link)
+ tempprivs[i++] = *priv;
+
+ DRM_UNLOCK();
+
+ DRM_SYSCTL_PRINT("\na dev pid uid magic ioctls\n");
+ for (i = 0; i < privcount; i++) {
+ priv = &tempprivs[i];
+ DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
+ priv->authenticated ? 'y' : 'n',
+ priv->minor,
+ priv->pid,
+ priv->uid,
+ priv->magic,
+ priv->ioctl_count);
+ }
+
+ SYSCTL_OUT(req, "", 1);
+done:
+ free(tempprivs, M_DRM);
+ return retcode;
+}
diff --git a/nx-X11/extras/drm/bsd-core/drm_vm.c b/nx-X11/extras/drm/bsd-core/drm_vm.c
new file mode 100644
index 000000000..05ac7b154
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/drm_vm.c
@@ -0,0 +1,126 @@
+/*-
+ * Copyright 2003 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
+int drm_mmap(struct cdev *kdev, vm_offset_t offset, vm_paddr_t *paddr,
+ int prot)
+#elif defined(__FreeBSD__)
+int drm_mmap(dev_t kdev, vm_offset_t offset, int prot)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+paddr_t drm_mmap(dev_t kdev, off_t offset, int prot)
+#endif
+{
+ DRM_DEVICE;
+ drm_local_map_t *map;
+ drm_file_t *priv;
+ drm_map_type_t type;
+
+ DRM_LOCK();
+ priv = drm_find_file_by_proc(dev, DRM_CURPROC);
+ DRM_UNLOCK();
+ if (priv == NULL) {
+ DRM_ERROR("can't find authenticator\n");
+ return EINVAL;
+ }
+
+ if (!priv->authenticated)
+ return DRM_ERR(EACCES);
+
+ if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) {
+ drm_device_dma_t *dma = dev->dma;
+
+ DRM_SPINLOCK(&dev->dma_lock);
+
+ if (dma->pagelist != NULL) {
+ unsigned long page = offset >> PAGE_SHIFT;
+ unsigned long phys = dma->pagelist[page];
+
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
+ *paddr = phys;
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ return 0;
+#else
+ return atop(phys);
+#endif
+ } else {
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ return -1;
+ }
+ DRM_SPINUNLOCK(&dev->dma_lock);
+ }
+
+ /* A sequential search of a linked list is
+ fine here because: 1) there will only be
+ about 5-10 entries in the list and, 2) a
+ DRI client only has to do this mapping
+ once, so it doesn't have to be optimized
+ for performance, even if the list was a
+ bit longer. */
+ DRM_LOCK();
+ TAILQ_FOREACH(map, &dev->maplist, link) {
+ if (offset >= map->offset && offset < map->offset + map->size)
+ break;
+ }
+
+ if (map == NULL) {
+ DRM_UNLOCK();
+ DRM_DEBUG("can't find map\n");
+ return -1;
+ }
+ if (((map->flags&_DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) {
+ DRM_UNLOCK();
+ DRM_DEBUG("restricted map\n");
+ return -1;
+ }
+ type = map->type;
+ DRM_UNLOCK();
+
+ switch (type) {
+ case _DRM_FRAME_BUFFER:
+ case _DRM_REGISTERS:
+ case _DRM_AGP:
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
+ *paddr = offset;
+ return 0;
+#else
+ return atop(offset);
+#endif
+ case _DRM_SCATTER_GATHER:
+ case _DRM_SHM:
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
+ *paddr = vtophys(offset);
+ return 0;
+#else
+ return atop(vtophys(offset));
+#endif
+ default:
+ return -1; /* This should never happen. */
+ }
+ DRM_DEBUG("bailing out\n");
+
+ return -1;
+}
+
diff --git a/nx-X11/extras/drm/bsd-core/i915/.cvsignore b/nx-X11/extras/drm/bsd-core/i915/.cvsignore
new file mode 100644
index 000000000..350f6c68c
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/i915/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+i915.kld
+i915.ko
diff --git a/nx-X11/extras/drm/bsd-core/i915/Makefile b/nx-X11/extras/drm/bsd-core/i915/Makefile
new file mode 100644
index 000000000..6fd7d7287
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/i915/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = i915
+NO_MAN = YES
+SRCS = i915_dma.c i915_drv.c i915_irq.c i915_mem.c
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/i915_drv.c b/nx-X11/extras/drm/bsd-core/i915_drv.c
new file mode 100644
index 000000000..d99061416
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/i915_drv.c
@@ -0,0 +1,111 @@
+/* i915_drv.c -- ATI Radeon driver -*- linux-c -*-
+ * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
+ */
+/*-
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t i915_pciidlist[] = {
+ i915_PCI_IDS
+};
+
+extern drm_ioctl_desc_t i915_ioctls[];
+extern int i915_max_ioctl;
+
+static void i915_configure(drm_device_t *dev)
+{
+ dev->buf_priv_size = 1; /* No dev_priv */
+ dev->preclose = i915_driver_preclose;
+ dev->lastclose = i915_driver_lastclose;
+ dev->device_is_agp = i915_driver_device_is_agp,
+ dev->irq_preinstall = i915_driver_irq_preinstall;
+ dev->irq_postinstall = i915_driver_irq_postinstall;
+ dev->irq_uninstall = i915_driver_irq_uninstall;
+ dev->irq_handler = i915_driver_irq_handler;
+
+ dev->ioctls = i915_ioctls;
+ dev->max_ioctl = i915_max_ioctl;
+
+ dev->driver_name = DRIVER_NAME;
+ dev->driver_desc = DRIVER_DESC;
+ dev->driver_date = DRIVER_DATE;
+ dev->driver_major = DRIVER_MAJOR;
+ dev->driver_minor = DRIVER_MINOR;
+ dev->driver_patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->use_agp = 1;
+ dev->require_agp = 1;
+ dev->use_mtrr = 1;
+ dev->use_irq = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+i915_probe(device_t dev)
+{
+ return drm_probe(dev, i915_pciidlist);
+}
+
+static int
+i915_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ i915_configure(dev);
+ return drm_attach(nbdev, i915_pciidlist);
+}
+
+static device_method_t i915_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, i915_probe),
+ DEVMETHOD(device_attach, i915_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t i915_driver = {
+ "drmsub",
+ i915_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(i915, pci, i915_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(i915, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+CFDRIVER_DECL(i915, DV_TTY, NULL);
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/mach64/.cvsignore b/nx-X11/extras/drm/bsd-core/mach64/.cvsignore
new file mode 100644
index 000000000..b9a7055b1
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/mach64/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+mach64.kld
+mach64.ko
diff --git a/nx-X11/extras/drm/bsd-core/mach64/Makefile b/nx-X11/extras/drm/bsd-core/mach64/Makefile
new file mode 100644
index 000000000..1e6210d97
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/mach64/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = mach64
+NO_MAN = YES
+SRCS = mach64_dma.c mach64_drv.c mach64_irq.c mach64_state.c
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/mach64_drv.c b/nx-X11/extras/drm/bsd-core/mach64_drv.c
new file mode 100644
index 000000000..e63f56e5e
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/mach64_drv.c
@@ -0,0 +1,117 @@
+/* mach64_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+ * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
+ */
+/*-
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+
+#include <sys/types.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "mach64_drm.h"
+#include "mach64_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t mach64_pciidlist[] = {
+ mach64_PCI_IDS
+};
+
+extern drm_ioctl_desc_t mach64_ioctls[];
+extern int mach64_max_ioctl;
+
+static void mach64_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = 1; /* No dev_priv */
+ dev->driver.lastclose = mach64_driver_lastclose;
+ dev->driver.vblank_wait = mach64_driver_vblank_wait;
+ dev->driver.irq_preinstall = mach64_driver_irq_preinstall;
+ dev->driver.irq_postinstall = mach64_driver_irq_postinstall;
+ dev->driver.irq_uninstall = mach64_driver_irq_uninstall;
+ dev->driver.irq_handler = mach64_driver_irq_handler;
+ dev->driver.dma_ioctl = mach64_dma_buffers;
+
+ dev->driver.ioctls = mach64_ioctls;
+ dev->driver.max_ioctl = mach64_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_agp = 1;
+ dev->driver.use_mtrr = 1;
+ dev->driver.use_pci_dma = 1;
+ dev->driver.use_dma = 1;
+ dev->driver.use_irq = 1;
+ dev->driver.use_vbl_irq = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+mach64_probe(device_t dev)
+{
+ return drm_probe(dev, mach64_pciidlist);
+}
+
+static int
+mach64_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ mach64_configure(dev);
+ return drm_attach(nbdev, mach64_pciidlist);
+}
+
+static device_method_t mach64_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, mach64_probe),
+ DEVMETHOD(device_attach, mach64_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t mach64_driver = {
+ "drm",
+ mach64_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(mach64, pci, mach64_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(mach64, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+CFDRIVER_DECL(mach64, DV_TTY, NULL);
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/mga/.cvsignore b/nx-X11/extras/drm/bsd-core/mga/.cvsignore
new file mode 100644
index 000000000..0da9b1144
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/mga/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+mga.kld
+mga.ko
diff --git a/nx-X11/extras/drm/bsd-core/mga/Makefile b/nx-X11/extras/drm/bsd-core/mga/Makefile
new file mode 100644
index 000000000..2e534ce70
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/mga/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD= mga
+NO_MAN= YES
+SRCS= mga_drv.c mga_state.c mga_warp.c mga_dma.c mga_irq.c
+SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS+= ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/mga_drv.c b/nx-X11/extras/drm/bsd-core/mga_drv.c
new file mode 100644
index 000000000..c95561a86
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/mga_drv.c
@@ -0,0 +1,148 @@
+/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*-
+ * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
+ */
+/*-
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "mga_drm.h"
+#include "mga_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t mga_pciidlist[] = {
+ mga_PCI_IDS
+};
+
+extern drm_ioctl_desc_t mga_ioctls[];
+extern int mga_max_ioctl;
+
+/**
+ * Determine if the device really is AGP or not.
+ *
+ * In addition to the usual tests performed by \c drm_device_is_agp, this
+ * function detects PCI G450 cards that appear to the system exactly like
+ * AGP G450 cards.
+ *
+ * \param dev The device to be tested.
+ *
+ * \returns
+ * If the device is a PCI G450, zero is returned. Otherwise non-zero is
+ * returned.
+ *
+ * \bug
+ * This function needs to be filled in! The implementation in
+ * linux-core/mga_drv.c shows what needs to be done.
+ */
+static int mga_driver_device_is_agp(drm_device_t * dev)
+{
+ return 1;
+}
+
+static void mga_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = sizeof(drm_mga_buf_priv_t);
+ dev->driver.load = mga_driver_load;
+ dev->driver.unload = mga_driver_unload;
+ dev->driver.lastclose = mga_driver_lastclose;
+ dev->driver.vblank_wait = mga_driver_vblank_wait;
+ dev->driver.irq_preinstall = mga_driver_irq_preinstall;
+ dev->driver.irq_postinstall = mga_driver_irq_postinstall;
+ dev->driver.irq_uninstall = mga_driver_irq_uninstall;
+ dev->driver.irq_handler = mga_driver_irq_handler;
+ dev->driver.dma_ioctl = mga_dma_buffers;
+ dev->driver.dma_quiescent = mga_driver_dma_quiescent;
+ dev->driver.device_is_agp = mga_driver_device_is_agp;
+
+ dev->driver.ioctls = mga_ioctls;
+ dev->driver.max_ioctl = mga_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_agp = 1;
+ dev->driver.require_agp = 1;
+ dev->driver.use_mtrr = 1;
+ dev->driver.use_dma = 1;
+ dev->driver.use_irq = 1;
+ dev->driver.use_vbl_irq = 1;
+}
+
+
+
+#ifdef __FreeBSD__
+static int
+mga_probe(device_t dev)
+{
+ return drm_probe(dev, mga_pciidlist);
+}
+
+static int
+mga_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ mga_configure(dev);
+ return drm_attach(nbdev, mga_pciidlist);
+}
+
+static device_method_t mga_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, mga_probe),
+ DEVMETHOD(device_attach, mga_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t mga_driver = {
+ "drm",
+ mga_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(mga, pci, mga_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(mga, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef _LKM
+CFDRIVER_DECL(mga, DV_TTY, NULL);
+#else
+CFATTACH_DECL(mga, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach,
+ drm_activate);
+#endif
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/r128/.cvsignore b/nx-X11/extras/drm/bsd-core/r128/.cvsignore
new file mode 100644
index 000000000..0ee047ddd
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/r128/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+r128.kld
+r128.ko
diff --git a/nx-X11/extras/drm/bsd-core/r128/Makefile b/nx-X11/extras/drm/bsd-core/r128/Makefile
new file mode 100644
index 000000000..0b62d0b5a
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/r128/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = r128
+NO_MAN = YES
+SRCS = r128_cce.c r128_drv.c r128_state.c r128_irq.c
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/r128_drv.c b/nx-X11/extras/drm/bsd-core/r128_drv.c
new file mode 100644
index 000000000..a0e44c200
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/r128_drv.c
@@ -0,0 +1,122 @@
+/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
+ * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
+ */
+/*-
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "r128_drm.h"
+#include "r128_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t r128_pciidlist[] = {
+ r128_PCI_IDS
+};
+
+extern drm_ioctl_desc_t r128_ioctls[];
+extern int r128_max_ioctl;
+
+static void r128_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = sizeof(drm_r128_buf_priv_t);
+ dev->driver.preclose = r128_driver_preclose;
+ dev->driver.lastclose = r128_driver_lastclose;
+ dev->driver.vblank_wait = r128_driver_vblank_wait;
+ dev->driver.irq_preinstall = r128_driver_irq_preinstall;
+ dev->driver.irq_postinstall = r128_driver_irq_postinstall;
+ dev->driver.irq_uninstall = r128_driver_irq_uninstall;
+ dev->driver.irq_handler = r128_driver_irq_handler;
+ dev->driver.dma_ioctl = r128_cce_buffers;
+
+ dev->driver.ioctls = r128_ioctls;
+ dev->driver.max_ioctl = r128_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_agp = 1;
+ dev->driver.use_mtrr = 1;
+ dev->driver.use_pci_dma = 1;
+ dev->driver.use_sg = 1;
+ dev->driver.use_dma = 1;
+ dev->driver.use_irq = 1;
+ dev->driver.use_vbl_irq = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+r128_probe(device_t dev)
+{
+ return drm_probe(dev, r128_pciidlist);
+}
+
+static int
+r128_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ r128_configure(dev);
+ return drm_attach(nbdev, r128_pciidlist);
+}
+
+static device_method_t r128_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, r128_probe),
+ DEVMETHOD(device_attach, r128_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t r128_driver = {
+ "drm",
+ r128_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(r128, pci, r128_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(r128, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef _LKM
+CFDRIVER_DECL(r128, DV_TTY, NULL);
+#else
+CFATTACH_DECL(r128, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach,
+ drm_activate);
+#endif
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/radeon/.cvsignore b/nx-X11/extras/drm/bsd-core/radeon/.cvsignore
new file mode 100644
index 000000000..83df81daf
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/radeon/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+radeon.kld
+radeon.ko
diff --git a/nx-X11/extras/drm/bsd-core/radeon/Makefile b/nx-X11/extras/drm/bsd-core/radeon/Makefile
new file mode 100644
index 000000000..3348a869d
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/radeon/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = radeon
+NO_MAN = YES
+SRCS = r300_cmdbuf.c radeon_cp.c radeon_drv.c radeon_state.c radeon_irq.c \
+ radeon_mem.c
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/radeon_drv.c b/nx-X11/extras/drm/bsd-core/radeon_drv.c
new file mode 100644
index 000000000..470b6d3a0
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/radeon_drv.c
@@ -0,0 +1,127 @@
+/* radeon_drv.c -- ATI Radeon driver -*- linux-c -*-
+ * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
+ */
+/*-
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+#include "drm_pciids.h"
+
+int radeon_no_wb;
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t radeon_pciidlist[] = {
+ radeon_PCI_IDS
+};
+
+extern drm_ioctl_desc_t radeon_ioctls[];
+extern int radeon_max_ioctl;
+
+static void radeon_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = sizeof(drm_radeon_buf_priv_t);
+ dev->driver.load = radeon_driver_load;
+ dev->driver.unload = radeon_driver_unload;
+ dev->driver.firstopen = radeon_driver_firstopen;
+ dev->driver.open = radeon_driver_open;
+ dev->driver.preclose = radeon_driver_preclose;
+ dev->driver.postclose = radeon_driver_postclose;
+ dev->driver.lastclose = radeon_driver_lastclose;
+ dev->driver.vblank_wait = radeon_driver_vblank_wait;
+ dev->driver.irq_preinstall = radeon_driver_irq_preinstall;
+ dev->driver.irq_postinstall = radeon_driver_irq_postinstall;
+ dev->driver.irq_uninstall = radeon_driver_irq_uninstall;
+ dev->driver.irq_handler = radeon_driver_irq_handler;
+ dev->driver.dma_ioctl = radeon_cp_buffers;
+
+ dev->driver.ioctls = radeon_ioctls;
+ dev->driver.max_ioctl = radeon_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_agp = 1;
+ dev->driver.use_mtrr = 1;
+ dev->driver.use_pci_dma = 1;
+ dev->driver.use_sg = 1;
+ dev->driver.use_dma = 1;
+ dev->driver.use_irq = 1;
+ dev->driver.use_vbl_irq = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+radeon_probe(device_t dev)
+{
+ return drm_probe(dev, radeon_pciidlist);
+}
+
+static int
+radeon_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ radeon_configure(dev);
+ return drm_attach(nbdev, radeon_pciidlist);
+}
+
+static device_method_t radeon_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, radeon_probe),
+ DEVMETHOD(device_attach, radeon_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t radeon_driver = {
+ "drm",
+ radeon_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(radeon, pci, radeon_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(radeon, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef _LKM
+CFDRIVER_DECL(radeon, DV_TTY, NULL);
+#else
+CFATTACH_DECL(radeon, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach,
+ drm_activate);
+#endif
+#endif /* __FreeBSD__ */
diff --git a/nx-X11/extras/drm/bsd-core/savage/.cvsignore b/nx-X11/extras/drm/bsd-core/savage/.cvsignore
new file mode 100644
index 000000000..67e39f637
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/savage/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+savage.kld
+savage.ko
diff --git a/nx-X11/extras/drm/bsd-core/savage/Makefile b/nx-X11/extras/drm/bsd-core/savage/Makefile
new file mode 100644
index 000000000..ac51e3596
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/savage/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = savage
+NO_MAN = YES
+SRCS = savage_bci.c savage_drv.c savage_state.c
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/savage_drv.c b/nx-X11/extras/drm/bsd-core/savage_drv.c
new file mode 100644
index 000000000..c9a2fb103
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/savage_drv.c
@@ -0,0 +1,107 @@
+/* savage_drv.c -- Savage DRI driver
+ */
+/*-
+ * Copyright 2005 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "savage_drm.h"
+#include "savage_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t savage_pciidlist[] = {
+ savage_PCI_IDS
+};
+
+extern drm_ioctl_desc_t savage_ioctls[];
+extern int savage_max_ioctl;
+
+static void savage_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = sizeof(drm_savage_buf_priv_t);
+ dev->load = savage_driver_load;
+ dev->firstopen = savage_driver_firstopen;
+ dev->lastclose = savage_driver_lastclose;
+ dev->unload = savage_driver_unload;
+ dev->reclaim_buffers = savage_reclaim_buffers;
+ dev->dma_ioctl = savage_bci_buffers;
+
+ dev->ioctls = savage_ioctls;
+ dev->max_ioctl = savage_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->use_agp = 1;
+ dev->use_mtrr = 1;
+ dev->use_pci_dma = 1;
+ dev->use_dma = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+savage_probe(device_t dev)
+{
+ return drm_probe(dev, savage_pciidlist);
+}
+
+static int
+savage_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ savage_configure(dev);
+ return drm_attach(nbdev, savage_pciidlist);
+}
+
+static device_method_t savage_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, savage_probe),
+ DEVMETHOD(device_attach, savage_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t savage_driver = {
+ "drm",
+ savage_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(savage, pci, savage_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(savage, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+CFDRIVER_DECL(savage, DV_TTY, NULL);
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/sis/.cvsignore b/nx-X11/extras/drm/bsd-core/sis/.cvsignore
new file mode 100644
index 000000000..7495508ea
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/sis/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+sis.kld
+sis.ko
diff --git a/nx-X11/extras/drm/bsd-core/sis/Makefile b/nx-X11/extras/drm/bsd-core/sis/Makefile
new file mode 100644
index 000000000..e21a4ba41
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/sis/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD= sis
+NO_MAN= YES
+SRCS= sis_drv.c sis_ds.c sis_mm.c
+SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS+= ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/sis_drv.c b/nx-X11/extras/drm/bsd-core/sis_drv.c
new file mode 100644
index 000000000..342c7385f
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/sis_drv.c
@@ -0,0 +1,105 @@
+/* sis.c -- sis driver -*- linux-c -*-
+ */
+/*-
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drmP.h"
+#include "sis_drm.h"
+#include "sis_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t sis_pciidlist[] = {
+ sis_PCI_IDS
+};
+
+extern drm_ioctl_desc_t sis_ioctls[];
+extern int sis_max_ioctl;
+
+static void sis_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = 1; /* No dev_priv */
+ dev->driver.context_ctor = sis_init_context;
+ dev->driver.context_dtor = sis_final_context;
+
+ dev->driver.ioctls = sis_ioctls;
+ dev->driver.max_ioctl = sis_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_agp = 1;
+ dev->driver.use_mtrr = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+sis_probe(device_t dev)
+{
+ return drm_probe(dev, sis_pciidlist);
+}
+
+static int
+sis_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ sis_configure(dev);
+ return drm_attach(nbdev, sis_pciidlist);
+}
+
+static device_method_t sis_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sis_probe),
+ DEVMETHOD(device_attach, sis_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t sis_driver = {
+ "drm",
+ sis_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(sisdrm, pci, sis_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(sisdrm, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef _LKM
+CFDRIVER_DECL(sis, DV_TTY, NULL);
+#else
+CFATTACH_DECL(sis, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach,
+ drm_activate);
+#endif
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/tdfx/.cvsignore b/nx-X11/extras/drm/bsd-core/tdfx/.cvsignore
new file mode 100644
index 000000000..bf7cb7691
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/tdfx/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+tdfx.kld
+tdfx.ko
diff --git a/nx-X11/extras/drm/bsd-core/tdfx/Makefile b/nx-X11/extras/drm/bsd-core/tdfx/Makefile
new file mode 100644
index 000000000..5770491a3
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/tdfx/Makefile
@@ -0,0 +1,23 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD= tdfx
+NO_MAN= YES
+SRCS= tdfx_drv.c
+SRCS+= device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS+= ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/tdfx_drv.c b/nx-X11/extras/drm/bsd-core/tdfx_drv.c
new file mode 100644
index 000000000..40a552b9e
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/tdfx_drv.c
@@ -0,0 +1,106 @@
+/* tdfx_drv.c -- tdfx driver -*- linux-c -*-
+ * Created: Thu Oct 7 10:38:32 1999 by faith@precisioninsight.com
+ */
+/*-
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Daryll Strauss <daryll@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+#include "tdfx_drv.h"
+#include "drmP.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t tdfx_pciidlist[] = {
+ tdfx_PCI_IDS
+};
+
+extern drm_ioctl_desc_t tdfx_ioctls[];
+extern int tdfx_max_ioctl;
+
+static void tdfx_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = 1; /* No dev_priv */
+
+ dev->driver.max_ioctl = 0;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_mtrr = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+tdfx_probe(device_t dev)
+{
+ return drm_probe(dev, tdfx_pciidlist);
+}
+
+static int
+tdfx_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ tdfx_configure(dev);
+ return drm_attach(nbdev, tdfx_pciidlist);
+}
+
+static device_method_t tdfx_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, tdfx_probe),
+ DEVMETHOD(device_attach, tdfx_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t tdfx_driver = {
+ "drm",
+ tdfx_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(tdfx, pci, tdfx_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(tdfx, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef _LKM
+CFDRIVER_DECL(tdfx, DV_TTY, NULL);
+#else
+CFATTACH_DECL(tdfx, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach,
+ drm_activate);
+#endif
+#endif
diff --git a/nx-X11/extras/drm/bsd-core/via/.cvsignore b/nx-X11/extras/drm/bsd-core/via/.cvsignore
new file mode 100644
index 000000000..7a23987a5
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/via/.cvsignore
@@ -0,0 +1,8 @@
+.depend
+bus_if.h
+device_if.h
+export_syms
+opt_drm.h
+pci_if.h
+via.kld
+via.ko
diff --git a/nx-X11/extras/drm/bsd-core/via/Makefile b/nx-X11/extras/drm/bsd-core/via/Makefile
new file mode 100644
index 000000000..7aaa01dfe
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/via/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/..
+KMOD = via
+NO_MAN = YES
+SRCS = via_dma.c via_drv.c via_ds.c via_irq.c via_map.c via_mm.c \
+ via_verifier.c via_video.c
+SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
+CFLAGS += ${DEBUG_FLAGS} -I. -I..
+
+.if defined(DRM_DEBUG)
+DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
+.endif
+
+.if !defined(DRM_NOLINUX)
+DRM_LINUX_OPT= "\#define DRM_LINUX 1"
+.endif
+
+opt_drm.h:
+ touch opt_drm.h
+ echo $(DRM_DEBUG_OPT) >> opt_drm.h
+ echo $(DRM_LINUX_OPT) >> opt_drm.h
+
+.include <bsd.kmod.mk>
diff --git a/nx-X11/extras/drm/bsd-core/via_drv.c b/nx-X11/extras/drm/bsd-core/via_drv.c
new file mode 100644
index 000000000..c90af66d0
--- /dev/null
+++ b/nx-X11/extras/drm/bsd-core/via_drv.c
@@ -0,0 +1,118 @@
+/* via_drv.c -- VIA unichrome driver -*- linux-c -*-
+ * Created: Fri Aug 12 2005 by anholt@FreeBSD.org
+ */
+/*-
+ * Copyright 2005 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_drv.h"
+#include "drm_pciids.h"
+
+/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
+static drm_pci_id_list_t via_pciidlist[] = {
+ viadrv_PCI_IDS
+};
+
+extern drm_ioctl_desc_t via_ioctls[];
+extern int via_max_ioctl;
+
+static void via_configure(drm_device_t *dev)
+{
+ dev->driver.buf_priv_size = 1;
+ dev->driver.load = via_driver_load;
+ dev->driver.unload = via_driver_unload;
+ dev->driver.context_ctor = via_init_context;
+ dev->driver.context_dtor = via_final_context;
+ dev->driver.vblank_wait = via_driver_vblank_wait;
+ dev->driver.irq_preinstall = via_driver_irq_preinstall;
+ dev->driver.irq_postinstall = via_driver_irq_postinstall;
+ dev->driver.irq_uninstall = via_driver_irq_uninstall;
+ dev->driver.irq_handler = via_driver_irq_handler;
+ dev->driver.dma_quiescent = via_driver_dma_quiescent;
+
+ dev->driver.ioctls = via_ioctls;
+ dev->driver.max_ioctl = via_max_ioctl;
+
+ dev->driver.name = DRIVER_NAME;
+ dev->driver.desc = DRIVER_DESC;
+ dev->driver.date = DRIVER_DATE;
+ dev->driver.major = DRIVER_MAJOR;
+ dev->driver.minor = DRIVER_MINOR;
+ dev->driver.patchlevel = DRIVER_PATCHLEVEL;
+
+ dev->driver.use_agp = 1;
+ dev->driver.use_mtrr = 1;
+ dev->driver.use_irq = 1;
+ dev->driver.use_vbl_irq = 1;
+}
+
+#ifdef __FreeBSD__
+static int
+via_probe(device_t dev)
+{
+ return drm_probe(dev, via_pciidlist);
+}
+
+static int
+via_attach(device_t nbdev)
+{
+ drm_device_t *dev = device_get_softc(nbdev);
+
+ bzero(dev, sizeof(drm_device_t));
+ via_configure(dev);
+ return drm_attach(nbdev, via_pciidlist);
+}
+
+static device_method_t via_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, via_probe),
+ DEVMETHOD(device_attach, via_attach),
+ DEVMETHOD(device_detach, drm_detach),
+
+ { 0, 0 }
+};
+
+static driver_t via_driver = {
+ "drm",
+ via_methods,
+ sizeof(drm_device_t)
+};
+
+extern devclass_t drm_devclass;
+DRIVER_MODULE(via, pci, via_driver, drm_devclass, 0, 0);
+MODULE_DEPEND(via, drm, 1, 1, 1);
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#ifdef _LKM
+CFDRIVER_DECL(via, DV_TTY, NULL);
+#else
+CFATTACH_DECL(via, sizeof(drm_device_t), drm_probe, drm_attach, drm_detach,
+ drm_activate);
+#endif
+#endif