DRM update to git snapshot from 2008-01-04.
authorHasso Tepper <hasso@dragonflybsd.org>
Sat, 5 Apr 2008 18:12:30 +0000 (18:12 +0000)
committerHasso Tepper <hasso@dragonflybsd.org>
Sat, 5 Apr 2008 18:12:30 +0000 (18:12 +0000)
116 files changed:
sys/conf/files
sys/config/LINT
sys/dev/drm/Makefile
sys/dev/drm/Makefile.inc [deleted file]
sys/dev/drm/ati_pcigart.c [new file with mode: 0644]
sys/dev/drm/ati_pcigart.h [deleted file]
sys/dev/drm/drm.h
sys/dev/drm/drm/Makefile [new file with mode: 0644]
sys/dev/drm/drmP.h
sys/dev/drm/drm_agpsupport.c [new file with mode: 0644]
sys/dev/drm/drm_agpsupport.h [deleted file]
sys/dev/drm/drm_atomic.h [new file with mode: 0644]
sys/dev/drm/drm_auth.c [moved from sys/dev/drm/drm_auth.h with 51% similarity]
sys/dev/drm/drm_bufs.c [new file with mode: 0644]
sys/dev/drm/drm_bufs.h [deleted file]
sys/dev/drm/drm_context.c [new file with mode: 0644]
sys/dev/drm/drm_context.h [deleted file]
sys/dev/drm/drm_dma.c [new file with mode: 0644]
sys/dev/drm/drm_dma.h [deleted file]
sys/dev/drm/drm_drawable.c [new file with mode: 0644]
sys/dev/drm/drm_drv.c [new file with mode: 0644]
sys/dev/drm/drm_drv.h [deleted file]
sys/dev/drm/drm_fops.c [moved from sys/dev/drm/drm_fops.h with 58% similarity]
sys/dev/drm/drm_internal.h [moved from sys/dev/drm/drm_drawable.h with 57% similarity]
sys/dev/drm/drm_ioctl.c [new file with mode: 0644]
sys/dev/drm/drm_ioctl.h [deleted file]
sys/dev/drm/drm_irq.c [new file with mode: 0644]
sys/dev/drm/drm_linux_list.h [new file with mode: 0644]
sys/dev/drm/drm_lock.c [new file with mode: 0644]
sys/dev/drm/drm_lock.h [deleted file]
sys/dev/drm/drm_memory.c [new file with mode: 0644]
sys/dev/drm/drm_memory.h [deleted file]
sys/dev/drm/drm_os_freebsd.h [deleted file]
sys/dev/drm/drm_pci.c [new file with mode: 0644]
sys/dev/drm/drm_pciids.h [new file with mode: 0644]
sys/dev/drm/drm_sarea.h
sys/dev/drm/drm_scatter.c [new file with mode: 0644]
sys/dev/drm/drm_scatter.h [deleted file]
sys/dev/drm/drm_sysctl.c [new file with mode: 0644]
sys/dev/drm/drm_sysctl.h [deleted file]
sys/dev/drm/drm_vm.c [new file with mode: 0644]
sys/dev/drm/drm_vm.h [deleted file]
sys/dev/drm/i915/Makefile [new file with mode: 0644]
sys/dev/drm/i915_dma.c [new file with mode: 0644]
sys/dev/drm/i915_drm.h [new file with mode: 0644]
sys/dev/drm/i915_drv.c [new file with mode: 0644]
sys/dev/drm/i915_drv.h [new file with mode: 0644]
sys/dev/drm/i915_irq.c [new file with mode: 0644]
sys/dev/drm/i915_mem.c [new file with mode: 0644]
sys/dev/drm/mach64/Makefile [new file with mode: 0644]
sys/dev/drm/mach64_dma.c [new file with mode: 0644]
sys/dev/drm/mach64_drm.h [new file with mode: 0644]
sys/dev/drm/mach64_drv.c [new file with mode: 0644]
sys/dev/drm/mach64_drv.h [new file with mode: 0644]
sys/dev/drm/mach64_irq.c [new file with mode: 0644]
sys/dev/drm/mach64_state.c [new file with mode: 0644]
sys/dev/drm/mga/Makefile
sys/dev/drm/mga/mga.h [deleted file]
sys/dev/drm/mga/mga_dma.c [deleted file]
sys/dev/drm/mga/mga_drv.c [deleted file]
sys/dev/drm/mga/mga_irq.c [deleted file]
sys/dev/drm/mga/mga_state.c [deleted file]
sys/dev/drm/mga/mga_ucode.h [deleted file]
sys/dev/drm/mga/mga_warp.c [deleted file]
sys/dev/drm/mga_dma.c [new file with mode: 0644]
sys/dev/drm/mga_drm.h [moved from sys/dev/drm/mga/mga_drm.h with 51% similarity]
sys/dev/drm/mga_drv.c [new file with mode: 0644]
sys/dev/drm/mga_drv.h [moved from sys/dev/drm/mga/mga_drv.h with 68% similarity]
sys/dev/drm/mga_irq.c [new file with mode: 0644]
sys/dev/drm/mga_state.c [new file with mode: 0644]
sys/dev/drm/mga_ucode.h [new file with mode: 0644]
sys/dev/drm/mga_warp.c [new file with mode: 0644]
sys/dev/drm/r128/Makefile
sys/dev/drm/r128/r128.h [deleted file]
sys/dev/drm/r128/r128_cce.c [deleted file]
sys/dev/drm/r128/r128_drv.c [deleted file]
sys/dev/drm/r128/r128_state.c [deleted file]
sys/dev/drm/r128_cce.c [new file with mode: 0644]
sys/dev/drm/r128_drm.h [moved from sys/dev/drm/r128/r128_drm.h with 67% similarity]
sys/dev/drm/r128_drv.c [new file with mode: 0644]
sys/dev/drm/r128_drv.h [moved from sys/dev/drm/r128/r128_drv.h with 77% similarity]
sys/dev/drm/r128_irq.c [moved from sys/dev/drm/r128/r128_irq.c with 56% similarity]
sys/dev/drm/r128_state.c [new file with mode: 0644]
sys/dev/drm/r300_cmdbuf.c [new file with mode: 0644]
sys/dev/drm/r300_reg.h [new file with mode: 0644]
sys/dev/drm/radeon/Makefile
sys/dev/drm/radeon/radeon.h [deleted file]
sys/dev/drm/radeon/radeon_cp.c [deleted file]
sys/dev/drm/radeon/radeon_drm.h [deleted file]
sys/dev/drm/radeon/radeon_drv.c [deleted file]
sys/dev/drm/radeon/radeon_irq.c [deleted file]
sys/dev/drm/radeon/radeon_state.c [deleted file]
sys/dev/drm/radeon_cp.c [new file with mode: 0644]
sys/dev/drm/radeon_drm.h [new file with mode: 0644]
sys/dev/drm/radeon_drv.c [new file with mode: 0644]
sys/dev/drm/radeon_drv.h [moved from sys/dev/drm/radeon/radeon_drv.h with 57% similarity]
sys/dev/drm/radeon_irq.c [new file with mode: 0644]
sys/dev/drm/radeon_mem.c [moved from sys/dev/drm/radeon/radeon_mem.c with 50% similarity]
sys/dev/drm/radeon_state.c [new file with mode: 0644]
sys/dev/drm/savage/Makefile [new file with mode: 0644]
sys/dev/drm/savage_bci.c [new file with mode: 0644]
sys/dev/drm/savage_drm.h [new file with mode: 0644]
sys/dev/drm/savage_drv.c [new file with mode: 0644]
sys/dev/drm/savage_drv.h [new file with mode: 0644]
sys/dev/drm/savage_state.c [new file with mode: 0644]
sys/dev/drm/sis/Makefile [new file with mode: 0644]
sys/dev/drm/sis_drm.h [new file with mode: 0644]
sys/dev/drm/sis_drv.c [new file with mode: 0644]
sys/dev/drm/sis_drv.h [new file with mode: 0644]
sys/dev/drm/sis_ds.c [new file with mode: 0644]
sys/dev/drm/sis_ds.h [new file with mode: 0644]
sys/dev/drm/sis_mm.c [new file with mode: 0644]
sys/dev/drm/tdfx/Makefile
sys/dev/drm/tdfx/tdfx_drv.c [deleted file]
sys/dev/drm/tdfx_drv.c [new file with mode: 0644]
sys/dev/drm/tdfx_drv.h [moved from sys/dev/drm/tdfx/tdfx.h with 82% similarity]

index 3cf7a16..be9196e 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $
-# $DragonFly: src/sys/conf/files,v 1.211 2008/03/22 21:24:44 dillon Exp $
+# $DragonFly: src/sys/conf/files,v 1.212 2008/04/05 18:12:28 hasso Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -1349,22 +1349,54 @@ opencrypto/rmd160.c                     optional crypto
 opencrypto/skipjack.c                  optional crypto
 opencrypto/xform.c                     optional crypto
 dev/crypto/ubsec/ubsec.c               optional ubsec
-dev/crypto/hifn/hifn7751.c             optional hifn 
-dev/drm/mga/mga_dma.c                  optional mgadrm
-dev/drm/mga/mga_drv.c                  optional mgadrm
-dev/drm/mga/mga_irq.c                  optional mgadrm
-dev/drm/mga/mga_state.c                        optional mgadrm
-dev/drm/mga/mga_warp.c                 optional mgadrm
-dev/drm/r128/r128_cce.c                        optional r128drm
-dev/drm/r128/r128_drv.c                        optional r128drm
-dev/drm/r128/r128_irq.c                        optional r128drm
-dev/drm/r128/r128_state.c              optional r128drm
-dev/drm/radeon/radeon_cp.c             optional radeondrm
-dev/drm/radeon/radeon_drv.c            optional radeondrm
-dev/drm/radeon/radeon_irq.c            optional radeondrm
-dev/drm/radeon/radeon_mem.c            optional radeondrm
-dev/drm/radeon/radeon_state.c          optional radeondrm
-dev/drm/tdfx/tdfx_drv.c                        optional tdfxdrm
+dev/crypto/hifn/hifn7751.c             optional hifn
+dev/drm/ati_pcigart.c                  optional drm
+dev/drm/drm_agpsupport.c               optional drm
+dev/drm/drm_auth.c                     optional drm
+dev/drm/drm_bufs.c                     optional drm
+dev/drm/drm_context.c                  optional drm
+dev/drm/drm_dma.c                      optional drm
+dev/drm/drm_drawable.c                 optional drm
+dev/drm/drm_drv.c                      optional drm
+dev/drm/drm_fops.c                     optional drm
+dev/drm/drm_ioctl.c                    optional drm
+dev/drm/drm_irq.c                      optional drm
+dev/drm/drm_lock.c                     optional drm
+dev/drm/drm_memory.c                   optional drm
+dev/drm/drm_pci.c                      optional drm
+dev/drm/drm_scatter.c                  optional drm
+dev/drm/drm_sysctl.c                   optional drm
+dev/drm/drm_vm.c                       optional drm
+dev/drm/i915_dma.c                     optional i915drm drm
+dev/drm/i915_drv.c                     optional i915drm drm
+dev/drm/i915_irq.c                     optional i915drm drm
+dev/drm/i915_mem.c                     optional i915drm drm
+dev/drm/mach64_dma.c                   optional mach64drm drm
+dev/drm/mach64_drv.c                   optional mach64drm drm
+dev/drm/mach64_irq.c                   optional mach64drm drm
+dev/drm/mach64_state.c                 optional mach64drm drm
+dev/drm/mga_drv.c                      optional mgadrm drm
+dev/drm/mga_state.c                    optional mgadrm drm
+dev/drm/mga_warp.c                     optional mgadrm drm
+dev/drm/mga_dma.c                      optional mgadrm drm
+dev/drm/mga_irq.c                      optional mgadrm drm
+dev/drm/r128_cce.c                     optional r128drm drm
+dev/drm/r128_drv.c                     optional r128drm drm
+dev/drm/r128_state.c                   optional r128drm drm
+dev/drm/r128_irq.c                     optional r128drm drm
+dev/drm/r300_cmdbuf.c                  optional radeondrm drm
+dev/drm/radeon_cp.c                    optional radeondrm drm
+dev/drm/radeon_drv.c                   optional radeondrm drm
+dev/drm/radeon_state.c                 optional radeondrm drm
+dev/drm/radeon_irq.c                   optional radeondrm drm
+dev/drm/radeon_mem.c                   optional radeondrm drm
+dev/drm/savage_bci.c                   optional savagedrm drm
+dev/drm/savage_drv.c                   optional savagedrm drm
+dev/drm/savage_state.c                 optional savagedrm drm
+dev/drm/sis_drv.c                      optional sisdrm drm
+dev/drm/sis_ds.c                       optional sisdrm drm
+dev/drm/sis_mm.c                       optional sisdrm drm
+dev/drm/tdfx_drv.c                     optional tdfxdrm drm
 dev/powermng/it/it.c                   optional it isa
 dev/powermng/lm/lm78.c                 optional lm isa
 dev/powermng/lm/lm78_isa.c             optional lm isa
index 2dd6ecb..3da4c1b 100644 (file)
@@ -3,7 +3,7 @@
 #      as much of the source tree as it can.
 #
 # $FreeBSD: src/sys/i386/conf/LINT,v 1.749.2.144 2003/06/04 17:56:59 sam Exp $
-# $DragonFly: src/sys/config/LINT,v 1.153 2008/04/02 13:11:48 sephe Exp $
+# $DragonFly: src/sys/config/LINT,v 1.154 2008/04/05 18:12:28 hasso Exp $
 #
 # NB: You probably don't want to try running a kernel built from this
 # file.  Instead, you should start from GENERIC, and add options from
@@ -2642,18 +2642,28 @@ device          acpi            # basic ACPI support
 device         pmtimer         # adjust the system clock after resume
 
 # DRM options:
-# mgadrm:    AGP Matrox G200, G400, G450, G550
-# tdfxdrm:   3dfx Voodoo 3/4/5 and Banshee
-# r128drm:   ATI Rage 128
-# radeondrm: ATI Radeon up to 9000/9100
-# DRM_DEBUG: include debug printfs, very slow
-#
-# mga requires AGP in the kernel, and it is recommended
-# for AGP r128 and radeon cards.
-
+# drm:         General DRM code
+# i915drm:     Intel i830, i845, i915, i945, i965, G33/35
+# mach64drm:   ATI Mach64 cards - Rage and 3D Rage series
+# mgadrm:      AGP Matrox G200, G400, G450, G550
+# r128drm:     ATI Rage 128 cards
+# radeondrm:   ATI Radeon cards
+# savagedrm:   Savage cards
+# sisdrm:      Sis cards
+# tdfxdrm:     3dfx Voodoo 3/4/5 and Banshee
+#
+# DRM_DEBUG:   include debug printfs, very slow
+#
+# DRM requires AGP in the kernel.
+
+device         drm
+device         "i915drm"
+device         "mach64drm"
 device         mgadrm
 device         "r128drm"
 device         radeondrm
+device         savagedrm
+device         sisdrm
 device         tdfxdrm
 
 options        DRM_DEBUG
index 26177ec..c3f0918 100644 (file)
@@ -1,6 +1,6 @@
-# $FreeBSD: src/sys/modules/drm/Makefile,v 1.2.2.1 2003/04/26 07:31:06 anholt Exp $
-# $DragonFly: src/sys/dev/drm/Makefile,v 1.2 2003/06/17 04:28:43 dillon Exp $
+# $DragonFly: src/sys/dev/drm/Makefile,v 1.3 2008/04/05 18:12:28 hasso Exp $
 
-SUBDIR = mga r128 radeon tdfx
+SUBDIR = drm mach64 mga r128 radeon savage sis tdfx i915
+
+.include <bsd.obj.mk>
 
-.include <bsd.subdir.mk>
diff --git a/sys/dev/drm/Makefile.inc b/sys/dev/drm/Makefile.inc
deleted file mode 100644 (file)
index 3509a20..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# $FreeBSD: src/sys/modules/drm/Makefile.inc,v 1.1.4.1 2003/04/26 07:31:06 anholt Exp $
-# $DragonFly: src/sys/dev/drm/Attic/Makefile.inc,v 1.3 2003/08/15 08:32:29 dillon Exp $
-
-#.include "../Makefile.inc"
diff --git a/sys/dev/drm/ati_pcigart.c b/sys/dev/drm/ati_pcigart.c
new file mode 100644 (file)
index 0000000..487348f
--- /dev/null
@@ -0,0 +1,108 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/ati_pcigart.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file ati_pcigart.c
+ * Implementation of ATI's PCIGART, which provides an aperture in card virtual
+ * address space with addresses remapped to system memory.
+ */
+
+#include "drmP.h"
+
+#define ATI_PCIGART_PAGE_SIZE          4096    /* PCI GART page size */
+
+int drm_ati_pcigart_init(drm_device_t *dev, struct 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, gart_info->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, gart_info->table_size / sizeof(u32));
+
+       bzero(pci_gart, gart_info->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++) {
+                       switch(gart_info->gart_reg_if) {
+                       case DRM_ATI_GART_IGP:
+                               *pci_gart = cpu_to_le32(page_base | 0xc);
+                               break;
+                       case DRM_ATI_GART_PCIE:
+                               *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
+                               break;
+                       default:
+                               *pci_gart = cpu_to_le32(page_base);
+                               break;
+                       }
+                       pci_gart++;
+                       page_base += ATI_PCIGART_PAGE_SIZE;
+               }
+       }
+
+       DRM_MEMORYBARRIER();
+
+       return 1;
+}
+
+int drm_ati_pcigart_cleanup(drm_device_t *dev, struct 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/sys/dev/drm/ati_pcigart.h b/sys/dev/drm/ati_pcigart.h
deleted file mode 100644 (file)
index 48bd3d1..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* 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>
- *
- * $FreeBSD: src/sys/dev/drm/ati_pcigart.h,v 1.1.2.1 2003/04/26 07:05:27 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/ati_pcigart.h,v 1.3 2004/02/13 01:23:57 joerg Exp $
- */
-
-#include "dev/drm/drmP.h"
-
-#if PAGE_SIZE == 8192
-# define ATI_PCIGART_TABLE_ORDER       2
-# define ATI_PCIGART_TABLE_PAGES       (1 << 2)
-#elif PAGE_SIZE == 4096
-# define ATI_PCIGART_TABLE_ORDER       3
-# define ATI_PCIGART_TABLE_PAGES       (1 << 3)
-#elif
-# error - PAGE_SIZE not 8K or 4K
-#endif
-
-# define ATI_MAX_PCIGART_PAGES         8192    /* 32 MB aperture, 4K pages */
-# define ATI_PCIGART_PAGE_SIZE         4096    /* PCI GART page size */
-
-int DRM(ati_pcigart_init)( drm_device_t *dev,
-                          unsigned long *addr,
-                          dma_addr_t *bus_addr)
-{
-       drm_sg_mem_t *entry = dev->sg;
-       unsigned long address = 0;
-       unsigned long pages;
-       u32 *pci_gart=0, page_base, bus_address = 0;
-       int i, j, ret = 0;
-
-       if ( !entry ) {
-               DRM_ERROR( "no scatter/gather memory!\n" );
-               goto done;
-       }
-
-       address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, 
-           DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0);
-       if ( !address ) {
-               DRM_ERROR( "cannot allocate PCI GART page!\n" );
-               goto done;
-       }
-
-       /* XXX: we need to busdma this */
-       bus_address = vtophys( address );
-
-       pci_gart = (u32 *)address;
-
-       pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
-               ? entry->pages : ATI_MAX_PCIGART_PAGES;
-
-       bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
-
-       for ( i = 0 ; i < pages ; i++ ) {
-               entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) );
-               page_base = (u32) entry->busaddr[i];
-
-               for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
-                       *pci_gart++ = cpu_to_le32( page_base );
-                       page_base += ATI_PCIGART_PAGE_SIZE;
-               }
-       }
-
-       ret = 1;
-
-done:
-       *addr = address;
-       *bus_addr = bus_address;
-       return ret;
-}
-
-int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
-                             unsigned long addr,
-                             dma_addr_t bus_addr)
-{
-       drm_sg_mem_t *entry = dev->sg;
-
-       /* we need to support large memory configurations */
-       if ( !entry ) {
-               DRM_ERROR( "no scatter/gather memory!\n" );
-               return 0;
-       }
-
-#if defined(__FreeBSD__) && __FreeBSD_version > 500000
-       contigfree( (void *)addr, (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM));      /* Not available on 4.x */
-#endif
-       return 1;
-}
index 95eadd3..c50f843 100644 (file)
@@ -1,6 +1,14 @@
-/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
- * Created: Mon Jan  4 10:05:05 1999 by faith@precisioninsight.com
+/**
+ * \file drm.h
+ * Header for the Direct Rendering Manager
  *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ * \par Acknowledgments:
+ * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
+ */
+
+/*
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All rights reserved.
  * 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>
+ * $DragonFly: src/sys/dev/drm/drm.h,v 1.4 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/**
+ * \mainpage
+ *
+ * The Direct Rendering Manager (DRM) is a device-independent kernel-level
+ * device driver that provides support for the XFree86 Direct Rendering
+ * Infrastructure (DRI).
  *
- * Acknowledgements:
- * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
+ * The DRM supports the Direct Rendering Infrastructure (DRI) in four major
+ * ways:
+ *     -# The DRM provides synchronized access to the graphics hardware via
+ *        the use of an optimized two-tiered lock.
+ *     -# The DRM enforces the DRI security policy for access to the graphics
+ *        hardware by only allowing authenticated X11 clients access to
+ *        restricted regions of memory.
+ *     -# The DRM provides a generic DMA engine, complete with multiple
+ *        queues and the ability to detect the need for an OpenGL context
+ *        switch.
+ *     -# The DRM is extensible via the use of small device-specific modules
+ *        that rely extensively on the API exported by the DRM module.
  *
- * $FreeBSD: src/sys/dev/drm/drm.h,v 1.3.2.1 2003/04/26 07:05:27 anholt Exp $
- * $DragonFly: src/sys/dev/drm/drm.h,v 1.3 2004/02/13 01:23:57 joerg Exp $
  */
 
 #ifndef _DRM_H_
 #define _DRM_H_
 
