diff options
Diffstat (limited to 'nx-X11/extras/drm/bsd-core')
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 |