+#ifndef __user
+#define __user
+#endif
+#ifndef __iomem
+#define __iomem
+#endif
+
+#ifdef __GNUC__
+# define DEPRECATED  __attribute__ ((deprecated))
+#else
+# define DEPRECATED
+#endif
+
 #if defined(__linux__)
-#include <linux/config.h>
 #include <asm/ioctl.h>         /* For _IO* macros */
 #define DRM_IOCTL_NR(n)                _IOC_NR(n)
 #define DRM_IOC_VOID           _IOC_NONE
 #define DRM_IOC_WRITE          _IOC_WRITE
 #define DRM_IOC_READWRITE      _IOC_READ|_IOC_WRITE
 #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
-#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
-#if (defined(__DragonFly__) || defined(__FreeBSD__)) && defined(XFree86Server)
-/* Prevent name collision when including sys/ioccom.h */
-#undef ioctl
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
 #include <sys/ioccom.h>
-#define ioctl(a,b,c)           xf86ioctl(a,b,c)
-#else
-#include <sys/ioccom.h>
-#endif /* __FreeBSD__ && xf86ioctl */
 #define DRM_IOCTL_NR(n)                ((n) & 0xff)
 #define DRM_IOC_VOID           IOC_VOID
 #define DRM_IOC_READ           IOC_OUT
 #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
 #endif
 
-#define XFREE86_VERSION(major,minor,patch,snap) \
-               ((major << 16) | (minor << 8) | patch)
-
-#ifndef CONFIG_XFREE86_VERSION
-#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
-#endif
-
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
-#define DRM_PROC_DEVICES "/proc/devices"
-#define DRM_PROC_MISC   "/proc/misc"
-#define DRM_PROC_DRM    "/proc/drm"
-#define DRM_DEV_DRM     "/dev/drm"
-#define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID     0
-#define DRM_DEV_GID     0
+#ifdef __OpenBSD__
+#define DRM_MAJOR       81
 #endif
-
-#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
+#if defined(__linux__) || defined(__NetBSD__)
 #define DRM_MAJOR       226
-#define DRM_MAX_MINOR   15
 #endif
-#define DRM_NAME       "drm"     /* Name in kernel, /dev, and /proc        */
-#define DRM_MIN_ORDER  5         /* At least 2^5 bytes = 32 bytes          */
-#define DRM_MAX_ORDER  22        /* Up to 2^22 bytes = 4MB                 */
-#define DRM_RAM_PERCENT 10       /* How much system ram can we lock?       */
+#define DRM_MAX_MINOR   15
+
+#define DRM_NAME       "drm"     /**< Name in kernel, /dev, and /proc */
+#define DRM_MIN_ORDER  5         /**< At least 2^5 bytes = 32 bytes */
+#define DRM_MAX_ORDER  22        /**< Up to 2^22 bytes = 4MB */
+#define DRM_RAM_PERCENT 10       /**< How much system ram can we lock? */
 
-#define _DRM_LOCK_HELD 0x80000000 /* Hardware lock is held                 */
-#define _DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended            */
+#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
+#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
 #define _DRM_LOCK_IS_HELD(lock)           ((lock) & _DRM_LOCK_HELD)
 #define _DRM_LOCK_IS_CONT(lock)           ((lock) & _DRM_LOCK_CONT)
 #define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
 
-typedef unsigned long drm_handle_t;
-typedef unsigned int  drm_context_t;
-typedef unsigned int  drm_drawable_t;
-typedef unsigned int  drm_magic_t;
-
-/* Warning: If you change this structure, make sure you change
- * XF86DRIClipRectRec in the server as well */
+#if defined(__linux__)
+typedef unsigned int drm_handle_t;
+#else
+#include <sys/types.h>
+typedef unsigned long drm_handle_t;    /**< To mapped regions */
+#endif
+typedef unsigned int drm_context_t;    /**< GLXContext handle */
+typedef unsigned int drm_drawable_t;
+typedef unsigned int drm_magic_t;      /**< Magic for authentication */
 
-/* KW: Actually it's illegal to change either for
+/**
+ * Cliprect.
+ *
+ * \warning If you change this structure, make sure you change
+ * XF86DRIClipRectRec in the server as well
+ *
+ * \note KW: Actually it's illegal to change either for
  * backwards-compatibility reasons.
  */
+struct drm_clip_rect {
+       unsigned short x1;
+       unsigned short y1;
+       unsigned short x2;
+       unsigned short y2;
+};
+
+/**
+ * Texture region,
+ */
+struct drm_tex_region {
+       unsigned char next;
+       unsigned char prev;
+       unsigned char in_use;
+       unsigned char padding;
+       unsigned int age;
+};
+
+/**
+ * Hardware lock.
+ *
+ * The lock structure is a simple cache-line aligned integer.  To avoid
+ * processor bus contention on a multiprocessor system, there should not be any
+ * other data stored in the same cache line.
+ */
+struct drm_hw_lock {
+       __volatile__ unsigned int lock;         /**< lock variable */
+       char padding[60];                       /**< Pad to cache line */
+};
+
+/* This is beyond ugly, and only works on GCC.  However, it allows me to use
+ * drm.h in places (i.e., in the X-server) where I can't use size_t.  The real
+ * fix is to use uint32_t instead of size_t, but that fix will break existing
+ * LP64 (i.e., PowerPC64, SPARC64, IA-64, Alpha, etc.) systems.  That *will*
+ * eventually happen, though.  I chose 'unsigned long' to be the fallback type
+ * because that works on all the platforms I know about.  Hopefully, the
+ * real fix will happen before that bites us.
+ */
+
+#ifdef __SIZE_TYPE__
+# define DRM_SIZE_T __SIZE_TYPE__
+#else
+# warning "__SIZE_TYPE__ not defined.  Assuming sizeof(size_t) == sizeof(unsigned long)!"
+# define DRM_SIZE_T unsigned long
+#endif
+
+/**
+ * DRM_IOCTL_VERSION ioctl argument type.
+ *
+ * \sa drmGetVersion().
+ */
+struct drm_version {
+       int version_major;        /**< Major version */
+       int version_minor;        /**< Minor version */
+       int version_patchlevel;   /**< Patch level */
+       DRM_SIZE_T name_len;      /**< Length of name buffer */
+       char __user *name;                /**< Name of driver */
+       DRM_SIZE_T date_len;      /**< Length of date buffer */
+       char __user *date;                /**< User-space buffer to hold date */
+       DRM_SIZE_T desc_len;      /**< Length of desc buffer */
+       char __user *desc;                /**< User-space buffer to hold desc */
+};
+
+/**
+ * DRM_IOCTL_GET_UNIQUE ioctl argument type.
+ *
+ * \sa drmGetBusid() and drmSetBusId().
+ */
+struct drm_unique {
+       DRM_SIZE_T unique_len;    /**< Length of unique */
+       char __user *unique;              /**< Unique name for driver instantiation */
+};
+
+#undef DRM_SIZE_T
+
+struct drm_list {
+       int count;                /**< Length of user-space structures */
+       struct drm_version __user *version;
+};
+
+struct drm_block {
+       int unused;
+};
 
-typedef struct drm_clip_rect {
-       unsigned short  x1;
-       unsigned short  y1;
-       unsigned short  x2;
-       unsigned short  y2;
-} drm_clip_rect_t;
-
-typedef struct drm_tex_region {
-       unsigned char   next;
-       unsigned char   prev;
-       unsigned char   in_use;
-       unsigned char   padding;
-       unsigned int    age;
-} drm_tex_region_t;
-
-typedef struct drm_version {
-       int    version_major;     /* Major version                          */
-       int    version_minor;     /* Minor version                          */
-       int    version_patchlevel;/* Patch level                            */
-       size_t name_len;          /* Length of name buffer                  */
-       char   *name;             /* Name of driver                         */
-       size_t date_len;          /* Length of date buffer                  */
-       char   *date;             /* User-space buffer to hold date         */
-       size_t desc_len;          /* Length of desc buffer                  */
-       char   *desc;             /* User-space buffer to hold desc         */
-} drm_version_t;
-
-typedef struct drm_unique {
-       size_t unique_len;        /* Length of unique                       */
-       char   *unique;           /* Unique name for driver instantiation   */
-} drm_unique_t;
-
-typedef struct drm_list {
-       int              count;   /* Length of user-space structures        */
-       drm_version_t    *version;
-} drm_list_t;
-
-typedef struct drm_block {
-       int              unused;
-} drm_block_t;
-
-typedef struct drm_control {
+/**
+ * DRM_IOCTL_CONTROL ioctl argument type.
+ *
+ * \sa drmCtlInstHandler() and drmCtlUninstHandler().
+ */
+struct drm_control {
        enum {
                DRM_ADD_COMMAND,
                DRM_RM_COMMAND,
                DRM_INST_HANDLER,
                DRM_UNINST_HANDLER
-       }                func;
-       int              irq;
-} drm_control_t;
-
-typedef enum drm_map_type {
-       _DRM_FRAME_BUFFER   = 0,  /* WC (no caching), no core dump          */
-       _DRM_REGISTERS      = 1,  /* no caching, no core dump               */
-       _DRM_SHM            = 2,  /* shared, cached                         */
-       _DRM_AGP            = 3,  /* AGP/GART                               */
-       _DRM_SCATTER_GATHER = 4   /* Scatter/gather memory for PCI DMA      */
-} drm_map_type_t;
-
-typedef enum drm_map_flags {
-       _DRM_RESTRICTED      = 0x01, /* Cannot be mapped to user-virtual    */
-       _DRM_READ_ONLY       = 0x02,
-       _DRM_LOCKED          = 0x04, /* shared, cached, locked              */
-       _DRM_KERNEL          = 0x08, /* kernel requires access              */
-       _DRM_WRITE_COMBINING = 0x10, /* use write-combining if available    */
-       _DRM_CONTAINS_LOCK   = 0x20, /* SHM page that contains lock         */
-       _DRM_REMOVABLE       = 0x40  /* Removable mapping                   */
-} drm_map_flags_t;
-
-typedef struct drm_ctx_priv_map {
-       unsigned int    ctx_id;  /* Context requesting private mapping */
-       void            *handle; /* Handle of map */
-} drm_ctx_priv_map_t;
-
-typedef struct drm_map {
-       unsigned long   offset;  /* Requested physical address (0 for SAREA)*/
-       unsigned long   size;    /* Requested physical size (bytes)         */
-       drm_map_type_t  type;    /* Type of memory to map                   */
-       drm_map_flags_t flags;   /* Flags                                   */
-       void            *handle; /* User-space: "Handle" to pass to mmap    */
-                                /* Kernel-space: kernel-virtual address    */
-       int             mtrr;    /* MTRR slot used                          */
-                                /* Private data                            */
-} drm_map_t;
-
-typedef struct drm_client {
-       int             idx;    /* Which client desired?                    */
-       int             auth;   /* Is client authenticated?                 */
-       unsigned long   pid;    /* Process id                               */
-       unsigned long   uid;    /* User id                                  */
-       unsigned long   magic;  /* Magic                                    */
-       unsigned long   iocs;   /* Ioctl count                              */
-} drm_client_t;
+       } func;
+       int irq;
+};
 
-typedef enum {
+/**
+ * Type of memory to map.
+ */
+enum drm_map_type {
+       _DRM_FRAME_BUFFER = 0,    /**< WC (no caching), no core dump */
+       _DRM_REGISTERS = 1,       /**< no caching, no core dump */
+       _DRM_SHM = 2,             /**< shared, cached */
+       _DRM_AGP = 3,             /**< AGP/GART */
+       _DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
+       _DRM_CONSISTENT = 5,      /**< Consistent memory for PCI DMA */
+       _DRM_TTM = 6
+};
+
+/**
+ * Memory mapping flags.
+ */
+enum drm_map_flags {
+       _DRM_RESTRICTED = 0x01,      /**< Cannot be mapped to user-virtual */
+       _DRM_READ_ONLY = 0x02,
+       _DRM_LOCKED = 0x04,          /**< shared, cached, locked */
+       _DRM_KERNEL = 0x08,          /**< kernel requires access */
+       _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
+       _DRM_CONTAINS_LOCK = 0x20,   /**< SHM page that contains lock */
+       _DRM_REMOVABLE = 0x40,       /**< Removable mapping */
+       _DRM_DRIVER = 0x80           /**< Managed by driver */
+};
+
+struct drm_ctx_priv_map {
+       unsigned int ctx_id;     /**< Context requesting private mapping */
+       void *handle;            /**< Handle of map */
+};
+
+/**
+ * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
+ * argument type.
+ *
+ * \sa drmAddMap().
+ */
+struct drm_map {
+       unsigned long offset;    /**< Requested physical address (0 for SAREA)*/
+       unsigned long size;      /**< Requested physical size (bytes) */
+       enum drm_map_type type;  /**< Type of memory to map */
+       enum drm_map_flags flags;        /**< Flags */
+       void *handle;            /**< User-space: "Handle" to pass to mmap() */
+                                /**< Kernel-space: kernel-virtual address */
+       int mtrr;                /**< MTRR slot used */
+       /*   Private data */
+};
+
+/**
+ * DRM_IOCTL_GET_CLIENT ioctl argument type.
+ */
+struct drm_client {
+       int idx;                /**< Which client desired? */
+       int auth;               /**< Is client authenticated? */
+       unsigned long pid;      /**< Process ID */
+       unsigned long uid;      /**< User ID */
+       unsigned long magic;    /**< Magic */
+       unsigned long iocs;     /**< Ioctl count */
+};
+
+enum drm_stat_type {
        _DRM_STAT_LOCK,
        _DRM_STAT_OPENS,
        _DRM_STAT_CLOSES,
        _DRM_STAT_IOCTLS,
        _DRM_STAT_LOCKS,
        _DRM_STAT_UNLOCKS,
-       _DRM_STAT_VALUE,        /* Generic value                      */
-       _DRM_STAT_BYTE,         /* Generic byte counter (1024bytes/K) */
-       _DRM_STAT_COUNT,        /* Generic non-byte counter (1000/k)  */
-
-       _DRM_STAT_IRQ,          /* IRQ */
-       _DRM_STAT_PRIMARY,      /* Primary DMA bytes */
-       _DRM_STAT_SECONDARY,    /* Secondary DMA bytes */
-       _DRM_STAT_DMA,          /* DMA */
-       _DRM_STAT_SPECIAL,      /* Special DMA (e.g., priority or polled) */
-       _DRM_STAT_MISSED        /* Missed DMA opportunity */
-
-                               /* Add to the *END* of the list */
-} drm_stat_type_t;
+       _DRM_STAT_VALUE,        /**< Generic value */
+       _DRM_STAT_BYTE,         /**< Generic byte counter (1024bytes/K) */
+       _DRM_STAT_COUNT,        /**< Generic non-byte counter (1000/k) */
+
+       _DRM_STAT_IRQ,          /**< IRQ */
+       _DRM_STAT_PRIMARY,      /**< Primary DMA bytes */
+       _DRM_STAT_SECONDARY,    /**< Secondary DMA bytes */
+       _DRM_STAT_DMA,          /**< DMA */
+       _DRM_STAT_SPECIAL,      /**< Special DMA (e.g., priority or polled) */
+       _DRM_STAT_MISSED        /**< Missed DMA opportunity */
+           /* Add to the *END* of the list */
+};
 
-typedef struct drm_stats {
+/**
+ * DRM_IOCTL_GET_STATS ioctl argument type.
+ */
+struct drm_stats {
        unsigned long count;
        struct {
-               unsigned long   value;
-               drm_stat_type_t type;
+               unsigned long value;
+               enum drm_stat_type type;
        } data[15];
-} drm_stats_t;
-
-typedef enum drm_lock_flags {
-       _DRM_LOCK_READY      = 0x01, /* Wait until hardware is ready for DMA */
-       _DRM_LOCK_QUIESCENT  = 0x02, /* Wait until hardware quiescent        */
-       _DRM_LOCK_FLUSH      = 0x04, /* Flush this context's DMA queue first */
-       _DRM_LOCK_FLUSH_ALL  = 0x08, /* Flush all DMA queues first           */
-                               /* These *HALT* flags aren't supported yet
-                                  -- they will be used to support the
-                                  full-screen DGA-like mode. */
-       _DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues   */
-       _DRM_HALT_CUR_QUEUES = 0x20  /* Halt all current queues              */
-} drm_lock_flags_t;
-
-typedef struct drm_lock {
-       int              context;
-       drm_lock_flags_t flags;
-} drm_lock_t;
-
-typedef enum drm_dma_flags {         /* These values *MUST* match xf86drm.h */
-                                     /* Flags for DMA buffer dispatch       */
-       _DRM_DMA_BLOCK        = 0x01, /* Block until buffer dispatched.
-                                        Note, the buffer may not yet have
-                                        been processed by the hardware --
-                                        getting a hardware lock with the
-                                        hardware quiescent will ensure
-                                        that the buffer has been
-                                        processed.                          */
-       _DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held            */
-       _DRM_DMA_PRIORITY     = 0x04, /* High priority dispatch              */
-
-                                     /* Flags for DMA buffer request        */
-       _DRM_DMA_WAIT         = 0x10, /* Wait for free buffers               */
-       _DRM_DMA_SMALLER_OK   = 0x20, /* Smaller-than-requested buffers ok   */
-       _DRM_DMA_LARGER_OK    = 0x40  /* Larger-than-requested buffers ok    */
-} drm_dma_flags_t;
-
-typedef struct drm_buf_desc {
-       int           count;     /* Number of buffers of this size           */
-       int           size;      /* Size in bytes                            */
-       int           low_mark;  /* Low water mark                           */
-       int           high_mark; /* High water mark                          */
+};
+
+/**
+ * Hardware locking flags.
+ */
+enum drm_lock_flags {
+       _DRM_LOCK_READY = 0x01,      /**< Wait until hardware is ready for DMA */
+       _DRM_LOCK_QUIESCENT = 0x02,  /**< Wait until hardware quiescent */
+       _DRM_LOCK_FLUSH = 0x04,      /**< Flush this context's DMA queue first */
+       _DRM_LOCK_FLUSH_ALL = 0x08,  /**< Flush all DMA queues first */
+       /* These *HALT* flags aren't supported yet
+          -- they will be used to support the
+          full-screen DGA-like mode. */
+       _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
+       _DRM_HALT_CUR_QUEUES = 0x20  /**< Halt all current queues */
+};
+
+/**
+ * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
+ *
+ * \sa drmGetLock() and drmUnlock().
+ */
+struct drm_lock {
+       int context;
+       enum drm_lock_flags flags;
+};
+
+/**
+ * DMA flags
+ *
+ * \warning
+ * These values \e must match xf86drm.h.
+ *
+ * \sa drm_dma.
+ */
+enum drm_dma_flags {
+       /* Flags for DMA buffer dispatch */
+       _DRM_DMA_BLOCK = 0x01,        /**<
+                                      * Block until buffer dispatched.
+                                      *
+                                      * \note The buffer may not yet have
+                                      * been processed by the hardware --
+                                      * getting a hardware lock with the
+                                      * hardware quiescent will ensure
+                                      * that the buffer has been
+                                      * processed.
+                                      */
+       _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
+       _DRM_DMA_PRIORITY = 0x04,     /**< High priority dispatch */
+
+       /* Flags for DMA buffer request */
+       _DRM_DMA_WAIT = 0x10,         /**< Wait for free buffers */
+       _DRM_DMA_SMALLER_OK = 0x20,   /**< Smaller-than-requested buffers OK */
+       _DRM_DMA_LARGER_OK = 0x40     /**< Larger-than-requested buffers OK */
+};
+
+/**
+ * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
+ *
+ * \sa drmAddBufs().
+ */
+struct drm_buf_desc {
+       int count;               /**< Number of buffers of this size */
+       int size;                /**< Size in bytes */
+       int low_mark;            /**< Low water mark */
+       int high_mark;           /**< High water mark */
        enum {
-               _DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA  */
-               _DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space            */
-               _DRM_SG_BUFFER  = 0x04  /* Scatter/gather memory buffer      */
-       }             flags;
-       unsigned long agp_start; /* Start address of where the agp buffers
-                                 * are in the agp aperture */
-} drm_buf_desc_t;
-
-typedef struct drm_buf_info {
-       int            count;   /* Entries in list                           */
-       drm_buf_desc_t *list;
-} drm_buf_info_t;
-
-typedef struct drm_buf_free {
-       int            count;
-       int            *list;
-} drm_buf_free_t;
-
-typedef struct drm_buf_pub {
-       int               idx;         /* Index into master buflist          */
-       int               total;       /* Buffer size                        */
-       int               used;        /* Amount of buffer in use (for DMA)  */
-       void              *address;    /* Address of buffer                  */
-} drm_buf_pub_t;
-
-typedef struct drm_buf_map {
-       int           count;    /* Length of buflist                        */
-       void          *virtual; /* Mmaped area in user-virtual              */
-       drm_buf_pub_t *list;    /* Buffer information                       */
-} drm_buf_map_t;
-
-typedef struct drm_dma {
-                               /* Indices here refer to the offset into
-                                  buflist in drm_buf_get_t.  */
-       int             context;          /* Context handle                 */
-       int             send_count;       /* Number of buffers to send      */
-       int             *send_indices;    /* List of handles to buffers     */
-       int             *send_sizes;      /* Lengths of data to send        */
-       drm_dma_flags_t flags;            /* Flags                          */
-       int             request_count;    /* Number of buffers requested    */
-       int             request_size;     /* Desired size for buffers       */
-       int             *request_indices; /* Buffer information             */
-       int             *request_sizes;
-       int             granted_count;    /* Number of buffers granted      */
-} drm_dma_t;
+               _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
+               _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
+               _DRM_SG_BUFFER  = 0x04, /**< Scatter/gather memory buffer */
+               _DRM_FB_BUFFER  = 0x08, /**< Buffer is in frame buffer */
+               _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
+       } flags;
+       unsigned long agp_start; /**<
+                                 * Start address of where the AGP buffers are
+                                 * in the AGP aperture
+                                 */
+};
 
-typedef enum {
-       _DRM_CONTEXT_PRESERVED = 0x01,
-       _DRM_CONTEXT_2DONLY    = 0x02
-} drm_ctx_flags_t;
+/**
+ * DRM_IOCTL_INFO_BUFS ioctl argument type.
+ */
+struct drm_buf_info {
+       int count;                /**< Number of buffers described in list */
+       struct drm_buf_desc __user *list; /**< List of buffer descriptions */
+};
 
-typedef struct drm_ctx {
-       drm_context_t   handle;
-       drm_ctx_flags_t flags;
-} drm_ctx_t;
+/**
+ * DRM_IOCTL_FREE_BUFS ioctl argument type.
+ */
+struct drm_buf_free {
+       int count;
+       int __user *list;
+};
 
-typedef struct drm_ctx_res {
-       int             count;
-       drm_ctx_t       *contexts;
-} drm_ctx_res_t;
+/**
+ * Buffer information
+ *
+ * \sa drm_buf_map.
+ */
+struct drm_buf_pub {
+       int idx;                       /**< Index into the master buffer list */
+       int total;                     /**< Buffer size */
+       int used;                      /**< Amount of buffer in use (for DMA) */
+       void __user *address;          /**< Address of buffer */
+};
+
+/**
+ * DRM_IOCTL_MAP_BUFS ioctl argument type.
+ */
+struct drm_buf_map {
+       int count;              /**< Length of the buffer list */
+#if defined(__cplusplus)
+       void __user *c_virtual;
+#else
+       void __user *virtual;           /**< Mmap'd area in user-virtual */
+#endif
+       struct drm_buf_pub __user *list;        /**< Buffer information */
+};
 
-typedef struct drm_draw {
-       drm_drawable_t  handle;
-} drm_draw_t;
+/**
+ * DRM_IOCTL_DMA ioctl argument type.
+ *
+ * Indices here refer to the offset into the buffer list in drm_buf_get.
+ *
+ * \sa drmDMA().
+ */
+struct drm_dma {
+       int context;                      /**< Context handle */
+       int send_count;                   /**< Number of buffers to send */
+       int __user *send_indices;         /**< List of handles to buffers */
+       int __user *send_sizes;           /**< Lengths of data to send */
+       enum drm_dma_flags flags;         /**< Flags */
+       int request_count;                /**< Number of buffers requested */
+       int request_size;                 /**< Desired size for buffers */
+       int __user *request_indices;     /**< Buffer information */
+       int __user *request_sizes;
+       int granted_count;                /**< Number of buffers granted */
+};
 
-typedef struct drm_auth {
-       drm_magic_t     magic;
-} drm_auth_t;
+enum drm_ctx_flags {
+       _DRM_CONTEXT_PRESERVED = 0x01,
+       _DRM_CONTEXT_2DONLY = 0x02
+};
 
-typedef struct drm_irq_busid {
-       int irq;
-       int busnum;
-       int devnum;
-       int funcnum;
-} drm_irq_busid_t;
+/**
+ * DRM_IOCTL_ADD_CTX ioctl argument type.
+ *
+ * \sa drmCreateContext() and drmDestroyContext().
+ */
+struct drm_ctx {
+       drm_context_t handle;
+       enum drm_ctx_flags flags;
+};
 
+/**
+ * DRM_IOCTL_RES_CTX ioctl argument type.
+ */
+struct drm_ctx_res {
+       int count;
+       struct drm_ctx __user *contexts;
+};
+
+/**
+ * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
+ */
+struct drm_draw {
+       drm_drawable_t handle;
+};
+
+/**
+ * DRM_IOCTL_UPDATE_DRAW ioctl argument type.
+ */
 typedef enum {
-    _DRM_VBLANK_ABSOLUTE = 0x0,                /* Wait for specific vblank sequence number */
-    _DRM_VBLANK_RELATIVE = 0x1,                /* Wait for given number of vblanks */
-    _DRM_VBLANK_SIGNAL   = 0x40000000  /* Send signal instead of blocking */
-} drm_vblank_seq_type_t;
+       DRM_DRAWABLE_CLIPRECTS,
+} drm_drawable_info_type_t;
+
+struct drm_update_draw {
+       drm_drawable_t handle;
+       unsigned int type;
+       unsigned int num;
+       unsigned long long data;
+};
+
+/**
+ * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
+ */
+struct drm_auth {
+       drm_magic_t magic;
+};
+
+/**
+ * DRM_IOCTL_IRQ_BUSID ioctl argument type.
+ *
+ * \sa drmGetInterruptFromBusID().
+ */
+struct drm_irq_busid {
+       int irq;        /**< IRQ number */
+       int busnum;     /**< bus number */
+       int devnum;     /**< device number */
+       int funcnum;    /**< function number */
+};
+
+enum drm_vblank_seq_type {
+       _DRM_VBLANK_ABSOLUTE = 0x0,     /**< Wait for specific vblank sequence number */
+       _DRM_VBLANK_RELATIVE = 0x1,     /**< Wait for given number of vblanks */
+       _DRM_VBLANK_FLIP = 0x8000000,   /**< Scheduled buffer swap should flip */
+       _DRM_VBLANK_NEXTONMISS = 0x10000000,    /**< If missed, wait for next vblank */
+       _DRM_VBLANK_SECONDARY = 0x20000000,     /**< Secondary display controller */
+       _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
+};
 
-#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
+#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
+#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \
+                               _DRM_VBLANK_NEXTONMISS)
 
 struct drm_wait_vblank_request {
-       drm_vblank_seq_type_t type;
+       enum drm_vblank_seq_type type;
        unsigned int sequence;
        unsigned long signal;
 };
 
 struct drm_wait_vblank_reply {
-       drm_vblank_seq_type_t type;
+       enum drm_vblank_seq_type type;
        unsigned int sequence;
        long tval_sec;
        long tval_usec;
 };
 
-typedef union drm_wait_vblank {
+/**
+ * DRM_IOCTL_WAIT_VBLANK ioctl argument type.
+ *
+ * \sa drmWaitVBlank().
+ */
+union drm_wait_vblank {
        struct drm_wait_vblank_request request;
        struct drm_wait_vblank_reply reply;
-} drm_wait_vblank_t;
+};
+
+/**
+ * DRM_IOCTL_AGP_ENABLE ioctl argument type.
+ *
+ * \sa drmAgpEnable().
+ */
+struct drm_agp_mode {
+       unsigned long mode;     /**< AGP mode */
+};
+
+/**
+ * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
+ *
+ * \sa drmAgpAlloc() and drmAgpFree().
+ */
+struct drm_agp_buffer {
+       unsigned long size;     /**< In bytes -- will round to page boundary */
+       unsigned long handle;   /**< Used for binding / unbinding */
+       unsigned long type;     /**< Type of memory to allocate */
+       unsigned long physical; /**< Physical used by i810 */
+};
+
+/**
+ * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
+ *
+ * \sa drmAgpBind() and drmAgpUnbind().
+ */
+struct drm_agp_binding {
+       unsigned long handle;   /**< From drm_agp_buffer */
+       unsigned long offset;   /**< In bytes -- will round to page boundary */
+};
 
-typedef struct drm_agp_mode {
+/**
+ * DRM_IOCTL_AGP_INFO ioctl argument type.
+ *
+ * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
+ * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(),
+ * drmAgpVendorId() and drmAgpDeviceId().
+ */
+struct drm_agp_info {
+       int agp_version_major;
+       int agp_version_minor;
        unsigned long mode;
-} drm_agp_mode_t;
-
-                               /* For drm_agp_alloc -- allocated a buffer */
-typedef struct drm_agp_buffer {
-       unsigned long size;     /* In bytes -- will round to page boundary */
-       unsigned long handle;   /* Used for BIND/UNBIND ioctls */
-       unsigned long type;     /* Type of memory to allocate  */
-        unsigned long physical; /* Physical used by i810       */
-} drm_agp_buffer_t;
-
-                               /* For drm_agp_bind */
-typedef struct drm_agp_binding {
-       unsigned long handle;   /* From drm_agp_buffer */
-       unsigned long offset;   /* In bytes -- will round to page boundary */
-} drm_agp_binding_t;
-
-typedef struct drm_agp_info {
-       int            agp_version_major;
-       int            agp_version_minor;
-       unsigned long  mode;
-       unsigned long  aperture_base;  /* physical address */
-       unsigned long  aperture_size;  /* bytes */
-       unsigned long  memory_allowed; /* bytes */
-       unsigned long  memory_used;
-
-                               /* PCI information */
+       unsigned long aperture_base;   /**< physical address */
+       unsigned long aperture_size;   /**< bytes */
+       unsigned long memory_allowed;  /**< bytes */
+       unsigned long memory_used;
+
+       /** \name PCI information */
+       /*@{ */
        unsigned short id_vendor;
        unsigned short id_device;
-} drm_agp_info_t;
+       /*@} */
+};
+
+/**
+ * DRM_IOCTL_SG_ALLOC ioctl argument type.
+ */
+struct drm_scatter_gather {
+       unsigned long size;     /**< In bytes -- will round to page boundary */
+       unsigned long handle;   /**< Used for mapping / unmapping */
+};
+
+/**
+ * DRM_IOCTL_SET_VERSION ioctl argument type.
+ */
+struct drm_set_version {
+       int drm_di_major;
+       int drm_di_minor;
+       int drm_dd_major;
+       int drm_dd_minor;
+};
+
+
+#define DRM_FENCE_FLAG_EMIT                0x00000001
+#define DRM_FENCE_FLAG_SHAREABLE           0x00000002
+#define DRM_FENCE_FLAG_WAIT_LAZY           0x00000004
+#define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008
+#define DRM_FENCE_FLAG_NO_USER             0x00000010
+
+/* Reserved for driver use */
+#define DRM_FENCE_MASK_DRIVER              0xFF000000
+
+#define DRM_FENCE_TYPE_EXE                 0x00000001
+
+struct drm_fence_arg {
+       unsigned int handle;
+       unsigned int fence_class;
+       unsigned int type;
+       unsigned int flags;
+       unsigned int signaled;
+       unsigned int error;
+       unsigned int sequence;
+       unsigned int pad64;
+       uint64_t expand_pad[2]; /*Future expansion */
+};
+
+/* Buffer permissions, referring to how the GPU uses the buffers.
+ * these translate to fence types used for the buffers.
+ * Typically a texture buffer is read, A destination buffer is write and
+ *  a command (batch-) buffer is exe. Can be or-ed together.
+ */
 
-typedef struct drm_scatter_gather {
-       unsigned long size;     /* In bytes -- will round to page boundary */
-       unsigned long handle;   /* Used for mapping / unmapping */
-} drm_scatter_gather_t;
+#define DRM_BO_FLAG_READ        (1ULL << 0)
+#define DRM_BO_FLAG_WRITE       (1ULL << 1)
+#define DRM_BO_FLAG_EXE         (1ULL << 2)
+
+/*
+ * All of the bits related to access mode
+ */
+#define DRM_BO_MASK_ACCESS     (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE)
+/*
+ * Status flags. Can be read to determine the actual state of a buffer.
+ * Can also be set in the buffer mask before validation.
+ */
+
+/*
+ * Mask: Never evict this buffer. Not even with force. This type of buffer is only
+ * available to root and must be manually removed before buffer manager shutdown
+ * or lock.
+ * Flags: Acknowledge
+ */
+#define DRM_BO_FLAG_NO_EVICT    (1ULL << 4)
+
+/*
+ * Mask: Require that the buffer is placed in mappable memory when validated.
+ *       If not set the buffer may or may not be in mappable memory when validated.
+ * Flags: If set, the buffer is in mappable memory.
+ */
+#define DRM_BO_FLAG_MAPPABLE    (1ULL << 5)
+
+/* Mask: The buffer should be shareable with other processes.
+ * Flags: The buffer is shareable with other processes.
+ */
+#define DRM_BO_FLAG_SHAREABLE   (1ULL << 6)
+
+/* Mask: If set, place the buffer in cache-coherent memory if available.
+ *       If clear, never place the buffer in cache coherent memory if validated.
+ * Flags: The buffer is currently in cache-coherent memory.
+ */
+#define DRM_BO_FLAG_CACHED      (1ULL << 7)
+
+/* Mask: Make sure that every time this buffer is validated,
+ *       it ends up on the same location provided that the memory mask is the same.
+ *       The buffer will also not be evicted when claiming space for
+ *       other buffers. Basically a pinned buffer but it may be thrown out as
+ *       part of buffer manager shutdown or locking.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_NO_MOVE     (1ULL << 8)
+
+/* Mask: Make sure the buffer is in cached memory when mapped
+ * Flags: Acknowledge.
+ * Buffers allocated with this flag should not be used for suballocators
+ * This type may have issues on CPUs with over-aggressive caching
+ * http://marc.info/?l=linux-kernel&m=102376926732464&w=2
+ */
+#define DRM_BO_FLAG_CACHED_MAPPED    (1ULL << 19)
+
+
+/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_FORCE_CACHING  (1ULL << 13)
+
+/*
+ * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14)
+#define DRM_BO_FLAG_TILE           (1ULL << 15)
+
+/*
+ * Memory type flags that can be or'ed together in the mask, but only
+ * one appears in flags.
+ */
+
+/* System memory */
+#define DRM_BO_FLAG_MEM_LOCAL  (1ULL << 24)
+/* Translation table memory */
+#define DRM_BO_FLAG_MEM_TT     (1ULL << 25)
+/* Vram memory */
+#define DRM_BO_FLAG_MEM_VRAM   (1ULL << 26)
+/* Up to the driver to define. */
+#define DRM_BO_FLAG_MEM_PRIV0  (1ULL << 27)
+#define DRM_BO_FLAG_MEM_PRIV1  (1ULL << 28)
+#define DRM_BO_FLAG_MEM_PRIV2  (1ULL << 29)
+#define DRM_BO_FLAG_MEM_PRIV3  (1ULL << 30)
+#define DRM_BO_FLAG_MEM_PRIV4  (1ULL << 31)
+/* We can add more of these now with a 64-bit flag type */
+
+/*
+ * This is a mask covering all of the memory type flags; easier to just
+ * use a single constant than a bunch of | values. It covers
+ * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4
+ */
+#define DRM_BO_MASK_MEM         0x00000000FF000000ULL
+/*
+ * This adds all of the CPU-mapping options in with the memory
+ * type to label all bits which change how the page gets mapped
+ */
+#define DRM_BO_MASK_MEMTYPE     (DRM_BO_MASK_MEM | \
+                                DRM_BO_FLAG_CACHED_MAPPED | \
+                                DRM_BO_FLAG_CACHED | \
+                                DRM_BO_FLAG_MAPPABLE)
+                                
+/* Driver-private flags */
+#define DRM_BO_MASK_DRIVER      0xFFFF000000000000ULL
+
+/*
+ * Don't block on validate and map. Instead, return EBUSY.
+ */
+#define DRM_BO_HINT_DONT_BLOCK  0x00000002
+/*
+ * Don't place this buffer on the unfenced list. This means
+ * that the buffer will not end up having a fence associated
+ * with it as a result of this operation
+ */
+#define DRM_BO_HINT_DONT_FENCE  0x00000004
+/*
+ * Sleep while waiting for the operation to complete.
+ * Without this flag, the kernel will, instead, spin
+ * until this operation has completed. I'm not sure
+ * why you would ever want this, so please always
+ * provide DRM_BO_HINT_WAIT_LAZY to any operation
+ * which may block
+ */
+#define DRM_BO_HINT_WAIT_LAZY   0x00000008
+/*
+ * The client has compute relocations refering to this buffer using the
+ * offset in the presumed_offset field. If that offset ends up matching
+ * where this buffer lands, the kernel is free to skip executing those
+ * relocations
+ */
+#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010
+
+#define DRM_BO_INIT_MAGIC 0xfe769812
+#define DRM_BO_INIT_MAJOR 1
+#define DRM_BO_INIT_MINOR 0
+#define DRM_BO_INIT_PATCH 0
+
+
+struct drm_bo_info_req {
+       uint64_t mask;
+       uint64_t flags;
+       unsigned int handle;
+       unsigned int hint;
+       unsigned int fence_class;
+       unsigned int desired_tile_stride;
+       unsigned int tile_info;
+       unsigned int pad64;
+       uint64_t presumed_offset;
+};
+
+struct drm_bo_create_req {
+       uint64_t flags;
+       uint64_t size;
+       uint64_t buffer_start;
+       unsigned int hint;
+       unsigned int page_alignment;
+};
+
+
+/*
+ * Reply flags
+ */
+
+#define DRM_BO_REP_BUSY 0x00000001
+
+struct drm_bo_info_rep {
+       uint64_t flags;
+       uint64_t proposed_flags;
+       uint64_t size;
+       uint64_t offset;
+       uint64_t arg_handle;
+       uint64_t buffer_start;
+       unsigned int handle;
+       unsigned int fence_flags;
+       unsigned int rep_flags;
+       unsigned int page_alignment;
+       unsigned int desired_tile_stride;
+       unsigned int hw_tile_stride;
+       unsigned int tile_info;
+       unsigned int pad64;
+       uint64_t expand_pad[4]; /*Future expansion */
+};
+
+struct drm_bo_arg_rep {
+       struct drm_bo_info_rep bo_info;
+       int ret;
+       unsigned int pad64;
+};
+
+struct drm_bo_create_arg {
+       union {
+               struct drm_bo_create_req req;
+               struct drm_bo_info_rep rep;
+       } d;
+};
+
+struct drm_bo_handle_arg {
+       unsigned int handle;
+};
+
+struct drm_bo_reference_info_arg {
+       union {
+               struct drm_bo_handle_arg req;
+               struct drm_bo_info_rep rep;
+       } d;
+};
+
+struct drm_bo_map_wait_idle_arg {
+       union {
+               struct drm_bo_info_req req;
+               struct drm_bo_info_rep rep;
+       } d;
+};
+
+struct drm_bo_op_req {
+       enum {
+               drm_bo_validate,
+               drm_bo_fence,
+               drm_bo_ref_fence,
+       } op;
+       unsigned int arg_handle;
+       struct drm_bo_info_req bo_req;
+};
+
+
+struct drm_bo_op_arg {
+       uint64_t next;
+       union {
+               struct drm_bo_op_req req;
+               struct drm_bo_arg_rep rep;
+       } d;
+       int handled;
+       unsigned int pad64;
+};
+
+
+#define DRM_BO_MEM_LOCAL 0
+#define DRM_BO_MEM_TT 1
+#define DRM_BO_MEM_VRAM 2
+#define DRM_BO_MEM_PRIV0 3
+#define DRM_BO_MEM_PRIV1 4
+#define DRM_BO_MEM_PRIV2 5
+#define DRM_BO_MEM_PRIV3 6
+#define DRM_BO_MEM_PRIV4 7
+
+#define DRM_BO_MEM_TYPES 8 /* For now. */
+
+#define DRM_BO_LOCK_UNLOCK_BM       (1 << 0)
+#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1)
+
+struct drm_bo_version_arg {
+       uint32_t major;
+       uint32_t minor;
+       uint32_t patchlevel;
+};
+
+struct drm_mm_type_arg {
+       unsigned int mem_type;
+       unsigned int lock_flags;
+};
+
+struct drm_mm_init_arg {
+       unsigned int magic;
+       unsigned int major;
+       unsigned int minor;
+       unsigned int mem_type;
+       uint64_t p_offset;
+       uint64_t p_size;
+};
+
+/**
+ * \name Ioctls Definitions
+ */
+/*@{*/
 
 #define DRM_IOCTL_BASE                 'd'
 #define DRM_IO(nr)                     _IO(DRM_IOCTL_BASE,nr)
@@ -416,61 +941,147 @@ typedef struct drm_scatter_gather {
 #define DRM_IOW(nr,type)               _IOW(DRM_IOCTL_BASE,nr,type)
 #define DRM_IOWR(nr,type)              _IOWR(DRM_IOCTL_BASE,nr,type)
 
-#define DRM_IOCTL_VERSION              DRM_IOWR(0x00, drm_version_t)
-#define DRM_IOCTL_GET_UNIQUE           DRM_IOWR(0x01, drm_unique_t)
-#define DRM_IOCTL_GET_MAGIC            DRM_IOR( 0x02, drm_auth_t)
-#define DRM_IOCTL_IRQ_BUSID            DRM_IOWR(0x03, drm_irq_busid_t)
-#define DRM_IOCTL_GET_MAP               DRM_IOWR(0x04, drm_map_t)
-#define DRM_IOCTL_GET_CLIENT            DRM_IOWR(0x05, drm_client_t)
-#define DRM_IOCTL_GET_STATS             DRM_IOR( 0x06, drm_stats_t)
-
-#define DRM_IOCTL_SET_UNIQUE           DRM_IOW( 0x10, drm_unique_t)
-#define DRM_IOCTL_AUTH_MAGIC           DRM_IOW( 0x11, drm_auth_t)
-#define DRM_IOCTL_BLOCK                        DRM_IOWR(0x12, drm_block_t)
-#define DRM_IOCTL_UNBLOCK              DRM_IOWR(0x13, drm_block_t)
-#define DRM_IOCTL_CONTROL              DRM_IOW( 0x14, drm_control_t)
-#define DRM_IOCTL_ADD_MAP              DRM_IOWR(0x15, drm_map_t)
-#define DRM_IOCTL_ADD_BUFS             DRM_IOWR(0x16, drm_buf_desc_t)
-#define DRM_IOCTL_MARK_BUFS            DRM_IOW( 0x17, drm_buf_desc_t)
-#define DRM_IOCTL_INFO_BUFS            DRM_IOWR(0x18, drm_buf_info_t)
-#define DRM_IOCTL_MAP_BUFS             DRM_IOWR(0x19, drm_buf_map_t)
-#define DRM_IOCTL_FREE_BUFS            DRM_IOW( 0x1a, drm_buf_free_t)
-
-#define DRM_IOCTL_RM_MAP               DRM_IOW( 0x1b, drm_map_t)
-
-#define DRM_IOCTL_SET_SAREA_CTX                DRM_IOW( 0x1c, drm_ctx_priv_map_t)
-#define DRM_IOCTL_GET_SAREA_CTX        DRM_IOWR(0x1d, drm_ctx_priv_map_t)
-
-#define DRM_IOCTL_ADD_CTX              DRM_IOWR(0x20, drm_ctx_t)
-#define DRM_IOCTL_RM_CTX               DRM_IOWR(0x21, drm_ctx_t)
-#define DRM_IOCTL_MOD_CTX              DRM_IOW( 0x22, drm_ctx_t)
-#define DRM_IOCTL_GET_CTX              DRM_IOWR(0x23, drm_ctx_t)
-#define DRM_IOCTL_SWITCH_CTX           DRM_IOW( 0x24, drm_ctx_t)
-#define DRM_IOCTL_NEW_CTX              DRM_IOW( 0x25, drm_ctx_t)
-#define DRM_IOCTL_RES_CTX              DRM_IOWR(0x26, drm_ctx_res_t)
-#define DRM_IOCTL_ADD_DRAW             DRM_IOWR(0x27, drm_draw_t)
-#define DRM_IOCTL_RM_DRAW              DRM_IOWR(0x28, drm_draw_t)
-#define DRM_IOCTL_DMA                  DRM_IOWR(0x29, drm_dma_t)
-#define DRM_IOCTL_LOCK                 DRM_IOW( 0x2a, drm_lock_t)
-#define DRM_IOCTL_UNLOCK               DRM_IOW( 0x2b, drm_lock_t)
-#define DRM_IOCTL_FINISH               DRM_IOW( 0x2c, drm_lock_t)
+#define DRM_IOCTL_VERSION              DRM_IOWR(0x00, struct drm_version)
+#define DRM_IOCTL_GET_UNIQUE           DRM_IOWR(0x01, struct drm_unique)
+#define DRM_IOCTL_GET_MAGIC            DRM_IOR( 0x02, struct drm_auth)
+#define DRM_IOCTL_IRQ_BUSID            DRM_IOWR(0x03, struct drm_irq_busid)
+#define DRM_IOCTL_GET_MAP               DRM_IOWR(0x04, struct drm_map)
+#define DRM_IOCTL_GET_CLIENT            DRM_IOWR(0x05, struct drm_client)
+#define DRM_IOCTL_GET_STATS             DRM_IOR( 0x06, struct drm_stats)
+#define DRM_IOCTL_SET_VERSION          DRM_IOWR(0x07, struct drm_set_version)
+
+#define DRM_IOCTL_SET_UNIQUE           DRM_IOW( 0x10, struct drm_unique)
+#define DRM_IOCTL_AUTH_MAGIC           DRM_IOW( 0x11, struct drm_auth)
+#define DRM_IOCTL_BLOCK                        DRM_IOWR(0x12, struct drm_block)
+#define DRM_IOCTL_UNBLOCK              DRM_IOWR(0x13, struct drm_block)
+#define DRM_IOCTL_CONTROL              DRM_IOW( 0x14, struct drm_control)
+#define DRM_IOCTL_ADD_MAP              DRM_IOWR(0x15, struct drm_map)
+#define DRM_IOCTL_ADD_BUFS             DRM_IOWR(0x16, struct drm_buf_desc)
+#define DRM_IOCTL_MARK_BUFS            DRM_IOW( 0x17, struct drm_buf_desc)
+#define DRM_IOCTL_INFO_BUFS            DRM_IOWR(0x18, struct drm_buf_info)
+#define DRM_IOCTL_MAP_BUFS             DRM_IOWR(0x19, struct drm_buf_map)
+#define DRM_IOCTL_FREE_BUFS            DRM_IOW( 0x1a, struct drm_buf_free)
+
+#define DRM_IOCTL_RM_MAP               DRM_IOW( 0x1b, struct drm_map)
+
+#define DRM_IOCTL_SET_SAREA_CTX                DRM_IOW( 0x1c, struct drm_ctx_priv_map)
+#define DRM_IOCTL_GET_SAREA_CTX                DRM_IOWR(0x1d, struct drm_ctx_priv_map)
+
+#define DRM_IOCTL_ADD_CTX              DRM_IOWR(0x20, struct drm_ctx)
+#define DRM_IOCTL_RM_CTX               DRM_IOWR(0x21, struct drm_ctx)
+#define DRM_IOCTL_MOD_CTX              DRM_IOW( 0x22, struct drm_ctx)
+#define DRM_IOCTL_GET_CTX              DRM_IOWR(0x23, struct drm_ctx)
+#define DRM_IOCTL_SWITCH_CTX           DRM_IOW( 0x24, struct drm_ctx)
+#define DRM_IOCTL_NEW_CTX              DRM_IOW( 0x25, struct drm_ctx)
+#define DRM_IOCTL_RES_CTX              DRM_IOWR(0x26, struct drm_ctx_res)
+#define DRM_IOCTL_ADD_DRAW             DRM_IOWR(0x27, struct drm_draw)
+#define DRM_IOCTL_RM_DRAW              DRM_IOWR(0x28, struct drm_draw)
+#define DRM_IOCTL_DMA                  DRM_IOWR(0x29, struct drm_dma)
+#define DRM_IOCTL_LOCK                 DRM_IOW( 0x2a, struct drm_lock)
+#define DRM_IOCTL_UNLOCK               DRM_IOW( 0x2b, struct drm_lock)
+#define DRM_IOCTL_FINISH               DRM_IOW( 0x2c, struct drm_lock)
 
 #define DRM_IOCTL_AGP_ACQUIRE          DRM_IO(  0x30)
 #define DRM_IOCTL_AGP_RELEASE          DRM_IO(  0x31)
-#define DRM_IOCTL_AGP_ENABLE           DRM_IOW( 0x32, drm_agp_mode_t)
-#define DRM_IOCTL_AGP_INFO             DRM_IOR( 0x33, drm_agp_info_t)
-#define DRM_IOCTL_AGP_ALLOC            DRM_IOWR(0x34, drm_agp_buffer_t)
-#define DRM_IOCTL_AGP_FREE             DRM_IOW( 0x35, drm_agp_buffer_t)
-#define DRM_IOCTL_AGP_BIND             DRM_IOW( 0x36, drm_agp_binding_t)
-#define DRM_IOCTL_AGP_UNBIND           DRM_IOW( 0x37, drm_agp_binding_t)
-
-#define DRM_IOCTL_SG_ALLOC             DRM_IOW( 0x38, drm_scatter_gather_t)
-#define DRM_IOCTL_SG_FREE              DRM_IOW( 0x39, drm_scatter_gather_t)
-
-#define DRM_IOCTL_WAIT_VBLANK          DRM_IOWR(0x3a, drm_wait_vblank_t)
-
-/* Device specfic ioctls should only be in their respective headers
- * The device specific ioctl range is 0x40 to 0x79.                  */
+#define DRM_IOCTL_AGP_ENABLE           DRM_IOW( 0x32, struct drm_agp_mode)
+#define DRM_IOCTL_AGP_INFO             DRM_IOR( 0x33, struct drm_agp_info)
+#define DRM_IOCTL_AGP_ALLOC            DRM_IOWR(0x34, struct drm_agp_buffer)
+#define DRM_IOCTL_AGP_FREE             DRM_IOW( 0x35, struct drm_agp_buffer)
+#define DRM_IOCTL_AGP_BIND             DRM_IOW( 0x36, struct drm_agp_binding)
+#define DRM_IOCTL_AGP_UNBIND           DRM_IOW( 0x37, struct drm_agp_binding)
+
+#define DRM_IOCTL_SG_ALLOC             DRM_IOW( 0x38, struct drm_scatter_gather)
+#define DRM_IOCTL_SG_FREE              DRM_IOW( 0x39, struct drm_scatter_gather)
+
+#define DRM_IOCTL_WAIT_VBLANK          DRM_IOWR(0x3a, union drm_wait_vblank)
+
+#define DRM_IOCTL_UPDATE_DRAW           DRM_IOW(0x3f, struct drm_update_draw)
+
+#define DRM_IOCTL_MM_INIT               DRM_IOWR(0xc0, struct drm_mm_init_arg)
+#define DRM_IOCTL_MM_TAKEDOWN           DRM_IOWR(0xc1, struct drm_mm_type_arg)
+#define DRM_IOCTL_MM_LOCK               DRM_IOWR(0xc2, struct drm_mm_type_arg)
+#define DRM_IOCTL_MM_UNLOCK             DRM_IOWR(0xc3, struct drm_mm_type_arg)
+
+#define DRM_IOCTL_FENCE_CREATE          DRM_IOWR(0xc4, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_REFERENCE       DRM_IOWR(0xc6, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_UNREFERENCE     DRM_IOWR(0xc7, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_SIGNALED        DRM_IOWR(0xc8, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_FLUSH           DRM_IOWR(0xc9, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_WAIT            DRM_IOWR(0xca, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_EMIT            DRM_IOWR(0xcb, struct drm_fence_arg)
+#define DRM_IOCTL_FENCE_BUFFERS         DRM_IOWR(0xcc, struct drm_fence_arg)
+
+#define DRM_IOCTL_BO_CREATE             DRM_IOWR(0xcd, struct drm_bo_create_arg)
+#define DRM_IOCTL_BO_MAP                DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg)
+#define DRM_IOCTL_BO_UNMAP              DRM_IOWR(0xd0, struct drm_bo_handle_arg)
+#define DRM_IOCTL_BO_REFERENCE          DRM_IOWR(0xd1, struct drm_bo_reference_info_arg)
+#define DRM_IOCTL_BO_UNREFERENCE        DRM_IOWR(0xd2, struct drm_bo_handle_arg)
+#define DRM_IOCTL_BO_SETSTATUS          DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg)
+#define DRM_IOCTL_BO_INFO               DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
+#define DRM_IOCTL_BO_WAIT_IDLE          DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
+#define DRM_IOCTL_BO_VERSION          DRM_IOR(0xd6, struct drm_bo_version_arg)
+
+
+/*@}*/
+
+/**
+ * Device specific ioctls should only be in their respective headers
+ * The device specific ioctl range is from 0x40 to 0x99.
+ * Generic IOCTLS restart at 0xA0.
+ *
+ * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
+ * drmCommandReadWrite().
+ */
 #define DRM_COMMAND_BASE                0x40
+#define DRM_COMMAND_END                 0xA0
+
+/* typedef area */
+#if !defined(__KERNEL__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+    defined(__NetBSD__) || defined(__DragonFly__)
+typedef struct drm_clip_rect drm_clip_rect_t;
+typedef struct drm_tex_region drm_tex_region_t;
+typedef struct drm_hw_lock drm_hw_lock_t;
+typedef struct drm_version drm_version_t;
+typedef struct drm_unique drm_unique_t;
+typedef struct drm_list drm_list_t;
+typedef struct drm_block drm_block_t;
+typedef struct drm_control drm_control_t;
+typedef enum drm_map_type drm_map_type_t;
+typedef enum drm_map_flags drm_map_flags_t;
+typedef struct drm_ctx_priv_map drm_ctx_priv_map_t;
+typedef struct drm_map drm_map_t;
+typedef struct drm_client drm_client_t;
+typedef enum drm_stat_type drm_stat_type_t;
+typedef struct drm_stats drm_stats_t;
+typedef enum drm_lock_flags drm_lock_flags_t;
+typedef struct drm_lock drm_lock_t;
+typedef enum drm_dma_flags drm_dma_flags_t;
+typedef struct drm_buf_desc drm_buf_desc_t;
+typedef struct drm_buf_info drm_buf_info_t;
+typedef struct drm_buf_free drm_buf_free_t;
+typedef struct drm_buf_pub drm_buf_pub_t;
+typedef struct drm_buf_map drm_buf_map_t;
+typedef struct drm_dma drm_dma_t;
+typedef union drm_wait_vblank drm_wait_vblank_t;
+typedef struct drm_agp_mode drm_agp_mode_t;
+typedef enum drm_ctx_flags drm_ctx_flags_t;
+typedef struct drm_ctx drm_ctx_t;
+typedef struct drm_ctx_res drm_ctx_res_t;
+typedef struct drm_draw drm_draw_t;
+typedef struct drm_update_draw drm_update_draw_t;
+typedef struct drm_auth drm_auth_t;
+typedef struct drm_irq_busid drm_irq_busid_t;
+typedef enum drm_vblank_seq_type drm_vblank_seq_type_t;
+typedef struct drm_agp_buffer drm_agp_buffer_t;
+typedef struct drm_agp_binding drm_agp_binding_t;
+typedef struct drm_agp_info drm_agp_info_t;
+typedef struct drm_scatter_gather drm_scatter_gather_t;
+typedef struct drm_set_version drm_set_version_t;
+
+typedef struct drm_fence_arg drm_fence_arg_t;
+typedef struct drm_mm_type_arg drm_mm_type_arg_t;
+typedef struct drm_mm_init_arg drm_mm_init_arg_t;
+typedef enum drm_bo_type drm_bo_type_t;
+#endif
 
 #endif
diff --git a/sys/dev/drm/drm/Makefile b/sys/dev/drm/drm/Makefile
new file mode 100644 (file)
index 0000000..c545962
--- /dev/null
@@ -0,0 +1,41 @@
+# $DragonFly: src/sys/dev/drm/drm/Makefile,v 1.1 2008/04/05 18:12:29 hasso Exp $
+
+.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>
index 4776f25..ff35964 100644 (file)
@@ -1,6 +1,7 @@
 /* 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.
@@ -27,8 +28,8 @@
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- * $FreeBSD: src/sys/dev/drm/drmP.h,v 1.4.2.1 2003/04/26 07:05:27 anholt Exp $
- * $DragonFly: src/sys/dev/drm/drmP.h,v 1.4 2006/09/10 01:26:34 dillon Exp $
+ *
+ * $DragonFly: src/sys/dev/drm/drmP.h,v 1.5 2008/04/05 18:12:29 hasso Exp $
  */
 
 #ifndef _DRM_P_H_
 
 #if defined(_KERNEL) || defined(__KERNEL__)
 
-/* DRM template customization defaults
- */
-#ifndef __HAVE_AGP
-#define __HAVE_AGP             0
-#endif
-#ifndef __HAVE_MTRR
-#define __HAVE_MTRR            0
+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>
+#if __FreeBSD_version >= 700000
+#include <sys/priv.h>
 #endif
-#ifndef __HAVE_CTX_BITMAP
-#define __HAVE_CTX_BITMAP      0
+#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 <sys/tree.h>
+#include <sys/taskqueue.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>
+#ifdef __DragonFly__
+#include <sys/bus.h>
+#include <sys/resource.h>
+#else
+#include <machine/bus.h>
+#include <machine/resource.h>
 #endif
-#ifndef __HAVE_DMA
-#define __HAVE_DMA             0
+#include <machine/sysarch.h>
+#include <sys/endian.h>
+#include <sys/mman.h>
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/rman.h>
+#include <sys/memrange.h>
+#if __FreeBSD_version >= 800004 || defined(__DragonFly__)
+#include <dev/agp/agpvar.h>
+#else /* __FreeBSD_version >= 800004 */
+#include <pci/agpvar.h>
+#endif /* __FreeBSD_version >= 800004 */
+#include <sys/agpio.h>
+#if defined(__DragonFly__)
+#include <sys/thread2.h>
+#include <sys/device.h>
+#include <sys/lock.h>
+#include <bus/pci/pcivar.h>
+#include <sys/selinfo.h>
+#elif __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
-#ifndef __HAVE_DMA_IRQ
-#define __HAVE_DMA_IRQ         0
+#include <sys/bus.h>
+
+#include "drm.h"
+#include "drm_linux_list.h"
+#include "drm_atomic.h"
+#include "drm_internal.h"
+
+#ifdef __FreeBSD__
+#include <opt_drm.h>
+#ifdef DRM_DEBUG
+#undef DRM_DEBUG
+#define DRM_DEBUG_DEFAULT_ON 1
+#endif /* DRM_DEBUG */
 #endif
 
-#define DRM_DEBUG_CODE 0         /* Include debugging code (if > 1, then
-                                    also include looping detection. */
-
-typedef struct drm_device drm_device_t;
-typedef struct drm_file drm_file_t;
-
-/* There's undoubtably more of this file to go into these OS dependent ones. */
-
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-#include "dev/drm/drm_os_freebsd.h"
-#elif defined __NetBSD__
-#include "dev/drm/drm_os_netbsd.h"
+#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
 
-#include "dev/drm/drm.h"
-
-/* Begin the DRM... */
-
 #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_FLAG_DEBUG   0x01
-
 #define DRM_MEM_DMA       0
 #define DRM_MEM_SAREA     1
 #define DRM_MEM_DRIVER    2
@@ -98,41 +171,337 @@ typedef struct drm_file drm_file_t;
 #define DRM_MEM_CTXBITMAP 17
 #define DRM_MEM_STUB     18
 #define DRM_MEM_SGLISTS          19
+#define DRM_MEM_DRAWABLE  20
 
 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
 
-                               /* Mapping helper macros */
-#define DRM_IOREMAP(map)                                               \
-       (map)->handle = DRM(ioremap)( dev, map )
-
-#define DRM_IOREMAP_NOCACHE(map)                                       \
-       (map)->handle = DRM(ioremap_nocache)( dev, map )
-
-#define DRM_IOREMAPFREE(map)                                           \
-       do {                                                            \
-               if ( (map)->handle && (map)->size )                     \
-                       DRM(ioremapfree)( map );                        \
-       } while (0)
-
                                /* 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_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
-#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
-#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
+#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 {(void)(queue);} 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_IRQSAVE(l, irqflags) do {         \
+       mtx_lock(l);                                    \
+       (void)irqflags;                                 \
+} while (0)
+#define DRM_SPINUNLOCK_IRQRESTORE(u, irqflags) mtx_unlock(u)
+#define DRM_SPINLOCK_ASSERT(l) mtx_assert(l, MA_OWNED)
+#define DRM_CURRENTPID         curthread->td_proc->p_pid
+#define DRM_LOCK()             mtx_lock(&dev->dev_lock)
+#define DRM_UNLOCK()           mtx_unlock(&dev->dev_lock)
+#define DRM_SYSCTL_HANDLER_ARGS        (SYSCTL_HANDLER_ARGS)
+#elif defined(__DragonFly__)
+#define DRM_CURPROC            curthread
+#define DRM_STRUCTPROC         struct thread
+#define DRM_SPINTYPE           struct lock
+#define DRM_SPININIT(l,name)   lockinit(l, name, 0, LK_CANRECURSE)
+#define DRM_SPINUNINIT(l)      
+#define DRM_SPINLOCK(l)                lockmgr(l, LK_EXCLUSIVE|LK_RETRY)
+#define DRM_SPINUNLOCK(u)      lockmgr(u, LK_RELEASE);
+#define DRM_SPINLOCK_IRQSAVE(l, irqflags) do {         \
+       DRM_SPINLOCK(l);                                        \
+       (void)irqflags;                                 \
+} while (0)
+#define DRM_SPINUNLOCK_IRQRESTORE(u, irqflags) DRM_SPINUNLOCK(u)
+#define DRM_SPINLOCK_ASSERT(l)
+#define DRM_CURRENTPID         curthread->td_proc->p_pid
+#define DRM_LOCK()             DRM_SPINLOCK(&dev->dev_lock)
+#define DRM_UNLOCK()           DRM_SPINUNLOCK(&dev->dev_lock)
+#define DRM_SYSCTL_HANDLER_ARGS        (SYSCTL_HANDLER_ARGS)
+#else /* __FreeBSD__ && __FreeBSD_version >= 500000 || __DragonFly__ */
+#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__ */
+
+#define DRM_IRQ_ARGS           void *arg
+typedef void                   irqreturn_t;
+#define IRQ_HANDLED            /* nothing */
+#define IRQ_NONE               /* nothing */
+
+enum {
+       DRM_IS_NOT_AGP,
+       DRM_IS_AGP,
+       DRM_MIGHT_BE_AGP
+};
+#define DRM_AGP_MEM            struct agp_memory_info
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#define drm_get_device_from_kdev(_kdev) (_kdev->si_drv1)
+#elif defined(__NetBSD__)
+#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, minor(_kdev))
+#elif defined(__OpenBSD__)
+#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, \
+    minor(_kdev)))->dv_cfdata->cf_driver->cd_devs[minor(_kdev)]
+#endif
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#define PAGE_ALIGN(addr) round_page(addr)
+/* DRM_SUSER returns true if the user is superuser */
+#if __FreeBSD_version >= 700000
+#define DRM_SUSER(p)           (priv_check(p, PRIV_DRIVER) == 0)
+#else
+#define DRM_SUSER(p)           (suser(p) == 0)
+#endif
+#define DRM_AGP_FIND_DEVICE()  agp_find_device()
+#define DRM_MTRR_WC            MDF_WRITECOMBINE
+#define jiffies                        ticks
+
+#else /* __FreeBSD__ || __DragonFly__ */
+
+#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__ && !__DragonFly__ */
+
+/* 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_int64_t u64;
+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
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#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__ || __DragonFly__ */
+
+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__ && !__DragonFly__ */
+
+#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_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 LOCK_TEST_WITH_RETURN(dev, file_priv)                          \
+do {                                                                   \
+       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ||              \
+            dev->lock.file_priv != file_priv) {                        \
+               DRM_ERROR("%s called without lock held\n",              \
+                          __FUNCTION__);                               \
+               return EINVAL;                                          \
+       }                                                               \
+} while (0)
+
+#if defined(__FreeBSD__) && __FreeBSD_version > 500000
+/* Returns -errno to shared code */
+#define DRM_WAIT_ON( ret, queue, timeout, condition )          \
+for ( ret = 0 ; !ret && !(condition) ; ) {                     \
+       DRM_UNLOCK();                                           \
+       mtx_lock(&dev->irq_lock);                               \
+       if (!(condition))                                       \
+          ret = -mtx_sleep(&(queue), &dev->irq_lock,           \
+                        PZERO | PCATCH, "drmwtq", (timeout));  \
+       mtx_unlock(&dev->irq_lock);                             \
+       DRM_LOCK();                                             \
+}
+#elif defined(__DragonFly__)
+#define DRM_WAIT_ON( ret, queue, timeout, condition )          \
+for ( ret = 0 ; !ret && !(condition) ; ) {                     \
+       DRM_UNLOCK();                                           \
+       lwkt_serialize_enter(&dev->irq_lock);                   \
+       if (!(condition)) {                                     \
+          crit_enter();                                        \
+          tsleep_interlock(&(queue));                          \
+          lwkt_serialize_exit(&dev->irq_lock);                 \
+          ret = -tsleep(&(queue), PCATCH,                      \
+                        "drmwtq", (timeout));                  \
+          crit_exit();                                         \
+       } else {                                                \
+               lwkt_serialize_exit(&dev->irq_lock);            \
+       }                                                       \
+       DRM_LOCK();                                             \
+}
+#else
+/* Returns -errno to shared code */
+#define DRM_WAIT_ON( ret, queue, timeout, condition )  \
+for ( ret = 0 ; !ret && !(condition) ; ) {             \
+        int s = spldrm();                              \
+       if (!(condition))                               \
+          ret = -tsleep( &(queue), PZERO | PCATCH,     \
+                        "drmwtq", (timeout) );         \
+       splx(s);                                        \
+}
+#endif
+
+#ifdef __DragonFly__
+#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
+#define printf kprintf
+#define snprintf ksnprintf
+#define sscanf ksscanf
+#define malloc kmalloc
+#define realloc        krealloc
+
+__inline static void
+free(void *addr, struct malloc_type *type)
+{
+       if (addr != NULL)
+               kfree(addr, type);
+}
+#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                  auth_needed;
-       int                  root_only;
+       unsigned long cmd;
+       int (*func)(drm_device_t *dev, void *data, struct drm_file *file_priv);
+       int flags;
 } drm_ioctl_desc_t;
+/**
+ * Creates a driver or general drm_ioctl_desc array entry for the given
+ * ioctl, for use by drm_ioctl().
+ */
+#define DRM_IOCTL_DEF(ioctl, func, flags) \
+       [DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags}
 
 typedef struct drm_magic_entry {
        drm_magic_t            magic;
@@ -155,7 +524,7 @@ typedef struct drm_buf {
        unsigned long     bus_address; /* Bus address of buffer              */
        struct drm_buf    *next;       /* Kernel-only: used for free list    */
        __volatile__ int  pending;     /* On hardware DMA queue              */
-       DRMFILE           filp;        /* Unique identifier of holding process */
+       struct drm_file   *file_priv;  /* Unique identifier of holding process */
        int               context;     /* Kernel queue for this buffer       */
        enum {
                DRM_LIST_NONE    = 0,
@@ -170,17 +539,6 @@ typedef struct drm_buf {
        void              *dev_private;  /* Per-buffer private storage       */
 } drm_buf_t;
 
-                               /* bufs is one longer than it has to be */
-typedef struct drm_waitlist {
-       int               count;        /* Number of possible buffers      */
-       drm_buf_t         **bufs;       /* List of pointers to buffers     */
-       drm_buf_t         **rp;         /* Read pointer                    */
-       drm_buf_t         **wp;         /* Write pointer                   */
-       drm_buf_t         **end;        /* End pointer                     */
-       DRM_SPINTYPE      read_lock;
-       DRM_SPINTYPE      write_lock;
-} drm_waitlist_t;
-
 typedef struct drm_freelist {
        int               initialized; /* Freelist in use                  */
        atomic_t          count;       /* Number of free buffers           */
@@ -188,45 +546,58 @@ typedef struct drm_freelist {
 
        int               low_mark;    /* Low water mark                   */
        int               high_mark;   /* High water mark                  */
-       DRM_SPINTYPE   lock;
 } drm_freelist_t;
 
+typedef struct drm_dma_handle {
+       void *vaddr;
+       bus_addr_t busaddr;
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+       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;
-       unsigned long     *seglist;
 
        drm_freelist_t    freelist;
 } drm_buf_entry_t;
 
-typedef struct drm_hw_lock {
-       __volatile__ unsigned int lock;
-       char                      padding[60]; /* Pad to cache line */
-} drm_hw_lock_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;
-       struct drm_device *devXX;
+       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)*/
-       wait_queue_head_t lock_queue;   /* Queue of blocked processes      */
+       struct drm_file   *file_priv;   /* Unique identifier of holding process (NULL is kernel)*/
+       int               lock_queue;   /* Queue of blocked processes      */
        unsigned long     lock_time;    /* Time of last lock in jiffies    */
 } drm_lock_data_t;
 
+/* 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;
@@ -239,13 +610,8 @@ typedef struct drm_device_dma {
                _DRM_DMA_USE_AGP = 0x01,
                _DRM_DMA_USE_SG  = 0x02
        } flags;
-
-                               /* DMA support */
-       drm_buf_t         *this_buffer; /* Buffer being sent               */
-       drm_buf_t         *next_buffer; /* Selected buffer to send         */
 } drm_device_dma_t;
 
-#if __REALLY_HAVE_AGP
 typedef struct drm_agp_mem {
        void               *handle;
        unsigned long      bound; /* address */
@@ -263,19 +629,21 @@ typedef struct drm_agp_head {
        int                enabled;
        int                acquired;
        unsigned long      base;
-       int                agp_mtrr;
+       int                mtrr;
        int                cant_use_aperture;
        unsigned long      page_mask;
 } drm_agp_head_t;
-#endif
 
 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)           */
@@ -283,18 +651,16 @@ typedef struct drm_local_map {
        drm_map_flags_t flags;   /* Flags                                   */
        void            *handle; /* User-space: "Handle" to pass to mmap    */
                                 /* Kernel-space: kernel-virtual address    */
-       int             mtrr;    /* MTRR slot used                          */
+       int             mtrr;    /* Boolean: MTRR used */
                                 /* Private data                            */
-       bus_space_tag_t iot;
-       bus_space_handle_t ioh;
+       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;
 
-typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t;
-typedef struct drm_map_list_entry {
-       TAILQ_ENTRY(drm_map_list_entry) link;
-       drm_local_map_t *map;
-} drm_map_list_entry_t;
-
 TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
 typedef struct drm_vbl_sig {
        TAILQ_ENTRY(drm_vbl_sig) link;
@@ -303,27 +669,133 @@ typedef struct drm_vbl_sig {
        int             pid;
 } drm_vbl_sig_t;
 
+/* location of GART table */
+#define DRM_ATI_GART_MAIN 1
+#define DRM_ATI_GART_FB   2
+
+#define DRM_ATI_GART_PCI  1
+#define DRM_ATI_GART_PCIE 2
+#define DRM_ATI_GART_IGP  3
+
+struct drm_ati_pcigart_info {
+       int gart_table_location;
+       int gart_reg_if;
+       void *addr;
+       dma_addr_t bus_addr;
+       drm_local_map_t mapping;
+       int table_size;
+};
+
+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 *, struct drm_file *file_priv);
+       void    (*postclose)(struct drm_device *, drm_file_t *);
+       void    (*lastclose)(struct drm_device *);
+       int     (*unload)(struct drm_device *);
+       void    (*reclaim_buffers_locked)(struct drm_device *,
+                                         struct drm_file *file_priv);
+       int     (*dma_ioctl)(drm_device_t *dev, void *data, struct drm_file *file_priv);
+       void    (*dma_ready)(struct drm_device *);
+       int     (*dma_quiescent)(struct drm_device *);
+       int     (*dma_flush_block_and_flush)(struct drm_device *, int context,
+                                            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);
+       int     (*vblank_wait2)(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_vbl_irq2 :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 {
-#ifdef __NetBSD__
-       struct device     device;       /* NetBSD's softc is an extension of struct device */
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+       struct device     device; /* softc is an extension of struct device */
 #endif
-       const char        *name;        /* Simple driver name              */
+
+       struct drm_driver_info driver;
+       drm_pci_id_list_t *id_entry;    /* PCI ID, name, and chipset private */
+
+       u_int16_t pci_device;           /* PCI device id */
+       u_int16_t pci_vendor;           /* PCI vendor id */
+
        char              *unique;      /* Unique identifier: e.g., busid  */
        int               unique_len;   /* Length of unique field          */
-#if defined(__DragonFly__) || defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
        device_t          device;       /* Device instance from newbus     */
 #endif
-       cdev_t            devnode;      /* Device number for mknod         */
+       struct cdev       *devnode;     /* Device number for mknod         */
+       int               if_version;   /* Highest interface version set */
 
        int               flags;        /* Flags to open(2)                */
 
                                /* Locks */
-       DRM_SPINTYPE      count_lock;   /* For open_count, buf_use, buf_alloc */
-       struct lock       dev_lock;     /* For others                      */
+#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 */
+#elif defined(__DragonFly__)
+       struct lock       dma_lock;     /* protects dev->dma */
+       struct lwkt_serialize irq_lock; /* protects irq condition checks */
+       struct lock       dev_lock;     /* protects everything else */
+#endif
+       DRM_SPINTYPE      drw_lock;
+
                                /* Usage Counters */
        int               open_count;   /* Outstanding files open          */
        int               buf_use;      /* Buffers in use -- cannot alloc  */
-       int               buf_alloc;    /* Buffer allocation in progress   */
 
                                /* Performance counters */
        unsigned long     counters;
@@ -334,8 +806,8 @@ struct drm_device {
        drm_file_list_t   files;
        drm_magic_head_t  magiclist[DRM_HASH_SIZE];
 
-                               /* Memory management */
-       drm_map_list_t    *maplist;     /* Linked list of regions          */
+       /* Linked list of mappable regions. Protected by dev_lock */
+       drm_map_list_t    maplist;
 
        drm_local_map_t   **context_sareas;
        int               max_context;
@@ -347,30 +819,31 @@ struct drm_device {
 
                                /* Context support */
        int               irq;          /* Interrupt used by board         */
-       int               irqrid;               /* Interrupt used by board         */
-#if defined(__DragonFly__) || defined(__FreeBSD__)
+       int               irq_enabled;  /* True if the irq handler is enabled */
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+       int               irqrid;       /* Interrupt used by board */
        struct resource   *irqr;        /* Resource for interrupt used by board    */
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
        struct pci_attach_args  pa;
-       pci_intr_handle_t       ih;
 #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           */
-       struct callout    timer;        /* Timer for delaying ctx switch   */
        int               last_context; /* Last current context            */
-#if defined(__DragonFly__) || __FreeBSD_version >= 400005
-       struct task       task;
-#endif
-#if __HAVE_VBL_IRQ
-       wait_queue_head_t vbl_queue;    /* vbl wait channel */
+       int               vbl_queue;    /* vbl wait channel */
        atomic_t          vbl_received;
-#if 0 /* vbl signals are untested */
-       struct drm_vbl_sig_list vbl_sig_list;
-       DRM_SPINTYPE      vbl_lock;
-#endif
-#endif
+       atomic_t          vbl_received2;
 
-#if defined(__DragonFly__) || defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
        struct sigio      *buf_sigio;   /* Processes waiting for SIGIO     */
 #elif defined(__NetBSD__)
        pid_t             buf_pgid;
@@ -379,193 +852,253 @@ struct drm_device {
                                /* Sysctl support */
        struct drm_sysctl_info *sysctl;
 
-#if __REALLY_HAVE_AGP
        drm_agp_head_t    *agp;
-#endif
        drm_sg_mem_t      *sg;  /* Scatter gather memory */
        atomic_t          *ctx_bitmap;
        void              *dev_private;
-};
-
-extern int          DRM(flags);
-
-                               /* Authentication (drm_auth.h) */
-extern int           DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, 
-                                   drm_magic_t magic);
-extern int           DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic);
+       unsigned int      agp_buffer_token;
+       drm_local_map_t   *agp_buffer_map;
 
-                               /* Driver support (drm_drv.h) */
-extern int           DRM(version)( DRM_IOCTL_ARGS );
-
-                               /* Memory management support (drm_memory.h) */
-extern void         DRM(mem_init)(void);
-extern void         DRM(mem_uninit)(void);
-extern void         *DRM(alloc)(size_t size, int area);
-extern void         *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
-                                  int area);
-extern char         *DRM(strdup)(const char *s, int area);
-extern void         DRM(strfree)(char *s, int area);
-extern void         DRM(free)(void *pt, size_t size, int area);
-extern void         *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map);
-extern void         *DRM(ioremap_nocache)(drm_device_t *dev, drm_local_map_t *map);
-extern void         DRM(ioremapfree)(drm_local_map_t *map);
-
-#if __REALLY_HAVE_AGP
-extern agp_memory    *DRM(alloc_agp)(int pages, u32 type);
-extern int           DRM(free_agp)(agp_memory *handle, int pages);
-extern int           DRM(bind_agp)(agp_memory *handle, unsigned int start);
-extern int           DRM(unbind_agp)(agp_memory *handle);
+#ifdef __FreeBSD__
+       struct unrhdr     *drw_unrhdr;
 #endif
+       /* RB tree of drawable infos */
+       RB_HEAD(drawable_tree, bsd_drm_drawable_info) drw_head;
 
-extern int          DRM(context_switch)(drm_device_t *dev, int old, int new);
-extern int          DRM(context_switch_complete)(drm_device_t *dev, int new);
+       struct task       locked_task;
+       void              (*locked_task_call)(drm_device_t *dev);
+};
 
-#if __HAVE_CTX_BITMAP
-extern int          DRM(ctxbitmap_init)( drm_device_t *dev );
-extern void         DRM(ctxbitmap_cleanup)( drm_device_t *dev );
-extern void          DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle );
-extern int           DRM(ctxbitmap_next)( drm_device_t *dev );
+extern int     drm_debug_flag;
+
+/* Device setup support (drm_drv.c) */
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+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
-
-                               /* Locking IOCTL support (drm_lock.h) */
-extern int          DRM(lock_take)(__volatile__ unsigned int *lock,
+extern drm_local_map_t *drm_getsarea(drm_device_t *dev);
+
+/* File operations helpers (drm_fops.c) */
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+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(int handle, 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);
-extern int          DRM(lock_transfer)(drm_device_t *dev,
+int    drm_lock_transfer(drm_device_t *dev,
                                        __volatile__ unsigned int *lock,
                                        unsigned int context);
-extern int          DRM(lock_free)(drm_device_t *dev,
+int    drm_lock_free(drm_device_t *dev,
                                    __volatile__ unsigned int *lock,
                                    unsigned int context);
 
-                               /* Buffer management support (drm_bufs.h) */
-extern int          DRM(order)( unsigned long size );
-
-#if __HAVE_DMA
-                               /* DMA support (drm_dma.h) */
-extern int          DRM(dma_setup)(drm_device_t *dev);
-extern void         DRM(dma_takedown)(drm_device_t *dev);
-extern void         DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
-extern void         DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp);
-#if __HAVE_DMA_IRQ
-extern int           DRM(irq_install)( drm_device_t *dev, int irq );
-extern int           DRM(irq_uninstall)( drm_device_t *dev );
-extern void          DRM(dma_service)( DRM_IRQ_ARGS );
-extern void          DRM(driver_irq_preinstall)( drm_device_t *dev );
-extern void          DRM(driver_irq_postinstall)( drm_device_t *dev );
-extern void          DRM(driver_irq_uninstall)( drm_device_t *dev );
-#if __HAVE_DMA_IRQ_BH
-extern void          DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS );
-#endif
-#endif
-
-                               /* Buffer list support (drm_lists.h) */
-#if __HAVE_DMA_WAITLIST
-extern int          DRM(waitlist_create)(drm_waitlist_t *bl, int count);
-extern int          DRM(waitlist_destroy)(drm_waitlist_t *bl);
-extern int          DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf);
-extern drm_buf_t     *DRM(waitlist_get)(drm_waitlist_t *bl);
-#endif
-#endif /* __HAVE_DMA */
-#if __HAVE_VBL_IRQ
-extern int           DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
-extern void          DRM(vbl_send_signals)( drm_device_t *dev );
-#endif
-
-#if __REALLY_HAVE_AGP
-                               /* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *DRM(agp_init)(void);
-extern void           DRM(agp_uninit)(void);
-extern void           DRM(agp_do_release)(void);
-extern agp_memory     *DRM(agp_allocate_memory)(size_t pages, u32 type);
-extern int            DRM(agp_free_memory)(agp_memory *handle);
-extern int            DRM(agp_bind_memory)(agp_memory *handle, off_t start);
-extern int            DRM(agp_unbind_memory)(agp_memory *handle);
-#endif
-
-#if __HAVE_SG
-                               /* Scatter Gather Support (drm_scatter.h) */
-extern void           DRM(sg_cleanup)(drm_sg_mem_t *entry);
-#endif
-
-#if __REALLY_HAVE_SG
-                               /* ATI PCIGART support (ati_pcigart.h) */
-extern int            DRM(ati_pcigart_init)(drm_device_t *dev,
-                                           unsigned long *addr,
-                                           dma_addr_t *bus_addr);
-extern int            DRM(ati_pcigart_cleanup)(drm_device_t *dev,
-                                              unsigned long addr,
-                                              dma_addr_t bus_addr);
-#endif
-
-/* Locking IOCTL support (drm_drv.h) */
-extern int             DRM(lock)(DRM_IOCTL_ARGS);
-extern int             DRM(unlock)(DRM_IOCTL_ARGS);
-
-/* Misc. IOCTL support (drm_ioctl.h) */
-extern int             DRM(irq_busid)(DRM_IOCTL_ARGS);
-extern int             DRM(getunique)(DRM_IOCTL_ARGS);
-extern int             DRM(setunique)(DRM_IOCTL_ARGS);
-extern int             DRM(getmap)(DRM_IOCTL_ARGS);
-extern int             DRM(getclient)(DRM_IOCTL_ARGS);
-extern int             DRM(getstats)(DRM_IOCTL_ARGS);
-extern int             DRM(noop)(DRM_IOCTL_ARGS);
-
-/* Context IOCTL support (drm_context.h) */
-extern int             DRM(resctx)(DRM_IOCTL_ARGS);
-extern int             DRM(addctx)(DRM_IOCTL_ARGS);
-extern int             DRM(modctx)(DRM_IOCTL_ARGS);
-extern int             DRM(getctx)(DRM_IOCTL_ARGS);
-extern int             DRM(switchctx)(DRM_IOCTL_ARGS);
-extern int             DRM(newctx)(DRM_IOCTL_ARGS);
-extern int             DRM(rmctx)(DRM_IOCTL_ARGS);
-extern int             DRM(setsareactx)(DRM_IOCTL_ARGS);
-extern int             DRM(getsareactx)(DRM_IOCTL_ARGS);
-
-/* Drawable IOCTL support (drm_drawable.h) */
-extern int             DRM(adddraw)(DRM_IOCTL_ARGS);
-extern int             DRM(rmdraw)(DRM_IOCTL_ARGS);
-
-/* Authentication IOCTL support (drm_auth.h) */
-extern int             DRM(getmagic)(DRM_IOCTL_ARGS);
-extern int             DRM(authmagic)(DRM_IOCTL_ARGS);
-
-/* Buffer management support (drm_bufs.h) */
-extern int             DRM(addmap)(DRM_IOCTL_ARGS);
-extern int             DRM(rmmap)(DRM_IOCTL_ARGS);
-#if __HAVE_DMA
-extern int             DRM(addbufs)(DRM_IOCTL_ARGS);
-extern int             DRM(infobufs)(DRM_IOCTL_ARGS);
-extern int             DRM(markbufs)(DRM_IOCTL_ARGS);
-extern int             DRM(freebufs)(DRM_IOCTL_ARGS);
-extern int             DRM(mapbufs)(DRM_IOCTL_ARGS);
-#endif
-
-/* DMA support (drm_dma.h) */
-#if __HAVE_DMA
-extern int             DRM(control)(DRM_IOCTL_ARGS);
-#endif
-#if __HAVE_VBL_IRQ
-extern int             DRM(wait_vblank)(DRM_IOCTL_ARGS);
-#endif
-
-/* AGP/GART support (drm_agpsupport.h) */
-#if __REALLY_HAVE_AGP
-extern int             DRM(agp_acquire)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_release)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_enable)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_info)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_alloc)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_free)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_unbind)(DRM_IOCTL_ARGS);
-extern int             DRM(agp_bind)(DRM_IOCTL_ARGS);
-#endif
-
-/* Scatter Gather Support (drm_scatter.h) */
-#if __HAVE_SG
-extern int             DRM(sg_alloc)(DRM_IOCTL_ARGS);
-extern int             DRM(sg_free)(DRM_IOCTL_ARGS);
-#endif
-
+/* 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, struct drm_file *file_priv);
+#define drm_core_reclaim_buffers drm_reclaim_buffers
+
+/* 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);
+int    drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request);
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+/* 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__ || __DragonFly__ */
+
+/* ATI PCIGART support (ati_pcigart.c) */
+int    drm_ati_pcigart_init(drm_device_t *dev,
+                               struct drm_ati_pcigart_info *gart_info);
+int    drm_ati_pcigart_cleanup(drm_device_t *dev,
+                               struct drm_ati_pcigart_info *gart_info);
+
+/* Locking IOCTL support (drm_drv.c) */
+int    drm_lock(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_unlock(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_version(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_setversion(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* Misc. IOCTL support (drm_ioctl.c) */
+int    drm_irq_by_busid(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_getunique(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_setunique(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_getmap(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_getclient(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_getstats(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_noop(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* Context IOCTL support (drm_context.c) */
+int    drm_resctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_addctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_modctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_getctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_switchctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_newctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_rmctx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_setsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_getsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* Drawable IOCTL support (drm_drawable.c) */
+int    drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv);
+struct drm_drawable_info *drm_get_drawable_info(drm_device_t *dev, int handle);
+
+/* Authentication IOCTL support (drm_auth.c) */
+int    drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* Buffer management support (drm_bufs.c) */
+int    drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_rmmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_addbufs_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_infobufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_markbufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_freebufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* DMA support (drm_dma.c) */
+int    drm_dma(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* IRQ support (drm_irq.c) */
+int    drm_control(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv);
+void   drm_locked_tasklet(drm_device_t *dev,
+                          void (*tasklet)(drm_device_t *dev));
+
+/* AGP/GART support (drm_agpsupport.c) */
+int    drm_agp_acquire_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_release_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_enable_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_info_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_free_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_unbind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_agp_bind_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* Scatter Gather Support (drm_scatter.c) */
+int    drm_sg_alloc_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv);
+int    drm_sg_free(drm_device_t *dev, void *data, struct drm_file *file_priv);
+
+/* consistent PCI memory functions (drm_pci.c) */
+drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, size_t align,
+                               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/sys/dev/drm/drm_agpsupport.c b/sys/dev/drm/drm_agpsupport.c
new file mode 100644 (file)
index 0000000..36bc2de
--- /dev/null
@@ -0,0 +1,467 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/drm_agpsupport.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file drm_agpsupport.c
+ * Support code for tying the kernel AGP support to DRM drivers and
+ * the DRM's AGP ioctls.
+ */
+
+#include "drmP.h"
+
+#ifdef __FreeBSD__
+#if __FreeBSD_version >= 800004
+#include <dev/agp/agpreg.h>
+#else /* __FreeBSD_version >= 800004 */
+#include <pci/agpreg.h>
+#endif /* __FreeBSD_version >= 800004 */
+#include <dev/pci/pcireg.h>
+#elif defined(__DragonFly__)
+#include <dev/agp/agpreg.h>
+#include <bus/pci/pcireg.h>
+#endif
+
+/* Returns 1 if AGP or 0 if not. */
+static int
+drm_device_find_capability(drm_device_t *dev, int cap)
+{
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#if __FreeBSD_version >= 602102
+
+       return (pci_find_extcap(dev->device, cap, NULL) == 0);
+#else
+       /* 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;
+#endif
+#else
+       /* XXX: fill me in for non-FreeBSD */
+       return 1;
+#endif
+}
+
+int drm_device_is_agp(drm_device_t *dev)
+{
+       if (dev->driver.device_is_agp != NULL) {
+               int ret;
+
+               /* device_is_agp returns a tristate, 0 = not AGP, 1 = definitely
+                * AGP, 2 = fall back to PCI capability
+                */
+               ret = (*dev->driver.device_is_agp)(dev);
+               if (ret != DRM_MIGHT_BE_AGP)
+                       return ret;
+       }
+
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       int err;
+       drm_agp_info_t info;
+
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+
+       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->enabled = 1;
+       return 0;
+}
+
+int drm_agp_enable_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_agp_mode_t mode;
+
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       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->base = head->info.ai_aperture_base;
+               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/sys/dev/drm/drm_agpsupport.h b/sys/dev/drm/drm_agpsupport.h
deleted file mode 100644 (file)
index 0513994..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/* 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>
- * $FreeBSD: src/sys/dev/drm/drm_agpsupport.h,v 1.2.2.1 2003/04/26 07:05:28 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/drm_agpsupport.h,v 1.2 2003/06/17 04:28:24 dillon Exp $
- */
-
-#include "dev/drm/drmP.h"
-
-int DRM(agp_info)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       struct agp_info *kern;
-       drm_agp_info_t   info;
-
-       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;
-
-       *(drm_agp_info_t *) data = info;
-       return 0;
-}
-
-int DRM(agp_acquire)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       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)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-
-       if (!dev->agp || !dev->agp->acquired)
-               return EINVAL;
-       agp_release(dev->agp->agpdev);
-       dev->agp->acquired = 0;
-       return 0;
-       
-}
-
-void DRM(agp_do_release)(void)
-{
-       device_t agpdev;
-
-       agpdev = DRM_AGP_FIND_DEVICE();
-       if (agpdev)
-               agp_release(agpdev);
-}
-
-int DRM(agp_enable)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       drm_agp_mode_t mode;
-
-       if (!dev->agp || !dev->agp->acquired)
-               return EINVAL;
-
-       mode = *(drm_agp_mode_t *) data;
-       
-       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_alloc)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       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;
-
-       request = *(drm_agp_buffer_t *) data;
-
-       if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
-               return ENOMEM;
-   
-       bzero(entry, sizeof(*entry));
-
-       pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-       type = (u_int32_t) request.type;
-
-       if (!(handle = DRM(alloc_agp)(pages, type))) {
-               DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               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;
-
-       *(drm_agp_buffer_t *) data = request;
-
-       return 0;
-}
-
-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_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       drm_agp_binding_t request;
-       drm_agp_mem_t     *entry;
-       int retcode;
-
-       if (!dev->agp || !dev->agp->acquired)
-               return EINVAL;
-       request = *(drm_agp_binding_t *) data;
-       if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle)))
-               return EINVAL;
-       if (!entry->bound) return EINVAL;
-       retcode=DRM(unbind_agp)(entry->handle);
-       if (!retcode)
-       {
-               entry->bound=0;
-               return 0;
-       }
-       else
-               return retcode;
-}
-
-int DRM(agp_bind)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       drm_agp_binding_t request;
-       drm_agp_mem_t     *entry;
-       int               retcode;
-       int               page;
-       
-       DRM_DEBUG("agp_bind, page_size=%x\n", PAGE_SIZE);
-       if (!dev->agp || !dev->agp->acquired)
-               return EINVAL;
-       request = *(drm_agp_binding_t *) data;
-       if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle)))
-               return EINVAL;
-       if (entry->bound) return EINVAL;
-       page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
-       if ((retcode = DRM(bind_agp)(entry->handle, page)))
-               return retcode;
-       entry->bound = dev->agp->base + (page << PAGE_SHIFT);
-       return 0;
-}
-
-int DRM(agp_free)(DRM_IOCTL_ARGS)
-{
-       DRM_DEVICE;
-       drm_agp_buffer_t request;
-       drm_agp_mem_t    *entry;
-       
-       if (!dev->agp || !dev->agp->acquired)
-               return EINVAL;
-       request = *(drm_agp_buffer_t *) data;
-       if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle)))
-               return EINVAL;
-       if (entry->bound)
-               DRM(unbind_agp)(entry->handle);
-   
-       if (entry->prev)
-               entry->prev->next = entry->next;
-       else
-               dev->agp->memory  = entry->next;
-       if (entry->next)
-               entry->next->prev = entry->prev;
-       DRM(free_agp)(entry->handle, entry->pages);
-       DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-       return 0;
-}
-
-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) {
-               if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
-                       return NULL;
-               bzero((void *)head, sizeof(*head));
-               head->agpdev = agpdev;
-               agp_get_info(agpdev, &head->info);
-               head->memory = NULL;
-#if 0                          /* bogus */
-               switch (head->agp_info.chipset) {
-               case INTEL_GENERIC:  head->chipset = "Intel";          break;
-               case INTEL_LX:       head->chipset = "Intel 440LX";    break;
-               case INTEL_BX:       head->chipset = "Intel 440BX";    break;
-               case INTEL_GX:       head->chipset = "Intel 440GX";    break;
-               case INTEL_I810:     head->chipset = "Intel i810";     break;
-               case VIA_GENERIC:    head->chipset = "VIA";            break;
-               case VIA_VP3:        head->chipset = "VIA VP3";        break;
-               case VIA_MVP3:       head->chipset = "VIA MVP3";       break;
-               case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
-               case SIS_GENERIC:    head->chipset = "SiS";            break;
-               case AMD_GENERIC:    head->chipset = "AMD";            break;
-               case AMD_IRONGATE:   head->chipset = "AMD Irongate";   break;
-               case ALI_GENERIC:    head->chipset = "ALi";            break;
-               case ALI_M1541:      head->chipset = "ALi M1541";      break;
-               default:
-               }
-#endif
-               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_uninit)(void)
-{
-/* FIXME: What goes here */
-}
-
-
-agp_memory *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)(agp_memory *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)(agp_memory *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)(agp_memory *handle)
-{
-       device_t agpdev;
-
-       agpdev = DRM_AGP_FIND_DEVICE();
-       if (!agpdev || !handle)
-               return EINVAL;
-
-       return agp_unbind_memory(agpdev, handle);
-}
diff --git a/sys/dev/drm/drm_atomic.h b/sys/dev/drm/drm_atomic.h
new file mode 100644 (file)
index 0000000..0f69dc2
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+ * \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.
+ *
+ * $DragonFly: src/sys/dev/drm/drm_atomic.h,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/* Many of these implementations are rather fake, but good enough. */
+
+typedef u_int32_t atomic_t;
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#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__ || __DragonFly__ */
+/* 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__ && !__DragonFly__ */
+
+#ifndef __DragonFly__
+#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;
+}
+
+#else  /* __DragonFly__ */
+
+static __inline atomic_t
+test_and_set_bit(int b, volatile void *p)
+{
+       unsigned int m = 1<<b;
+       unsigned int o, n;
+
+       do {
+               o = *(volatile int *)p;
+               n = o | m;
+       } while (!atomic_cmpset_int(p, o, n));
+
+       return (o & m);
+}
+
+#endif /* __DragonFly__ */
+
+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;
+}
similarity index 51%
rename from sys/dev/drm/drm_auth.h
rename to sys/dev/drm/drm_auth.c
index d550348..4652fca 100644 (file)
@@ -1,6 +1,4 @@
-/* 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.
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- * $FreeBSD: src/sys/dev/drm/drm_auth.h,v 1.3.2.1 2003/04/26 07:05:28 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/drm_auth.h,v 1.2 2003/06/17 04:28:24 dillon Exp $
+ *
+ * $DragonFly: src/sys/dev/drm/drm_auth.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
  */
 
-#include "dev/drm/drmP.h"
+/** @file drm_auth.c
+ * Implementation of the get/authmagic ioctls implementing the authentication
+ * scheme between the master and clients.
+ */
 
-static int DRM(hash_magic)(drm_magic_t magic)
+#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)
+/**
+ * Returns the file private associated with the given magic number.
+ */
+static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
 {
-       drm_file_t        *retval = NULL;
        drm_magic_entry_t *pt;
-       int               hash    = DRM(hash_magic)(magic);
+       int hash = drm_hash_magic(magic);
+
+       DRM_SPINLOCK_ASSERT(&dev->dev_lock);
 
-       DRM_LOCK;
        for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
                if (pt->magic == magic) {
-                       retval = pt->priv;
-                       break;
+                       return pt->priv;
                }
        }
-       DRM_UNLOCK;
-       return retval;
+
+       return NULL;
 }
 
-int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+/**
+ * Inserts the given magic number into the hash table of used magic number
+ * lists.
+ */
+static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
 {
        int               hash;
        drm_magic_entry_t *entry;
 
        DRM_DEBUG("%d\n", magic);
 
-       hash         = DRM(hash_magic)(magic);
-       entry        = (drm_magic_entry_t*) DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
-       if (!entry) return DRM_ERR(ENOMEM);
-       memset(entry, 0, sizeof(*entry));
+       DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
+       hash = drm_hash_magic(magic);
+       entry = malloc(sizeof(*entry), M_DRM, M_ZERO | M_NOWAIT);
+       if (!entry) return ENOMEM;
        entry->magic = magic;
        entry->priv  = priv;
        entry->next  = NULL;
 
-       DRM_LOCK;
+       DRM_LOCK();
        if (dev->magiclist[hash].tail) {
                dev->magiclist[hash].tail->next = entry;
                dev->magiclist[hash].tail       = entry;
@@ -78,21 +88,26 @@ int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
                dev->magiclist[hash].head       = entry;
                dev->magiclist[hash].tail       = entry;
        }
-       DRM_UNLOCK;
+       DRM_UNLOCK();
 
        return 0;
 }
 
-int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
+/**
+ * Removes the given magic number from the hash table of used magic number
+ * lists.
+ */
+static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
 {
        drm_magic_entry_t *prev = NULL;
        drm_magic_entry_t *pt;
        int               hash;
 
+       DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
        DRM_DEBUG("%d\n", magic);
-       hash = DRM(hash_magic)(magic);
+       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) {
@@ -104,59 +119,69 @@ int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
                        if (prev) {
                                prev->next = pt->next;
                        }
-                       DRM_UNLOCK;
                        return 0;
                }
        }
-       DRM_UNLOCK;
 
-       DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC);
-       return DRM_ERR(EINVAL);
+       free(pt, M_DRM);
+       return EINVAL;
 }
 
-int DRM(getmagic)(DRM_IOCTL_ARGS)
+/**
+ * Called by the client, this returns a unique magic number to be authorized
+ * by the master.
+ *
+ * The master may use its own knowledge of the client (such as the X
+ * connection that the magic is passed over) to determine if the magic number
+ * should be authenticated.
+ */
+int drm_getmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
 {
        static drm_magic_t sequence = 0;
-       drm_auth_t         auth;
-       DRM_DEVICE;
-       DRM_PRIV;
+       drm_auth_t *auth = data;
 
                                /* Find unique magic */
-       if (priv->magic) {
-               auth.magic = priv->magic;
+       if (file_priv->magic) {
+               auth->magic = file_priv->magic;
        } else {
+               DRM_LOCK();
                do {
                        int old = sequence;
-                       
-                       auth.magic = old+1;
-                       
-                       if (!atomic_cmpset_int(&sequence, old, auth.magic))
+
+                       auth->magic = old+1;
+
+                       if (!atomic_cmpset_int(&sequence, old, auth->magic))
                                continue;
-               } while (DRM(find_file)(dev, auth.magic));
-               priv->magic = auth.magic;
-               DRM(add_magic)(dev, priv, auth.magic);
+               } while (drm_find_file(dev, auth->magic));
+               file_priv->magic = auth->magic;
+               drm_add_magic(dev, file_priv, auth->magic);
+               DRM_UNLOCK();
        }
 
-       DRM_DEBUG("%u\n", auth.magic);
-
-       DRM_COPY_TO_USER_IOCTL((drm_auth_t *)data, auth, sizeof(auth));
+       DRM_DEBUG("%u\n", auth->magic);
 
        return 0;
 }
 
-int DRM(authmagic)(DRM_IOCTL_ARGS)
+/**
+ * Marks the client associated with the given magic number as authenticated.
+ */
+int drm_authmagic(drm_device_t *dev, void *data, struct drm_file *file_priv)
 {
-       drm_auth_t         auth;
-       drm_file_t         *file;
-       DRM_DEVICE;
+       drm_auth_t *auth = data;
+       drm_file_t *priv;
 
-       DRM_COPY_FROM_USER_IOCTL(auth, (drm_auth_t *)data, sizeof(auth));
+       DRM_DEBUG("%u\n", auth->magic);
 
-       DRM_DEBUG("%u\n", auth.magic);
-       if ((file = DRM(find_file)(dev, auth.magic))) {
-               file->authenticated = 1;
-               DRM(remove_magic)(dev, auth.magic);
+       DRM_LOCK();
+       priv = drm_find_file(dev, auth->magic);
+       if (priv != NULL) {
+               priv->authenticated = 1;
+               drm_remove_magic(dev, auth->magic);
+               DRM_UNLOCK();
                return 0;
+       } else {
+               DRM_UNLOCK();
+               return EINVAL;
        }
-       return DRM_ERR(EINVAL);
 }
diff --git a/sys/dev/drm/drm_bufs.c b/sys/dev/drm/drm_bufs.c
new file mode 100644 (file)
index 0000000..4912c3f
--- /dev/null
@@ -0,0 +1,1121 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/drm_bufs.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file drm_bufs.c
+ * Implementation of the ioctls for setup of DRM mappings and DMA buffers.
+ */
+
+#ifdef __DragonFly__
+#include <bus/pci/pcireg.h>
+#else
+#include "dev/pci/pcireg.h"
+#endif
+
+#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;
+       }
+
+       DRM_UNLOCK();
+       if (dev->pcir[resource] != NULL) {
+               DRM_LOCK();
+               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);
+       DRM_LOCK();
+
+       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 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 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 EBUSY;
+                       }
+                       dev->lock.hw_lock = map->handle; /* Pointer to lock */
+                       DRM_UNLOCK();
+               }
+               break;
+       case _DRM_AGP:
+               /*valid = 0;*/
+               /* In some cases (i810 driver), user space may have already
+                * added the AGP base itself, because dev->agp->base previously
+                * only got set during AGP enable.  So, only add the base
+                * address if the map's offset isn't already within the
+                * aperture.
+                */
+               if (map->offset < dev->agp->base ||
+                   map->offset > dev->agp->base +
+                   dev->agp->info.ai_aperture_size - 1) {
+                       map->offset += dev->agp->base;
+               }
+               map->mtrr   = dev->agp->mtrr; /* for getmap */
+               /*for (entry = dev->agp->memory; entry; entry = entry->next) {
+                       if ((map->offset >= entry->bound) &&
+                           (map->offset + map->size <=
+                           entry->bound + entry->pages * PAGE_SIZE)) {
+                               valid = 1;
+                               break;
+                       }
+               }
+               if (!valid) {
+                       free(map, M_DRM);
+                       return EACCES;
+               }*/
+               break;
+       case _DRM_SCATTER_GATHER:
+               if (!dev->sg) {
+                       free(map, M_DRM);
+                       return 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 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 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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_map_t *request = data;
+       drm_local_map_t *map;
+       int err;
+
+       if (!(dev->flags & (FREAD|FWRITE)))
+               return EACCES; /* Require read/write */
+
+       if (!DRM_SUSER(DRM_CURPROC) && request->type != _DRM_AGP)
+               return EACCES;
+
+       DRM_LOCK();
+       err = drm_addmap(dev, request->offset, request->size, request->type,
+           request->flags, &map);
+       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;
+       }
+
+       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(0, 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;
+       default:
+               DRM_ERROR("Bad map type %d\n", map->type);
+               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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_local_map_t *map;
+       drm_map_t *request = data;
+
+       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 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 EINVAL;
+       }*/
+
+       entry = &dma->bufs[order];
+
+       entry->buflist = malloc(count * sizeof(*entry->buflist), M_DRM,
+           M_NOWAIT | M_ZERO);
+       if ( !entry->buflist ) {
+               return 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->file_priv = 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 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 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 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 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->file_priv = 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 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 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 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->file_priv = 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 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 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 EINVAL;
+       
+       order = drm_order(request->size);
+       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+               return EINVAL;
+
+       /* No more allocations after first buffer-using ioctl. */
+       if (dev->buf_use != 0) {
+               DRM_SPINUNLOCK(&dev->dma_lock);
+               return EBUSY;
+       }
+       /* No more than one allocation per order */
+       if (dev->dma->bufs[order].buf_count != 0) {
+               DRM_SPINUNLOCK(&dev->dma_lock);
+               return 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 EACCES;
+
+       if (request->count < 0 || request->count > 4096)
+               return EINVAL;
+       
+       order = drm_order(request->size);
+       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+               return EINVAL;
+
+       /* No more allocations after first buffer-using ioctl. */
+       if (dev->buf_use != 0) {
+               DRM_SPINUNLOCK(&dev->dma_lock);
+               return EBUSY;
+       }
+       /* No more than one allocation per order */
+       if (dev->dma->bufs[order].buf_count != 0) {
+               DRM_SPINUNLOCK(&dev->dma_lock);
+               return 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 EACCES;
+
+       if (request->count < 0 || request->count > 4096)
+               return EINVAL;
+       
+       order = drm_order(request->size);
+       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
+               return EINVAL;
+
+       /* No more allocations after first buffer-using ioctl. */
+       if (dev->buf_use != 0) {
+               DRM_SPINUNLOCK(&dev->dma_lock);
+               return EBUSY;
+       }
+       /* No more than one allocation per order */
+       if (dev->dma->bufs[order].buf_count != 0) {
+               DRM_SPINUNLOCK(&dev->dma_lock);
+               return ENOMEM;
+       }
+
+       ret = drm_do_addbufs_pci(dev, request);
+
+       DRM_SPINUNLOCK(&dev->dma_lock);
+
+       return ret;
+}
+
+int drm_addbufs_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_buf_desc_t *request = data;
+       int err;
+
+       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);
+
+       return err;
+}
+
+int drm_infobufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_info_t *request = data;
+       int i;
+       int count;
+       int retcode = 0;
+
+       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 = 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;
+
+       return retcode;
+}
+
+int drm_markbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_desc_t *request = data;
+       int order;
+
+       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 EINVAL;
+       }
+
+       DRM_SPINLOCK(&dev->dma_lock);
+       if (request->low_mark > dma->bufs[order].buf_count ||
+           request->high_mark > dma->bufs[order].buf_count) {
+               return EINVAL;
+       }
+
+       dma->bufs[order].freelist.low_mark  = request->low_mark;
+       dma->bufs[order].freelist.high_mark = request->high_mark;
+       DRM_SPINUNLOCK(&dev->dma_lock);
+
+       return 0;
+}
+
+int drm_freebufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_free_t *request = data;
+       int i;
+       int idx;
+       drm_buf_t *buf;
+       int retcode = 0;
+
+       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 = EFAULT;
+                       break;
+               }
+               if ( idx < 0 || idx >= dma->buf_count ) {
+                       DRM_ERROR( "Index %d (of %d max)\n",
+                                  idx, dma->buf_count - 1 );
+                       retcode = EINVAL;
+                       break;
+               }
+               buf = dma->buflist[idx];
+               if ( buf->file_priv != file_priv ) {
+                       DRM_ERROR("Process %d freeing buffer not owned\n",
+                                  DRM_CURRENTPID);
+                       retcode = EINVAL;
+                       break;
+               }
+               drm_free_buffer(dev, buf);
+       }
+       DRM_SPINUNLOCK(&dev->dma_lock);
+
+       return retcode;
+}
+
+int drm_mapbufs(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_device_dma_t *dma = dev->dma;
+       int retcode = 0;
+       const int zero = 0;
+       vm_offset_t address;
+       struct vmspace *vms;
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+       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 = data;
+       int i;
+
+#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 || defined(__DragonFly__)
+       vms = DRM_CURPROC->td_proc->p_vmspace;
+#else
+       vms = DRM_CURPROC->p_vmspace;
+#endif
+
+       DRM_SPINLOCK(&dev->dma_lock);
+       dev->buf_use++;         /* Can't allocate more after this call */
+       DRM_SPINUNLOCK(&dev->dma_lock);
+
+       if (request->count < dma->buf_count)
+               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;
+       }
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+       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, dev->devnode, foff);
+#else
+       retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
+           VM_PROT_ALL, MAP_SHARED, SLIST_FIRST(&dev->devnode->si_hlist),
+           foff);
+#endif
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+       vaddr = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
+       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 );
+
+       return retcode;
+}
diff --git a/sys/dev/drm/drm_bufs.h b/sys/dev/drm/drm_bufs.h
deleted file mode 100644 (file)
index 615d580..0000000
+++ /dev/null
@@ -1,1025 +0,0 @@
-/* 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>
- * $FreeBSD: src/sys/dev/drm/drm_bufs.h,v 1.5.2.1 2003/04/26 07:05:28 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/drm_bufs.h,v 1.4 2004/02/13 01:23:57 joerg Exp $
- */
-
-#include "dev/drm/drmP.h"
-
-#ifndef __HAVE_PCI_DMA
-#define __HAVE_PCI_DMA         0
-#endif
-
-#ifndef __HAVE_SG
-#define __HAVE_SG              0
-#endif
-
-#ifndef DRIVER_BUF_PRIV_T
-#define DRIVER_BUF_PRIV_T              u32
-#endif
-#ifndef DRIVER_AGP_BUFFERS_MAP
-#if __HAVE_AGP && __HAVE_DMA
-#error "You must define DRIVER_AGP_BUFFERS_MAP()"
-#else
-#define DRIVER_AGP_BUFFERS_MAP( dev )  NULL
-#endif
-#endif
-
-/*
- * 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;
-}
-
-int DRM(addmap)( DRM_IOCTL_ARGS )
-{
-       DRM_DEVICE;
-       drm_map_t request;
-       drm_local_map_t *map;
-       drm_map_list_entry_t *list;
-       
-       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) );
-
-       map = (drm_local_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
-       if ( !map )
-               return DRM_ERR(ENOMEM);
-
-       map->offset = request.offset;
-       map->size = request.size;
-       map->type = request.type;
-       map->flags = request.flags;
-       map->mtrr   = -1;
-       map->handle = 0;
-       
-       /* 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 ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
-               DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-               return DRM_ERR(EINVAL);
-       }
-       DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-                  map->offset, map->size, map->type );
-       if ( (map->offset & PAGE_MASK) || (map->size & PAGE_MASK) ) {
-               DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-               return DRM_ERR(EINVAL);
-       }
-
-       switch ( map->type ) {
-       case _DRM_REGISTERS:
-       case _DRM_FRAME_BUFFER:
-               if ( map->offset + map->size < map->offset ) {
-                       DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-                       return DRM_ERR(EINVAL);
-               }
-#if __REALLY_HAVE_MTRR
-               if ( map->type == _DRM_FRAME_BUFFER ||
-                    (map->flags & _DRM_WRITE_COMBINING) ) {
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-                       int retcode = 0, act;
-                       struct mem_range_desc mrdesc;
-                       mrdesc.mr_base = map->offset;
-                       mrdesc.mr_len = map->size;
-                       mrdesc.mr_flags = MDF_WRITECOMBINE;
-                       act = MEMRANGE_SET_UPDATE;
-                       bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME));
-                       retcode = mem_range_attr_set(&mrdesc, &act);
-                       map->mtrr=1;
-#elif defined __NetBSD__
-                       struct mtrr mtrrmap;
-                       int one = 1;
-                       mtrrmap.base = map->offset;
-                       mtrrmap.len = map->size;
-                       mtrrmap.type = MTRR_TYPE_WC;
-                       mtrrmap.flags = MTRR_VALID;
-                       map->mtrr = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL );
-#endif
-               }
-#endif /* __REALLY_HAVE_MTRR */
-               DRM_IOREMAP(map);
-               break;
-
-       case _DRM_SHM:
-               map->handle = (void *)DRM(alloc)(map->size, DRM_MEM_SAREA);
-               DRM_DEBUG( "%ld %d %p\n",
-                          map->size, DRM(order)( map->size ), map->handle );
-               if ( !map->handle ) {
-                       DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-                       return DRM_ERR(ENOMEM);
-               }
-               map->offset = (unsigned long)map->handle;
-               if ( map->flags & _DRM_CONTAINS_LOCK ) {
-                       dev->lock.hw_lock = map->handle; /* Pointer to lock */
-               }
-               break;
-#if __REALLY_HAVE_AGP
-       case _DRM_AGP:
-               map->offset += dev->agp->base;
-               map->mtrr   = dev->agp->agp_mtrr; /* for getmap */
-               break;
-#endif
-       case _DRM_SCATTER_GATHER:
-               if (!dev->sg) {
-                       DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-                       return DRM_ERR(EINVAL);
-               }
-               map->offset = map->offset + dev->sg->handle;
-               break;
-
-       default:
-               DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-               return DRM_ERR(EINVAL);
-       }
-
-       list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
-       if(!list) {
-               DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-               return DRM_ERR(EINVAL);
-       }
-       memset(list, 0, sizeof(*list));
-       list->map = map;
-
-       DRM_LOCK;
-       TAILQ_INSERT_TAIL(dev->maplist, list, link);
-       DRM_UNLOCK;
-
-       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;
-}
-
-
-/* Remove a map private from list and deallocate resources if the mapping
- * isn't in use.
- */
-
-int DRM(rmmap)( DRM_IOCTL_ARGS )
-{
-       DRM_DEVICE;
-       drm_map_list_entry_t *list;
-       drm_local_map_t *map;
-       drm_map_t request;
-       int found_maps = 0;
-
-       DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(request) );
-
-       DRM_LOCK;
-       TAILQ_FOREACH(list, dev->maplist, link) {
-               map = list->map;
-               if(map->handle == request.handle &&
-                  map->flags & _DRM_REMOVABLE) break;
-       }
-
-       /* List has wrapped around to the head pointer, or its empty we didn't
-        * find anything.
-        */
-       if(list == NULL) {
-               DRM_UNLOCK;
-               return DRM_ERR(EINVAL);
-       }
-       TAILQ_REMOVE(dev->maplist, list, link);
-       DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
-
-
-       if(!found_maps) {
-               switch (map->type) {
-               case _DRM_REGISTERS:
-               case _DRM_FRAME_BUFFER:
-#if __REALLY_HAVE_MTRR
-                       if (map->mtrr >= 0) {
-                               int retcode;
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-                               int act;
-                               struct mem_range_desc mrdesc;
-                               mrdesc.mr_base = map->offset;
-                               mrdesc.mr_len = map->size;
-                               mrdesc.mr_flags = MDF_WRITECOMBINE;
-                               act = MEMRANGE_SET_REMOVE;
-                               bcopy(DRIVER_NAME, &mrdesc.mr_owner, strlen(DRIVER_NAME));
-                               retcode = mem_range_attr_set(&mrdesc, &act);
-#elif defined __NetBSD__
-                               struct mtrr mtrrmap;
-                               int one = 1;
-                               mtrrmap.base = map->offset;
-                               mtrrmap.len = map->size;
-                               mtrrmap.type = 0;
-                               mtrrmap.flags = 0;
-                               mtrrmap.owner = p->p_pid;
-                               retcode = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL);
-                               DRM_DEBUG("mtrr_del = %d\n", retcode);
-#endif
-                       }
-#endif
-                       DRM(ioremapfree)( map );
-                       break;
-               case _DRM_SHM:
-                       DRM(free)( map->handle, map->size, DRM_MEM_SAREA );
-                       break;
-               case _DRM_AGP:
-               case _DRM_SCATTER_GATHER:
-                       break;
-               }
-               DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-       }
-       DRM_UNLOCK;
-       return 0;
-}
-
-#if __HAVE_DMA
-
-
-static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
-{
-       int i;
-
-       if (entry->seg_count) {
-               for (i = 0; i < entry->seg_count; i++) {
-                       DRM(free)((void *)entry->seglist[i],
-                                       entry->buf_size,
-                                       DRM_MEM_DMA);
-               }
-               DRM(free)(entry->seglist,
-                         entry->seg_count *
-                         sizeof(*entry->seglist),
-                         DRM_MEM_SEGS);
-
-               entry->seg_count = 0;
-       }
-
-       if(entry->buf_count) {
-               for(i = 0; i < entry->buf_count; i++) {
-                       if(entry->buflist[i].dev_private) {
-                               DRM(free)(entry->buflist[i].dev_private,
-                                         entry->buflist[i].dev_priv_size,
-                                         DRM_MEM_BUFS);
-                       }
-               }
-               DRM(free)(entry->buflist,
-                         entry->buf_count *
-                         sizeof(*entry->buflist),
-                         DRM_MEM_BUFS);
-
-               entry->buf_count = 0;
-       }
-}
-
-#if __REALLY_HAVE_AGP
-static int DRM(addbufs_agp)(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 = 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 );
-
-       if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) 
-               return DRM_ERR(EINVAL);
-
-       DRM_LOCK;
-       entry = &dma->bufs[order];
-       if ( entry->buf_count ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM); /* May only call once for each order */
-       }
-
-       entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-                                   DRM_MEM_BUFS );
-       if ( !entry->buflist ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM);
-       }
-       memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-       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 = sizeof(DRIVER_BUF_PRIV_T);
-               buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
-                                              DRM_MEM_BUFS );
-               if(!buf->dev_private) {
-                       /* Set count correctly so we free the proper amount. */
-                       entry->buf_count = count;
-                       DRM(cleanup_buf_error)(entry);
-               }
-               memset( buf->dev_private, 0, buf->dev_priv_size );
-
-               offset += alignment;
-               entry->buf_count++;
-               byte_count += PAGE_SIZE << page_order;
-       }
-
-       DRM_DEBUG( "byte_count: %d\n", byte_count );
-
-       temp_buflist = DRM(realloc)( dma->buflist,
-                                    dma->buf_count * sizeof(*dma->buflist),
-                                    (dma->buf_count + entry->buf_count)
-                                    * sizeof(*dma->buflist),
-                                    DRM_MEM_BUFS );
-       if(!temp_buflist) {
-               /* Free the entry because it isn't valid */
-               DRM(cleanup_buf_error)(entry);
-               DRM_UNLOCK;
-               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 );
-
-       DRM_UNLOCK;
-
-       request->count = entry->buf_count;
-       request->size = size;
-
-       dma->flags = _DRM_DMA_USE_AGP;
-
-       return 0;
-}
-#endif /* __REALLY_HAVE_AGP */
-
-#if __HAVE_PCI_DMA
-static int DRM(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;
-       unsigned long page;
-       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 );
-
-       if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) 
-               return DRM_ERR(EINVAL);
-
-       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;
-
-       DRM_LOCK;
-       entry = &dma->bufs[order];
-       if ( entry->buf_count ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM); /* May only call once for each order */
-       }
-
-       entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-                                   DRM_MEM_BUFS );
-       if ( !entry->buflist ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM);
-       }
-       memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-       entry->seglist = DRM(alloc)( count * sizeof(*entry->seglist),
-                                   DRM_MEM_SEGS );
-       if ( !entry->seglist ) {
-               DRM(free)( entry->buflist,
-                         count * sizeof(*entry->buflist),
-                         DRM_MEM_BUFS );
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM);
-       }
-       memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
-
-       temp_pagelist = DRM(realloc)( dma->pagelist,
-                                     dma->page_count * sizeof(*dma->pagelist),
-                                     (dma->page_count + (count << page_order))
-                                     * sizeof(*dma->pagelist),
-                                     DRM_MEM_PAGES );
-       if(!temp_pagelist) {
-               DRM(free)( entry->buflist,
-                          count * sizeof(*entry->buflist),
-                          DRM_MEM_BUFS );
-               DRM(free)( entry->seglist,
-                          count * sizeof(*entry->seglist),
-                          DRM_MEM_SEGS );
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM);
-       }
-
-       dma->pagelist = temp_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 ) {
-               page = (unsigned long)DRM(alloc)( size, DRM_MEM_DMA );
-               if ( !page ) break;
-               entry->seglist[entry->seg_count++] = page;
-               for ( i = 0 ; i < (1 << page_order) ; i++ ) {
-                       DRM_DEBUG( "page %d @ 0x%08lx\n",
-                                  dma->page_count + page_count,
-                                  page + PAGE_SIZE * i );
-                       dma->pagelist[dma->page_count + page_count++]
-                               = page + 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 = (void *)(page + offset);
-                       buf->next    = NULL;
-                       buf->pending = 0;
-                       buf->filp    = NULL;
-                       DRM_DEBUG( "buffer %d @ %p\n",
-                                  entry->buf_count, buf->address );
-               }
-               byte_count += PAGE_SIZE << page_order;
-       }
-
-       temp_buflist = DRM(realloc)( dma->buflist,
-                                    dma->buf_count * sizeof(*dma->buflist),
-                                    (dma->buf_count + entry->buf_count)
-                                    * sizeof(*dma->buflist),
-                                    DRM_MEM_BUFS );
-       if(!temp_buflist) {
-               /* Free the entry because it isn't valid */
-               DRM(cleanup_buf_error)(entry);
-               DRM_UNLOCK;
-               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->seg_count += entry->seg_count;
-       dma->page_count += entry->seg_count << page_order;
-       dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-
-       DRM_UNLOCK;
-
-       request->count = entry->buf_count;
-       request->size = size;
-
-       return 0;
-
-}
-#endif /* __HAVE_PCI_DMA */
-
-#if __REALLY_HAVE_SG
-static int DRM(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 );
-
-       if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) 
-               return DRM_ERR(EINVAL);
-
-       DRM_LOCK;
-       entry = &dma->bufs[order];
-       if ( entry->buf_count ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM); /* May only call once for each order */
-       }
-
-       entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-                                    DRM_MEM_BUFS );
-       if ( !entry->buflist ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM);
-       }
-       memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-       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 = sizeof(DRIVER_BUF_PRIV_T);
-               buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
-                                              DRM_MEM_BUFS );
-               if(!buf->dev_private) {
-                       /* Set count correctly so we free the proper amount. */
-                       entry->buf_count = count;
-                       DRM(cleanup_buf_error)(entry);
-                       DRM_UNLOCK;
-                       return DRM_ERR(ENOMEM);
-               }
-
-               memset( buf->dev_private, 0, buf->dev_priv_size );
-
-               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 = DRM(realloc)( dma->buflist,
-                                    dma->buf_count * sizeof(*dma->buflist),
-                                    (dma->buf_count + entry->buf_count)
-                                    * sizeof(*dma->buflist),
-                                    DRM_MEM_BUFS );
-       if(!temp_buflist) {
-               /* Free the entry because it isn't valid */
-               DRM(cleanup_buf_error)(entry);
-               DRM_UNLOCK;
-               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 );
-
-       DRM_UNLOCK;
-
-       request->count = entry->buf_count;
-       request->size = size;
-
-       dma->flags = _DRM_DMA_USE_SG;
-
-       return 0;
-}
-#endif /* __REALLY_HAVE_SG */
-
-int DRM(addbufs)( 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 (dev->dma == NULL)
-               return DRM_ERR(EINVAL);
-
-       if (request.count < 0 || request.count > 4096)
-               return DRM_ERR(EINVAL);
-
-       DRM_SPINLOCK(&dev->count_lock);
-       if (dev->buf_use) {
-               DRM_SPINUNLOCK(&dev->count_lock);
-               return DRM_ERR(EBUSY);
-       }
-       /* dev->buf_alloc acts as a lock to prevent infobufs/mapbufs from
-        * trying to read from the dma->bufs while buffers are being allocated */
-       dev->buf_alloc++;
-       DRM_SPINUNLOCK(&dev->count_lock);
-
-
-#if __REALLY_HAVE_AGP
-       if ( request.flags & _DRM_AGP_BUFFER )
-               err = DRM(addbufs_agp)(dev, &request);
-       else
-#endif
-#if __REALLY_HAVE_SG
-       if ( request.flags & _DRM_SG_BUFFER )
-               err = DRM(addbufs_sg)(dev, &request);
-       else
-#endif
-#if __HAVE_PCI_DMA
-               err = DRM(addbufs_pci)(dev, &request);
-#else
-               err = DRM_ERR(EINVAL);
-#endif
-
-       DRM_COPY_TO_USER_IOCTL((drm_buf_desc_t *)data, request, sizeof(request));
-
-       DRM_SPINLOCK(&dev->count_lock);
-       dev->buf_alloc--;
-       DRM_SPINUNLOCK(&dev->count_lock);
-
-       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;
-
-       if ( !dma ) return DRM_ERR(EINVAL);
-
-       DRM_SPINLOCK( &dev->count_lock );
-       if (dev->buf_alloc != 0) {
-               DRM_SPINUNLOCK( &dev->count_lock );
-               return DRM_ERR(EBUSY);
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       DRM_SPINUNLOCK( &dev->count_lock );
-
-       DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_info_t *)data, sizeof(request) );
-
-       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)
-                                       return DRM_ERR(EFAULT);
-
-                               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 0;
-}
-
-int DRM(markbufs)( DRM_IOCTL_ARGS )
-{
-       DRM_DEVICE;
-       drm_device_dma_t *dma = dev->dma;
-       drm_buf_desc_t request;
-       int order;
-       drm_buf_entry_t *entry;
-
-       if ( !dma ) return DRM_ERR(EINVAL);
-
-       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 ) 
-               return DRM_ERR(EINVAL);
-       entry = &dma->bufs[order];
-
-       if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
-               return DRM_ERR(EINVAL);
-       if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
-               return DRM_ERR(EINVAL);
-
-       entry->freelist.low_mark  = request.low_mark;
-       entry->freelist.high_mark = request.high_mark;
-
-       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;
-
-       if ( !dma ) return DRM_ERR(EINVAL);
-
-       DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_free_t *)data, sizeof(request) );
-
-       DRM_DEBUG( "%d\n", request.count );
-       for ( i = 0 ; i < request.count ; i++ ) {
-               if ( DRM_COPY_FROM_USER( &idx,
-                                    &request.list[i],
-                                    sizeof(idx) ) )
-                       return DRM_ERR(EFAULT);
-               if ( idx < 0 || idx >= dma->buf_count ) {
-                       DRM_ERROR( "Index %d (of %d max)\n",
-                                  idx, dma->buf_count - 1 );
-                       return DRM_ERR(EINVAL);
-               }
-               buf = dma->buflist[idx];
-               if ( buf->filp != filp ) {
-                       DRM_ERROR("Process %d freeing buffer not owned\n",
-                                  DRM_CURRENTPID);
-                       return DRM_ERR(EINVAL);
-               }
-               DRM(free_buffer)( dev, buf );
-       }
-
-       return 0;
-}
-
-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 virtual, address;
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-       struct vmspace *vms = p->td_proc->p_vmspace;
-#endif /* __FreeBSD__ */
-#ifdef __NetBSD__
-       struct vnode *vn;
-       struct vmspace *vms = p->p_vmspace;
-#endif /* __NetBSD__ */
-
-       drm_buf_map_t request;
-       int i;
-
-       if ( !dma ) return DRM_ERR(EINVAL);
-
-       DRM_SPINLOCK( &dev->count_lock );
-       if (dev->buf_alloc != 0) {
-               DRM_SPINUNLOCK( &dev->count_lock );
-               return DRM_ERR(EBUSY);
-       }
-       dev->buf_use++;         /* Can't allocate more after this call */
-       DRM_SPINUNLOCK( &dev->count_lock );
-
-       DRM_COPY_FROM_USER_IOCTL( request, (drm_buf_map_t *)data, sizeof(request) );
-
-#ifdef __NetBSD__
-       if(!vfinddev(kdev, VCHR, &vn))
-               return 0;       /* FIXME: Shouldn't this be EINVAL or something? */
-#endif /* __NetBSD__ */
-
-       if ( request.count >= dma->buf_count ) {
-               if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
-                    (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
-                       drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
-
-                       if ( !map ) {
-                               retcode = EINVAL;
-                               goto done;
-                       }
-
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-                       virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ);
-                       retcode = vm_mmap(&vms->vm_map,
-                                         &virtual,
-                                         round_page(map->size),
-                                         PROT_READ|PROT_WRITE, VM_PROT_ALL,
-                                         MAP_SHARED,
-                                         SLIST_FIRST(&kdev->si_hlist),
-                                         (unsigned long)map->offset );
-#elif defined(__NetBSD__)
-                       virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
-                       retcode = uvm_mmap(&vms->vm_map,
-                                          (vaddr_t *)&virtual,
-                                          round_page(map->size),
-                                          UVM_PROT_READ | UVM_PROT_WRITE,
-                                          UVM_PROT_ALL, MAP_SHARED,
-                                          &vn->v_uobj, map->offset,
-                                          p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
-#endif /* __NetBSD__ */
-               } else {
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-                       virtual = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ);
-                       retcode = vm_mmap(&vms->vm_map,
-                                         &virtual,
-                                         round_page(dma->byte_count),
-                                         PROT_READ|PROT_WRITE, VM_PROT_ALL,
-                                         MAP_SHARED,
-                                         SLIST_FIRST(&kdev->si_hlist),
-                                         0);
-#elif defined(__NetBSD__)
-                       virtual = round_page((vaddr_t)vms->vm_daddr + MAXDSIZ);
-                       retcode = uvm_mmap(&vms->vm_map,
-                                          (vaddr_t *)&virtual,
-                                          round_page(dma->byte_count),
-                                          UVM_PROT_READ | UVM_PROT_WRITE,
-                                          UVM_PROT_ALL, MAP_SHARED,
-                                          &vn->v_uobj, 0,
-                                          p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
-#endif /* __NetBSD__ */
-               }
-               if (retcode)
-                       goto done;
-               request.virtual = (void *)virtual;
-
-               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 = virtual + 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);
-}
-
-#endif /* __HAVE_DMA */
-
diff --git a/sys/dev/drm/drm_context.c b/sys/dev/drm/drm_context.c
new file mode 100644 (file)
index 0000000..2319bc7
--- /dev/null
@@ -0,0 +1,316 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/drm_context.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file drm_context.c
+ * Implementation of the context management ioctls.
+ */
+
+#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 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_device_t *dev, void *data, struct drm_file *file_priv )
+{
+       drm_ctx_priv_map_t *request = data;
+       drm_local_map_t *map;
+
+       DRM_LOCK();
+       if (dev->max_context < 0 ||
+           request->ctx_id >= (unsigned) dev->max_context) {
+               DRM_UNLOCK();
+               return EINVAL;
+       }
+
+       map = dev->context_sareas[request->ctx_id];
+       DRM_UNLOCK();
+
+       request->handle = map->handle;
+
+       return 0;
+}
+
+int drm_setsareactx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_priv_map_t *request = data;
+       drm_local_map_t *map = NULL;
+
+       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 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 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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_res_t *res = data;
+       drm_ctx_t ctx;
+       int i;
+
+       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 EFAULT;
+               }
+       }
+       res->count = DRM_RESERVED_CONTEXTS;
+
+       return 0;
+}
+
+int drm_addctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_t *ctx = data;
+
+       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 ENOMEM;
+       }
+
+       if (dev->driver.context_ctor && ctx->handle != DRM_KERNEL_CONTEXT) {
+               DRM_LOCK();
+               dev->driver.context_ctor(dev, ctx->handle);
+               DRM_UNLOCK();
+       }
+
+       return 0;
+}
+
+int drm_modctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       /* This does nothing */
+       return 0;
+}
+
+int drm_getctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_t *ctx = data;
+
+       /* This is 0, because we don't handle any context flags */
+       ctx->flags = 0;
+
+       return 0;
+}
+
+int drm_switchctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_t *ctx = data;
+
+       DRM_DEBUG( "%d\n", ctx->handle );
+       return drm_context_switch(dev, dev->last_context, ctx->handle);
+}
+
+int drm_newctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_t *ctx = data;
+
+       DRM_DEBUG( "%d\n", ctx->handle );
+       drm_context_switch_complete(dev, ctx->handle);
+
+       return 0;
+}
+
+int drm_rmctx(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_ctx_t *ctx = data;
+
+       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/sys/dev/drm/drm_context.h b/sys/dev/drm/drm_context.h
deleted file mode 100644 (file)
index be6e8e6..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/* 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>
- * $FreeBSD: src/sys/dev/drm/drm_context.h,v 1.4.2.1 2003/04/26 07:05:28 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/drm_context.h,v 1.2 2003/06/17 04:28:24 dillon Exp $
- */
-
-#include "dev/drm/drmP.h"
-
-#if !__HAVE_CTX_BITMAP
-#error "__HAVE_CTX_BITMAP must be defined"
-#endif
-
-/* ================================================================
- * Context bitmap support
- */
-
-void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
-{
-       if ( ctx_handle < 0 ) goto failed;
-       if ( !dev->ctx_bitmap ) goto failed;
-
-       if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
-               DRM_LOCK;
-               clear_bit( ctx_handle, dev->ctx_bitmap );
-               dev->context_sareas[ctx_handle] = NULL;
-               DRM_UNLOCK;
-               return;
-       }
-failed:
-               DRM_ERROR( "Attempt to free invalid context handle: %d\n",
-                  ctx_handle );
-               return;
-}
-
-int DRM(ctxbitmap_next)( drm_device_t *dev )
-{
-       int bit;
-
-       if(!dev->ctx_bitmap) return -1;
-
-       DRM_LOCK;
-       bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
-       if ( bit < DRM_MAX_CTXBITMAP ) {
-               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) {
-                               drm_local_map_t **ctx_sareas;
-
-                               ctx_sareas = DRM(realloc)(dev->context_sareas,
-                                               (dev->max_context - 1) * 
-                                               sizeof(*dev->context_sareas),
-                                               dev->max_context * 
-                                               sizeof(*dev->context_sareas),
-                                               DRM_MEM_MAPS);
-                               if(!ctx_sareas) {
-                                       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 = DRM(alloc)(
-                                               dev->max_context * 
-                                               sizeof(*dev->context_sareas),
-                                               DRM_MEM_MAPS);
-                               if(!dev->context_sareas) {
-                                       clear_bit(bit, dev->ctx_bitmap);
-                                       DRM_UNLOCK;
-                                       return -1;
-                               }
-                               dev->context_sareas[bit] = NULL;
-                       }
-               }
-               DRM_UNLOCK;
-               return bit;
-       }
-       DRM_UNLOCK;
-       return -1;
-}
-
-int DRM(ctxbitmap_init)( drm_device_t *dev )
-{
-       int i;
-       int temp;
-
-       DRM_LOCK;
-       dev->ctx_bitmap = (atomic_t *) DRM(alloc)( PAGE_SIZE,
-                                                       DRM_MEM_CTXBITMAP );
-       if ( dev->ctx_bitmap == NULL ) {
-               DRM_UNLOCK;
-               return DRM_ERR(ENOMEM);
-       }
-       memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
-       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 ) DRM(free)( dev->context_sareas,
-                                            sizeof(*dev->context_sareas) * 
-                                            dev->max_context,
-                                            DRM_MEM_MAPS );
-       DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
-       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_map_list_entry_t *list;
-
-       DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
-                          sizeof(request) );
-
-       DRM_LOCK;
-       TAILQ_FOREACH(list, dev->maplist, link) {
-               map=list->map;
-               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 ) {
-               memset( &ctx, 0, sizeof(ctx) );
-               for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
-                       ctx.handle = i;
-                       if ( DRM_COPY_TO_USER( &res.contexts[i],
-                                          &i, sizeof(i) ) )
-                               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);
-       }
-
-       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 ) {
-               DRM(ctxbitmap_free)( dev, ctx.handle );
-       }
-
-       return 0;
-}
diff --git a/sys/dev/drm/drm_dma.c b/sys/dev/drm/drm_dma.c
new file mode 100644 (file)
index 0000000..82dff2f
--- /dev/null
@@ -0,0 +1,136 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/drm_dma.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file drm_dma.c
+ * Support code for DMA buffer management.
+ *
+ * The implementation used to be significantly more complicated, but the
+ * complexity has been moved into the drivers as different buffer management
+ * schemes evolved.
+ */
+
+#include "drmP.h"
+
+int drm_dma_setup(drm_device_t *dev)
+{
+
+       dev->dma = malloc(sizeof(*dev->dma), M_DRM, M_NOWAIT | M_ZERO);
+       if (dev->dma == NULL)
+               return 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->file_priv= NULL;
+       buf->used     = 0;
+}
+
+void drm_reclaim_buffers(drm_device_t *dev, struct drm_file *file_priv)
+{
+       drm_device_dma_t *dma = dev->dma;
+       int              i;
+
+       if (!dma) return;
+       for (i = 0; i < dma->buf_count; i++) {
+               if (dma->buflist[i]->file_priv == file_priv) {
+                       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_device_t *dev, void *data, struct drm_file *file_priv)
+{
+
+       if (dev->driver.dma_ioctl) {
+               /* shared code returns -errno */
+               return -dev->driver.dma_ioctl(dev, data, file_priv);
+       } else {
+               DRM_DEBUG("DMA ioctl on driver with no dma handler\n");
+               return EINVAL;
+       }
+}
diff --git a/sys/dev/drm/drm_dma.h b/sys/dev/drm/drm_dma.h
deleted file mode 100644 (file)
index a066fb6..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/* 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>
- *
- * $FreeBSD: src/sys/dev/drm/drm_dma.h,v 1.5.2.1 2003/04/26 07:05:28 anholt Exp $
- * $DragonFly: src/sys/dev/drm/Attic/drm_dma.h,v 1.8 2006/09/03 18:29:15 dillon Exp $
- */
-
-#include "dev/drm/drmP.h"
-
-#ifndef __HAVE_DMA_WAITQUEUE
-#define __HAVE_DMA_WAITQUEUE   0
-#endif
-#ifndef __HAVE_DMA_RECLAIM
-#define __HAVE_DMA_RECLAIM     0
-#endif
-#ifndef __HAVE_SHARED_IRQ
-#define __HAVE_SHARED_IRQ      0
-#endif
-
-#if __HAVE_DMA
-
-int DRM(dma_setup)( drm_device_t *dev )
-{
-       int i;
-
-       dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER );
-       if ( !dev->dma )
-               return DRM_ERR(ENOMEM);
-
-       memset( dev->dma, 0, sizeof(*dev->dma) );
-
-       for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
-               memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
-
-       return 0;
-}
-
-void DRM(dma_takedown)(drm_device_t *dev)
-{
-       drm_device_dma_t  *dma = dev->dma;
-       int               i, j;
-
-       if (!dma) 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(free)((void *)dma->bufs[i].seglist[j],
-                                               dma->bufs[i].buf_size,
-                                               DRM_MEM_DMA);
-                       }
-                       DRM(free)(dma->bufs[i].seglist,
-                                 dma->bufs[i].seg_count
-                                 * sizeof(*dma->bufs[0].seglist),
-                                 DRM_MEM_SEGS);
-               }
-               if(dma->bufs[i].buf_count) {
-                       for(j = 0; j < dma->bufs[i].buf_count; j++) {
-                          if(dma->bufs[i].buflist[j].dev_private) {
-                             DRM(free)(dma->bufs[i].buflist[j].dev_private,
-                                       dma->bufs[i].buflist[j].dev_priv_size,
-                                       DRM_MEM_BUFS);
-                          }
-                       }
-                       DRM(free)(dma->bufs[i].buflist,
-                                 dma->bufs[i].buf_count *
-                                 sizeof(*dma->bufs[0].buflist),
-                                 DRM_MEM_BUFS);
-               }
-       }
-
-       if (dma->buflist) {
-               DRM(free)(dma->buflist,
-                         dma->buf_count * sizeof(*dma->buflist),
-                         DRM_MEM_BUFS);
-       }
-
-       if (dma->pagelist) {
-               DRM(free)(dma->pagelist,
-                         dma->page_count * sizeof(*dma->pagelist),
-                         DRM_MEM_PAGES);
-       }
-       DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
-       dev->dma = NULL;
-}
-
-
-void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
-{
-       if (!buf) return;
-
-       buf->pending  = 0;
-       buf->filp     = NULL;
-       buf->used     = 0;
-}
-
-#if !__HAVE_DMA_RECLAIM
-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;
-                       }
-               }
-       }
-}
-#endif
-
-
-#if __HAVE_DMA_IRQ
-
-int DRM(irq_install)( drm_device_t *dev, int irq )
-{
-       int retcode;
-
-       if ( !irq )
-               return DRM_ERR(EINVAL);
-
-       DRM_LOCK;
-       if ( dev->irq ) {
-               DRM_UNLOCK;
-               return DRM_ERR(EBUSY);
-       }
-       dev->irq = irq;
-       DRM_UNLOCK;
-
-       DRM_DEBUG( "%s: irq=%d\n", __func__, irq );
-
-       dev->context_flag = 0;
-
-       dev->dma->next_buffer = NULL;
-       dev->dma->this_buffer = NULL;
-
-#if __HAVE_DMA_IRQ_BH
-       TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev);
-#endif
-
-#if __HAVE_VBL_IRQ && 0 /* disabled */
-       DRM_SPININIT( dev->vbl_lock, "vblsig" );
-       TAILQ_INIT( &dev->vbl_sig_list );
-#endif
-
-                               /* Before installing handler */
-       DRM(driver_irq_preinstall)( dev );
-
-                               /* Install handler */
-       dev->irqrid = 0;
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-       dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid,
-                                     0, ~0, 1, RF_SHAREABLE);
-       if (!dev->irqr) {
-#elif defined(__NetBSD__)
-       if (pci_intr_map(&dev->pa, &dev->ih) != 0) {
-#endif
-               DRM_LOCK;
-               dev->irq = 0;
-               dev->irqrid = 0;
-               DRM_UNLOCK;
-               return ENOENT;
-       }
-       
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
-       retcode = bus_setup_intr(dev->device, dev->irqr, 0,
-                                DRM(dma_service), dev, &dev->irqh, NULL);
-#else
-       retcode = bus_setup_intr(dev->device, dev->irqr, INTR_MPSAFE,
-                                DRM(dma_service), dev, &dev->irqh, NULL);
-#endif
-       if ( retcode ) {
-#elif defined(__NetBSD__)
-       dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY,
-                                     (int (*)(DRM_IRQ_ARGS))DRM(dma_service), dev);
-       if ( !dev->irqh ) {
-#endif
-               DRM_LOCK;
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-               bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr);
-#endif
-               dev->irq = 0;
-               dev->irqrid = 0;
-               DRM_UNLOCK;
-               return retcode;
-       }
-
-                               /* After installing handler */
-       DRM(driver_irq_postinstall)( dev );
-
-       return 0;
-}
-
-int DRM(irq_uninstall)( drm_device_t *dev )
-{
-       int irq;
-       int irqrid;
-       
-       DRM_LOCK;
-       irq = dev->irq;
-       irqrid = dev->irqrid;
-       dev->irq = 0;
-       dev->irqrid = 0;
-       DRM_UNLOCK;
-
-       if ( !irq )
-               return DRM_ERR(EINVAL);
-
-       DRM_DEBUG( "%s: irq=%d\n", __func__, irq );
-
-       DRM(driver_irq_uninstall)( dev );
-
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-       bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
-       bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
-#elif defined(__NetBSD__)
-       pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
-#endif
-
-       return 0;
-}
-
-int DRM(control)( DRM_IOCTL_ARGS )
-{
-       DRM_DEVICE;
-       drm_control_t ctl;
-
-       DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
-
-       switch ( ctl.func ) {
-       case DRM_INST_HANDLER:
-               return DRM(irq_install)( dev, ctl.irq );
-       case DRM_UNINST_HANDLER:
-               return DRM(irq_uninstall)( dev );
-       default:
-               return DRM_ERR(EINVAL);
-       }
-}
-
-#if __HAVE_VBL_IRQ
-int DRM(wait_vblank)( DRM_IOCTL_ARGS )
-{
-       DRM_DEVICE;
-       drm_wait_vblank_t vblwait;
-       struct timeval now;
-       int ret;
-
-       if (!dev->irq)
-               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 = DRM_MALLOC(sizeof(drm_vbl_sig_t));
-               if (vbl_sig == NULL)
-                       return ENOMEM;
-               bzero(vbl_sig, sizeof(*vbl_sig));
-               
-               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->vbl_lock);
-               TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
-               DRM_SPINUNLOCK(&dev->vbl_lock);
-               ret = 0;
-#endif
-               ret = EINVAL;
-       } else {
-               ret = DRM(vblank_wait)(dev, &vblwait.request.sequence);
-               
-               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;
-
-       DRM_SPINLOCK(&dev->vbl_lock);
-
-loop:
-       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)
-                               ksignal(p, vbl_sig->signo);
-
-                       TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
-                       DRM_SPINUNLOCK(&dev->vbl_lock);
-                       DRM_FREE(vbl_sig,sizeof(*vbl_sig));
-                       goto loop;
-               }
-               vbl_sig = next;
-       }
-
-       DRM_SPINUNLOCK(&dev->vbl_lock);
-}
-#endif
-
-#endif /*  __HAVE_VBL_IRQ */
-
-#else
-
-int DRM(control)( DRM_IOCTL_ARGS )
-{
-       drm_control_t ctl;
-
-       DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
-
-       switch ( ctl.func ) {
-       case DRM_INST_HANDLER:
-       case DRM_UNINST_HANDLER:
-               return 0;
-       default:
-               return DRM_ERR(EINVAL);
-       }
-}
-
-#endif /* __HAVE_DMA_IRQ */
-
-#endif /* __HAVE_DMA */
-
diff --git a/sys/dev/drm/drm_drawable.c b/sys/dev/drm/drm_drawable.c
new file mode 100644 (file)
index 0000000..c525a67
--- /dev/null
@@ -0,0 +1,161 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/drm_drawable.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file drm_drawable.c
+ * This file implements ioctls to store information along with DRM drawables,
+ * such as the current set of cliprects for vblank-synced buffer swaps.
+ */
+
+#include "drmP.h"
+
+struct bsd_drm_drawable_info {
+       struct drm_drawable_info info;
+       int handle;
+       RB_ENTRY(bsd_drm_drawable_info) tree;
+};
+
+static int
+drm_drawable_compare(struct bsd_drm_drawable_info *a,
+    struct bsd_drm_drawable_info *b)
+{
+       if (a->handle > b->handle)
+               return 1;
+       if (a->handle < b->handle)
+               return -1;
+       return 0;
+}
+RB_PROTOTYPE_STATIC(drawable_tree, bsd_drm_drawable_info, tree,
+    drm_drawable_compare);
+RB_GENERATE_STATIC(drawable_tree, bsd_drm_drawable_info, tree,
+    drm_drawable_compare);
+
+struct drm_drawable_info *
+drm_get_drawable_info(drm_device_t *dev, int handle)
+{
+       struct bsd_drm_drawable_info find, *result;
+
+       find.handle = handle;
+       result = RB_FIND(drawable_tree, &dev->drw_head, &find);
+
+       return &result->info;
+}
+
+int drm_adddraw(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_draw_t *draw = data;
+       struct bsd_drm_drawable_info *info;
+
+       info = drm_calloc(1, sizeof(struct bsd_drm_drawable_info),
+           DRM_MEM_DRAWABLE);
+       if (info == NULL)
+               return ENOMEM;
+
+#ifdef __FreeBSD__
+       info->handle = alloc_unr(dev->drw_unrhdr);
+#else
+       /*
+        * XXX Only valid for sizeof(int) == sizeof(void *)
+        */
+       info->handle = (int)info;
+#endif
+       DRM_SPINLOCK(&dev->drw_lock);
+       RB_INSERT(drawable_tree, &dev->drw_head, info);
+       draw->handle = info->handle;
+       DRM_SPINUNLOCK(&dev->drw_lock);
+
+       DRM_DEBUG("%d\n", draw->handle);
+
+       return 0;
+}
+
+int drm_rmdraw(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       drm_draw_t *draw = (drm_draw_t *)data;
+       struct drm_drawable_info *info;
+
+       DRM_SPINLOCK(&dev->drw_lock);
+       info = drm_get_drawable_info(dev, draw->handle);
+       if (info != NULL) {
+               RB_REMOVE(drawable_tree, &dev->drw_head,
+                   (struct bsd_drm_drawable_info *)info);
+               DRM_SPINUNLOCK(&dev->drw_lock);
+#ifdef __FreeBSD__
+               free_unr(dev->drw_unrhdr, draw->handle);
+#endif
+               drm_free(info, sizeof(struct bsd_drm_drawable_info),
+                   DRM_MEM_DRAWABLE);
+               return 0;
+       } else {
+               DRM_SPINUNLOCK(&dev->drw_lock);
+               return EINVAL;
+       }
+}
+
+int drm_update_draw(drm_device_t *dev, void *data, struct drm_file *file_priv)
+{
+       struct drm_drawable_info *info;
+       struct drm_update_draw *update = (struct drm_update_draw *)data;
+       int ret;
+
+       info = drm_get_drawable_info(dev, update->handle);
+       if (info == NULL)
+               return EINVAL;
+
+       switch (update->type) {
+       case DRM_DRAWABLE_CLIPRECTS:
+               DRM_SPINLOCK(&dev->drw_lock);
+               if (update->num != info->num_rects) {
+                       drm_free(info->rects,
+                           sizeof(*info->rects) * info->num_rects,
+                           DRM_MEM_DRAWABLE);
+                       info->rects = NULL;
+                       info->num_rects = 0;
+               }
+               if (update->num == 0) {
+                       DRM_SPINUNLOCK(&dev->drw_lock);
+                       return 0;
+               }
+               if (info->rects == NULL) {
+                       info->rects = drm_alloc(sizeof(*info->rects) *
+                           update->num, DRM_MEM_DRAWABLE);
+                       if (info->rects == NULL)
+                               return ENOMEM;
+                       info->num_rects = update->num;
+               }
+               /* For some reason the pointer arg is unsigned long long. */
+               ret = copyin((void *)(intptr_t)update->data, info->rects,
+                   sizeof(*info->rects) * info->num_rects);
+               DRM_SPINUNLOCK(&dev->drw_lock);
+               return ret;
+       default:
+               return EINVAL;
+       }
+}
diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c
new file mode 100644 (file)
index 0000000..1fc007d
--- /dev/null
@@ -0,0 +1,1046 @@
+/*-
+ * 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>
+ *
+ * $DragonFly: src/sys/dev/drm/drm_drv.c,v 1.1 2008/04/05 18:12:29 hasso Exp $
+ */
+
+/** @file drm_drv.c
+ * The catch-all file for DRM device support, including module setup/teardown,
+ * open/close, and ioctl dispatch.
+ */
+
+#ifdef __DragonFly__
+#include <machine/limits.h>
+#else
+#include <sys/limits.h>
+#endif
+#include "drmP.h"
+#include "drm.h"
+#include "drm_sarea.h"
+
+#ifdef DRM_DEBUG_DEFAULT_ON
+int drm_debug_flag = 1;
+#else
+int drm_debug_flag = 0;
+#endif
+
+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);
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#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__ || __DragonFly__ */
+
+#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_DEF(DRM_IOCTL_VERSION, drm_version, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
+
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+       DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
+
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
+
+       DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DR